New UINavigationBar appearance in detail pane of UISplitViewController in iOS 13 - ios

Under iOS 13, if you setup a scrollable root view controller (such as a UITableViewController) in a navigation controller and then put that navigation controller in the detail pane of a UISplitViewController, then the nav bar's background isn't visible when the scrollable content is at the top.
You can see this by creating a new iOS project based on the Master/Detail template. Then modify the storyboard to use a UITableViewController inside the detail pane's nav controller. Put the device/simulator in Light Appearance mode (it shows the problem better than Dark mode). Run the app and notice the nav bar area is the same color as the table view background. Now scroll the table view up and the nav bar color changes to the standard light gray. Let the table view return to the top and the nav bar color disappears again.
I've only seen this in the detail pane of a split view controller.
How do you turn off this "feature" so that the nav bar looks normal just like every other nav bar used anywhere else other than the detail pane of a split view controller?
There are no relevant API changes for UISplitViewController or UISplitViewControllerDelegate. There's nothing in UINavigationController either.
After some digging I found one workaround but I'd love to find a way to avoid having to do this.
The UINavigationBar class now has some new properties for setting its appearance. Oddly, none of these are mentioned under the "Customizing the Appearance of a Navigation Bar" in the documentation for UINavigationBar.
There are three new properties in iOS 13:
standardAppearance
compactAppearance
scrollEdgeAppearance
All three are of type UINavigationBarAppearance.
Only the first one is set by default.
Even though scrollEdgeAppearance is nil, the detail pane of a split controller acts as if this has been set with the backgroundColor set to the clear color.
So the workaround is to add the following line to the viewDidLoad method of the navigation controller's root view controller:
navigationController?.navigationBar.scrollEdgeAppearance = navigationController?.navigationBar.standardAppearance
Why is this needed only in this one case? Is there a more correct solution other than adding this code?
I noticed that none of Apple's apps (Mail, Notes, and Files at least) seem to use this "feature".

The workaround you found is the 'official' way to disable this behavior, as explained in a thread on Twitter by David Duncan who is on the iOS System Experience team at Apple.
to control what happens when the UINavigationBar is completely
unfurled, you want to set the scrollEdgeAppearance. By setting
standardAppearance and scrollEdgeAppearance to the same values, you
will get a bar that doesn't change.
An Apple app that does not disable this behavior is the Settings app.

Related

Weird Fade On Navigation Bar

I was messing around on the IB on Xcode, and I some how got a fade on the navigation bar (take a look here). The color is whiter/lighter on the top part of the navigation bar and gets darker until the bottom of the navigation bar. I don't know how to return it back to a "solid" color (i.e. remove the gradient).
Anyone know how to accomplish this?
There are several ways. I don't know if this issue exists when you run the project so I will cover all the bases.
Here are some suggesstions:
Delete the Navigation Controller and embed your View Controller in a new Navigtaion Controller. The easiest way is to select your View Controller, go to the top navigation where you can see File, Edit, View, etc. and select Editor -> Embed In -> Navigation Controller.
In your viewDidLoad() you can set the colour of your navigation controller like so:
navigationController?.navigationBar.barTintColor = UIColor.blue
In your story board, you can select the Navigation Controller scene and select the Navigation Bar and play around there, however the above 2 would be preferred.
If you want the gradient at run time, see this answer: https://stackoverflow.com/a/43637829/4008175
I am making the assumption that you have not created a custom navigation bar class with an #IBDesignable element. I also have a feeling that when you run the project, the gradient won't be present, but since that is not mentioned, I would be ok if I am wrong.
See how these solutions work for you.

Can see Status Bar space but not information in iOS Swift

I add Navigation Controller(2nd View) and add one UIViewController(3rd View) as root view controller.
And then I connect segue to Navigation Controller(2nd View) from anther UIViewController(1st View).
So I can see navigation Bar with Status bar space when the view is presented.
But the information like Carriers, batteries, time information are not shown in Status Bar.
(I changed navigation Color to pink for showing you the problem.
The blue part is title view for navigation bar.)
So I tried 2 solutions.
First, I thought StatusBar Color problem. But it was not.
UIApplication.shared.statusBarStyle = .default
Second, I tried following code for showing. It was not also.
override var prefersStatusBarHidden: Bool {
return false
}
and
UIApplication.shared.setStatusBarHidden(false, with: UIStatusBarAnimation.none)
I need to solve this not-showing problem with status Bar.
I can see status Bar space but not information.
There are lots of ways to toggle the color and visibility of the status bar in iOS.
Similar question with possible correct answers for you:
How to change Status Bar text color in iOS 7
In short, if you want to toggle it between every screens, follow these steps:
In your info.plist, add this new key:
View controller-based status bar appearance and value should be NO.
In your viewWillAppear, toggle the status bar with the code you have posted:
UIApplication.shared.statusBarStyle = .lightContent - white
or
UIApplication.shared.statusBarStyle = .default - black
Edit:
Initial ViewController --> Present Modally --> NavigationController + ViewController.
This is how you set up your screens, right?. If so,
You can setup the status bar in your NavigationController properties in your Interface Builder.
And toggle the visibility and/or color of your status bar in side the viewWillAppear of your 3rd ViewController.
I suggest you check out Debug View Hierarchy.
Based on my experiences in previous projects, if I can't come up with code-based solutions on UI-related problems the simplest debugging technique that I can do is check the view hierarchy during run time.
See if the Navigation Controller View blocks the Main View which can possibly hide the status bar and if yes, work your way on solving it.
I hope it helps.

