UIViewController view not size correctly when running iOS7 simulator - ios

I have a custom UIViewController which create a view containing an action bar at the top (view with 4 buttons), a tableview and then another view below the tableview. Layout is done all in code and is not using auto layout.
Everything works perfectly on various device with iOS 7.0 and 7.0.2, but in the simulator, the root view of the controller get anchored at the top right corner of the screen (0,0) instead of below the navigation bar.
I'm going to force the relay out in the viewDidAppear: method, but this seem like a hack...
Thanks for any insights
Edit: added an image. You can see the UIView highlighted. As ManicMonkOnMac mentioned, the UIView is under the toolbar (but this only happens in the simulator, on the device, the view lines up fine)
In the loadView method on the controller, i set the frame when creating the view:
- (void)loadView
{
// Our parent view controller will resize us appropriately. The size set
// here is a convenience for initial view layout.
self.view = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 320, 320)];
self.view.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
}
But this frame is later changed. Not by my code, though, but by UIkit code)
Edit2: addded loadView method body

EDIT: After going through session 201 of WWDC 2013, I think I have the solution.
in iOS 7 there is a property that you can set on your view controllers to specify whether you want the views to be overlapped by navigation bar.
viewController.edgesForExtendedLayout = UIRectEdgeNone;//UIRectEdgeAll specifies that nav bars should overlap the view.
Unlike iOS 6, navigation bars are placed over the views in iOS 7.
Use the frame size that excludes the navigation bar.
code:
CGRect frame = CGRectMake(self.view.frame.origin.x,self.view.frame.origin.y+self.navigationController.navigationBar.frame.size.height,self.view.frame.size.width,self.view.frame.size.height);
CustomView *view = [[CustomView alloc] initWithFrame:frame];
[self.view addSubview: view];

Related

InputAccessoryView covers the bottom bar

Any idea how to get an inputAccessoryView to anchor to the tab bar rather than the bottom of the screen?
I have created a UIViewController and overridden the following methods:
-(BOOL)canBecomeFirstResponder {
return YES;
}
-(UIView *)inputAccessoryView {
CGRect frame = CGRectMake(0, 0, self.view.frame.size.width, 44);
self.keyboardInputAccessoryView =[[BRKeyboardInputBarView alloc] initWithFrame:frame leftButtonTitle:#"Left" andRightButtonTitle:#"Send"];
[self.keyboardInputAccessoryView setDelegate:self];
[self.keyboardInputAccessoryView setTranslatesAutoresizingMaskIntoConstraints:NO];
[self.keyboardInputAccessoryView removeFromSuperview];
return self.keyboardInputAccessoryView;
}
View controller with inputAccessoryView covering the tab bar
By the looks of it the view controller adds the view to the window rather than the current view controllers view, which would explain its positioning. However if I remove the line:
[self.keyboardInputAccessoryView removeFromSuperview];
I get a crash when I tap in the textview of my accessory view:
The view hierarchy is not prepared for the constraint:<NSLayoutConstraint:0x7fa0c2ca5f80 BRKeyboardInputBarView:0x7fa0c2d6fad0.bottom == UIInputSetContainerView:0x7fa0c295a2c0.bottom>
So I guess what I am asking is what is the correct way to add a keyboard accessory view so that it plays nicely with auto layout and avoids the crash, but also anchors itself to the view and not the window?
What you are seeing is the right behaviour.
The results you are seeing is because of the fact that UIViewController is a UIResponder subclass. By overriding the inputAccessoryView and returning an instance of a view, UIViewController will take care of placing that view at the bottom of the screen and animating it appropriately when keyboard appears or disappears.
If you want to add this bar on top of your keyboard, then you need to set the property inputAccessoryView of a textField/textView to your custom view.

iOS 7 UIScrollView doesn't scroll when presented as modal view controller, works fine otherwise

I have a storyboard in which I have a view controller, (InfoViewController) in which I have an UIScrollView with some labels, uitextviews, etc. this is all created in IB, no code has been written at all. The only thing that is left for me to do is to set the content size, which I do as following:
-(void)viewDidAppear:(BOOL)animated{
[super viewDidAppear:animated];
CGRect screenRect = [[UIScreen mainScreen] bounds];
[self.scrollView setContentSize:CGSizeMake(screenRect.size.width, 600)];
[self.scrollView setBackgroundColor:[UIColor greenColor]];
}
Whenever I make this view the entry point of my app, it works perfectly. I can see my view, the content size is set, the background color is being set to green.
Now it comes, I created another view controller, and this view controller is now my entry point of the app. I added a button in there, and on this button I did a "modal segue" to the earlier mentioned Info View Controller.
When I now run my app, I press this button, my Info View Controller shows up. The green background color is being set, but it's impossible to scroll. So the code is being executed (otherwise the background color couldn't been green, in the storyboard it's just plain white) but somehow whenever I use this "modal segue", the scroll functionality gets lost.
How can I fix this?
Try to insert a UIView into the scroll view...
Set the UIView with top, bottom, leading and trailing space to super view to 0.
Then insert everything into the UIView rather than into the ScrollView
Then modify the constraint height of the inner UIView instead of the contentsize of the scroll view, it works with iOS7

redraw view off screen - contains picker view and tool bar

Im trying to draw/place a view (which contains a picker view and a toolbar offscreen). On launch the View is still on the screen despite changing its coordinates in viewDidLoad.
self.pickerViewContainer.frame = CGRectMake(0, 722, 320, 207);
Im using the storyboard. I have created the view in the storyboard, visible in the view controller. I thought i could redraw it off screen as per coordinates above.
When you use Auto layout write your view's frame related code in viewDidLayoutSubviews
Here is a solution
-(void) viewDidLayoutSubviews
{
self.pickerViewContainer.frame = CGRectMake(0, 722, 320, 207);
}

Screen bounds extends visible area

I'm trying to make a square (50 x 50) UIView in the lower right hand of my main view, but I'm confused about why it's not entirely visible. In this instance, only the tip of it is visible from the bottom. Am I confusing some concept?
CGFloat width = CGRectGetWidth(self.view.bounds);
CGFloat height = CGRectGetHeight(self.view.bounds);
UIView *transparentFloater = [[UIView alloc] initWithFrame:CGRectMake(width - 50.f, height - 50.0f, 50.0f, 50.0f)];
[self.view addSubview:transparentFloater];
Try to add the autoresizing mask:
transparentFloater.autoresizingMask = UIViewAutoresizingFlexibleTopMargin | UIViewAutoresizingFlexibleLeftMargin;
If I am not wrong, You have created your ViewController with xib and in the attributes of view, you have forgot to mention that you are using a "navigation bar" as "top bar".
Reason
So in ViewDidLoad, view in .xib with a height X is returned. But as you might have loaded the viewController using UINavigationController, after loading the height of view is decreased by 44pixels.
Suggestions :
1) Whenever you know that you are going to have navigation bar on top please mention it in .xib file as well.
For doing so click on the view in xib and select the option called topbar in attributes Inspector of utilities area
2) Call the following api
NSLog(#"In ViewDidAppear %#",NSStringFromCGRect(self.view.bounds));
in
viewDidLoad
viewDidAppear
to track whats happening with the bounds of view
You does not need to do anything just put
transparentFloater.backgroundColor = [UIColor redColor];
because your view (custom) is invisible (because your main view color and custom view color are same (white) ) may be. I tried your code in my demo project. it worked perfectly for me.

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.

Resources