【问题标题】:constraints cause an ambiguousLayout约束导致歧义布局
【发布时间】:2016-12-22 07:01:42
【问题描述】:

我有一个NSWindow 实例,它有一个setupUi 方法。

-(void) setupUi {
    NSView* subView = [[NSView alloc] initWithFrame:NSZeroRect];
    subView.wantsLayer = YES;
    subView.layer.backgroundColor = [[NSColor greenColor] CGColor];
    [self.contentView addSubview:subView];
    [self.contentView setTranslatesAutoresizingMaskIntoConstraints:NO];
    [self.contentView addConstraint:[NSLayoutConstraint constraintWithItem:self.contentView
                              attribute:NSLayoutAttributeLeading
                              relatedBy:NSLayoutRelationEqual
                                 toItem:subView
                              attribute:NSLayoutAttributeLeading
                             multiplier:1
                               constant:0]];
    [self.contentView addConstraint:[NSLayoutConstraint constraintWithItem:self.contentView
                              attribute:NSLayoutAttributeTop
                              relatedBy:NSLayoutRelationEqual
                                 toItem:subView
                              attribute:NSLayoutAttributeTop
                             multiplier:1
                               constant:0]];
    [self.contentView addConstraint:[NSLayoutConstraint constraintWithItem:self.contentView
                              attribute:NSLayoutAttributeTrailing
                              relatedBy:NSLayoutRelationEqual
                                 toItem:subView
                              attribute:NSLayoutAttributeTrailing
                             multiplier:1
                               constant:0]];
    [self.contentView addConstraint:[NSLayoutConstraint constraintWithItem:self.contentView
                              attribute:NSLayoutAttributeBottom
                              relatedBy:NSLayoutRelationEqual
                                 toItem:subView
                              attribute:NSLayoutAttributeBottom
                             multiplier:1
                               constant:0]];

}

当我调用[self.contentView hasAmbiguousLayout] 时,它返回YES。为什么会这样?这段代码 sn-p 似乎与 Xib 在使用 pin panel 时为我们创建的代码相同。

并且窗口中没有出现绿色的子视图。

提前致谢。

【问题讨论】:

    标签: objective-c macos constraints


    【解决方案1】:

    NSWindow的contentView的translatesAutoresizingMaskIntoConstraints属性默认为YES。如果我将其设置为 NO,我无法猜测我对 FrameAutoResizingMaskAutoLayout 的了解会发生什么,因为我尝试过的行为让我很困惑。

    总之,如果我只想使用 AutoLayout,请将顶部 contentView 的 translatesAutoresizingMaskIntoConstraints 设置为 YES,但所有其他子视图设置为 NO。

    当你创建一个视图时,它的构造是 autoResizingMask 为 0,translatesAutoresizingMaskIntoConstraints 为 YES。如果 translatesAutoresizingMaskIntoConstraints 为 YES,它将使用 Frame、autoResizingMask 甚至约束(AutoLayout)来定位视图。

    考虑以下情况。

    NSView* subView = [[NSView alloc] initWithFrame:NSMakeRect(100, 100, 200, 200)];
    subView.wantsLayer = YES;
    subView.layer.backgroundColor = [[NSColor greenColor] CGColor];
    [subView setTranslatesAutoresizingMaskIntoConstraints:YES];
    [self.contentView addSubview:subView];
    
    [subView addConstraint:[NSLayoutConstraint constraintWithItem:subView
                              attribute:NSLayoutAttributeWidth
                              relatedBy:NSLayoutRelationEqual
                                 toItem:nil
                              attribute:NSLayoutAttributeNotAnAttribute
                             multiplier:1
                               constant:50]];
    [subView addConstraint:[NSLayoutConstraint constraintWithItem:subView
                              attribute:NSLayoutAttributeHeight
                              relatedBy:NSLayoutRelationEqual
                                 toItem:nil
                              attribute:NSLayoutAttributeNotAnAttribute
                             multiplier:1
                               constant:50]];
    

    subView 的 translatesAutoresizingMaskIntoConstraints 为 YES。然后它将使用 Point(100, 100) 来定位它。它将使用 Size(200, 200) 来调整它的大小。它将创建 NSAutoresizingMaskLayoutConstraint 使其无法调整大小,因为默认的 autoResizingMask 为 0,这意味着视图无法更改其宽度和高度。它还将使用 autoLayout 创建 NSLayoutConstraint,因为您调用了“addConstraint”。而且它也会破坏 NSLayoutConstraint 因为你的 NSLayoutConstraint 和 NSAutoresizingMaskLayoutConstraint 是冲突的。太可怕了。

    但是如果你调用[subView setTranslatesAutoresizingMaskIntoConstraints:NO],它不会使用Point、Size、NSAutoresizingMaskLayoutConstraint,它只会使用NSLayoutConstraint和autoLayout。因为你只是调整它的大小,而不是定位它。所以这是一个模棱两可的布局。太可怕了。

    下面的代码是真的。

    NSView* subView = [[NSView alloc] initWithFrame:NSMakeRect(100, 100, 200, 200)];
    subView.wantsLayer = YES;
    subView.layer.backgroundColor = [[NSColor greenColor] CGColor];
    [subView setTranslatesAutoresizingMaskIntoConstraints:NO];
    [self.contentView addSubview:subView];
    
    [subView addConstraint:[NSLayoutConstraint constraintWithItem:subView
                              attribute:NSLayoutAttributeWidth
                              relatedBy:NSLayoutRelationEqual
                                 toItem:nil
                              attribute:NSLayoutAttributeNotAnAttribute
                             multiplier:1
                               constant:50]];
    [subView addConstraint:[NSLayoutConstraint constraintWithItem:subView
                              attribute:NSLayoutAttributeHeight
                              relatedBy:NSLayoutRelationEqual
                                 toItem:nil
                              attribute:NSLayoutAttributeNotAnAttribute
                             multiplier:1
                               constant:50]];
    [self.conteView addConstraint:[NSLayoutConstraint constraintWithItem:subView
                              attribute:NSLayoutAttributeLeading
                              relatedBy:NSLayoutRelationEqual
                                 toItem:self.contentView
                              attribute:NSLayoutAttributeLeading
                             multiplier:1
                               constant:0]];
    [self.conteView addConstraint:[NSLayoutConstraint constraintWithItem:subView
                              attribute:NSLayoutAttributeTop
                              relatedBy:NSLayoutRelationEqual
                                 toItem:self.contentView
                              attribute:NSLayoutAttributeTop
                             multiplier:1
                               constant:0]];
    

    我觉得 cocoa 的布局太可怕了,原因很多。

    在 Qt 中,QHBoxLayout 可以很容易地做到这一点。不要告诉我cocoa里有NSStackView,无缘无故出错的时候我觉得调试很累。

    但我必须和可可一起工作。

    有谁能告诉我为什么我不能将 contentView 的 translatesAutoresizingMaskIntoConstraints 设置为 NO?

    提前致谢。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2023-04-02
      • 1970-01-01
      • 2012-12-06
      • 2014-04-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-10-08
      相关资源
      最近更新 更多