Bring UIButton to front layer - ios

I know there is a way of bringing a subview to the front of the hierarchy. However is there a way of bringing a button that i have placed on a story and calling a function that will make that button the top layer so its not hidden by any other elements that are added that aren't in the story board.
Thanks,

I am late for this question, but not too late to answer it by Swift 3
Swift 3
view.bringSubview(toFront: theButton)

A UIButton is a UIView, so you can call -bringSubviewToFront: on your button instance.

uiview's are displayed in the order they are stacked. One can change this to say were to insert the new uiview, which in your case is a uibutton.
One way of doing that is by creating a IBOUtlet of the uibutton and adding that button instance as a subview/newview above an existing uiview.
CODE:
[self.view insertSubview:<new Uiview> aboveSubview:<existing uiview>];
Also if you are not able to figure out the order of the uiview , then you can check that in xcode
When running the project in debug mode under debug window there is a button(highlighted in below image) Debug View Hierarchy, you need to click that. (highlighted in below image)
After that you will able to see all the views rendering on the screen at current instance, using this feature you will be able to understand were is your new uiview in the uiview stack order(shown below).

Swift
The following works great if the view you are working with is being hidden views that are in the same view.
superview?.bringSubviewToFront(self)

Swift 5
In my case I had to insert my view behind some buttons. By insert it at the zero position it was placed behind the buttons.
self.view.insertSubview(self.mapView!, at: 0)

i have the same problem with you and a friend of mine helped me
i can bring my button to another subview using this function on your view controller where you declare your button.
override func viewDidLoad() {
super.viewDidLoad()
UIApplication.shared.keyWindow?.addSubview(chatButton)
}

button.superview?.bringSubviewToFront(button)

Related

Swift, button part is outside view, and i wont handle events

So i have a layout in swift:
basically the greyed out part of the selected button wont handle events, i tried:
bottomView.bringSubview(toFront: startButton)
But its not working, im new to swift, but im thinking its because
the greyed out part is outside de UIView and thats why it can't handle the event. Any suggestions or workarounds?
Is the button over the grey area view(kind of Z index)? You can always verify if the button is above the view in storyboard's Document outline (that is on left).Below is a sample view in a view controller. Look at how rabbitButton is over the snailButton
There are a few possibilities here :
Make sure that your gray view is at the top of the view stack. To do that, identify your parent view and : parentView.bringSubview(toFront: grayStartView) just as you did. So the only thing you need to make sure in your case is that bottomView is indeed the parent view of grayStartView.
If grayStartView is a UIView or a UIImageView and not a UIButton, then you need to make sure that it allows user touches, by using : grayStartView.isUserInteractionEnabled = true.
Now it might sound trivial but just in case make sure that you add the target properly if its a button : grayStartButton.addTarget(self, action: #selector(yourMethod), for: .touchUpInside) or a view : grayStartView.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(yourMethod))).
Also you need to make sure that, if you add any subview to your grayStartView, or your grayStartButton, you need to call subviewOfGrayButton.isUserInteractionEnabled = false otherwise the subview would then absorb the touches.
Finally I would check that your method (especially the sender) is properly written :
#IBAction func yourMethod(sender: UIButton) {
// ... Do some cool things here
}
If it's still doesn't work, well it would be helpful to learn more about your view hierarchy :)
Note: From what I can see it seems like you're missing a width constraint here (or maybe is it intentional?) so even though it's not related to your problem you may want to check this as well

How can I bring a view in front of another view, in Swift?

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).
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.
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.
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)
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)
In Swift 5
To bring a subview to front
self.view.bringSubviewToFront(yourView)
To send a subview to back
self.view.sendSubviewToBack(yourView)
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.
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
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,
Forward
parent.bringSubviewToFront(child)
Backward
parent.sendSubviewToBack(child)
bringSubViewToFront did not work in my case, Take a look
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

Swift : View in a UIScrollView is unable to detect touch

