【问题标题】:iOS7 issues with NSIBPrototypingLayoutConstraint autolayout constraints generated by Interface BuilderNSIBPrototypingLayoutConstraint 由 Interface Builder 生成的自动布局约束的 iOS7 问题
【发布时间】:2013-09-29 07:22:26
【问题描述】:

以前在 iOS6 中,我的聊天消息视图控制器在 IB 中使用精心构建的自动布局约束正确显示和动画。这是在 Xcode 5 中删除了约束的当前视图层次结构:

在升级到 XCode 5 和 iOS7 后,我发现我需要清除所有旧的约束才能考虑到默认的半透明状态栏,否则我的工具栏会落在状态栏之下。尽管使用 UIRectEdgeNone 调用 setEdgesForExtendedLayout: 还是发生了这种情况。

我现在正尝试在 viewDidLoad 中以编程方式创建所有约束:

// self.view.translatesAutoresizingMaskIntoConstraints = NO; // errors either way
NSArray *viewHorizConstraints = [NSLayoutConstraint constraintsWithVisualFormat:@"H:|[_toolbar]|" options:0 metrics:nil views:NSDictionaryOfVariableBindings(_toolbar)];
[self.view addConstraints:viewHorizConstraints];
viewHorizConstraints = [NSLayoutConstraint constraintsWithVisualFormat:@"H:|[_viewContainer]|" options:0 metrics:nil views:NSDictionaryOfVariableBindings(_viewContainer)];
[self.view addConstraints:viewHorizConstraints];

NSArray *viewVertConstraints = [NSLayoutConstraint constraintsWithVisualFormat:@"V:|-(20)-[_toolbar(44)]-[_viewContainer]|" options:0 metrics:nil views:NSDictionaryOfVariableBindings(_toolbar, _viewContainer)];
[self.view addConstraints:viewVertConstraints];

NSArray *tableContainerVertConstraints = [NSLayoutConstraint constraintsWithVisualFormat:@"V:|[_tableView(<=460@999)][_viewInputContainer(44)]|" options:0 metrics:nil views:NSDictionaryOfVariableBindings(_tableView, _viewInputContainer)];
[_viewTableContainer addConstraints:tableContainerVertConstraints];


NSArray *containerVertConstraints = [NSLayoutConstraint constraintsWithVisualFormat:@"V:|[_viewTableContainer][_viewOptions]" options:0 metrics:nil views:NSDictionaryOfVariableBindings(_viewTableContainer, _viewOptions)];
[_viewContainer addConstraints:containerVertConstraints];

//    _constraintContainerVertSpace = [NSLayoutConstraint constraintWithItem:_viewTableContainer attribute:NSLayoutAttributeTrailing relatedBy:NSLayoutRelationEqual toItem:_viewContainer attribute:NSLayoutAttributeTrailing multiplier:1 constant:0]; // same as below

containerVertConstraints = [NSLayoutConstraint constraintsWithVisualFormat:@"V:[_viewTableContainer]|" options:0 metrics:nil views:NSDictionaryOfVariableBindings(_viewTableContainer)];
_constraintContainerVertSpace = [containerVertConstraints lastObject];
[_viewContainer addConstraint:_constraintContainerVertSpace];

containerVertConstraints = [NSLayoutConstraint constraintsWithVisualFormat:@"V:|-(>=0)-[_viewOptions]-(>=-216@999)-|" options:0 metrics:nil views:NSDictionaryOfVariableBindings(_viewOptions)];
[_viewContainer addConstraints:containerVertConstraints];

但是,如果我尝试更改 containerView 和 tableContainerView 之间的垂直空间约束,则会出现错误。 (我正在尝试调整 tableContainerView 的大小以随着键盘的外观缩小。)

[UIView animateWithDuration:0.25f
                      delay:0
                    options:UIViewAnimationOptionCurveEaseInOut
                 animations:^{
                     _constraintContainerVertSpace.constant = -keyboardHeight;
                 } completion:nil];

这些是不能同时满足的约束:

(
"<NSIBPrototypingLayoutConstraint:0x140d7bb0 'IB auto generated at build time for view with fixed frame' V:|-(460)-[UIView:0x140ddef0]   (Names: '|':UIView:0x140dde60 )>",
"<NSIBPrototypingLayoutConstraint:0x140d7c10 'IB auto generated at build time for view with fixed frame' V:[UIView:0x140ddef0(44)]>",
"<NSLayoutConstraint:0x14d9db30 V:[UIView:0x140ddef0]-(0)-|   (Names: '|':UIView:0x140dde60 )>",
"<NSIBPrototypingLayoutConstraint:0x140e0290 'IB auto generated at build time for view with fixed frame' V:|-(0)-[UIView:0x140dde60]   (Names: '|':UIView:0x140dddd0 )>",
"<NSLayoutConstraint:0x14d9df60 V:[UIView:0x140dde60]-(-216)-|   (Names: '|':UIView:0x140dddd0 )>",
"<NSIBPrototypingLayoutConstraint:0x140e0830 'IB auto generated at build time for view with fixed frame' V:|-(64)-[UIView:0x140dddd0]   (Names: '|':UIView:0x140e0470 )>",
"<NSLayoutConstraint:0x14d9d820 V:[UIView:0x140dddd0]-(0)-|   (Names: '|':UIView:0x140e0470 )>",
"<NSAutoresizingMaskLayoutConstraint:0x1403a0b0 h=--& v=--& V:[UIView:0x140e0470(568)]>"
)

Will attempt to recover by breaking constraint 
<NSLayoutConstraint:0x14d9db30 V:[UIView:0x140ddef0]-(0)-|   (Names: '|':UIView:0x140dde60 )>

UIView:0x140dde60 在这种情况下是 _viewTableContainer。 0x140ddef0 = _viewInputContainer。 0x140dddd0 = _viewContainer。

当我将 translatesAutoresizingMaskIntoConstraints 设置为 NO 并且我已经在 _viewInputContainer 和_tableView 上面呢?

我曾尝试在 Instruments 中使用 Cocoa Layout,但噪音太大,无法理解。

【问题讨论】:

标签: objective-c xcode ios7 autolayout xcode5


【解决方案1】:

除了使用 translatesAutoresizingMaskIntoConstraints 之外,我还必须手动删除视图上的约束。

[_viewContainer removeConstraints:_viewContainer.constraints];
[self.view removeConstraints:self.view.constraints];

添加这些更改后,动画不再出现错误。

【讨论】:

    【解决方案2】:

    为了去除IB生成的NSIBPrototypingLayoutConstraint,可以通过在IB上添加一些虚拟约束来解决,设置remove at build time。然后,IB 不会为您生成 NSIBPrototypingLayoutConstraint

    【讨论】:

    • @smileyborg 给good link。这个问题比较清楚。
    【解决方案3】:

    强制 Swift:

    view.removeConstraints(view.constraints)
    

    或者,如果您想在代码中删除一个特定界面项的约束,您可以只删除一个对象的约束。以下是几个例子:

    myTableView.removeConstraints(myTableView.constraints)
    myButton.removeConstraints(myButton.constraints)
    myImageView.removeConstraints(myImageView.constraints)
    

    例如,如果您要创建应用的付费或免费版本,这可能特别有用。您可以在界面生成器中完成大部分界面布局,然后使用可视格式语言对代码中的布局进行调整。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-03-22
      • 2013-10-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-04-06
      相关资源
      最近更新 更多