UIToolbar as inputAccessoryView hides labels during push/pop animation - ios

I have a UIViewController inside a UINavigationController. The UIViewController class overrides -(BOOL)canBecomeFirstResponder and -(UIView *)inputAccessoryView, such that it has a UIToolbar docked at the bottom. This UIToolbar has a UILabel as a subview. I should mention that both are fully wired up programmatically using auto layout. Now when the view controller is pushed onto the navigation stack, the label is not visible during the push animation. Only after the push animation has finished, the label suddenly appears on the tool bar docked at the bottom. The exact same thing happens when the navigation stack pops back to this view controller. What could be causing this behavior?

Are you programmatically creating your constraints? I had a similar issue where the UILabel wasn't appearing at all, and I switched my constraints to use the Visual Format Language and it magically worked.

Related

UIViewController edges not extended behind top/bottom bars during a UINavigationController animation if it has a translucent UIToolbar subview

I'm displaying a translucent UIToolbar as a subview of a UIViewController which is a child of a UINavigationController (I don't use the UINavigationController toolbar as I want to subclass it).
Everything works fine but one thing: when I push another UIViewController on the UINavigationController stack, the next UIViewController edges are not extended behind the NavigationBar until the animation is over. The same issue occurs when the pop animation of the next UIViewController starts.
Side notes:
The NavigationBar is translucent (by default)
Both UIViewControllers are set to extend edges under top and bottom bars
The issue is not reproducible if the UIToolbar is not translucent (of if a tint is set).
The same issue occurs if the UINavigationController is inside a UITabBarController: the next UIViewController edges are not extended under the tabBar.
It's easily reproducible on iOS 12 and iOS 13 devices/simulators, with no code, just storyboard editing.
Does anyone has any clue regarding what's looks like a UINavigationController push/pop animation issue to me?
Here is what it looks like:
I don't observe any such issue checked on iOS 13.2 in iPhone 11 Simulator.

Add UIView that hovers over UINavigationController's UINavigationBar, but pushes with the view that adds it?

So, adding a view that appears over the UINavigationBar in a UINavigationController is easy enough:
self.navigationController?.view.addSubview(testView);
However, getting that UIView to push/transition alongside UIViewController changes in that navigation flow is more tricky. Aside from simply fading the view alpha from 1 to 0 or vice versa on appear/disappear, is there an elegant solution/hack for getting the horizontal position of the view to stay centered, for example?
EDIT: The reason why setting titleView on the UIViewController's navigationItem won't work is because when another view is popping it clips the titleView... (compare this image to the one above)

TableView Scrolls Over NavBar

When I scroll my TableView, it scrolls over my navigation bar (which I made without using the built in navigation bar for various reasons). See below:
Unscrolled:
Scrolled up:
How do I make it so that the TableView scrolls under the Navbar?
SOLVED:
I checked the "clips subviews" box for the table view to fix this problem.
To me, it looks like there may be an issue with your view hierarchy. Now, I assume that you built your own navigation bar by subclassing UINavigationBar.
In order to get the kind of behavior you need, you should have the following:
UIWindow's rootViewController is an instance of UINavigationController.
UINavigationController.navigationBar = your subclass of UINavigationBar.
UINavigationController.viewControllers[0] = UITableViewController
The UITableViewController.view = your UITableView

UIViewController auto layout in iOS8

After updating device to iOS 8 the next issues with layout occur.
I have an UITabBarController which contains two UITableViewController embedded in UINavigationController. This is main view.
Also there are several UIViewControllers designed in StoryBoard (not embedded in UINavigationViewControllers). These are secondary views. All of them have "Hide Bottom bar on Push" set to YES. Constraints are set to determine layout.
All secondary views are shown with:
UIStoryboard* sb = [UIStoryboard storyboardWithName:STORYBOARD_NAME bundle:nil];
UIViewController* secondaryView = [sb instantiateViewControllerWithIdentifier:_name];
[navigationController pushViewController:secondaryView animated:YES];
All works fine on iOS7.
But with iOS8 there are some problems when secondary view controller appears:
All pinned to bottom UIViews are shown on wrong places for a moment and then "jump" to correct place. Looks like first position is calculated including bottom bar (which is hidden due to "Hide on Push")
If there is UITableView as subview: top pinned subviews again are show on wrong place for a moment and then "jump" to correct place. Looks like first position is calculated not including navigation bar size. If i remove UITableView from controller - all works fine (except p.1)
Tried to set Simulated metrics for secondary views - did not help.
These "jumps" are really annoying. Would appreciate for any advices.
I had a similar problem with jumping when hiding the tab bar from the Storyboard.
Make sure your bottom subviews are pinned to the superview rather than the Bottom Layout Constraint.
You have to do this from the menu - Editor - Pin - Bottom Space to Superview, because the Auto Layout menu in Interface Builder pins to Bottom Layout Constraint by default.
As far as i experienced iOS 8 have issue in tabbar controller mixed with navigation bar controller .. removing one of them will make it run ok again.

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