1

在一个viewcontroller的视图对应的XIB文件中,在Autolayout开启的情况下,我拖出一个按钮并将其放置在任意位置,这样Interface Builder就会自动在按钮和它的superview之间生成垂直和水平间距约束(即VC的看法)。在视图控制器 .m 文件中,我为这两个约束创建 IBOutlets,并在 viewDidLoad 方法中,将它们从 VC 的视图中移除[self.view removeConstraint:self.vConstraint]等。(不,我没有忘记建立出口连接)

在运行该应用程序时,我希望 Xcode(版本 4.5.1,如果这很重要)会抱怨布局模棱两可,但令人惊讶的是(对我而言),事实并非如此。

那么按钮框架的原点是如何计算的呢?该按钮确实出现在其在 Interface Builder 中放置的位置的超级视图中,但我想确切地知道 Autolayout 在这种情况下正在做什么(最好参考官方文档)。

4

1 回答 1

1

It seems difficult to find exact documentation or other references on this. A look at Florian Kugler's page on the Advanced Auto Layout Toolbox had some great information. As I thought this was an interesting question I did some digging around.

I set up a test project with a UIButton myButton setup in the Xib and a couple of space constraint outlets:

@property (weak, nonatomic) IBOutlet NSLayoutConstraint *hSpaceConstraint;
@property (weak, nonatomic) IBOutlet NSLayoutConstraint *vSpaceConstraint;

As you stated, removing these constraints in viewDidLoad had no effect. Even outputting [self.myButton hasAmbiguousLayout] immediately after removing the constraints in viewDidLoad shows false.

However, by viewDidAppear, things have changed. myButton is correctly flagged as ambiguous by both hasAmbiguousLayout and also by doing an Auto Layout trace in lldb:

(lldb) po [[UIWindow keyWindow] _autolayoutTrace]

*<UIWindow:0x8a94fe0> - AMBIGUOUS LAYOUT
|   *<UIView:0x8c55340>
|   |   *<UIRoundedRectButton:0x8c54100> - AMBIGUOUS LAYOUT
|   |   |   <UIImageView:0x8c54580>
|   |   |   <UIButtonLabel:0x8c595a0>
(lldb)

At this stage, we can also exercise the ambiguity:

- (void)viewDidAppear:(BOOL)animated {
    [super viewDidAppear:animated];
    [self.myButton exerciseAmbiguityInLayout];
}

Without exercising: enter image description here Exercising: enter image description here

There's nothing on the console either. That surprised me as I'm used to Auto Layout splurging a ton of constraint exceptions at the first sign of trouble.

Investigating that, a quick search here on SO revealed that

"ambiguity can be temporarily tolerated (unlike unsatisfiability, which immediately raises an exception)"

So that explains the clear console, at least for now.

To conclude then, I believe that by the time viewDidLoad executes, a measure, layout, and display pass has already occurred. Removing the constraints then renders the view ambiguous. Auto Layout then does the common sense thing on a view that it no longer knows how to layout; nothing. The view remains in situ.

于 2013-12-23T14:49:39.253 回答