Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/cocoa/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Cocoa 如何以编程方式展开和折叠NSSplitView的部分?_Cocoa_Expand_Nssplitview - Fatal编程技术网

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