如何使NSView移动到所有NSView的前面

Dha*_*raj 32 cocoa nsview

我有一个超级视图,它有2个子视图.这些子视图是重叠的.

每当我从菜单中选择一个视图时,相应的视图应该成为前视图并处理动作.也就是说,它应该是最前面的子视图.

acceptsFirstResponder辞去所有工作.但是鼠标按下事件被发送到已设置的最顶层子视图.

此致,Dhana

Ada*_*ble 38

这是实现这一目标的另一种方式,它更加清晰简洁:

[viewToBeMadeForemost removeFromSuperview];
[self addSubview:viewToBeMadeForemost positioned:NSWindowAbove relativeTo:nil];
Run Code Online (Sandbox Code Playgroud)

根据此方法的文档,当您使用relativeTo:nil视图时,会NSWindowBelow在其所有兄弟节点上方(或下方)添加视图.

  • 上述方法存在问题.首先,当您将**removeFromSuperview**发送到视图时,它将被释放.因此,您首先需要保留视图,然后稍后将原始保留与发布进行平衡.其次,您需要在层次结构中删除和添加视图的开销(根据视图层次结构的复杂性,这可能会很昂贵).还有另一种方法可以避免使用NSView的内置子视图排序功能从视图层次结构中删除和添加视图.见下文. (4认同)

Dal*_*zio 15

另一种方法是使用NSView的sortSubviewsUsingFunction:context:方法根据自己的喜好重新排序兄弟视图的集合.例如,定义比较函数:

static NSComparisonResult myCustomViewAboveSiblingViewsComparator( NSView * view1, NSView * view2, void * context )
{    
    if ([view1 isKindOfClass:[MyCustomView class]])    
        return NSOrderedDescending;    
    else if ([view2 isKindOfClass:[MyCustomView class]])    
        return NSOrderedAscending;    

    return NSOrderedSame;
}
Run Code Online (Sandbox Code Playgroud)

然后,当您想确保自定义视图保持在所有同级视图之上时,请将此消息发送到您的自定义视图的超级视图:

[[myCustomView superview] sortSubviewsUsingFunction:myCustomViewAboveSiblingViewsComparator context:NULL];
Run Code Online (Sandbox Code Playgroud)

或者,您可以将此代码移动到superview本身,并将消息sortSubviewsUsingFunction:context:发送给self.

  • @Jonathan.这是UIViews的一部分,它是iOS框架的一部分.问题是关于用于OS X应用程序的NSView. (2认同)

Con*_*lon 7

在模仿等效的UIView方法的Swift 4类别中使用@Dalmazio的答案可得出以下结果:

extension NSView {

    func bringSubviewToFront(_ view: NSView) {
            var theView = view
            self.sortSubviews({(viewA,viewB,rawPointer) in
                let view = rawPointer?.load(as: NSView.self)

                switch view {
                case viewA:
                    return ComparisonResult.orderedDescending
                case viewB:
                    return ComparisonResult.orderedAscending
                default:
                    return ComparisonResult.orderedSame
                }
            }, context: &theView)
    }

}
Run Code Online (Sandbox Code Playgroud)

所以,带到subView前面containerView

containerView.bringSubviewToFront(subView)
Run Code Online (Sandbox Code Playgroud)

与删除和重新添加视图的解决方案不同,这使约束保持不变