Storyboard white space at top in all model controllers - ios

Am getting a white space at top in all containers. if I do a model transition that white space is clearly visible on top of all navigation controllers.
that space is around 20px.
How to remove this white space..??
Any suggestion ???

You didn't really give us enough details in your question, but the most likely cause for your problem is that you are instantiating the subviews programmatically for your viewcontrollers using the viewcontroller's view frame rather than the bounds.
If in your viewDidLoad method you do something like:
- (void)viewDidLoad
{
[super viewDidLoad];
MyView* myView = [[MyView alloc] initWithFrame:self.view.frame];
[self.view addSubview:myView];
}
then your view will be initialized with an offset of 20px, because your self.view.frame's origin is (0, 20), in order to not overlap with the navigation bar. If you then set your subview's frame with that same origin, it means that the view's origin will be 20 px further translated down (it's not really pixels but points, as the value stays the same whether it's a retina display or not, but whatever).
So, if you want to add a subview that is the size of the view controller's view that is presenting it, then you should always initialize it with:
MyView* myView = [[MyView alloc] initWithFrame:self.view.bounds];
I hope this helps, you didn't give us much to work with in your question, in the future try to give us (many many) more details about what it is that you do, both in the code and in the storyboard.

Related

Finding The Center of a View

I have an iphone app with 2 ViewControllers . Both screens(viewcontrollers) show a loading screen. I create the loading screen programmatically:
UIView *loadingScreen = [[UIView alloc] initWithFrame:CGRectMake(100,200,144,144)];
loadingScreen.center = CGPointMake(self.view.frame.size.width / 2.0, self.view.frame.size.height / 2.0);
//{.. Other customizations to loading screen
// ..}
[self.view addSubview:loadingScreen];
For some reason, the second viewcontroller's loadingScreen is significantly lower and it isn't centered on the screen. The first viewcontroller works perfectly and is dead center like I want.
The second viewcontroller is a UITableView and it shows the uinavigationbar, whereas the first viewcontroller doesn't show the uinavigationbar. Also, I use storyboard for my app.
I've outputted to the NSLog self.view.frame.size.height and loadingScreen.center in both instances and THEY HAVE THE SAME COORDINATES! So, not sure why it is showing up lower. Any ideas why the second loadingScreen is lower and how to fix? Thanks!
You mention that one screen displays a UINavigationBar while the other does not. When you display a navigation bar, it offsets the rest of your view - in this case by shifting it down.
There are two quick fixes. You can either adjust your center point up by the size of the UINavigationBar (65 pts - unless it's a custom UINavigationBar and you've changed its size) or you can set the "Adjust Scroll View Insets" value to false in the attributes inspector.
The latter is probably the easiest and comes most recommended. Note though, that the top of your UITableView will now be underneath the UINavigationBar.
My final note would be that if you wanted to do it programmatically than in your UITableView's delegate you can call
- (BOOL)automaticallyAdjustsScrollViewInsets
{
return NO;
}

How come a UIViewController's view coordinate system starts after the navbar, but its height includes the navbar?

