Подтвердить что ты не робот

Как развернуть и свернуть части NSSplitView программно?

Я хочу заменить RBSplitView на NSSplitView в моем существующем проекте. Приложение теперь является леопардом, и я хотел бы заменить RBSplitView на новый NSSplitView, поставляемый с Leopard.

Однако мне не хватает RBSplitView удобных методов expand и collapse в NSSplitView. Как я могу развернуть и свернуть части программного обеспечения NSSplitView?

4b9b3361

Ответ 1

Я только что получил программное расширение и рушительство NSSplitView для работы. Я также сконфигурировал мой NSSplitView, чтобы развернуть/свернуть subview всякий раз, когда разделитель дважды щелкнул, поэтому я хотел, чтобы это играло хорошо с этой функцией (и, похоже,). Это то, что я сделал:

(в этом примере splitView сам NSSplitView, splitViewSubViewLeft - это subview, который я хочу развернуть/свернуть, а lastSplitViewSubViewLeftWidth - это переменная экземпляра типа CGFloat.)

// subscribe to splitView 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

Просто скройте подпункт, который хотите свернуть, например

[aSubViewToCollapse setHidden:YES];

Вы также можете реализовать метод делегата - (BOOL) splitView: shouldHideDividerAtIndex: вернуть YES, чтобы скрыть разделитель, когда он рухнул.

Ответ 3

Я попробовал решение выше и нашел, что он не работает, поскольку isSubviewCollapsed никогда не возвращался YES

Комбинация предложений дала результат, который работает

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

Ответ 4

После некоторых экспериментов с предложениями это было самое простое решение, которое я нашел:

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

Функция представляет собой пользовательское действие первого ответчика. Он активируется элементом меню (или нажатием клавиши). CollapsibleView является подразделением в splitView, оба из которых связаны в IB с их свойствами.

Ответ 5

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

Я не написал никакого кода для OS X через ~ 2 года, поэтому я не смог проверить это, но согласно lemonmojo в комментарии ниже, _setSubview:isCollapsed: было переименовано в El Capitan в _setArrangedView:isCollapsed:.

Ответ 6

В El Capitan это помогло мне.

splitViewItem.collapsed = YES;

Ответ 7

Вы можете попробовать Brandon Walkin BWToolKit.

Класс BWSplitView имеет метод

- (IBAction)toggleCollapse:(id)sender;

Ответ 8

В быстрой работе

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

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

назовите это от IBAction, outline - это OutlineViewController с собственным xib, и нам нужно представление, следовательно, 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. Как переключить видимость поднабора NSSplitView subview + скрыть разделитель разделителей панелей? https://github.com/Dis3buted/SplitViewController

Ответ 9

В macOS Sierra свойство collapsed изменено на isCollapsed. Прямо, просто устанавливая свойство на true или false. Следующий код из моего WindowController, где у меня два SplitViewItem s.

@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
        }
    }
}