MatterGoal
MatterGoal

Reputation: 16430

Change NSView subviews order

I'm working at a custom control that presents different handles. I want to be sure that the selected handle has a Z-index grater then the others handles.

Is there a way to swap view order? I found this function sortSubviewsUsingFunction:context: but i can't understand whether this is the right solution.

Upvotes: 8

Views: 10950

Answers (4)

Axel Guilmin
Axel Guilmin

Reputation: 11746

Cocoa introduced a new API in macOS 10.0.
It's similar to iOS, you can pass another view to be displayed below or above.

[self.view addSubview:myView positioned:NSWindowBelow relativeTo:myViewInBackground];

Checkout the documentation; in my experience NSWindowBelow and NSWindowAbove seemed reversed though.

Upvotes: 7

Marco Pace
Marco Pace

Reputation: 3870

It is pretty simple, you can use a function that compare 2 subviews to reorder them. Here a simple solution based on view's tag:

[mainView sortSubviewsUsingFunction:(NSComparisonResult (*)(id, id, void*))compareViews context:nil];

...

NSComparisonResult compareViews(id firstView, id secondView, void *context) { 
    int firstTag = [firstView tag];
    int secondTag = [secondView tag];

    if (firstTag == secondTag) {
        return NSOrderedSame;
    } else {
        if (firstTag < secondTag) {
            return NSOrderedAscending;
        } else { 
            return NSOrderedDescending;
        }
    }
}

Upvotes: 6

Alex Westholm
Alex Westholm

Reputation: 898

Yes, sortSubviewsUsingFunction:context: can do what you're looking to do, however it might be overkill if all you'd like is for one particular view to sit on top of the (unordered) others. In that case, you should look into the bringSubviewToFront: method of UIView. That way, you could do something like this in your IBAction for bringing up the handle:

[self.view bringSubviewToFront: handle];

Assuming that handle is an object that is/inherits from UIView. If this isn't what you're looking for, then by all means, go with sortSubviewsUsingFunction:context:, in which case you'll need to alter the individual tag properties for each subview, and sort accordingly.

Upvotes: -4

Mina Nabil
Mina Nabil

Reputation: 676

As i understand from you question you can loop all you view and add them to array then you have the option to add them to you view with index .. and you have the following functions.

[self.view insertSubview:view1 atIndex:2]
[self.view insertSubview:view1 aboveSubview:0]
[self.view insertSubview:view1 belowSubview:1]

then you can swap it's order as you need..

Upvotes: -6

Related Questions