【问题标题】:HowTo show/hide a second vertical-splitted view in Cocoa?如何在 Cocoa 中显示/隐藏第二个垂直分割视图?
【发布时间】:2012-01-02 21:21:09
【问题描述】:

让我介绍一下。我是一个狂热的程序员(不是专业的),有 c、c++、java 经验,现在开始在 MacOsx 上使用 Objective-C 和 Cocoa。

在我的第一个程序中,我想创建两个垂直分割的视图,左侧(主)始终打开,右侧根据按钮按下显示/隐藏(其用途将用于调试输出)。

我已经在 Xcode 4.2 下看到了我想要的东西,我们可以在其中隐藏/显示导航器/调试/实用程序。我正在寻找“实用程序”行为,这正是我想要的。该垂直视图的用途是从我的程序中输出“调试”文本,我正在考虑在 NSScrollView 中使用 NSTextView 来模拟“控制台”。我知道我可以只使用 Xcode 的终端或调试视图,这就是现在的工作。我需要这个只是为了学习如何做到这一点并改进我的程序。

我在谷歌上搜索了很多并阅读了类似的请求,但我找不到确切的方法。

提前感谢您的帮助。

路易斯

【问题讨论】:

    标签: objective-c xcode cocoa


    【解决方案1】:

    正如所承诺的,这就是我最终解决问题的方法。

    • 目标:我想要两个垂直分割的视图:
      • 显示/隐藏右侧视图的按钮并相应调整窗口大小。
      • 留下一个(主)始终打开且宽度不可调整(它可以调整高度)
      • 右侧显示/隐藏,可以调整宽度/高度大小,必须始终具有最小宽度。
      • 当右隐藏时,主窗口最小宽度/高度等于左视图

    我创建了一个带有 2 个自定义视图的 NSSplitView(垂直),在 Interface Builder(“springs”/“struts”)中有足够的自动调整大小限制。然后我做了以下事情:

    Controller.h
    :
    @interface Controller : NSWindowController <NSSplitViewDelegate, NSWindowDelegate> {
    :
    
    
    Controller.m
    :
    // To control the Splitter (next 3 methods)
    // =======================================
    // The splitter cannot be moved. I always return "widthViewLeft" which is "fixed static sized to the left view width"
    // I return NO to resize the left panel and YES to the right panel.
    
    -(CGFloat)splitView:(NSSplitView *)splitView constrainMaxCoordinate:(CGFloat)proposedMax ofSubviewAt:(NSInteger)dividerIndex {
        return (widthViewLeft);    
    }
    -(CGFloat)splitView:(NSSplitView *)splitView constrainMinCoordinate:(CGFloat)proposedMin ofSubviewAt:(NSInteger)dividerIndex {
        return (widthViewLeft);
    }
    -(BOOL)splitView:(NSSplitView *)splitView shouldAdjustSizeOfSubview:(NSView *)subview {
        return subview != splitViewLeft;
    }
    
    // To control the Main Window resize
    // =======================================
    // I allow to resize if the Right panel is open. 
    // I restrict to a fixed size if the Right panel is closed(hidden), so I don't allow to resize. 
    
    - (NSSize)windowWillResize:(NSWindow *)window toSize:(NSSize)proposedFrameSize 
    {
        if ( [[leftViewController view] isHidden ] ) {
            proposedFrameSize.width = widthViewLeft + 2;
            proposedFrameSize.height = heightViewLeft + titleBarHeight + 2;
        }    
        return proposedFrameSize;
    }
    
    
    // To HIDE the right panel 
    // =======================================
    //
    -(void)handleNotificationHideConsola:(NSNotification *)pNotification
    {
        NSRect newFrame;
        NSSize newMinSize;
        NSSize newMaxSize;
    
        // Hide the right panel
        [[rightViewController view] setHidden:TRUE];
    
        // Values that do not change
        newMinSize.height = [theWindow minSize].height;    
        newMaxSize.height = [theWindow maxSize].height;    
        newFrame.origin.x = [theWindow frame].origin.x;
        //newFrame.origin.y = [theWindow frame].origin.y;
    
        // Values that change
        newMinSize.width = widthViewLeft;
        newMaxSize.width = widthViewLeft;
        newFrame.size.width = widthViewLeft + 2;
        newFrame.size.height = heightViewLeft + titleBarHeight + 2;
        newFrame.origin.y = [theWindow frame].origin.y + ([theWindow frame].size.height - newFrame.size.height) ;
    
        // Perform the change
        [theWindow setMinSize:newMinSize];
        [theWindow setFrame:newFrame display:YES animate:YES];
    
    } 
    
    // To SHOW the right panel 
    // =======================================
    //
    -(void)handleNotificationShowConsola:(NSNotification *)pNotification
    {
        if ( [[rightViewController view] isHidden] ) {
            NSRect newFrame;
            NSSize newMinSize;
    
            // Show the right panel
            [[rightViewController view] setHidden:FALSE];
    
        // Values that do not change
            newMinSize.height = [theWindow minSize].height;    
            newFrame.origin.x = [theWindow frame].origin.x;
            newFrame.origin.y = [theWindow frame].origin.y ;
    
            // Values that change
            newMinSize.width = widthViewLeft + widthViewRigth;             
            newFrame.size.width = widthViewLeft + widthViewRigth;         
            newFrame.size.height = newMinSize.height + titleBarHeight;  
            newFrame.origin.y = [theWindow frame].origin.y - (newFrame.size.height - [theWindow frame].size.height);
    
            // Perform the change
            [theWindow setMinSize:newMinSize];
            [theWindow setFrame:newFrame display:YES animate:YES];
        }  
    } 
    

    再次感谢@markhunte 的想法,并希望上述示例对其他人有所帮助。

    路易斯

    【讨论】:

      【解决方案2】:

      一个非常粗略的想法。使用 setPosition:ofDividerAtIndex: 更改视图的宽度 setPosition:(CGFloat)DividerAtIndex的位置:(NSInteger)dividerIndex

      声明一个 CGFloat splitterlength

      并将其放入 applicationDidFinishLaunching 中。

          splitterlength  = splitView.bounds.size.width;
      [splitView setPosition:splitterlength ofDividerAtIndex:0];
      

      然后使用这个动作

           - (IBAction)moveSplitter:(id)sender {
      
          NSArray *splitterViews =splitView.subviews;
         CGFloat splitterCheckLength =[[splitterViews objectAtIndex:0]bounds].size.width;
          CGFloat openSplitter=splitterlength/2;
      
          if (splitterCheckLength ==openSplitter) {
            [splitView setPosition:splitterlength ofDividerAtIndex:0];
          }else {
              [splitView setPosition:openSplitter ofDividerAtIndex:0];
          }
      
      
      
      
      }
      

      使用任何你想要的长度。

      尽管如此。我会使用普通的 customViews 并调整它们。这样我就不用担心用户拖动拆分器了。

      【讨论】:

      • 非常感谢@markhunte。我已经对其进行了测试,并且效果很好。也给了我关于如何解决这个问题的总体思路。在这里找到另一个有趣的话题link。我将对此进行更多研究,并在完成后发布我的最终代码。再次感谢。路易斯
      猜你喜欢
      • 2019-11-09
      • 2017-08-06
      • 2014-04-29
      • 2013-09-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多