iOS:以编程方式更改从 Interface Builder 设置的约束
Posted
技术标签:
【中文标题】iOS:以编程方式更改从 Interface Builder 设置的约束【英文标题】:iOS: programmatically changing constraints set from Interface Builder 【发布时间】:2015-01-16 01:59:57 【问题描述】:朋友们,美好的一天!
我未能尝试通过代码为在 IB 中设置的视图设置动画。应用程序崩溃,原因如下:
视图层次结构没有为约束做好准备...
我在这里看到了一些类似的问题,原因总是以编程方式创建的视图尚未添加到超级视图中。但我在 IB 中创建了所有视图!
控制台还说:
在容器层次结构中找不到视图:(这里是超级视图)
这对我来说没有任何意义,因为实际上它是适当超级视图的子视图,xcode 知道 - 它会立即打印视图层次结构并且它适合。
可能是什么原因? 谢谢!
编辑:我使用的代码:
- (void)setEditingConstraintsForView:(UIView *)view
// Pin given view to top, fix it height
NSDictionary *givenView = @@"view":view;
view.translatesAutoresizingMaskIntoConstraints = NO;
NSArray *horizontalConstraints = [NSLayoutConstraint constraintsWithVisualFormat:@"H:|[view]|" options:0 metrics:nil views:givenView];
NSArray *verticalConstraints = [NSLayoutConstraint constraintsWithVisualFormat:@"V:|[view(height)]" options:0 metrics:@@"height":@(viewHeight) views:givenView];
[self.animatedVIew addSubview:view];
for (NSArray *constraints in @[horizontalConstraints, verticalConstraints])
[view addConstraints:constraints];
我还删除了我在安装新的之前在 IB 中设置的所有约束:
- (NSDictionary *)constraintsFromIB
if (!_constraintsFromIB)
_constraintsFromIB = @@"view1":self.view1.referencingConstraintsInSuperviews,
@"view2":self.view2.referencingConstraintsInSuperviews,
@"view3":self.view3.referencingConstraintsInSuperviews ;
return _constraintsFromIB;
然后:
- (void)updateViewConstraints
[super updateViewConstraints];
// clear all constraints
for (NSString *viewName in self.constraintsFromIB.allKeys)
for (NSLayoutConstraint *constraint in self.constraintsFromIB[viewName])
[constraint remove];
更新 2:我使用调用更改的方法:当用户触摸视图时,调用此方法:
- (void)animateConstraintsForState:(LDYEditingLabel)state
self.editingLabel = state;
[UIView animateWithDuration:0.3 animations:^
[self updateViewConstraints];
[self.view layoutIfNeeded];
];
后来在updateViewConstraints:
有一段代码触发了我的方法setEditingConstraintsForView:(UIView *)view
【问题讨论】:
你能显示一些代码吗? 您从哪个方法调用此代码?viewDidAppear
? viewDidAppear
?还是其他方法?
刚刚添加了另一个编辑。它使用动画块从屏幕上的点击触发。
我看不出您在此处显示的问题。您可能需要设置断点,但我打算建议 Charlie Wu 刚刚在他的答案中添加的内容 - 如果可以的话,修改现有的约束 - 更容易
感谢您的建议。似乎将 IB 和硬编码方法混为一谈并不好。
【参考方案1】:
如果您使用 IB 创建约束,您可以添加约束作为出口。
然后更新约束并调用 [self updateViewConstraints];在动画块中
【讨论】:
感谢您的回答,这肯定会奏效。但是,如果我有很多限制要调整怎么办?我需要视图出现和消失,改变它们在屏幕上的位置等等。我认为如果我为每个约束创建出口 - 视图控制器实现将是一个可怕的混乱 如果您正在使用代码,您不会有代码循环通过视图约束并寻找正确的语气吗?当视图布局发生变化时,维护起来要困难得多。这可能不是最干净的代码,但应该很容易维护和理解【参考方案2】:如果是我,我会将约束连接到 IBOutlets 并修改现有约束。它可能最终会比以编程方式添加和删除它们更容易。
您可能还需要在修改约束后调用setNeedsLayout
。
【讨论】:
感谢您的建议!它工作得很好。但是我之所以尝试以编程方式进行,是因为我有很多改变约束的观点。在某些时候,我需要所有视图从屏幕上消失并显示新视图 - 特别是 datePicker 和几个自定义控件。而且它应该返回到以前的状态。在那种情况下你会怎么做?再次感谢! 我在设置视图时保留了一系列不断变化的约束,因为无论如何您只能更改常量。我继承了 UIVIew 并且对我来说很好。以上是关于iOS:以编程方式更改从 Interface Builder 设置的约束的主要内容,如果未能解决你的问题,请参考以下文章