How to Change the Z Index or Stack Order of Uiview

How to set iPhone UIView z index?

UIView siblings are stacked in the order in which they are added to their superview. The UIView hierarchy methods and properties are there to manage view order. In UIView.h:

@property(nonatomic,readonly) UIView *superview;
@property(nonatomic,readonly,copy) NSArray *subviews;

- (void)removeFromSuperview;
- (void)insertSubview:(UIView *)view atIndex:(NSInteger)index;
- (void)exchangeSubviewAtIndex:(NSInteger)index1 withSubviewAtIndex:(NSInteger)index2;

- (void)addSubview:(UIView *)view;
- (void)insertSubview:(UIView *)view belowSubview:(UIView *)siblingSubview;
- (void)insertSubview:(UIView *)view aboveSubview:(UIView *)siblingSubview;

- (void)bringSubviewToFront:(UIView *)view;
- (void)sendSubviewToBack:(UIView *)view;

The sibling views are ordered back to front in the subviews array. So the topmost view will be:

[parentView.subviews lastObject];

and bottom view will be:

[parentView.subviews objectAtIndex:0];

Like Kolin Krewinkel said, [parentView bringSubviewToFront:view] will bring the view to the top, but this is only the case if the views are all siblings in the hierarchy.

How do I change the z index or stack order of UIView?

I would recommend looking in the UIView documentation, where are several methods listed for the manipulation of the order of subviews:

bringSubviewToFront(_:)
sendSubviewToBack(_:)
removeFromSuperview()
insertSubview(_:atIndex:)
insertSubview(_:aboveSubview:)
insertSubview(_:belowSubview:)
exchangeSubviewAtIndex(_:withSubviewAtIndex:)

In your situation, you could try:

self.view.sendSubviewToBack(myGradientView)
// self is your view controller in this case.

Alternatively, because you created the myGradientView in IB, you could change the view hierarchy to change which views appeared on top. Here's a picture to illustrate:

Sample Image

Hope that helps.

Is there a way of setting some kind of z-index for z-position of UIImageView objects?

You said you used UIImageView. Drawing an image with UIImageView means initializing it and then adding it to a container view.

Can't you just use this code in your loop?

[containerView insertSubview:image atIndex:[[containerView subviews] count]]

The result would be that the view added first is on the top of the view stack (I haven't been able to test this yet though :) )

place button over image (level / z-index)

You can use the following methods to organise the UIView programmatically:

bringSubviewToFront:
sendSubviewToBack:
insertSubview:aboveSubview:
insertSubview:belowSubview:
insertSubview:atIndex:
exchangeSubviewAtIndex:withSubviewAtIndex:

Here you can read up on the above.

However if you're creating the views with storyboards or in an xib then reordering the items will give you the desired effect.

example ordering

Here the username UIView is behind the email UIView.

Another way of ordering is mentioned by PudiPudi, you can click the item and change it through the menus.

Another solution is the ordering at which you're adding the views programmatically. Simply changing the order of the, for example, addSubView() function will give a different layering.

UIView Positioning for iPhone: Any concept of Z-Index ?

Subviews are layered, you can send a subview to the back with...

[myView sendSubviewToBack:mySubView];

or bringSubviewToFront etc.

You can also do one of these...

[myView insertSubview:mySubview atIndex:0]; //Places it at the bottom

[myView insertSubview:mySubview belowSubview:anotherSubview]; //Places it below anotherSubview

As soon as you add a view as a subview to another view however, the parent view is the bottom of the stack. You can play around with CALayer z orders but you are bypassing the general approach of views and subviews.

Create a single view as a parent for both the bg view and the imageview, then you can order them how you like.

UPDATE: I have a UIView+Layout category which has nice [subview sendToBack]; and [subview bringToFront]; which you may find useful.... article here

Swift - UIViews order programmatically

Views are ordered from back-most to front-most in view.subviews array.


For example, here are 3 subview added to an empty view.

view.addSubview(UILabel())
view.addSubview(UIButton())
view.addSubview(UITextField())

Printing the subviews with the following code

for view in view.subviews {
print(view.debugDescription)
}

has the output

<UILabel: 0x7feef00042e0; frame = (0 0; 0 0); userInteractionEnabled = NO; layer = <_UILabelLayer: 0x60400008c210>>
<UIButton: 0x7feef00045c0; frame = (0 0; 0 0); opaque = NO; layer = <CALayer: 0x604000222300>>
<UITextField: 0x7feeef02c800; frame = (0 0; 0 0); text = ''; opaque = NO; gestureRecognizers = <NSArray: 0x60800005b090>; layer = <CALayer: 0x604000222280>>

When the views are reordered, the position in view.subviews changes

if let button = view.subviews.first(where: { $0 is UIButton }) {
view.bringSubview(toFront: button)
}

Now, printing the view, has the output

<UILabel: 0x7feef00042e0; frame = (0 0; 0 0); userInteractionEnabled = NO; layer = <_UILabelLayer: 0x60400008c210>>
<UITextField: 0x7feeef02c800; frame = (0 0; 0 0); text = ''; opaque = NO; gestureRecognizers = <NSArray: 0x60800005b090>; layer = <CALayer: 0x604000222280>>
<UIButton: 0x7feef00045c0; frame = (0 0; 0 0); opaque = NO; layer = <CALayer: 0x604000222300>>

Lower Z index of view in storyboard

First make sure the Document Outline is opened in your storyboard. It's the icon at the bottom-left of your screen.

Button at bottom-left of screen "Show Document Outline"

Then just drag the image view before the tab bar. This will bring it to the bottom.

Image is ordered before the tab bar

ios change subview index runtime

sendSubviewToBack: and bringSubviewToFront: are the methods you are looking for. Another possibility is exchangeSubviewAtIndex:withSubviewAtIndex: if you want to exchange the layer of two views.



Related Topics



Leave a reply



Submit