NSScrollView 中的自动布局约束

Posted

技术标签:

【中文标题】NSScrollView 中的自动布局约束【英文标题】:Automatic Layout Constraints in NSScrollView 【发布时间】:2012-10-02 21:10:17 【问题描述】:

我正在以编程方式在 NSScrollView 中创建一个 NSTableView,但是当我尝试将框架设置为滚动视图时,我遇到了约束错误。

Unable to simultaneously satisfy constraints:
(
    "<NSAutoresizingMaskLayoutConstraint:0x107d4ec50 h=--& v=--& V:[NSScrollView:0x10068c570(372.5)]>",
    "<NSAutoresizingMaskLayoutConstraint:0x107d4d020 h=-&- v=-&- V:[NSClipView:0x10068d7f0]-(673)-|   (Names: '|':NSScrollView:0x10068c570 )>",
    "<NSAutoresizingMaskLayoutConstraint:0x107d4cfc0 h=-&- v=-&- V:|-(2)-[NSClipView:0x10068d7f0]   (Names: '|':NSScrollView:0x10068c570 )>"
)

Will attempt to recover by breaking constraint 
<NSAutoresizingMaskLayoutConstraint:0x107d4d020 h=-&- v=-&- V:[NSClipView:0x10068d7f0]-(673)-|   (Names: '|':NSScrollView:0x10068c570 )>

Set the NSUserDefault NSConstraintBasedLayoutVisualizeMutuallyExclusiveConstraints to YES to have -[NSWindow visualizeConstraints:] automatically called when this happens.  And/or, break on objc_exception_throw to catch this in the debugger.

它们似乎是自动创建的。

这是我的创建代码(使用 arc)我正在继承 NSView

-(void)addColumnsToTable
    NSTableColumn *col = [[NSTableColumn alloc]initWithIdentifier:@"priority"];
    [col.headerCell setStringValue:@"priority"];
    [col setWidth:10];
    [col setMinWidth:1];
    [col setMaxWidth:10];
    [self.tableView addTableColumn:col];

   // col = [[NSTableColumn alloc]initWithIdentifier:@"name"];
   // [self.tableView addTableColumn:col];   



-(void)createTable
    NSTableView *tableView = [[NSTableView alloc]initWithFrame:NSZeroRect];

    [tableView setDelegate:self];
    [tableView setDataSource:self];

    NSScrollView *scrollView = [[NSScrollView alloc]initWithFrame:self.bounds];
    [scrollView setBorderType:NSGrooveBorder];

    [self addSubview:scrollView];
    [scrollView setDocumentView:tableView];
    [scrollView setHasVerticalScroller:YES];
    [scrollView setAutohidesScrollers:YES];


    self.tableView = tableView;
    self.scrollView = scrollView;

    [self addColumnsToTable];


这就是它崩溃的地方:

-(void)setFrame:(NSRect)frameRect
    [super setFrame:frameRect];
    [self.scrollView setFrame:self.bounds];


有没有办法关闭这些自动约束?

【问题讨论】:

【参考方案1】:

知道了,问题是正在根据视图的自动调整大小掩码创建自动约束。要停用此行为:

[scrollView setTranslatesAutoresizingMaskIntoConstraints:NO];

scrollView 是 NSView 的子视图

【讨论】:

【参考方案2】:

NSView 子类的DrawRect 方法中设置NSScrollViewframe 时,我也遇到了完全相同的问题。将TranslatesAutoresizingMaskIntoConstraints 设置为NO 的上述解决方案摆脱了异常。但在我的情况下,我有一个动态窗口。事实上,我的 tableview 不再遵循我正在计算和设置为 NSScrollView 的新帧大小。

折腾了一阵子,我终于想出了正确的解决方案。看来问题不在于NSScrollView 自动调整大小设置,而是设置我的NSView 子类的AutoresizesSubviews 是动态自定义视图的正确解决方案。

- (void)awakeFromNib


[super awakeFromNib];   
[self setAutoresizesSubviews:NO];   // <- Here is the solution

    // …


- (void)drawRect:(NSRect)dirtyRect


[super drawRect:dirtyRect];

    // From DirtyRect (dimensions of the my subclass NSView)
    // Calculate the rectangle allowable for MyScrollView
    // and setting local NSRect mRect..

    [MyScrollView setFrame:mRect];      // no more ‘exception’ here

我还必须以编程方式创建其他NSView 子类,这也有NSScrollViewframe 设置需求。由于这些对象没有 awakeFromNib 方法……只需将其设置在其他地方……就像在 NSView 子类的 Init 方法中一样。

- (id)init:(NSInteger)aSpecialTag


[self setAutoresizesSubviews:NO];   // <- Here is the solution

    _mTag = aSpecialTag;

    // …

【讨论】:

以上是关于NSScrollView 中的自动布局约束的主要内容,如果未能解决你的问题,请参考以下文章

缩进 UITableViewCell 中的所有自动布局约束

自动布局中的比例距离约束

UITableViewHeaderFooterView 不支持笔尖中的自动布局约束

同一行中的 UIButton 的自动布局约束

代码中的自动布局约束与 XIB 中的大小冲突

Interface Builder 中的相对自动布局约束