When I switch navigationBar to translucent, my UISearchDisplayController went crazy.
The dimmed area is missplaced by 64px, same for first row in results table.
I know how to fix resultTableView missplacement, but I cannot find a way to fix dimmed area frame.
Strangely enough I found that my main view is in origin.y = 64.0f when translucent is set to YES.
It happens somewhere in between viewDidLoad, viewDidAppear. If I change it it works, but than transitions between views in navigations controller are broken.
=============
Problem solved by: extendedLayoutIncludesOpaqueBars
Check the search bar's AutoLayout/AutoResizingMask settings.
Also make sure you're not manually modifying the bar's frame as the system will try to animate the bar into its position along the dimmed view and results' table view.
When you set the translucent property and automaticallyAdjustsScrollViewInsets to YES (default): a) the view gets stretched under the navigation bar and b) a top contentInset is added to the underlying UIScrollView (table view is a subclass).
My guess is that only b) is happening in your case for some reason. You can try to solve it by either:
Clear automaticallyAdjustsScrollViewInsets.
Removing the automatically added contentInset from your scroll view.
Setting your controller to do a) even with opaque bars by setting extendedLayoutIncludesOpaqueBars.
Related
My case navigation bar color different for two controllers. When I pop from a second view controller to first one there is white line glitch in UI appears. I don't understand why issues happen, is set navigation bar shadow image to nil and use a background image for setting navigation bar background.
one reason that can cause this, is extra content from other screens overlapping each other..
try to set each view controller to have
clipsToBounds = true
See Description from Apple...
Setting this value to true causes subviews to be clipped to the bounds
of the receiver. If set to false, subviews whose frames extend beyond
the visible bounds of the receiver are not clipped. The default value
is false.
another cause is, some view controller has a background with clear color...
make sure each view controller has a non clear background.
EDIT
the question was not clear enough, it looks like I didn't understand well, try to change the tint color of navigation bar to clear.
Finally, I found my issues, issues are when I am setting a navigation bar from orange to white I set the translucent property of the navigation bar is true. which cause the problem for me to display a white line.
I'm using a UITableViewController embedded in a navigation controller, I've checked the "hide bars on swipe" for the navigation controller in the storyboard. No crazy code, scrollview functions are not overridden, didn't write any code that would offset any views.
When I scroll up the tableview a tiny bit and release it when the navigation bar is half hidden, the whole table gets offset and it's off screen (sometimes the top left corner of the table is visible), then if I scroll up the table view a bit, it's back to its normal position, if I check "adjust scroll view insets" in the storyboard, the whole screen flashes black.
Has anyone encountered the same problem?
p.s. I'm using Xcode 9 beta with iOS 10.3, not sure if this has anything to do with it.
EDIT:
Scroll navigation bar half way
The view after releasing
So I created a new set of TableviewController and NavigationController, and tested it step by step by adding changes to it, it turned out that I had set my navigation bar to be translucent in the storyboard, once I unchecked it the issue was resolved. There's still an unwanted bounce effect if I release the navigation bar at half hidden position, which appears to be the view adjusting the offset, but it's way better than what it was like.
P.S. make sure "Adjust scroll view insets" is checked.
EDIT:
Turns out setting extendedLayoutIncludesOpaqueBars to True also resolves this issue, if you want to keep the navigation bar opaque.
This a little bit wierd i have made UIPageController that works and everything is fine. But when i put it inside UINavigationController, it offset from the for status bar. Than i swipe up on that screen it positions itself right and everything is ok. I don't really understand what is happening. Here are the images
try setting adjustScrollViewInsets to false on UIPageController.
This is the property that determines whether the system should automatically add inset to a UIScrollView in your view controller's view hierarchy when it is being displayed behind transparent bars (here , the navigation bar). What happened here is that the system assumed the bounds of the page controller overlaps with that of the nav bar and so it adds insets so that the view's contents is fully visible and is not obscured by the nav bar. But in this case it is wrong since it seems your page controller's bounds starts at the bottom edge of the nav bar.
I think you can also set the nav bar as opaque to disable the automatic adding of insets.
I don't know why UITableView has bottom inset automatically despite I make UITabBarController be hidden by calling [setHidden:YES] before.
The view controller who has UITableView is a child of UITabBarController. I already know that automaticallyAdjustsScrollViewInsets helps any UIScrollView get proper 'contentInset' depending on status of it's container view controller.
So, I expected that UITableView's bottom contentInset will be 0 if UITabBar is hidden. But, doesn't do that.
Although automaticallyAdjustsScrollViewInsets is YES, should I manually adjust that value when UITabBar is hidden?
Tab bars have never been meant to be hidden - after all why have a UITabBarController if you want to hide the tab bar. In the documentation, you are warned not to modify the tab bar object directly:
You should never attempt to manipulate the UITabBar object itself
stored in this property.
This is exactly what you are doing when setting it to hidden.
In iOS6 this has worked, but now in iOS7, it doesn't. And it seems very error prone to hide it. When you finally manage to hide it, if the app goes to the background and returns, Apple's layout logic overrides your changes. There are many such triggers.
My suggestion is to change your design. Perhaps display the data modally.
Putting this here for anyone who gets this problem for nested view controllers.
My view controller containment hierarchy is:
UINavigationController
|--UIViewController
|--UITabBarController
|--UIViewController
The last view controller has a UITableView whose scrollIndicatorInsets keep getting offset by the tab bar controller's UITabBar height even if it is hidden.
Solution: Set automaticallyAdjustsScrollViewInsets to false in the view controller that contains the tab bar controller (and is inside the UINavigationController). No need to set additional properties in the tab bar controller itself and the second view controller where the UITableView is.
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.