Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I make an NSView move to the front of all NSViews

Tags:

cocoa

nsview

I have a super view, which has 2 subviews. These subviews are overlapped.

Whenever i choose a view from a menu, corresponding view should become the front view and handle actions. i.e., it should be the front most subview.

acceptsFirstResponder resigns all work fine. But the mouse down events are sent to the topmost sub view which was set.

Regards, Dhana

like image 864
Dhanaraj Avatar asked May 20 '10 10:05

Dhanaraj


4 Answers

Here's another way to accomplish this that's a bit more clear and succinct:

[viewToBeMadeForemost removeFromSuperview];
[self addSubview:viewToBeMadeForemost positioned:NSWindowAbove relativeTo:nil];

Per the documentation for this method, when you use relativeTo:nil the view is added above (or below, with NSWindowBelow) all of its siblings.

like image 98
Adam Preble Avatar answered Nov 15 '22 21:11

Adam Preble


Another way is to use NSView's sortSubviewsUsingFunction:context: method to re-order a collection of sibling views to your liking. For example, define your comparison function:

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

Then when you want to ensure your custom view remains above all sibling views, send this message to your custom view's superview:

[[myCustomView superview] sortSubviewsUsingFunction:myCustomViewAboveSiblingViewsComparator context:NULL];

Alternatively, you can move this code to the superview itself, and send the message sortSubviewsUsingFunction:context: to self instead.

like image 41
Dalmazio Avatar answered Nov 15 '22 20:11

Dalmazio


using @Dalmazio's answer in a Swift 4 category that mimics the equivalent UIView method gives the following:

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

}

so, to bring subView to the front in containerView

containerView.bringSubviewToFront(subView)

unlike solutions which remove and re-add the view, this keeps constraints unchanged

like image 18
Confused Vorlon Avatar answered Nov 15 '22 21:11

Confused Vorlon


I was able to get this to work without calling removeFromSuperView

// pop to top
[self addSubview:viewToBeMadeForemost positioned:NSWindowAbove relativeTo:nil];
like image 3
user511037 Avatar answered Nov 15 '22 21:11

user511037