2

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

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

到目前为止,我没有成功使用具有自动布局的单个 NSSplitView 成功地做到这一点。

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

在此处输入图像描述

你之前有成功过​​类似配置的 NSSplitView 吗?

或者,一般来说,一些建议来进一步调试这个问题?

有人建议使用嵌套的 NSSplitView 来实现这种行为。但我想检查如何使用单个 NSSplitView 来完成。(看起来“Notes”应用程序是用一个 NSSplitView 完成的)

感谢负载

账单

我的测试代码在这里

4

2 回答 2

2

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

于 2015-03-17T13:11:48.477 回答
1

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

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

在此处输入图像描述

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

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

为了研究“Notes”应用程序的拆分视图在调整分隔线大小时的行为方式,我使用 Xcode Instruments 的“Cocoa Layout”工具打开它,并研究当我向右移动分隔线 0 时的约束事件。

在此处输入图像描述

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

在此处输入图像描述

我发现主要区别是......最右边的子视图与拆分视图的左边缘之间的约束在“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]);
    }
}

你可以在这里找到代码。

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

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

在此处输入图像描述

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

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

任何帮助/建议?

谢谢比尔

于 2014-11-05T08:06:24.117 回答