How to expand and collapse parts of NSSplitView pr

2020-02-17 05:42发布

I want to replace RBSplitView with NSSplitView in my existing project. The application is now leopard only and I would like to replace RBSplitView with the new NSSplitView shipped with Leopard.

However, I'm missing RBSplitView's handy methods expand and collapse in NSSplitView. How can I expand and collapse parts of NSSplitView programmatically?

10条回答
SAY GOODBYE
2楼-- · 2020-02-17 06:20

I just got programmatic expanding and collapsing of NSSplitView to work. I've also configured my NSSplitView to expand/collapse a subview whenever the divider is double-clicked, so I wanted this to play nice with that feature (and it seems to). This is what I did:

(in this example, splitView is the NSSplitView itself, splitViewSubViewLeft is the subview I wish to expand/collapse and lastSplitViewSubViewLeftWidth is an instance variable of type CGFloat.)

// 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
         ];
}
查看更多
爷的心禁止访问
3楼-- · 2020-02-17 06:20

I recommend to use NSSplitViewController instead, and NSSplitViewItem.isCollapsed to control them. This just work.

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

To make this to work properly, you have to configure split-UI components with mainly view-controllers. Otherwise, it can be broken.

查看更多
We Are One
4楼-- · 2020-02-17 06:22

Simply hide the subview you want to collapse, e.g.

[aSubViewToCollapse setHidden:YES];

You might also want to implement the delegate method -(BOOL)splitView:shouldHideDividerAtIndex: to return YES to hide the divider when a collapsed.

查看更多
你好瞎i
5楼-- · 2020-02-17 06:27

After some experimenting with the suggestions this was the easiest solution I found:

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

The function is a user defined first-responder action. It is triggered by a menu-item (or keystroke). The collapsibleView is a subview in the splitView both of which are connected in IB with their properties.

查看更多
男人必须洒脱
6楼-- · 2020-02-17 06:27

NSSplitView actually has a private method -(void)_setSubview:(NSView *)view isCollapsed:(BOOL)collapsed that does this. Those who would like to ignore all warnings against using private methods, behold:

- (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];
}

I implemented this as a category on NSSplitView. The only issue is that Xcode gives a warning about _setSubview:isCollapsed: being undeclared... I'm not really sure how to get around that.


El Capitan Update

I haven't written any code for OS X in ~2 years now so I haven't been able to verify this, but according to lemonmojo in the comments below, _setSubview:isCollapsed: was renamed in El Capitan to _setArrangedView:isCollapsed:.

查看更多
劫难
7楼-- · 2020-02-17 06:28

You could try Brandon Walkin's BWToolKit.

The BWSplitView class has a method

- (IBAction)toggleCollapse:(id)sender;
查看更多
登录 后发表回答