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 设置的约束的主要内容,如果未能解决你的问题,请参考以下文章

以编程方式快速更改设备方向 4 IOS 11 [重复]

在运行中以编程方式更改 iOS7 状态栏颜色?

iOS SDK Interface Builder 的 RGB 滑块产生不同于 UIColor withRGB 的颜色

iOS:以编程方式更改选项卡 - 故事板

如何以编程方式更改 iOS 设备音量?

如何以编程方式更改轮廓按钮图标?