IOS Custom View or Navigation Bar Controller

I am new to IOS Swift development. I have a navigation bar design which includes, increasing the height (thus increased text size with custom colors), custom UIButton for closing (instead of the usual back button)
and title at the left side (instead of center)
Basically a lot of customization to do. My question is, is it okay to do a custom UIView to act as a navigation bar or should I push through with a NavigationController and just customize it via code?
Thank you.
First of all the navigation bar offer the push navigation through different view controllers in a smarter way, it stacking all the view controllers pushed and it offers some useful features; for example pushing another view controller from storyboard you don't have the need to set the back button and you can come back to the main controller in a simple way.
You can set a custom image for left/right button, set custom fonts and also change the height without big problems; I suggest to keep the navigation bar and evaluate, you should discover in a short time if a nav bar is enough for your needs.

Apple News app scrolling buttons in UINavigationBar

How to implement such a navigation bar? I am aware of the title view but not aware of any subtitle view.
One way I can think of is setting UINavigationBar shadow image to nil and place collection view below the navigation bar. But that won't give me translucency of Navigation bar.
Is there a native way (which may have been introduced in iOS9) of doing so?
I think you'll have to make custom view and will have to use it as navigation bar. Hide the default navigation bar and use your custom view.
I wanted to make the nav.bar as shown in picture with the functionality like tab bar and i've made custom view for that purpose.
You can use a library like PageMenu or PagingMenuController to do this easily.

How to add buttons to navigation controller visible after segueing?

I have set up a view controller in Storyboard which is embedded in a navigation controller. In this nav controller I have checked Shows Navigation Bar and Shows Toolbar and enabled a navigation bar and toolbar in Top Bar and Bottom Bar respectively in Simulated Metrics. I then "Show e.g. Push" segue from the view controller to another view controller. On both view controllers I've set up Simulated Metrics the same way, so both the navigation bar and toolbar are visible on all three controllers.
The problem is, I can add bar button items to the first view controller to both the navigation bar and the toolbar, but I cannot add a bar button item to the navigation bar on the second view controller. When I drop a button on the navigation bar, it's added to the toolbar instead. And I cannot double click the nav bar to add a title. In the outline I see there is no navigation item on the second view controller, but it is there in the first view controller.
I can probably add buttons to the navigation bar programmatically, but I want to do this visually in Storyboard. My question is, what is wrong with this setup, or is this a bug with Xcode?
For XCode 6, the UINavigationItem for the 2nd view controller onwards is not added automatically on the View Controller Object inside the storyboard. You will have to drag the UINavigationItem onto the Navigation Bar for that view Controller Object before adding UIBarButtonItem on top of it.
I am not sure why it is designed that way. I only discovered about this a few weeks ago.
If you have a ton of view controllers and very little custom auto-layout stuff in place, you can disable size classes, then re-enable it will add all missing nav bars across your storyboard.
Obviously not recommended if you have a ton of custom auto layout stuff linked up.
If you have just a single UIViewController that's missing a nav bar, just drop a UINavigationItem onto it.
If you're using Xcode 7 beta 4/5, try restarting Xcode it solved the issue for me
I just bumped into this issue and it seems to be affected by the segue that shows the view controller.
If "Kind" setting in segue is "Show (e.g. Push)", it's not possible to drag the item to top right corner. However, if you explicitly change "Kind" setting to "Push", this can be done.
Edit: actually I just noticed that "Push" is deprecated. Not sure what Apple is thinking here. However, you can just change it back to "Show" after adding the button and it seems to work :D
For second view controller in hierarchy, you can setup title in attributes, without adding "navigation item"
I think it is a bug. I had the same problem.I fixed this problem by disable the size classes, then enable it.
You can disable and enable the size classes in Interface builder doc.
It's very simple. You just need to use navigaitonItem first as the holder of the buttons and then you can add barButtonItems on top of that.

Resources