Check if a subview is in a view
Solution 1
You are probably looking for UIView's -(BOOL)isDescendantOfView:(UIView *)view;
taken in UIView class reference.
Return Value YES if the receiver is an immediate or distant subview of view or if view is the receiver itself; otherwise NO.
You will end up with a code like :
Objective-C
- (IBAction)showPopup:(id)sender {
if(![self.myView isDescendantOfView:self.view]) {
[self.view addSubview:self.myView];
} else {
[self.myView removeFromSuperview];
}
}
Swift 3
@IBAction func showPopup(sender: AnyObject) {
if !self.myView.isDescendant(of: self.view) {
self.view.addSubview(self.myView)
} else {
self.myView.removeFromSuperview()
}
}
Solution 2
Try this:
-(IBAction)showPopup:(id)sender
{
if (!myView.superview)
[self.view addSubview:myView];
else
[myView removeFromSuperview];
}
Solution 3
UIView *subview = ...;
if([self.view.subviews containsObject:subview]) {
...
}
Solution 4
The Swift equivalent will look something like this:
if(!myView.isDescendantOfView(self.view)) {
self.view.addSubview(myView)
} else {
myView.removeFromSuperview()
}
Solution 5
Check the superview of the subview...
-(IBAction)showPopup:(id)sender {
if([[self myView] superview] == self.view) {
[[self myView] removeFromSuperview];
} else {
[self.view addSubview:[self myView]];
}
}
pmerino
Software developer with experience with Ruby, Ruby on Rails, Java, HTML, CSS, PHP, C#, JavaScript, Bash, Objective-C, MySQL, Postgres, SQLite, MongoDB, Redis as well as UNIX system administration.
Updated on July 08, 2022Comments
-
pmerino almost 2 years
I'm making an app where I add a subview to a view using
addSubview:
on anIBAction
. In the same way, when the button with thatIBAction
is touched again should callremoveFromSuperview
on that subview added on thatIBAction
:PSEUDO CODE
-(IBAction)showPopup:(id)sender { System_monitorAppDelegate *delegate = (System_monitorAppDelegate *)[[UIApplication sharedApplication] delegate]; UIView *rootView = delegate.window.rootViewController.view; if([self popoverView] is not on rootView) { [rootView addSubview:[self popoverView]]; } else { [[self popoverView] removeFromSuperview]; } }
-
pmerino over 12 yearsDoesn't works, just adds the view over it. I'll edit the code to show the real case
-
pmerino over 12 yearsDoesn't works, just adds the view over it. I'll edit the code to show the real case – zad0xsis 1 min ago edit
-
Admin over 12 years@zad0xsis - I don't understand the real case. If you added the second view using
addSubview:
method (which is probably the case the first time), the next time, you'll reach the else part because the second view now is a subview of the first. Isn't it what you were trying to do ? You are maybe looking another mecanism like prensenting a view controller modally ? -
pmerino over 12 yearswell,
popoverView
is a subview of rootView (rootViewController). I want to check if it's on screen (if it has rootView as superview) and if so remove it or else add it if it's not -
bshirley over 12 yearsis
[self popoverView]
returning a newly created popover each time? it cannot add a view "over it" if it's the same view, adding a view that's already there is a no-op. if thepopoverView
method is creating a new one every time, then it will always not be in the view hierarchy -
paulmelnikow over 12 years@zad0xsis Would you clarify what you mean by "just adds the view over it"? Does that happen on the first call when the view should display, or on the second when the view should hide?
-
paulmelnikow over 12 yearsThis is a slight modification of Michael Frederick's answer. Does it give different results from Vincent's code which uses
isDescendantOfView:
? -
Lior Frenkel over 12 yearsawesome! sometimes it needs myView.view.superview, but it worked like magic for me. Thanks @MarkGranoff
-
Rhubarb over 11 yearsOne important consideration that tripped me up here: when removing then adding subviews that you're holding onto with IBOutlet properties (or ivars) you need to make sure the properties (ivars) are strong, or that (pre ARC) they're retain. By default if you ctrl-drag from a view to a controller to create an outlet, it will create it as weak because it assumes that the view created in the nib will own it so you dont need a strong reference. But if you then remove it programmatically, it will dealloc the control and set your reference to nil (in ARC).
-
Rhubarb over 11 yearsNote also that Objective-C is so lenient about calling methods on
nil
that you won't see any exception when your view references are dealloced only weird behaviour like missing views -
Thomas Kekeisen over 11 years@pmerino Congrats for being that lazy that you also copied "zad0xsis 1 min ago edit" :-)
-
Sami Samhuri almost 10 yearsIt absolutely yields a different result. This only checks if it is a child view, not a grandchild or great grandchild, etc.
-
SimplyKiwi almost 8 yearsI think this is more expensive than the other solutions to be honest because it has to iterate through all subviews
-
Chirag Purohit over 6 yearsIt worked for me. I am checking whether particular element exist in tableview cell or not
-
Ali Pacman over 2 yearsI think the problem here is that if a view is a subview of a subview, it won't be found.