我正在以Mail.app的方式为OS X编写一个Cocoa应用程序,其中有3个窗格。我通过在另一个NSSplitView中嵌入一个NSSplitView来实现这一目标。我正在尝试模仿Mail.app的功能,当窗口调整大小小于特定宽度时,它会自动折叠最左边的窗格。我正在使用NSWindowDelegate的以下方法来做这件事
- (NSSize)windowWillResize:(NSWindow *)sender toSize:(NSSize)frameSize
我对此方法的实现如下所示,但简而言之,当窗口调整为较小时,左窗格会按照我的意愿折叠,但是在它折叠之后窗口应该允许继续变小但是踢球者是没有的。 我在此过程中返回的NSSize是正确的,但窗口不会调整大小以匹配此值。我已检查以确保NSWindow没有任何其他最小大小限制。我被卡住了。任何人都可以帮我理解造成这个问题的原因吗?
我的实施:
- (NSSize)windowWillResize:(NSWindow *)sender toSize:(NSSize)frameSize
{
CGFloat minWidth;
if ([outerSplitView isSubviewCollapsed:leftPane])
{
minWidth = [outerSplitView dividerThickness] + MIDDLE_PANE_MINIMUM + [innerSplitView dividerThickness] + RIGHT_PANE_MINIMUM;
}
else
{
minWidth = LEFT_PANE_MINIMUM + [outerSplitView dividerThickness] + MIDDLE_PANE_MINIMUM + [innerSplitView dividerThickness] + RIGHT_PANE_MINIMUM;
}
if (![outerSplitView isSubviewCollapsed:leftPane])
{
// make sure the width is not smaller than current minimum width
// find the difference proposed size and current size
if (sender.frame.size.width - frameSize.width > LEFT_PANE_MINIMUM / 2.0 )
{
//Collapse the left pane. Don't modify framesize.
[outerSplitView setPosition:0.0 ofDividerAtIndex:0];
}
else if (frameSize.width < minWidth )
{
frameSize.width = minWidth;
}
}
else if (frameSize.width < minWidth)
{
frameSize.width = minWidth;
}
return frameSize;
}
答案 0 :(得分:0)
我认为你没有使用自动布局。你可能会考虑这样做。我认为,一旦设置了适当的最小宽度约束并在子视图上保持优先级,您就可以免费获得此行为。 (最小宽度可以来自直接对子视图的显式约束,也可以来自子视图中的子视图及其内在大小等。)
鉴于您的拆分视图都是垂直的,您是否有理由不使用包含三个子视图的单个拆分视图?在UI中使用拆分视图后,您只需将另一个视图拖入其中即可增加窗格数。
您决定何时折叠视图的逻辑对我来说没有意义。你有if (sender.frame.size.width - frameSize.width > LEFT_PANE_MINIMUM / 2.0 )
确定用户是否试图拖动左窗格最小值的一半以上。但是用户拖动的距离并不重要。它们可能从比左窗格最小的大小开始。
我想你只是想知道建议的宽度是否小于LEFT_PANE_MINIMUM / 2.0 + [outerSplitView dividerThickness] + MIDDLE_PANE_MINIMUM + [innerSplitView dividerThickness] + RIGHT_PANE_MINIMUM
。
此外,由于存在绝对最小宽度,因此您始终需要调整建议的frameSize
。也就是说,即使在折叠左窗格的分支中,您仍然希望强制执行最小宽度 - 当左窗格折叠时。
例如,尝试这个逻辑:
- (NSSize)windowWillResize:(NSWindow *)sender toSize:(NSSize)frameSize
{
CGFloat minWidth = [outerSplitView dividerThickness] + MIDDLE_PANE_MINIMUM + [innerSplitView dividerThickness] + RIGHT_PANE_MINIMUM;
CGFloat minUncollapsedWidth = LEFT_PANE_MINIMUM + minWidth;
CFGloat forceCollapseWidth = LEFT_PANE_MINIMUM / 2.0 + minWidth;
if (![outerSplitView isSubviewCollapsed:leftPane])
{
if (frameSize.width < forceCollapseWidth)
{
//Collapse the left pane.
[outerSplitView setPosition:0.0 ofDividerAtIndex:0];
}
else if (frameSize.width < minUncollapsedWidth)
{
frameSize.width = minUncollapsedWidth;
}
}
if (frameSize.width < minWidth)
{
frameSize.width = minWidth;
}
return frameSize;
}
如果仍然没有让窗口继续缩小,那么:
minUncollapsedWidth
?