I'm making an app where I add a subview to a view using addSubview: on an IBAction. In the same way, when the button with that IBAction is touched again should call removeFromSuperview on that subview added on that IBAction:
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];
}
}
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()
}
}
Try this:
-(IBAction)showPopup:(id)sender
{
if (!myView.superview)
[self.view addSubview:myView];
else
[myView removeFromSuperview];
}
UIView *subview = ...;
if([self.view.subviews containsObject:subview]) {
...
}
The Swift equivalent will look something like this:
if(!myView.isDescendantOfView(self.view)) {
self.view.addSubview(myView)
} else {
myView.removeFromSuperview()
}
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]];
}
}
Your if condition should go like
if (!([rootView subviews] containsObject:[self popoverView])) {
[rootView addSubview:[self popoverView]];
} else {
[[self popoverView] removeFromSuperview];
}
Here we used two different views. Parent view is the view in which we are searching for descendant view and check wether added to parent view or not.
if parentView.subviews.contains(descendantView) {
// descendant view added to the parent view.
}else{
// descendant view not added to the parent view.
}
Related
I am about create "No connection" view in gap between navigation bar and view controller content.
I want to subclass UINavigationViewController and move content of view controllers inside a bit down.
Question is how to do this in right way?
My current solution is working but it is also quite hacky. I would like make it better.
// subclass of AGNavigationController
-(void)viewDidAppear:(BOOL)animated {
[super viewDidAppear:animated];
static BOOL firstTime = YES;
if (firstTime) {
contentView = nil;
for (UIView *v in self.view.subviews) {
if ([v isKindOfClass:[NSClassFromString(#"UINavigationTransitionView") class]]) {
contentView = v;
break;
}
}
firstTime = NO;
origFrame = contentView.frame;
noConnectionView.frame = CGRectMake(0, self.navigationBar.frame.origin.y+self.navigationBar.frame.size.height, 320, 20);
}
[self adjustToConnection:NO withAnimation:NO];
}
-(void)adjustToConnection:(BOOL)isConnection withAnimation:(BOOL)animation {
if (isConnection) {
[noConnectionView removeFromSuperview];
contentView.frame = origFrame;
} else {
[self.view addSubview:noConnectionView];
contentView.frame = CGRectMake(0, origFrame.origin.y+20, 320, origFrame.size.height-20);
}
}
Create your UIView and set its frame to something like (0, 0, self.view.frame.size.witdh, 40).
Use [self.view addSubview:myView]; to add the view to your UIViewController.
Move your elements down in your main view, with the vertical offset set at myView.frame.size.height.
This is all you can get with a question like this one. If you need more help, you have to be more precise about what you tried, and what doesn't work.
I would like to create a popover with white color border. I have done by assigning instance of subclass to popoverBackgroundViewClass. I am able to achieve this with white color (using white image at the background )but with border of the popover is not removed. A white color border Still appears. Is there any way to remove it?
Yes, there is one crazy solution ) After you presentPopover, you need call this method
-(void)removeInnerShadow {
UIWindow *window = [[[UIApplication sharedApplication] delegate] window];
for (UIView *windowSubView in window.subviews) {
if ([NSStringFromClass([windowSubView class]) isEqualToString:#"UIDimmingView"]) {
for (UIView *dimmingViewSubviews in windowSubView.subviews) {
for (UIView *popoverSubview in dimmingViewSubviews.subviews) {
if([NSStringFromClass([popoverSubview class]) isEqualToString:#"UIView"]) {
for (UIView *subviewA in popoverSubview.subviews) {
if ([NSStringFromClass([subviewA class]) isEqualToString:#"UILayoutContainerView"]) {
subviewA.layer.cornerRadius = 0;
}
for (UIView *subviewB in subviewA.subviews) {
if ([NSStringFromClass([subviewB class]) isEqualToString:#"UIImageView"] ) {
[subviewB removeFromSuperview];
}
if ([NSStringFromClass([subviewB class]) isEqualToString:#"UILayoutContainerView"] ) {
for (UIView *subviewC in subviewB.subviews) {
if ([NSStringFromClass([subviewC class]) isEqualToString:#"UIImageView"]) {
[subviewC removeFromSuperview];
}
}
}
}
}
}
}
}
}
}
}
You can try this library https://github.com/ddebin/DDPopoverBackgroundView
UIPopoverController *popOver = [[UIPopoverController alloc] initWithContentViewController:content];
[popOver setPopoverBackgroundViewClass:[DDPopoverBackgroundView class]];
just set
[popOver.popoverBackgroundViewClass setContentInset:0.0f];
thats it.
But remember this will only work on iOS 5+
How to know if there is a UIActionSheet showing in View Hierarchy?
Also I want to get a reference to that UIActionSheet, any good idea?
Notice that on iOS6, you need a recursive search to finde the UIActionSheet, it is not a direct subview of UIWindow now.
static UIView *actionSheet = nil;
-(void)findActionSheetInSubviewsOfView:(id)view
{
if (actionSheet) {
return;
}
if ([[view valueForKey:#"subviews"] count] != 0) {
for (id subview in [view valueForKey:#"subviews"]) {
if ([subview isKindOfClass:[UIActionSheet class]]) {
actionSheet = subview;
}
else
[self findActionSheetInSubviewsOfView:subview];
}
}
}
-(UIActionSheet*) actionSheetShowing {
actionSheet = nil;
for (UIWindow* window in [UIApplication sharedApplication].windows) {
[self findActionSheetInSubviewsOfView:window];
}
if (actionSheet) {
return (UIActionSheet*)actionSheet;
}
return nil;
}
I am developing an application. In that I get all subviews of UITableViewCell.
The code for this one is:
(void)listSubviewsOfView:(UIView *)view {
// Get the subviews of the view
NSArray *subviews = [view subviews];
// Return if there are no subviews
if ([subviews count] == 0) return;
for (UIView *subview in subviews) {
NSLog(#"%#", subview);
// List the subviews of subview
[self listSubviewsOfView:subview];
}
}
But my problem is how to find out button from that subviews list. Please tell me how to solve this one.
You can iterate through all subviews like this.
for (id subview in subviews) {
if ([subview isKindOfClass:[UIButton class]]) {
//do your code
}
}
Swift
for subview in view.subviews {
if subview is UIButton {
// this is a button
}
}
Check if the subview is a button with is AnyClass, isKind(of aClass: AnyClass) or isMember(of aClass: AnyClass) API.
Using is-
for subview in self.view.subviews{
if subview is UIButton{
//do whatever you want
}
}
Using isMember(of:)-
for subview in self.view.subviews{
if subview.isMember(of: UIButton.self){
//do whatever you want
}
}
Using isKind(of:)-
for subview in self.view.subviews{
if subview.isKind(of: UIButton.self){
//do whatever you want
}
}
To expand on the 'do your code' part of Martin's answer. Once I got the subview, I wanted to test whether it was the right button and then remove it. I can't check the titleLabel of the button directly by using subview.titleLabel so I assigned the subview to a UIButton and then checked the button's titleLabel.
- (void)removeCheckboxes {
for ( id subview in self.parentView.subviews ) {
if ( [subview isKindOfClass:[UIButton class]] ) {
UIButton *checkboxButton = subview;
if ( [checkboxButton.titleLabel.text isEqualToString:#"checkBoxR1C1"] ) [subview removeFromSuperview];
}
}
}
I have a UINavigationController. On the right top i have a button on click of which i have to get a drop down table view. I created another UIViewController Class, with xib and added it as a subView to the current view. It should appear on 1st click and disappear on the 2nd click. This should happen for all click(open view and close view). I wrote this code but dont know where i'm going wrong. someone please help
-(void)modalTableView
{
tableView1 = [[TableViewController alloc] initWithNibName:#"TableViewController" bundle:nil];
for (UIView *subView in self.view.subviews)
{
if ([subView isKindOfClass:[TableViewController class]])
{
[subView removeFromSuperview];
}
else
{
[self.view addSubview:tableView1.view];
}
}
}
What am i missing here?
EDIT : TableViewController is the name of my UIViewController Class
The clue is here
for (UIView *subView in self.view.subviews)
each subView is of class UIView and your test
isKindOfClass:[TableViewController class]
is testing for class TableViewController
I would suggest a way of doing this would be by tagging the views that you add dynamically, with say 99 - and then in your loop you can identify those views by their tag.
eg.
for (UIView *subView in self.view.subviews)
{
if (subView.tag == 99)
{
[subView removeFromSuperview];
}
}
Swift version
To remove a single subview:
subView.removeFromSuperview()
To remove all subviews:
for subView in self.subviews as [UIView] {
subView.removeFromSuperview()
}
Source: What is the best way to remove all views from parent view / super view?
Try this,
if ([subView isKindOfClass:[UITableView class]])
{
[subView removeFromSuperview];
}
Here is something that should go some way to working - assuming that tableView1 is a retained #property (If not then maybe this SO answer on lazy loading techniques is for you).
-(void)modalTableView
{
if (tableView1 != nil)
{
tableView1 = [[TableViewController alloc] initWithNibName:#"TableViewController" bundle:nil];
}
if (tableView1.view.superview == nil)
{
[self.view addSubview:tableView1.view];
} else
{
[tableView1.view removeFormSuperview];
}
}