【问题标题】:iOS: programmatically changing constraints set from Interface BuilderiOS:以编程方式更改从 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 和硬编码方法混为一谈并不好。

标签: ios objective-c autolayout nslayoutconstraint


【解决方案1】:

如果您使用 IB 创建约束,您可以添加约束作为出口。

然后更新约束并调用 [self updateViewConstraints];在动画块中

【讨论】:

  • 感谢您的回答,这肯定会奏效。但是,如果我有很多限制要调整怎么办?我需要视图出现和消失,改变它们在屏幕上的位置等等。我认为如果我为每个约束创建出口 - 视图控制器实现将是一个可怕的混乱
  • 如果您正在使用代码,您不会有代码循环通过视图约束并寻找正确的语气吗?当视图布局发生变化时,维护起来要困难得多。这可能不是最干净的代码,但应该很容易维护和理解
【解决方案2】:

如果是我,我会将约束连接到 IBOutlets 并修改现有约束。它可能最终会比以编程方式添加和删除它们更容易。

您可能还需要在修改约束后调用setNeedsLayout

【讨论】:

  • 感谢您的建议!它工作得很好。但是我之所以尝试以编程方式进行,是因为我有很多改变约束的观点。在某些时候,我需要所有视图从屏幕上消失并显示新视图 - 特别是 datePicker 和几个自定义控件。而且它应该返回到以前的状态。在那种情况下你会怎么做?再次感谢!
  • 我在设置视图时保留了一系列不断变化的约束,因为无论如何您只能更改常量。我继承了 UIVIew 并且对我来说很好。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-04-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-01-22
  • 1970-01-01
相关资源
最近更新 更多