Do an UIViewController that don't use the full screen - objective-c

I'want to do an UIViewController that don't use the full screen. The purpose is to put this view controller always on the top of other views. How can I do that ?

You can do this by setting the width and length of the view in the xib/nib. Then with set it as a subview to your view.
[self.view addSubview:yourViewController];
this should do the job.

Related

Change self.view's class type

I have a app out for testing right now that's almost completely done - just a few bug fixes left. Unfortunately, the customer decided that they'd like the entire main page of the app to be inside of a scroll view (so that there's more room for the table at the bottom). I already have everything set up and I don't really want to move everything and change references. Is there an easy way to change the class of the main view to a scroll view? I've already tried changing the class in IB and setting the class type in the init method. If there isn't I'll probably just throw the top section of the view into a nib file and load it as a custom cell.
-EDIT- I ended up changing the class type in IB and then doing
[(UIScrollView *) self.view setScrollEnabled:YES];
[(UIScrollView *) self.view setContentSize:CGSizeMake(0,2000)];
in viewDidLoad. Thanks for the help, wish I could accept all your answers.
When you are referring to [self view], I am going to assume you mean in a view controller. The view of a view controller can be any view that derives from UIView. Thus a scrollview is completely acceptable.
I don't really want to move everything and change references.
what would you have to move? why would you have to change references? Only thing you should need to do is add a scroll view to your view controller, set the view controllers view to it, and add the current view as a subview to the new scroll view. No references need to be changed, nothing has to be moved.
Refer to loadView method in documentation of view controller.
Here is a simple (untested!) example
- (void)loadView {
UIScrollView *scrollView = [[UIScrollView alloc] init] autorelease];
//Set the properties of scrollview appropriately....
self.view = scrollView;
}
Now the root view of your view controller will be a scroll view.
Note
- As the documentation states, do not do this if you are using interface builder to initialize your views/view controller. I could not tell from your description if this was the case or not. If it is, you should be able to change the view type in interface builder.
You need to set the contentSize property of your scrollview.
Since you are using IB, the easiest way to do this is to put all your UI elements into a view and add this single view to your scroll view. In the viewDidLoad method, set the content size of the scrollview to be the same size as the view that contains all your UI.
As an aside, there are much easier ways to reference views than walking down the view hierarchy, as you seem to be doing. viewcontroller.view.something.tableview. Add a connection to the tableview from your view controller in IB and it doesn't matter where that tableview is in the view hierarchy. You'll always be able to reach it from viewcontroller.tableview, no matter how you rearrange your nibs.
I think you have to use a pointer with proper type. Example for Google Maps: let's say you changed you base view's class to GMSMapView.
MapViewController.h
#property GMSMapView *mapView;
MapViewController.m
-(void)awakeFromNib{
[super awakeFromNib];
self.mapView = (GMSMapView*)self.view;
// ... etc.
}

UINavigationBar to a higher xib layer index

Similar to how z-index works in HTML, I want to make my UINavigationBar be on the highest layer so that everything in my scroll view goes underneath it.
I currently just have a xib with a UINavigationBar located at the top with a UIScrollView below it vertically that has Bounce Vertically checked. When you slide the scroll view the content from the scroll view will appear to be above the UINavigationBar and covers it.
You can set the zPosition of navigationBar to the topmost layer as below
navigationController.navigationBar.layer.zPosition =[[self.view subviews] count];
If you use a UIViewController I would suggest using this code :
self.navigationController.navigationBarHidden = false;
But if you are using a plain UIView I will refer you to the UIView documentation http://developer.apple.com/library/ios/#DOCUMENTATION/UIKit/Reference/UIView_Class/UIView/UIView.html#//apple_ref/doc/c_ref/UIView
Look for the #property(nonatomic, readonly, copy) NSArray *subviews and other subviews related method.
You can order your view relative to each other with those method.

Xcode Adding Subview on entire screen above everything

