如何以编程方式展开和折叠部分NSSplitView?

时间:2009-05-29 08:43:04

标签: cocoa expand nssplitview

我想在现有项目中将RBSplitView替换为NSSplitView。该应用程序现在只是leopard,我想将RBSplitView替换为Leopard附带的 new NSSplitView

但是,我在RBSplitView中遗漏了expand方便的方法collapseNSSplitView。如何以编程方式展开和折叠部分NSSplitView?

10 个答案:

答案 0 :(得分:29)

只需隐藏您想要折叠的子视图,例如

[aSubViewToCollapse setHidden:YES];

您可能还想实现委托方法 - (BOOL)splitView:shouldHideDividerAtIndex:返回YES以在折叠时隐藏分隔符。

答案 1 :(得分:9)

我只是将NSSplitView的程序化扩展和折叠工作。我还配置了我的NSSplitView以便在双击分割器时展开/折叠子视图,所以我希望这对于该功能很好玩(似乎)。这就是我所做的:

(在此示例中,splitViewNSSplitView本身,splitViewSubViewLeft是我希望展开/折叠的子视图,lastSplitViewSubViewLeftWidthCGFloat类型的实例变量1}}。)

// subscribe to splitView's notification of subviews resizing
// (I do this in -(void)awakeFromNib)
[[NSNotificationCenter defaultCenter]
 addObserver:self
 selector:@selector(mainSplitViewWillResizeSubviewsHandler:)
 name:NSSplitViewWillResizeSubviewsNotification
 object:splitView
 ];

// this is the handler the above snippet refers to
- (void) mainSplitViewWillResizeSubviewsHandler:(id)object
{
    lastSplitViewSubViewLeftWidth = [splitViewSubViewLeft frame].size.width;
}

// wire this to the UI control you wish to use to toggle the
// expanded/collapsed state of splitViewSubViewLeft
- (IBAction) toggleLeftSubView:(id)sender
{
    [splitView adjustSubviews];
    if ([splitView isSubviewCollapsed:splitViewSubViewLeft])
        [splitView
         setPosition:lastSplitViewSubViewLeftWidth
         ofDividerAtIndex:0
         ];
    else
        [splitView
         setPosition:[splitView minPossiblePositionOfDividerAtIndex:0]
         ofDividerAtIndex:0
         ];
}

答案 2 :(得分:6)

我尝试了上面的解决方案,发现它没有用,因为isSubviewCollapsed从未返回YES

这些建议的组合产生了一个有效的结果

if ([splitViewTop isHidden]) {
    [splitViewTop setHidden:NO];
    [split
     setPosition:previousSplitViewHeight
     ofDividerAtIndex:0];
}
else {
    [splitViewTop setHidden:YES];
}
[split adjustSubviews];

答案 3 :(得分:3)

在尝试了一些建议之后,这是我找到的最简单的解决方案:

-(void)toggleCollapsibleView:(ib)sender {
   [collapsibleView setHidden:![splitView isSubviewCollapsed:collapsibleView]];
   [splitView adjustSubviews];
}

该功能是用户定义的第一响应者操作。它由菜单项(或按键)触发。 collapsibleView是splitView中的子视图,它们都在IB中与它们的属性相连接。

答案 4 :(得分:3)

在El Capitan,这对我有用。

splitViewItem.collapsed = YES;

答案 5 :(得分:1)

NSSplitView实际上有一个私有方法 -(void)_setSubview:(NSView *)view isCollapsed:(BOOL)collapsed来执行此操作。那些想要忽略所有使用私人方法的警告的人,请注意:

- (void)toggleSubview:(NSView *)view {
    SEL selector = @selector(_setSubview:isCollapsed:);
    NSMethodSignature *signature = [NSSplitView instanceMethodSignatureForSelector:selector];
    NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:signature];
    invocation.target = self;
    invocation.selector = selector;
    [invocation setArgument:&view atIndex:2];
    BOOL arg = ![self isSubviewCollapsed:view];
    [invocation setArgument:&arg atIndex:3];
    [invocation invoke];
}

我在NSSplitView上将其实现为一个类别。唯一的问题是Xcode会发出关于_setSubview:isCollapsed:未声明的警告...我不确定如何解决这个问题。


El Capitan更新

我在2年内没有为OS X编写任何代码,所以我无法对此进行验证,但根据lemonmojo在下面的评论中,_setSubview:isCollapsed:已重命名为El Capitan到_setArrangedView:isCollapsed:

答案 6 :(得分:1)

在swift中,这是有效的

func togglePanel() {
    let splitViewItem = self.mySplitView.arrangedSubviews

    if mySplitView.isSubviewCollapsed(outline.view){
        splitViewItem[0].hidden = false
    } else {
        splitViewItem[0].hidden = true
    }

从IBAction调用此信息, outline是一个带有自己的xib的OutlineViewController,我们需要视图,因此outline.view,保持简单,但希望你能得到这个想法

@IBAction func segmentAction(sender: NSSegmentedControl) {
    splitVC?.togglePanel(sender.selectedSegment)
}

func togglePanel(segmentID: Int) {
    let splitViewItem = self.mySplitView.arrangedSubviews

    switch segmentID {

    case segmentID:
        if mySplitView.isSubviewCollapsed(splitViewItem[segmentID]) {
            splitViewItem[segmentID].hidden = false
        } else {
            splitViewItem[segmentID].hidden = true
        }
    default:
        break
    }

}

并实施委托

func splitView(splitView: NSSplitView, shouldHideDividerAtIndex dividerIndex: Int) -> Bool {
    return true
}

使用10.11 ,您可能只使用toggleSidebar操作方法。 How to toggle visibility of NSSplitView subView + hide Pane Splitter divider? https://github.com/Dis3buted/SplitViewController

答案 7 :(得分:1)

在macOS Sierra中,collapsed属性更改为isCollapsed。直接将该属性设置为truefalse。以下代码来自我的WindowController,其中我有两个SplitViewItem

@IBAction func toggleMap(_ sender: Any) {
    if let splitViewController = contentViewController as? NSSplitViewController {
        let splitViewItem = splitViewController.splitViewItems
        if splitViewItem.first!.isCollapsed {
            splitViewItem.first!.isCollapsed = false
        } else if splitViewItem.last!.isCollapsed {
            splitViewItem.last!.isCollapsed = false
        } else {
            if splitViewItem.first!.isCollapsed {
                splitViewItem.first!.isCollapsed = false
            }
            splitViewItem.last!.isCollapsed = true
        }
    }
}

答案 8 :(得分:1)

我建议改为使用NSSplitViewControllerNSSplitViewItem.isCollapsed来控制它们。这样就可以了。

let item: NSSplitViewItem = ...
item.isCollapsed = true

要使其正常工作,您必须使用主要的视图控制器配置split-UI组件。否则,它可能会损坏。

答案 9 :(得分:0)

你可以试试Brandon Walkin的BWToolKit

BWSplitView类有一个方法

- (IBAction)toggleCollapse:(id)sender;