So I have A UIButton in a UIView within a UIScrollView within a UIViewController within a UIScrollView.. that is whole lot of layers I know but that was required. But the result I got is that the UIButton cannot be tapped because the touch can't be detected on the button. ScrollViews are working perfectly but the elements in the final layer are not detecting touches.
The Layers are as follow:
UIViewController
~UIScrollView
~~UIViewController
~~~UIScrollView
~~~~UIView
~~~~~UIButton
Kindly tell me how can I detect the touch on the last UIView?
you should debug view hierarchy by clicking debug view hierarchy button
look like this.
So you come to know that your button actually get touch events or it is hidden by other views.
Update :
I am uploading another screenshot
You have to run your project then you will able to see this button above console pane.
You can refer Apple documentation for more details.
Hope this will help :)
To solve your current problem, you need to iterate through all gestures on each super view and call requireGestureRecognizerToFail for relevant gestures on subviews. This way you make sure that the subviews get the touches 'first' and superviews handle only those touches which are ignored or not recognize by subviews for whatever reason. (I know this sounds as ridiculous as having a view hierarchy like UIViewController -> UIScrollView -> UIViewController -> UIScrollView -> UIView -> UIButton)
It seems unlikely that you could not have solved your visual design using either UITableView or UICollectionView. So reconsider!! It will save you a lot of such issues.

How to assign a higher level on a uiview in order to make it override another view?

I created a uiview and added a sub-uiview on it. Then I allow user to drag the sub-view around the screen freely. But I have problem when moving the sub-view on top of the screen. Please see below picture. The sub view override the top uiview on the screen. What I want is to let the top uiview to override the sub-view. How can I change the level of a uiview in this case?
when I use self.titleView.bringSubviewToFront(sv)
I see another problem as shown in below image. The status bar is not at the top of the image view.
You can use bringSubviewToFronton parent view to bring sub view to front as follow:
objective-C:
[parentView bringSubviewToFront:childView];
swift:
parentView.bringSubviewToFront(childView)
Edit:
use below method to manage views:
bringSubviewToFront(_:)
sendSubviewToBack(_:)
removeFromSuperview()
insertSubview(_:atIndex:)
insertSubview(_:aboveSubview:)
insertSubview(_:belowSubview:)
exchangeSubviewAtIndex(_:withSubviewAtIndex:)
like,
self.view.sendSubviewToBack(myView)
For more detail check: https://developer.apple.com/library/ios/documentation/UIKit/Reference/UIView_Class/#//apple_ref/doc/uid/TP40006816-CH3-SW46
Hope this helps :)
parentView.bringSubviewToFront(view)
UPDATE
Pay attention: you must considered that parentView is the parent of your view. To explain better this concept if you have a line like this:
self.container.addSubview(view)
so self.container is the view parent's, dont confuse it with the view below your view...it may not be the same.
If your draggable view is a subview of the image view try to set masksToBounds to true:
imageView.layer.masksToBounds = True
But the reason of your issue is probably because you set zPosition of draggableView.layer to some positive number. Usually it is better to use methods such as insertSubview(_:aboveSubview:) and bringSubview(toFront:) to manage subview's order.

IOS: How to send an Image View back and front

In my storyboard I have a view on which I have an ImageView and a Button. The ImageView is currently covering my button and I would like to put the button over the ImageView. I found similar topics which were solved by going to "Editor" -> "Arrange" -> "Send to Front", however that was done for UIViews and this option is passive for ImageView and Buttons.
So how can I send my ImageView to background? Is the best solution for this to add an additional view only for the Button and then bring it to front?
You can rearrange your views on storyboard:
First view in order will be hidden by next view.
Maybe this options will be also useful for your running application:
myImageView.layer.zPosition = -5;
myImageView.layer.zPosition = 5;
Like in HTML/CSS.
The solution was to move the view components up and down in the "Document Outline" section.
Alternatively, you could've solved the problem using the bringSubviewToFront function:
[self.view bringSubviewToFront:self.yourButtonControl];

Resources