OS X自动布局可防止窗口大小调整

时间:2013-12-27 16:32:16

标签: macos autolayout

其中一个用于自动布局专家:我不明白为什么以下自动布局设置会阻止调整窗口大小。

我有三种观点以这种方式组织:

-----------------
|           |   |
|     F     | S |
|           |   |
-----------------
|     B     |
-------------

S有一个固定的,B有一个固定的高度,F应该总是有S的高度和B的宽度。 这是我在约束条件下设置的:

[self addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|[F(>=100)][S(==100)]|"
                                                             options:0
                                                             metrics:nil
                                                               views:@{ @"F": _f, @"S": _s }]];
[self addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|[F(>=100)][B(==100)]|"
                                                             options:0
                                                             metrics:nil
                                                               views:@{ @"F": _f, @"B": _b }]];
[self addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|[B(==F)]"
                                                             options:0
                                                             metrics:nil
                                                               views:@{ @"B": _b, @"F": _f }]];
[self addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|[S(==F)]"
                                                             options:0
                                                             metrics:nil
                                                               views:@{ @"S": _s, @"F": _f }]];

我看待事物的方式,这应该允许我自由调整窗口大小,F调整大小以填充空间。但约束会完全锁定窗口大小。

知道我做错了吗?

由于

2 个答案:

答案 0 :(得分:2)

我已经多次看到同样的基本问题,因为其中一个视图translatesAutoresizingMaskIntoConstraints属性为YES。

以前这是由Xcode的UI编辑器中的复选框控制的,但在Xcode 6.1.1中,复选框已经消失。但是,对于在代码中创建的视图(例如,WKWebView,它不支持从.xib文件进行实例化),或者对于使用早期版本的Xcode创建的视图,此属性可能设置为YES。

如果是这样,可能会导致自动布局以意外方式运行,通常包括无法调整窗口大小的症状。您已手动配置要使用窗口调整大小的视图,但是自动调整掩码到约束的自动转换可能会添加其他约束,如果窗口增长,则无法同时实现这些约束。

为了说明,请考虑以下方法。这扩展了NSView以添加一个方法,将另一个视图的大小调整为接收器的大小,将其添加为接收器的子视图,并设置自动布局约束,以便子视图随其超级视图(接收器)增长和缩小

但是,我们注意到这里有一个错误,它通常可以正常工作,但有时包含所有视图的窗口将变得无法调整大小。原因是subview.translatesAutoresizingMaskIntoConstraints在某些情况下为YES - 这导致了不必要的额外布局约束,导致窗口无法调整大小。添加倒数第二行修复了该错误。

这可能就是你的情况(取决于你的观点的创建方式)。

@implementation NSView (Nakahara)

- (void)nakahara_embedSubview:(NSView *)subview;
{
    subview.frame = self.bounds;
    [self addSubview:subview];

    NSArray *newConstraints =
    @[
      [NSLayoutConstraint constraintWithItem:subview attribute:NSLayoutAttributeTop relatedBy:NSLayoutRelationEqual toItem:self attribute:NSLayoutAttributeTop multiplier:1.0 constant:0.0],
      [NSLayoutConstraint constraintWithItem:subview attribute:NSLayoutAttributeWidth relatedBy:NSLayoutRelationEqual toItem:self attribute:NSLayoutAttributeWidth multiplier:1.0 constant:0.0],
      [NSLayoutConstraint constraintWithItem:subview attribute:NSLayoutAttributeHeight relatedBy:NSLayoutRelationEqual toItem:self attribute:NSLayoutAttributeHeight multiplier:1.0 constant:0.0],
      [NSLayoutConstraint constraintWithItem:subview attribute:NSLayoutAttributeTrailing relatedBy:NSLayoutRelationEqual toItem:self attribute:NSLayoutAttributeTrailing multiplier:1.0 constant:0.0],
      ];

    subview.translatesAutoresizingMaskIntoConstraints = NO;
      // IMPORTANT! It took a while to figure out why this was sometimes working and sometimes not. It was because subview.translatesAutoresizingMaskIntoConstraints is sometimes YES and sometimes NO, and if it is YES, autolayout will break in undefined ways (e.g., windows suddenly become unresizable).

    [self addConstraints:newConstraints];
}


@end

答案 1 :(得分:0)

创建新约束时,默认优先级为1000(NSLayoutPriorityRequired)。这意味着自动布局引擎可能会影响窗口大小以满足您的约束。

如果将约束的优先级设置为小于500(NSLayoutPriorityWindowSizeStayPut)的值,则应该得到所需的行为。

相关问题