I want to use addSubview method to add new view on my screen. However, new view must also include navigation bar etc. which means it should include entire screen. What should i do?
Whenever i try to addSubview it always shows new view under navigation bar.
I don't want to use pushViewController or presentModelViewController because new added view will be low opacity and i can see background but i do not want to interact with background objects like bar buttons table etc.
Sorry for english, i hope, i clearly told what problem is.
Just set the frame property of the view you add before, and set it with screen bounds.
[myView setFrame:[[UIScreen mainScreen] bounds];
[self.navigationController.view addSubview:myView];
If you want to disable interaction with the navigation bar :
[self.navigationController.navigationBar setUserInteractionEnabled:NO];
You could take a look at adding another UIWindow above your root window.
when I tried doing the navigationController.view addSubview, it wouldn't cover my tab bar so I did the following with my app delegate's window:
[self.window addSubview:myView];
if you need access to your appDelegate from another class, you'd just import your application delegate and call it from that.

Adding a Navigation Controller to a View based Application adds top margin

I am trying to programmatically add a Navigation Controller to my View based Application. This is the code I am using (this code gets called after a button press in a view controller):
MainMenu *control = [[MainMenu alloc] initWithNibName: #"MainMenu" bundle: nil];
UINavigationController *navControl = [[UINavigationController alloc] initWithRootViewController: control];
[self.view addSubview:navControl.view];
[control release];
That works, but this ends up happening:
Notice the odd margin above the Navigation control.... My View controller that I am adding the Navigation Controller to has a gray background which you can see.
Any ideas??
If you have a better way of adding a Navigation Controller to a View based Application I am very open to suggestions!
Thank you in advance!
Thank you both for your response, but unfortunately, wantsFullScreenLayout set to YES or NO in the code didn't have any effect. I was able to push the Navigation Controller up by 20 using this line of code:
self.navigationController.navigationBar.frame = CGRectOffset(self.navigationController.navigationBar.frame, 0.0, -20.0);
but then what happened was that the View Controller did not move up with the Navigation bar and left a gap below the Navigation Bar and the View Controller. What eventually worked was checking the Wants Full Screen checkbox in IB in the MainWindow view controller that is automatically generated when you set up a view based application.
The gap you are seeing is the same height as a status bar. Check the status bar settings in your NIB file.
Chances are you want to make the UINavigationController the root view controller for the window, rather than whichever view controller you have now. That would be the better way to do it.
The reason you're seeing that extra margin at the top is because UINavigationController normally expects that it will be sized to fill the entire screen (except perhaps a tab bar at the bottom, if it's inside a UITabBarController), and therefore expects that the top edge of its view will be under the status bar if the status bar is visible. Therefore, it places its navigation bar 20 pixels below the top of its view to leave space for the status bar, without bothering to check whether its view actually is under the status bar. Interestingly, sometimes a re-layout operation will perform this check, but that's unreliable. What I've found works well in a situation like this is to set the UINavigationController's wantsFullScreenLayout property to NO. Then ti doesn't try to leave room for the status bar, so everything works as expected.
I've been struggling with this same issue this morning. Since setting the wantsFullScreenLayout property doesn't seem to have any effect, I resorted to using a little subclass, which worked fine:
#interface MyNavigationController : UINavigationController
#end
#implementation MyNavigationController
- (BOOL)wantsFullScreenLayout;
{
return NO;
}
#end
Its so simple to remove that gap..
self.navigationBar.view.frame = CGRectMake(0, -20, 320, 480);

Adding a UINavigationController as a subview of UIView

I'm trying to display a UILabel on top of a UINavigationController. The problem is that when I add the UILabel as a subview of UIWindow it will not automatically rotate since it is not a subview of UIViewController (UIViewController automatically handles updating subviews during rotations).
This is the hierarchy I was using:
UIWindow
UILabel
UINavigationController
So I was thinking I could use the following hierarchy:
UIWindow
UIViewController
UIView
UILabel
UINavigationController
This way the label could be displayed on top of the UINavigationController's bar while also automatically being rotated since it is a subview of UIViewController.
The problem is that when I try adding a UINavigationController as a subview of a view:
[myViewController.view addSubview:myNavigationController.view];
it will appear 20 pixels downwards. Which I'm guessing is because it thinks it needs to make room for the status bar. But, since the UINavigationController is being placed inside a UIView which does not overlay on top of the status bar, it is incorrectly adding an additional 20 pixels. In other words, the top of the UINavigationBar is at the screen's 40 pixel mark instead of at 20 pixels.
Is there any easy way to just shift the UINavigationController and all of its elements (e.g. navigation bar, tool bar, root view controller) up 20 pixels? Or to let it know that it shouldn't compensate for a status bar?
If not, I guess I would need to use my first hierarchy mentioned above and figure out how to rotate the label so it is consistent with the navigation bar's rotation. Where can I find more information on how to do this?
Note: by "displaying a label on top of the navigation bar", I mean it should overlay on top of the navigation bar... it can't simply be wrapped in a bar button item and placed as one of the items of the navigation bar.
Using this code seems to work:
nav.view.frame = CGRectMake(nav.view.frame.origin.x, nav.view.frame.origin.y - 20,
nav.view.frame.size.width, nav.view.frame.size.height);
I did this before adding the navigation controller as a subview. Using the [UIApplication sharedApplication].statusBarFrame instead of the hard coded 20 would probably be a good idea too.
I'm not sure if it's the best way to do it though.
If you want a frame representing the available content area, then you should just use: [[UIScreen mainScreen] applicationFrame]. Of course, this restricts your top-level view controller so that it can only be top level. So still kind of dodgy, but less so.
Why don't you use App Frame instead of adding some values to origins? I mean using:
CGRect appFrame = [[UIScreen mainScreen] applicationFrame];
as a reference frame, and do something like this:
nav.view.frame = CGRectMake(appFrame.origin.x, appFrame.origin.y, ...
This one worked for me.
I had this same problem actually but managed to fix it.
I noticed that my view controller's view had the correct frame, but the view controller's navigation bar did not (it had a frame origin of (0,20) ).
Insert this into the view's controller that is the superview of the navigation controller:
- (void) viewDidAppear:(BOOL)animated {
if (navigationController.navigationBar.frame.origin.y != 0) {
[[navigationController view] removeFromSuperview];
[[self view] addSubview:navigationController.view];
}
}
Swift 5:
add the following line in the viewDidLoad() of the root view controller of the UINavigationController.
self.edgesForExtendedLayout = [.top, .bottom]