Custom UITabBarController moved to top leaving white area - ios

I have a custom UITabBarController and using setFrame in the viewDidLoad I move the tabBar to the top of the screen. This works fine.
In Interface Builder I have pushed down the elements (buttons, labels, etc) in the XIB file of the so that there is room for the tabBar at the top. I have made sure to set the Bottom Bar to none (in the simulated metrics of the inspector) and made sure that the UIView is 480 in height.
When I test this however the tabBar is at the top as expected, but the view is clipped off where the tab bar would normally be. Even the background UIImage does not show through. It is just white. How can I increase the frame size of the viewController?
I tried changing adding a setFrame command to [self view] in the viewDidLoad of the subview, but that did not do the trick.
Thanks

UITabBarController automatically sets the frame for active view controllers.
You can try to modify the view's frame afterwards or try setting clipSubviews = NO for all views.
Maybe you want to try to execute the following in viewDidAppear: or some other place (try!). This will hopefully change back the frame of the view after the tab bar controller modified it.
dispatch_async(dispatch_get_main_queue(), ^(void){
[self.view setFrame:CGRectMake(0,0,320,480);
});

Related

ios - sendSubviewToBack and bringSubviewToFront causes subviews of root view controller to move up and be overlapped by navigation bar

I have a problem with sendSubviewToBack and bringSubviewToFront calls. I create UIImageView and ScrollView with several other elements (like buttons and labels) programmaticaly (only ScrollView is created in storyboard). UIImageView have to hold a background image. ScrollView and UIImageView are added as subviews of view controller (other elements are subviews of scrollview). After I create a UIImageView and set the image like this, I call
self.backgroundImage = [[UIImageView alloc] initWithFrame:CGRectMake(0,0,self.view.frame.size.width,self.view.frame.size.height)];
[self.backgroundImage setImage:[UIImage imageNamed:#"chooseDoctorBackground"]];
[self.view addSubview:self.backgroundImage];
[self.view sendSubviewToBack:self.backgroundImage];
After that, scroll view "moves up" and becomes overlapped by navigation bar (it doesn't happening if we won't call sendSubviewToFront). There is an easy workaround - just to define position of UIImageView and UIScrollView explicitly (using setFrame) with consideration of navigation bar and status bar height. However, I don't understand the root cause of such behavior. Could you please explain it to me?
Thanks in advance!
I came here looking for help with a similar issue, and have since figured out the cause of both our problems:
When a UIScrollView is the back-most subview of your view, iOS will auto-pad the UIScrollView's content to account for the status bar and navigation bar. That is why your scroll view's content appears fine at first.
When you call
[self.view sendSubviewToBack:self.backgroundImage];
your UIImageView becomes the back-most subview, and the UIScrollView ceases to get auto-padded. That's why the content of the UIScrollView moves up underneath the navigation bar.
You'll need to manually set your scroll view's frame or content offset to account for the status and navigation bars in order to support the background view appearing behind.
(In my experience, this auto-pad behavior on UIScrollView happens even if the y origin of the scroll view is non-zero and it sits lower on the screen, nowhere near the status or navigation bars.)

Removing extra space at top of uicollectionview

I have xib in which button and uicollectionview appears as follows:
Now, when I run it , it appears as follows:
I want to remove white space above photos. I want to show photos just below from button. I have not marked header section in xib too. But, when I scroll up, the images move upto just below buttton too.This means frame is starting from just below button, but, I am getting extra white space.
So, can anybody help me to remove extra white space?
Add this code to your Controller class
- (void)viewDidLoad
{
[super viewDidLoad];
self.automaticallyAdjustsScrollViewInsets = NO;
}
Here is doc for automaticallyAdjustsScrollViewInsets
Default value is YES, which allows the view controller to adjust its scroll view insets in response to the screen areas consumed by the status bar, navigation bar, and toolbar or tab bar. Set to NO if you want to manage scroll view inset adjustments yourself, such as when there is more than one scroll view in the view hierarchy.
I had the same problem. What work for me was to set automaticallyAdjustsScrollViewInsets = NO not only on the ViewController containing the CollectionView but on its parent ViewController too, because the child ViewController was in a ContainerView.
It can be done in the Interface builder too:
Auto adjust scroll view insets

ios interface builder layout oddity

I'm using XCode+IB to layout a pretty simple view. There is a standard NavigationController navigation bar at the top. Inside the main View is another View which contains a Label, and then a table below that takes up the rest of the screen. I put the label in this container view because I want that area below the navigation bar to have a background color (gray).
The problem is that even though the main View starts just below the navigationBar, the label's container view is exists underneath the navigation bar. Sort of. You see, the label appears below the nav bar, but the gray background is somehow under the navigation bar. If I set the height of the label's view to be 75px, it just starts to appear below the navigation bar. (22+44 for statusbar and navigation bar)
Auto-layout is disabled.
So why is the View container starting below the navigation bar for the background? (but not its internal label?)
Since IOS7, I use this in the ViewController so that the content starts below the navigation bar, instead of underneath it.
if ([self respondsToSelector:#selector(edgesForExtendedLayout)]){
self.edgesForExtendedLayout = UIRectEdgeNone;
}
I realize alternatively I can set the main view's background or make the label especially large perhaps and give it a background, but I'd like to see why this isn't working first.
EDIT:
I added a feature to this View where the main view will shift upwards 125px when the keyboard is opened for some UITextFields. Interestingly, the entire view shifted except for the Label's View container. That view remained in place while it's parent view shifted up and back. The label itself shifted up and down however. So once again, the middle View seems linked to the Window, and not the actual main View...
Check if you have Adjust Scroll view Insets on!
Go to your view controller, and it is under the Attributes Inspector
You might want to consider a header cell if you just want to be able to post a message or instructions just below the nav bar. You can then avoid the extra UIView thing. The header cell will not scroll with the table view if that is your concern and it will position just below nav and above the rest of the table cells. Here is a simplified example that uses a custom header cell setting the background color. You can also drop UILabels, etc. into the cell via IB if you choose.
-(UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section
{
MyCustomHeaderCell *headerCell = [tableView dequeueReusableCellWithIdentifier:#"MyCustomHeaderCell"];
headerCell.backgroundColor = [UIColor grayColor];
return headerCell;
}

Using Autolayout, unable to move the navigation bar down 20px

I have a UITabBarController which has four tabs. One of those tabs opens a my results screen (a UITableViewController).
On showing this screen, I want to move the UINavigationBar down 20px (to make room for a custom UIStatusBar which I show on all screens).
On all my other screens, I add some code to the viewWillAppear method to change the self.navigationController.navigationBar.frame.origin.y to 20.
but these are all "non-root" screens (i.e. a pushed view with a back button).
However on THIS screen the UINavigationBar must be initially visible, even though it is the root view. I use the same code, but it doesn't move the view down.
I'm assuming autolayout is moving it back into position, so I tried adding this code into viewWillLayoutSubviews and viewDidLayoutSubviews. But when I do this the navigationbar doesn't move down until the first time the tableview is scrolled.
What do I need to do to force the navigationBar to move down (and stay down) before the screen appears?
Are you using storyboards? Set the Y in storyboards to 20, Make your viewcontroller implement UINavigation bar, then add this code:
-(UIBarPosition)positionForBar:(id<UIBarPositioning>)bar{
return UIBarPositionTopAttached;
}
This will tell the app that the navigation bar is to be attached, it will remain at 20px but extend the background all the way up.. So essentially it'll look like it's at y = 20.

Animate Controls down with change to UINavigationBar

I have a UINavigationController with standard UINavigationBar. When presenting certain UIViewControllers and orientations, the UINavigationBar may or may not appear and it may or may not have a prompt element. This means that the bar height changes frequently.
I have some subviews below the UINavigationBar set with NSLayoutConstraints to topLayoutGuide. It generally lays out as expected, adjusting vertical position of the subviews appropriately based on the height of the UINavigationBar. What it does not do is move the subviews at times when the UINavigationBar is animated after the view is already displayed.
Specifically, coming from a state with UINavigationBar hidden, transition to a UIViewController which does not hide the navigation bar to one which does. The view displays, then navigation bar animates into place. The subviews do not move down. If I rotate the device, every things lays out appropriately again. Only when animating the navigation bar in and out or to display/hide the prompt I not find a hook to reevaluate the constraints.
I tried [self.view updateConstraints] and [self.view updateConstraintsIfNeeded] in various places such as viewDidAppear, viewDidLayoutSubviews. Nothing seems to update that topLayoutConstraint.
I am familiar with edge restraints, translucent navigation bar and other various methods of keeping the entire view from appearing under the navigation bar. I do want to keep view full size and I want the translucent bar so these are not solutions for me. It seems the constraints should handle this automatically, hence the "auto" in auto layout.
To simplify, for recreation, UINavigationController with rootViewcontroller showing normal navigation bar with just a title. In viewDidLoad of the next presented viewController I have [self.navigationContoller setPrompt:self.myPrompt]. The view is presented, when the prompt is set, the navigation bar grows larger. Some labels below the bar are set with relation to topLayoutGuide, which places them correctly initially. I expect they would move down when the bar grows. Rotate device back and forth, they now layout correctly. Pop the viewController and push back to top, repeats as above.
So, it turns out it was all me. After trying all manner of forcing layout updates in all sorts of ways, the solution was to move the [myView setPrompt:myPrompt] out of viewDidLoad and call it in viewDidAppear instead.
Works completely as expected. Navbar grows, subviews shift and shrink as needed. Now I have to hunt down all the experimental code I plastered everywhere trying to do it wrong.

Resources