Adding a new view on top of an existing view - ios

I want to add a view called anotherView on top of self.view. But I don't want anotherView to be a subview. Is this possible?
I want anotherView to be at the top of the page and push the contents of self.view down accordingly (without having to change the y or height values.
I have the following and it doesn't work:
UIView *anotherView = [[UIView alloc] initWithFrame: CGRectMake(0, 0, self.view.frame.size.width, 80)];
anotherView.backgroundColor = [UIColor yellowColor];
[self.view insertSubview:anotherView aboveSubview:self.view];
The box is simply on top of the existing view.

Any visible view is subview of some other view or window.
But you can add anotherView to
self.view.superview
or even
self.view.window
or create new UIWindow object and add your subview to this window

Have you tried to present anotherView modally? That way you can make it to appear on top of everything being a completly new view controller. Ex:
[self presentModalViewController:anotherView animated:YES];
assuming of course anotherView is a subclass of UIViewController and has its own View property. Because if anotherView is just subclass of UIView then you can't present it without being a subview of the current View Controller.
EDIT:
Oh yes, you can just pass a nil to the completion block:
[self presentViewController:anotherView animated:YES completion:nil];

Related

How can I add a common view to multiple ViewControllers in iOS Swift?

I'm kinda new to iOS development.
I want to have a custom View and some Labels inside it. And In some viewControllers of my app on a button click I want to add/show that View
at the bottom of that viewController.
As far as I'm manually adding the view in storyboard in all the viewControllers in which I want the view to display. But this is not efficient. How can I add this view in viewControllers programmatically on button click?
Make one BaseViewController class inherited with UIViewController
Now create method named as designFooter in BaseViewController
func designFooter() {
var viewFooter: UIView = UIView(frame: CGRectMake(0, self.view.bounds.size.height - 50, self.view.bounds.size.width, 50))
viewFooter.backgroundColor = UIColor.redColor()
self.view!.addSubview(viewFooter)
}
For Swift 4, 5.1:
func designFooter() {
let viewFooter: UIView = UIView(frame: CGRect(x:0, y:self.view.bounds.size.height - 50, width:self.view.bounds.size.width, height:50))
viewFooter.backgroundColor = UIColor.red
self.view.addSubview(viewFooter)
}
Now inherit this BaseViewController to you ViewController where you want to add footer, and on button click just call self.designFooter()
If this subview you want to add has some dynamic content or has much of its own logic, you might want to employ view controller containment, specifically not only add a subview, but add a controller associated with that subview, too. So, you can have a scene in your storyboard for this subview that will appear on the bottom, and associate it with its own view controller. Then, when you want to add it, you'd do something like:
let child = storyboard!.instantiateViewController(withIdentifier: "storyboardid")
addChild(child)
// set the `frame` or `constraints` such that it is in the correct place, perhaps animating it into place
view.addSubview(child.view)
child.didMove(toParent: self)
And when you want to remove it:
child.willMove(toParent: nil)
child.view.removeFromSuperview()
removeChild(child)
Personally, if this can really appear and disappear from any scene in my app I actually embed the whole app in a container view controller. Then this popping of the child in and out only has to be done once, on this master container view controller.
For example, consider this storyboard:
That is an embedded "container view" (the storyboard equivalent of view controller containment, discussed above). And I can then have a label animate in an out (by animating layoutIfNeeded after changing the height constraint of some view with a label). Then, this bottom view can animate in and out regardless of which view controller's view is currently visible:
Just create a UIView and call addSubview:
UIView *view = [[UIView alloc] initWithFrame:CGRectMake(0,0,100,100)];//change this frame for your purposes
UILabel *l = [[UILabel alloc] initWithFrame:CGRectMake(10,10,50,10)];
[l setText: #"My label"];
[view addSubview: l];
[self.view addSubview: view];
As far as adding this to multiple view controllers... I suppose if you had a lot of different view controllers with this same UIView you could create a subclass of UIViewController called CustomViewController. In that class add the above code to viewDidLoad. Then, subclass CustomViewController in all the view controllers with this particular view, and they will automatically add it for you.
Edit:
If you want to design the view in interface builder, make a custom subclass of UIView. Let's call this CustomView. Design it in a nib and add any code you want. Then, whenever you want to create that view, simply call CustomView *cv = [[CustomView alloc] initWithFrame:...] and then do [self.view addSubview:cv];

Creating UIView in UITableViewController that doesn't moves with the table view

I would like to display a small UIView with some text in the center of a UITableViewController when I call the showHud method.
- (void) showHud {
UIView *paintView=[[UIView alloc]initWithFrame:CGRectMake(150, 150, 120, 30)];
[paintView setBackgroundColor:[UIColor yellowColor]];
[self.view addSubview:paintView];
}
Actually the problem with this code is that the view doesn't stays on its place, when I scroll the tableview it goes up with cells. Is it possible to pin it somehow?
I don't think you can achieve that with a UITableViewController because the view property of such controller is a UITableView, so the content will always scroll with it.
You need to create a regular UIViewController and add a UITableView to that controller's main view. Then anything else you add to that main view, will stay in place as it is outside of the table view.
Try implementing scrollViewDidScroll delegate method and change the frame of paintView according to tableview offset.
eg:
- (void)scrollViewDidScroll:(UIScrollView *)scrollView {
CGPoint offset = scrollView.contentOffset
[paintView setFrame:CGRectMake(150, 150+offset.y, 120, 30)];
}
But the best way would be to create a simple UIViewController.
You must use UItableViewController because of pullToRefresh controller?
UI could add a view to the window and position it to the very front:
UIView testView = [[UIIView alloc]initWithFrame:CGRectMake(10, [[UIScreen mainScreen]applicationFrame].size.height - 85 , 75, 75)]; [[[[[NSApplication sharedApplication] mainWindow] contentView] addSubview:testbox]; addSubview: testView]; testView.layer.zPosition = MAXFLOAT;
An UITableViewController is typically embedded in a "parent" view controller, like UINavigationController. Its UITableView will then have a superview, like UINavigationControllerWrapperView. Even if your table view controller is a root view controller, the table view's superview is UIWindow.
So you can safely assume that your table view always has a superview. Then add your UIView to this superview instead of the table itself:
//Note: frame should be different here as it's in the superview's coordinate system
UIView *paintView=[[UIView alloc]initWithFrame:CGRectMake(150, 150, 120, 30)];
[paintView setBackgroundColor:[UIColor yellowColor]];
[self.view.superview addSubview:paintView];

Subclass UIView from ViewController

I'm trying to show an onscreen tutorial (like a picture with hints) in my viewController. I only know how to "open" a UIView with its drawRect method, where my paint code is inside, from the AppDelegate with:
BannerView *view = [[BannerView alloc] initWithFrame:self.window.frame];
[self.window addSubview:view];
[self.window makeKeyAndVisible];
Is it possible to activate the UIView (BannerView) by a button from inside a ViewController?
Thank you very much!
Simply use this code:
BannerView *view = [[BannerView alloc] initWithFrame:self.view.bounds];
[self.view addSubview:view];
in your button action method (if it is defined in your controller class). See this S.O. question to know how to create a button programmatically. Otherwise, you can use interface builder for that.
Using self.view.bounds in initWithFrame will make your banner view as large as the controller's view (which could be smaller than the display).
I believe what you are looking for is adding an event handler to a button on the view controller that will create the view and add the view by using something like
BannerView *view = [[BannerView alloc] initWithFrame:CGRectMake(x,y,width,height)];
[self.view addSubview:view];
where self is the view controller.

How to also animate subview in navigation bar?

I have a subview in my navigation bar. I try to add it by this way:
UIView *customView =
[[UIView alloc] initWithFrame:
CGRectMake(0, 0, image.size.width + label.frame.size.width, 44)];
UIImageView *imageView = [[UIImageView alloc] initWithImage:image];
[customView addSubview:imageView];
[customView addSubview:label];
[self.navigationController.navigationBar addSubview:customView];
However, when I try to push the navigation bar, the customView stays in the place, not animating following the sliding navigation bar. How can I achieve the animated subview? Is it even possible? Thanks!
you should not add subview in that way
you have tospecify your view location in the left , right or title view
self.navigationItem.titleView = YOURVIEW;
or choose another location left or right items in this way the the title view will added to the current view if you want to remove it just set it to nil in the place you want and reload it subviews again,
self.navigationItem.titleView = nil;
As you are using
[self.navigationController.navigationBar addSubview:customView];
that means the navigation bar you have create is in App delegate and is common for all the viewControllers in your project,that is why once you add a view on to it you see it on every view you have. Remove your sub-view in
-(void)viewWillDisappear:(BOOL)animated{
[Your subview remove fromSuperView];
[super viewWillDisappear:YES];
}
and add that subview in
-(void)viewWillAppear:(BOOL)animated{
[self.navigationController.navigationBar addSubview:Your subview];
[super viewWillAppear:YES];
}
this will add the subview in that particular view only and remove it as soon as that view is popped or pushed.The code given is not correct to the syntax please give a check on that.

Replacing self.view with new UIView shows black view

I want to change the existing view in a UIViewController to a new view. The new view contains the old view and a little banner view.
Doing this fairly simple change leaves me with a black view.
My code looks like this
UIView *existingView = self.view;
UIView *newView = [[UIView alloc] initWithFrame:existingView.frame];
UIView *bannerView = [[UIView alloc] initWithFrame:CGRectMake(0, (self.view.frame.size.height - 50), 320, 50)];
CGRect existingViewFrame = existingView.frame;
existingViewFrame.size.height -= 50;
existingView.frame = existingViewFrame;
[newView addSubview:existingView];
[newView addSubview:bannerView];
self.view = newView;
However when switch Tabs and come back to the view which changed the view is shown just like I want. I guess I need to set a flag or something to tell the controller to redraw it's (new) view.
Edit
I wrote an simple example for this problem. You can find it on GitHub: https://github.com/Oemera/ChangeView
You did not say where you do this. It may be that you need to save the original view's super view, then add the new view to that views subViews array. I'm betting that is the problem.

Resources