39

Below are how my views are organized in IB, top->bottom when the app is started.

The user can do something to make "Category Table View Header" temporarily expand over "Name View" - however once doing so, the .TouchDown action assigned to "Category Table View Header" no longer works wherever it overlaps with "Name View" (i.e., the user can tap the header anywhere it doesn't overlap with name view and it still works).

enter image description here

I know that may be confusing, so I drew out some boxes. On the left is the original, right is after user action - problem is on the right the action on the red box only works if the user taps the bottom half, not the top half.

enter image description here

My guess is its because the header is lower in the view hierarchy than the name view, but it would be hard for me to change that without messing around with a bunch of constraints.

I also tried setting nameView.hidden = true, but that doesn't work.

vk2015
  • 1,118
  • 1
  • 12
  • 16
  • it shouldnt mess with your constraints moving it around in the view hierarchy, so long as it stays at the same level, put your `Name View` below your `Choose Quote View` (not in it) and it should work – Fonix Aug 05 '16 at 03:46
  • Hey Fonix - thanks for the suggestion, but that seems to only make the view "appear" in front of the one below it in the view hierarchy. The actions associated with that view do not. In other words, I still run into the problem faced by the boxes I drew in my original question - the action doesn't work in the "overlap area". – vk2015 Aug 05 '16 at 22:05
  • 1
    I think I figured it out - you can't move a view's child in front of that same view's sibling. I fixed it by "upgrading" the view's child to be its sibling, then moving it to the front. – vk2015 Aug 06 '16 at 00:22

7 Answers7

78

If you want to bring a subview to the front, you can use:

SWIFT 4 + UPDATE

self.view.bringSubviewToFront(yourView)

SWIFT 3 UPDATE

self.view.bringSubview(toFront: yourView)

Send view to back:-

SWIFT 4+ UPDATE

self.view.sendSubviewToBack(yourView)

SWIFT 3 UPDATE

self.view.sendSubview(toBack: yourView)

SWIFT 4+ UPDATE - INSERT VIEW ON SPECIFIC LOCATION IN THE STACK

 parentView.insertSubview(yourView, belowSubview: requiredViewOnStack)
 parentView.insertSubview(yourView, aboveSubview: requiredViewOnStack)
Mudith Chathuranga Silva
  • 7,253
  • 2
  • 50
  • 58
  • 1
    That didn't work for me - the actions associated with the view moved to the front do not, also, "move to the front" In other words, I still run into the problem faced by the boxes I drew in my original question - the action doesn't work in the "overlap area". Maybe the title of this question is misleading as it suggests the solution involves reordering, when there is actually a different solution. – vk2015 Aug 05 '16 at 22:24
16

Swift 5.1+

UIKit draws views back to front, which means that views higher up the stack are drawn on top of those lower down. If you want to bring a subview to the front, there's a method just for you: bringSubviewToFront(). Here's an example:

parentView.bringSubviewToFront(childView)

This method can also be used to bring any subview to the front, even if you're not sure where it is:

childView.superview?.bringSubviewToFront(childView)
YodagamaHeshan
  • 4,996
  • 2
  • 26
  • 36
10

In Swift 5

To bring a subview to front

self.view.bringSubviewToFront(yourView)

To send a subview to back

self.view.sendSubviewToBack(yourView)
Vinoth Vino
  • 9,166
  • 3
  • 66
  • 70
4

You can take a control over the order of subviews using methods: bringSubviewToFront and sendSubviewToBack from the superview.

You can access all the subviews contained by superview using self.view.subview array.

tosha
  • 168
  • 1
  • 8
  • Thanks, Tosha - that didn't work for me - the actions associated with the view moved to the front do not, also, "move to the front" In other words, I still run into the problem faced by the boxes I drew in my original question - the action doesn't work in the "overlap area". Maybe the title of this question is misleading as it suggests the solution involves reordering, when there is actually a different solution. – vk2015 Aug 05 '16 at 22:24
  • I see. Please, tell me first - how did you actually associated action with the view (button, or tap gesture..,) ?? – tosha Aug 06 '16 at 05:31
  • Hey tosha - I think I figured it out, as mentioned in my comment above. I needed to upgrade my view from child to sibling. – vk2015 Aug 06 '16 at 11:56
1

The method has been updated since swift 3

What has worked for me and hopefully for you is using :

YourView.bringSubview(toFront: yourelementA)
YourView.bringSubview(toFront: yourelementB)

Alternatively you could use the following to send the object that is in the front:

YourView.sendSubview(toBack: yourelementC)

I hope this helps

K-A
  • 67
  • 6
1

Swift 5.4

views in UIKit are drawn from the back towards the front (like adding icing onto a cake). This means that the new views will be placed on top/over the previously placed views. (e.g. Icing is the new view and the base of the cake being the old view.

You can use the following to manipulate the views Z-position using,

  1. Forward
parent.bringSubviewToFront(child)
  1. Backward
parent.sendSubviewToBack(child)
Visal Rajapakse
  • 1,718
  • 1
  • 9
  • 15
-1

bringSubViewToFront did not work in my case, Take a look

enter image description here

As I wanted this notification count comes before image, bringSubViewToFront did not work, So I just drag this label below to stack view of my imgae and bottom label, it worked for me. I hope this will work for all

Deepak Ghadi
  • 163
  • 2
  • 5