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

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

Тем не менее, я скучаю RBSplitViewудобные методы expand а также collapse в NSSplitView, Как программно развернуть и свернуть части NSSplitView?

11 ответов

Решение

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

(в этом примере splitView это NSSplitView сам, splitViewSubViewLeft это подпредставление, которое я хочу развернуть / свернуть и lastSplitViewSubViewLeftWidth переменная экземпляра типа 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
         ];
}

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

[aSubViewToCollapse setHidden:YES];

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

Я пробовал решение выше, и обнаружил, что оно не работает, так как isSubviewCollapsed никогда не возвращал ДА

Сочетание предложений дало результат, который работает

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

В Эль-Капитане это помогло мне.

splitViewItem.collapsed = YES;

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

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

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

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

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

В скором времени это работает

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

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

Вызовите это из IBAction, контур - это 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 + скрыть разделитель Pane Splitter? https://github.com/Dis3buted/SplitViewController

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: быть необъявленным... Я не совсем уверен, как обойти это.


Эль Капитан Обновление

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

Я рекомендую использовать NSSplitViewController вместо этого и NSSplitViewItem.isCollapsed контролировать их. Это просто работа.

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

Чтобы это работало должным образом, вы должны сконфигурировать компоненты с разделенным пользовательским интерфейсом в основном с контроллерами представления. В противном случае это может быть сломано.

      @IBOutlet weak var horizontalSplitView: NSSplitView!
var splitViewItem : [NSView]?
var isSplitViewHidden: Bool = false

override func viewDidLoad() {
    super.viewDidLoad()
    // To Hide Particular Sub-View.
    splitViewItem = self.horizontalSplitView.arrangedSubviews
    splitViewItem?[0].isHidden = true
    isSplitViewHidden = true
}

//MARK: View / Manage All Jobs Button Tapped.
@IBAction func actionManageScheduleJobsButtonTapped(_ sender: Any) {
    if isSplitViewHidden == true {
        isSplitViewHidden = false
        splitViewItem?[0].isHidden = false
    } else {
        isSplitViewHidden = true
        splitViewItem?[0].isHidden = true
    }
}

--------- ИЛИ ----------

      //MARK: View / Manage All Jobs Button Tapped.
@IBAction func actionManageScheduleJobsButtonTapped(_ sender: Any) {
    if splitViewItem?[0].isHidden == true {
        splitViewItem?[0].isHidden = false
    } else {
        splitViewItem?[0].isHidden = true
    }
}

Вы можете попробовать BWToolKit Брэндона Уолкина.

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

- (IBAction)toggleCollapse:(id)sender;
Другие вопросы по тегам