Cocoa 如何以编程方式展开和折叠NSSplitView的部分?
我想在现有项目中将Cocoa 如何以编程方式展开和折叠NSSplitView的部分?,cocoa,expand,nssplitview,Cocoa,Expand,Nssplitview,我想在现有项目中将RBSplitView替换为NSSplitView。该应用程序现在仅限leopard,我想用leopard附带的新的NSSplitView替换RBSplitView 但是,我在NSSplitView中缺少了RBSplitView的方便方法展开和折叠。如何以编程方式展开和折叠NSSplitView的部分?您可以试试Brandon Walkin的 BWSplitView类有一个方法 - (IBAction)toggleCollapse:(id)sender; 我刚刚对NSSpli
RBSplitView
替换为NSSplitView
。该应用程序现在仅限leopard,我想用leopard附带的新的NSSplitView
替换RBSplitView
但是,我在
NSSplitView
中缺少了RBSplitView
的方便方法展开
和折叠
。如何以编程方式展开和折叠NSSplitView的部分?您可以试试Brandon Walkin的
BWSplitView类有一个方法
- (IBAction)toggleCollapse:(id)sender;
我刚刚对
NSSplitView
进行了编程扩展和折叠。我还将我的NSSplitView
配置为每当双击分隔符时展开/折叠一个子视图,因此我希望这能很好地发挥该功能(而且似乎是这样)。这就是我所做的:
(在本例中,splitView
是NSSplitView
本身,splitViewSubViewLeft
是我希望展开/折叠的子视图,lastSplitViewSubViewLeftWidth
是CGFloat
类型的实例变量)
只需隐藏要折叠的子视图,例如
[aSubViewToCollapse setHidden:YES];
您可能还希望实现委托方法-(BOOL)splitView:shouldHideDivideraIndex:返回YES以在折叠时隐藏分隔符。我尝试了上述解决方案,发现它不起作用,因为isSubviewCollapsed从未返回YES 这些建议的结合产生了一个有效的结果
if ([splitViewTop isHidden]) {
[splitViewTop setHidden:NO];
[split
setPosition:previousSplitViewHeight
ofDividerAtIndex:0];
}
else {
[splitViewTop setHidden:YES];
}
[split adjustSubviews];
NSSplitView
实际上有一个私有方法-(void)\u setSubview:(NSView*)视图已合并:(BOOL)折叠
,可以执行此操作。那些想忽略所有禁止使用私有方法的警告的人,请注意:
- (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给出了一个关于\u setSubview:isCollapsed:
未声明的警告。。。我真的不知道该怎么解决这个问题
El Capitan更新
我已经有2年没有为OS X编写任何代码了,所以我无法验证这一点,但根据下面的评论,
\u setSubview:isCollapsed:
在El Capitan被重命名为\u setArrangedView:isCollapsed:
在尝试了一些建议后,我发现这是最简单的解决方案:
-(void)toggleCollapsibleView:(ib)sender {
[collapsibleView setHidden:![splitView isSubviewCollapsed:collapsibleView]];
[splitView adjustSubviews];
}
该函数是用户定义的第一响应者操作。它由菜单项(或击键)触发。
可折叠视图是splitView中的一个子视图,这两个视图都通过其属性在IB中连接。在El Capitan中,这为我实现了这一目的
splitViewItem.collapsed = YES;
在斯威夫特这个作品
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 splitView(splitView: NSSplitView, shouldHideDividerAtIndex dividerIndex: Int) -> Bool {
return true
}
对于10.11,您可以只使用toggleSidebar操作方法。
在macOS Sierra中,
折叠的
属性更改为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
}
}
}
我建议改用
NSSplitViewController
和NSSplitViewItem.isCollapsed
来控制它们。这只是工作
let item: NSSplitViewItem = ...
item.isCollapsed = true
要使其正常工作,您必须使用视图控制器配置拆分UI组件。否则,它可能会被破坏。BWToolKit有非常好的控件。没有什么对插件不利的。但是我认为
NSSplitView
现在能够完成RBSplitView
能够完成的所有技巧?将isSubviewCollapsed更改为isHidden在我看来是设计失败。如果一个人不熟悉你的问题,他将来会遇到一些阅读困难。这里的困惑似乎集中在“崩溃”的定义上。折叠视图是否意味着将其大小设置为0,或将其隐藏。NSSplitViewDelegate协议在splitView:canCollapseSubview中给出了这样的定义:“折叠的子视图是隐藏的,但由拆分视图对象保留,其大小与折叠之前相同。”因此,@jemmons和Millways似乎位于它的右侧。这实际上并不“折叠”子视图。它只是将其缩小为0。这是一个问题,因为-isSubviewCollapsed:
仍然始终返回NO
,并且,如果子视图的界面应用了任何自动调整大小的遮罩,它们就会出错。请参阅下面涉及使用-setHidden:
的解决方案以获得正确答案。Divideratindex:的方法setPosition:ofDividerAtIndex:
不会将子视图缩小到零大小。在上面的代码中,作者将新位置设置为一个固定值(lastSplitViewSubViewLeftWidth
),但是可以使用divideratIndex:0的setPosition:NSMaxX(subview.frame)恢复预折叠的值。请注意,由于子视图保留其原始宽度,因此不需要通知来存储它。另请参见:当我尝试使用索引1折叠右侧拆分视图窗格时,此解决方案不起作用。我确信有一些东西可以让它工作,但这并不明显,安德烈亚斯·杰里登的解决方案工作得非常完美。+1这应该是答案,它确实如我所预期的那样工作-[NSSplitView isSubviewCollapsed:
如果子视图是隐藏的,则返回YES
。无论如何,您需要在设置隐藏后调用-[NSSplitView adjustsubview]
来更新图形。此方法有效,但是它有一个奇怪的副作用,当我将hidden设置为NO时,它会使我隐藏的视图变小,以解决@Will引用的奇怪副作用(隐藏视图会变窄),在视图取消隐藏后显式设置分隔符位置。我刚刚在OS X 10.11上测试了这个解决方案,它显示了我预期的结果:子视图
@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
}
}
}
let item: NSSplitViewItem = ...
item.isCollapsed = true