【问题标题】:NSWindow does not resize according to NSSize returned from windowWillResize:toSize:NSWindow 不会根据 windowWillResize:toSize 返回的 NSSize 调整大小:
【发布时间】:2015-02-28 14:20:13
【问题描述】:

我正在为 OS X 编写一个 Mail.app 风格的 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;
}

【问题讨论】:

    标签: objective-c cocoa nswindow


    【解决方案1】:

    我认为您没有使用自动布局。你可以考虑这样做。我认为一旦您设置了适当的最小宽度约束并在子视图上保持优先级,您将免费获得此行为。 (最小宽度可以来自直接对子视图的显式约束,也可以来自子视图中的子视图及其固有大小等)

    鉴于您的拆分视图都是垂直的,您是否有理由不只使用具有三个子视图的单个拆分视图?在 UI 中创建拆分视图后,您可以将另一个视图拖入其中以增加窗格的数量。

    您决定何时折叠视图的逻辑对我来说没有意义。您有if (sender.frame.size.width - frameSize.width &gt; 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. 您是如何确定没有其他限制窗口大小的?你检查了什么?

    【讨论】:

    • Ken - 非常感谢您的详细回复。不幸的是,您的实施似乎没有任何区别。左窗格仍然在适当的时间折叠,但折叠后窗口没有继续调整大小。第一个问题的答案是否定的 - 如果我停止拖动然后再次开始拖动,即使返回的 frameSize 的宽度分量小于当前帧大小,窗口仍然不会变小。为了回答您的第二个问题,我查看了界面生成器中 NSWindow 的属性,并确保没有最小宽度
    • 你没有使用自动布局我说对了吗?您是否正在使用窗口标题栏附件、堆栈视图或其他可能为您的窗口启用自动布局并建立导致最小宽度的约束的视图?在确定布局已经发生后,您可以尝试在某个时间点记录[window.contentView constraintsAffectingLayoutForOrientation:NSLayoutConstraintOrientationHorizontal]。如果您注释掉您的 -windowWillResize:toSize: 方法,窗口是否允许调整为更小的宽度?你确定LEFT_PANE_MINIMUM 不为零吗?
    猜你喜欢
    • 1970-01-01
    • 2016-06-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-08-14
    相关资源
    最近更新 更多