I noticed that with a NavigationController on an iPhone, the height is 460. So it includes the whole screen except the status bar.
However, when I add something at coordinate 0, it shows up after the NavigationBar, although the size of the navigation bar is included in the height (meaning the entire frame of this view sticks off the screen).
Did I make a mistake? If not, why is it structured this way?
NSLog(#"Frame: %#", [NSValue valueWithCGRect: self.view.frame]); // prints {(0, 20), (320, 460)}
UIScrollView* scrollView = [[UIScrollView alloc] initWithFrame: CGRectMake(0, self.navigationController.navigationBar.frame.size.height, self.view.frame.width, 50)];
[self.view addSubview: scrollView]; // showing up 44px *after* the nav bar
I already answered your other similar question, but here is one for this.
In viewDidLoad you will see the views height as 460 because at that point it hasn't resized to account for the Nav Bar.
But If you printed the same frame out in say viewWillAppear you will see that now the frames height has adjusted for the Nav Bar.
So if you want to add something in viewDidLoad, you need to add it based on the views frame, add whichever resizing mask will do the job you want, and see it adjust correctly once the view appears.

Frame sizing of tableview within nested child controllers/subviews

I'm a bit confused by the proper frame sizing of a table view to fit within my screen.
Here's my setup of view controllers within view controllers:
UITabBarController
UINavigationController as one of the tab bar viewcontrollers; title bar hidden
ViewController - a container view controller because I need the option to place some controls beneath the UITableView, sometimes (but not in the current scenario)
UITableViewController
Now, my question is what the proper frame dimensions of the UITableview should be. Here's what I've got in the ViewController viewDidLoad method. I used subtracted 49.0 (the size of the tab bar) from 480.0. However, this leaves a black bar at the bottom. 20.0 appears to do it (coincidentally?) the size of the status bar, but I don't understand why that would be. Wouldn't the true pixel dimensions of the tableview be 480-49?
// MessageTableViewController is my subclass of UITableViewController
MessagesTableViewController *vcMessagesTable = [[MessagesTableViewController alloc] init];
CGRect tableViewFrame = CGRectMake(0, 0, 320.0, 480.0 - 49.0);
[[vcMessagesTable view] setFrame:tableViewFrame];
self.tableViewController = vcMessagesTable;
[self addChildViewController:vcMessagesTable];
[[self view] addSubview:vcMessagesTable.view];
Here's how it looks:
I've run into this problem also -- I think it would be best not to hard code the size but to refer to the size of one its ancestor controllers. In this case, the UINavigationController, that's the direct child of the tabBar controller should have the right frame to fill the whole screen minus the tabBar. So I would subtract (if you need to) from that frame height if you want space at the bottom, otherwise, just use that frame. I think that self.navigationController finds the nearest nav controller above your controller of interest.

Figuring out initWithFrame:self.view.frame 20 pixel (status bar) issue once and for all

I have a simple UINavigationController. In the init method I am creating and adding a UITableView as a subview.
- (id)init {
self = [super init];
if (self) {
NSLog(#"%#", NSStringFromCGRect(self.view.frame)); // {{0, 20}, {320, 460}}
tableView = [[UITableView alloc] initWithFrame:self.view.frame];
[self.view addSubview:tableView];
}
return self;
}
I find I always run into the same annoying issue when working with new projects. Added subviews end up 20 pixels below the navigation bar.
Why is it that I end up with {{0, 20}, {320, 460}} for self.view.frame? I don't want to force the CGRect frame, I'd rather set it based on the view controller's frame so I don't run into issues with dynamic frame changes (tethering, phone call, etc. where the status bar is taller).
Update: Also noticed I am getting a 460 height for the frame. That doesn't make sense either. In my case, I actually have a tab bar, so the height shouldn't that be minus the status bar, minus the uinavigationbar and minus the tab bar heights?
Thanks
Frame of UIView takes valid arguments only when -viewWillAppear, -viewDidAppear methods are called. You should NOT rely on frame and make any calculations using it before.
Also you should NOT use (from other objects) view property of UIViewController (UItableViewController) before -viewDidLoad method is called, so you should not use view and add any controllers to it in init method, only in -loadView or (better) in -viewDidLoad. Add your subview in these methods and set its frame before appearance.
In viewController's lifecycle view can be loaded and unloaded many times (for example didReceiveMemoryWarning unloads view), view can never load at all.
You are mixing two different coordinate systems. self.view's frame is defined in the window's coordinate system (or whatever it's parent view is). tableView's frame is defined in self.view's coordinate system.
If you want something to fill the entire view, set
subView.frame = parentView.bounds;
bounds is defined in a view's own coordinate system. frame is defined in its parent view's coordinate system. So subView.frame and parentView.bounds are the same coordinate system.
When you set subview.frame = parentView.frame, they don't end up being the same thing any more than 20 grams = 20 ounces. The main view has origin at (0, 20); the subview has origin at (0, 20), but in a different coordinate system. In the window coordinate system that's (0, 40).

IOS: How to add one image just above Navigation Bar

I want to add a image just above the navigation bar. Here is the final result picture I want:
click me
At the beginning, I think it is quite simple:
Using UIBuilder add one UIImage and one UIView
Add navigation bar controller to UIView as its root view
The Hierarchy I thought should like this: UIViewController->UIView->NavigationBarController.(Here the UIView is one subview of the view of UIViewController)
Below is one of the code I tried, subView is the IBOutlet of one UIView builed by UIBuilder
UINavigationController *test;
test=[[UINavigationController alloc]init];
[[subView window] setRootViewController:test];
[subView.window makeKeyAndVisible];
But after trying several times,I found it is not working.
Does anyone do the same work before? If so, please give me some suggestions.
self.navigationController.navigationBar.frame = CGRectMake(0, //height of imageView//, self.view.bounds.size.width, 44.0f);
CodaFi's suggestion is almost there.
Try this:
test.view.frame = CGRectMake(0, //height of imageView//, self.window.bounds.size.width, //(total height of content... e.g. 460.0f if you leave the status bar visible)-(height of imageView)//);
There is one thing to note though... The navigation controller likes to take up all the usable space on screen so sometimes it will automatically resize its view to a rect like this, {{0.0f,0.0f},{320.0f,460.0f}} after rotating the device. I have experienced this many times on the iPad. You might have to start listening for the rotation event, and reset the frame of the navigation controller's view on every rotation to one that doesn't block your image.

Resources