NSWindow根据从windowWillResize返回的NSSize不调整大小:toSize:

时间:2015-02-28 14:20:13

标签: objective-c cocoa nswindow

我正在以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;
}

1 个答案:

答案 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;
}

如果仍然没有让窗口继续缩小,那么:

  1. 如果您停止拖动然后重新开始,那会有效吗?那 是,问题只是在连续调整大小操作期间 左窗格是否折叠,或者窗口永远不会崩溃 允许自己比我所说的更小 minUncollapsedWidth
  2. 您是如何确定没有其他限制窗口大小的?你检查了什么?