如何使用3个窗格配置NSSplitView的自动布局约束

时间:2014-11-03 09:53:59

标签: macos cocoa appkit nssplitview

我想实现一个类似邮件的NSSplitView,这样当拖动分隔符0时,它会推动分隔符1(压缩子视图2,而子视图1的宽度是固定的)。

-----------------
|   |   |       |
| 0 | 1 |   2   |
|   |   |       |
|   |   |       |
-----------------

到目前为止,对于使用自动布局的单个NSSplitView,我没有运气成功。

我尝试用Instruments检查问题。看起来,在某个点之后(截图中的#783),约束没有足够高的优先级来继续推动。

enter image description here

您之前是否成功配置了类似配置的NSSplitView?

或者,一般来说,还有一些建议可以进一步调试这个问题吗?

有人建议使用嵌套的NSSplitView来实现此行为。但我想检查如何使用单个NSSplitView完成此操作。 (看起来像#34; Notes" app是用单个NSSplitView完成的)

感谢加载

比尔

My test code is here

2 个答案:

答案 0 :(得分:1)

我想分享我过去几天所做的调查。我能够以我想要的方式运行NSSplitView。它还不是一个完整的解决方案。但是,希望有人可以帮助我回答我无法回答的部分。

“Notes”应用程序可能使用单个NSSplitView。

enter image description here

上面的屏幕截图显示了在Xcode 6 Veiw Debugger模式下运行的“Notes”应用程序。

它是NSSplitView的一个子类,名为MainSplitView。

为了研究“音符”应用程序的分割视图在调整分割器大小时的行为方式,我使用Xcode Instruments的“Cocoa Layout”乐器打开它,并在向右移动分割器0时研究约束事件。

enter image description here

研究约束事件并将其与运行原始版本的示例应用程序生成的日志进行比较......

enter image description here

我发现主要区别是......最右边的子视图与拆分视图的左边缘之间的约束在“Notes”应用程序中具有“低”优先级。类似的约束在我的示例应用程序中具有“必需”优先级。

所以,我尝试实现自己的MainSplitView。覆盖“addConstraints:”方法,以便将较低的优先级设置为约束。

- (void)addConstraints:(NSArray *)constraints {
    NSLog(@"adding constraints: %@", constraints);
    NSLayoutConstraint * theConstraint = constraints.firstObject;
    if ( theConstraint.firstItem == self.subviews.lastObject && theConstraint.secondItem == self ) {
        theConstraint.priority = NSLayoutPriorityDefaultLow;
        [super addConstraints:@[theConstraint]];
    } else {
        [super addConstraints:constraints];
    }
    NSLog(@"========== constraings affecting layout ===========");
    for (NSView * theView in self.subviews) {
        NSLog(@"view: %@\n%@", theView, [theView constraintsAffectingLayoutForOrientation:NSLayoutConstraintOrientationHorizontal]);
    }
}

您可以找到代码here

更改之后,我的示例应用程序,当我拖动分隔线0时,它会向右推中间子视图,保持其宽度,压缩最右边的视图。

但现在......我遇到了另一个问题......

enter image description here

每次移动分频器0时,它最多只能移动到分频器1的起始位置。

这是另一个约束配置问题吗?或者,我们需要自定义NSSplitView的其他一些初始行为?

任何帮助/建议?

由于 比尔

答案 1 :(得分:1)

您不需要自动布局。 NSSplitView的子视图具有“保持优先级”的概念。您应该将视图2的保持优先级设置为小于0和1。