Как программно развернуть и свернуть части 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
где у меня два 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
}
}
}
После некоторых экспериментов с предложениями это было самое простое решение, которое я нашел:
-(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
}
}