How to set title of Navigation Bar in Swift? [duplicate] - swift

This question already has answers here:
what would be a proper storyboard example of combining nav bars and tab bars in one app?
(2 answers)
Closed 7 years ago.
I'm trying to set title of Navigation Bar in Swift, I set Tab Bar and in Navigation Bar nothing is showing, no button, no title, nothing. I used some code but it's not working while I use Tab Bar, and when I deleted Tab Bar, code is working and everything is ok with Navigation Bar, title is showing and buttons are showing.
Code that I used for title is:
override func viewDidLoad() {
super.viewDidLoad()
self.navigationItem.title = "My Title"
}
And in Main.storyboard I connected Navigation Controller with Tab Bar Controller, as in picture.
So, how to fix this ? The problem is that Navigation Bar is not working while using Tab Bar.

Since the Tab Bar is actually the Root View Controller of the Navigation Bar, you need to set the UITabBarController's title instead in the viewWillAppear function so that it happens every time you switch tabs:
override func viewWillAppear(animated: Bool) {
super.viewWillAppear(animated)
self.tabBarController?.navigationItem.title = "My Title"
self.tabBarController?.navigationItem.leftBarButtonItem = settingsButton //This is the IBOutlet variable that you previously added
}
But a better way to do it would actually be to have it the other way around, like so
You should hook up a UINavigationController for each child of the UITabBarController, as it is more correct semantically, and simpler to maintain.

Your question is unclear, if the code you presented is from UIViewController that is kept inside UINavigationController and navigationBar is shown you can simply use:
override func viewDidLoad() {
super.viewDidLoad()
self.title = "My Title"
}

In UINavigationController Class Reference Apple wrote this:
init(rootViewController: UIViewController)
Parameters
rootViewController
The view controller that resides at the bottom of the navigation stack. This object cannot be an instance of the UITabBarController class.
But you can do it if you insisted.But in this case , your ViewControllers of tabbarController all shared the same title,which is the title of tabbarController.
A better way to do it is to give each of tabbarController's viewControllers a NavigationViewController.

Related

StatusBar text color doesn't change to Light Content [duplicate]

Adding
application.statusBarStyle = .lightContent
to my AppDelegate's didFinishLaunchingWithOptions method nor adding
override var preferredStatusBarStyle: UIStatusBarStyle {
return UIStatusBarStyle.lightContent
}
to the VC no longer works on iOS12/Xcode10
Any ideas?
This has nothing to do with iOS 12. You just have the rules wrong.
In a navigation controller situation, the color of the status bar is not determined by the view controller’s preferredStatusBarStyle.
It is determined, amazingly, by the navigation bar’s barStyle. To get light status bar text, say (in your view controller):
self.navigationController?.navigationBar.barStyle = .black
Hard to believe, but true. I got this info directly from Apple, years ago.
You can also perform this setting in the storyboard.
Example! Navigation bar's bar style is .default:
Navigation bar's bar style is .black:
NOTE for iOS 13 This still works in iOS 13 as long as you don't use large titles or UIBarAppearance. But basically you are supposed to stop doing this and let the status bar color be automatic with respect to the user's choice of light or dark mode.
If you choose a same status bar color for each View Controller:
<key>UIViewControllerBasedStatusBarAppearance</key>
<false/>
Ad this to your Info.plist and set status bar color from Project -> Targets -> Status Bar Style by desired color.
On the other hand, in your case, you have a navigation controller which is embedded in a view controller. Therefore, you want to different status bar color for each page.
<key>UIViewControllerBasedStatusBarAppearance</key>
<true/>
Ad this to your Info.plist. Then, create a custom class for your NavigationController. After that you can implement the method:
class LightContentNavigationController: UINavigationController {
override var preferredStatusBarStyle: UIStatusBarStyle {
return .lightContent
}
}
Thats it! Please, inform me whether this was useful!
If Matt's answer isn't working for you, try adding this line of code before you present your viewController.
viewController.modalPresentationCapturesStatusBarAppearance = true
I encountered a bug where setting modalPresentationStyle to overFullScreen does not give the status bar control to the presented view controller or navigation controller.
I was using navigation controller for each tab of UITabBarController. Subclassing UINavigationController and overriding childForStatusBarStyle fixed the issue for me.
class MyNavigationController: UINavigationController {
open override var childForStatusBarStyle: UIViewController? {
return topViewController?.childForStatusBarStyle ?? topViewController
}
}
If you have a modal UIViewController the situation becomes very tricky.
Short answer:
Present modal using UIModalPresentationStyle.fullScreen
override preferredStatusBarStyle (in your modal vc)
call setNeedsStatusBarAppearanceUpdate() in viewWillAppear (in your modal vc)
If you don't want to use UIModalPresentationStyle.fullScreen you have to set modalPresentationCapturesStatusBarAppearance
According to apple doc:
When you present a view controller by calling the
present(_:animated:completion:) method, status bar appearance
control is transferred from the presenting to the presented view
controller only if the presented controller's modalPresentationStyle
value is UIModalPresentationStyle.fullScreen. By setting this property
to true, you specify the presented view controller controls status bar
appearance, even though presented non-fullscreen.
The system ignores this property’s value for a view controller
presented fullscreen.
You can set
vc.modalPresentationCapturesStatusBarAppearance = true
to make the customization works.
Customizing UINavigationController can fix the issue
class ChangeableStatusBarNavigationController: UINavigationController {
override var preferredStatusBarStyle: UIStatusBarStyle {
return topViewController?.preferredStatusBarStyle ?? .default
}
}
Ref: https://serialcoder.dev/text-tutorials/ios-tutorials/change-status-bar-style-in-navigation-controller-based-apps/

How to get the navigation bar to show large title upon a segue back?

I have a tab bar app where one of the views is a UITableViewController containing static cells as content with 1 section and 1 row.
I want the Large Title to be set to "Always," so I made the selection on the storyboard and the title was large on the simulator. Now when the user taps "Start Chat," the app will segue to the Virtual Assistant View Controller, where the Large Title is set to "Never" on the storyboard. Now the problem is that when the user segues back to the previous view controller with the "Start Chat" table view cell, the title is not large anymore.
It is interesting that when I set the table view to be scrollable, the title becomes large again upon dragging down the table view. I made sure the navigation bar on the Navigation Controller storyboard is checked with the "Prefers Large Titles." I am using Xcode 11, and this was not a problem when using Xcode 10.
I tried creating a custom class for the view with the start chat button and this code did not work in making the title large from a segue back:
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
navigationController?.navigationItem.largeTitleDisplayMode = .always
navigationController?.navigationBar.prefersLargeTitles = true
What else could I do? Any help will be greatly appreciated!
I'd use willMove(toParent:) to change the title back before the segue is performed.
override func willMove(toParent parent: UIViewController?) {
navigationController?.navigationItem.largeTitleDisplayMode = .always
navigationController?.navigationBar.prefersLargeTitles = true
}
Set the properties when setting up the UINavigationController, before presenting it. If you already presented the navigation controller, try doing this to force-update the navigation bar:
navigationController?.navigationItem.prompt = ""
navigationController?.navigationItem.prompt = nil
I took this workaround from this question.
In your particular case, it would be better to subclass the navigation controller and set those properties in its viewDidLoad method, so its properties (largeTitleDisplayMode and prefersLargeTitles) are set in a self-contained code.

UINavigationController's children views don't have UINavigationItem to set the title

I have a UINavigationController implemented to have the kind of pop/push functionality. However, on the children views I cannot set the title of the Navigation Bar, but rather only on the first view:
On the "Buzzy" page as seen above, when I select the navigation bar, the utilities tab shows me that it is a UINavigationItem and I can edit its title. However, on one of the children views, such as the one with "Tappable Area", the navigation bar cannot be selected and the title cannot be added.
How do I add the title for children views as well?
Drag a Navigation Item object from the Objects palette (cmd-shift-L) onto the view controller and select it.
You should now be able to set the title, add UIBarButtonItems etc.
try with self.navigationItem.title = "Your title"
Normally this is done in view did load on the view controller:
override func viewDidLoad() {
super.viewDidLoad()
self.title = "some title"
}
However, this only works if you have your view controller embedded in a UINavigationController. I highly recommend doing this instead of creating a navigation bar yourself. If you insist on creating a navigation bar yourself, you can change the title by doing:
navigationBar.topItem.title = "some title"

Swift change tabBar title after touching a tabbar item

I have app with a tabBar and Navigation controller.
How can I change the tabBar title (visible in top application's window) when I touch it in tabbar?
For example i have these items in tabbar:
Pizza
Beer
Orange
Apple
After I click pizza I want to have pizza in the title app in the top menu.
How can I do this?
Depending on your implementation, one of the below methods should work for you.
self.navigationItem.title = "title"
or
self.navigationBar.topItem?.title = "title"
If you are using a custom tabbar made with UIButtons and container
view, then add this to the button action or if you are using a native
UITabBarController, then set it's delegate to self and call this on
the didSelectViewController delegate method of the UITabBarController.
.
EDIT
After seeing your code, you need to use this property :
self.tabBarController?.navigationItem.title = "Profile"
and call this in every view controller's viewWillAppear, example for ProfileViewController
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
self.tabBarController?.navigationItem.title = "Profile"
}
Also, make sure that in storyboard, you set the view controller's class to the respective code class like :
and remove the text from the custom navigation bar you used:

Tab Bar Controller isHidden, but stays hidden

Im currently designing an app that utilizes a tab bar controller.
On the messages tab (instant messages), I want the tab bar to disappear whenever a user is having/viewing his/her conversation with another person. To do so I used this:self.tabBarController?.tabBar.isHidden = true
It disables the tabBar, but now the issue is that whenever I hit the back button to return to previous views (embedded in a navigation controller), the tab bar is still hidden. On the other views, I've set tabBar.isHidden = false, but that doesn't seem to fix it and now I can't access any of the other tabs.
My question is: How can I hide the tabBar on one view but keep it visible when I return to previous views?
In TabBar firstViewController
override func viewWillAppear(animated: Bool) {
// Enable TabBar
self.tabBarController?.tabBar.hidden = false
}
In SecondViewController (Pushed from firstViewController)
override func viewDidLoad() {
super.viewDidLoad()
// Disable TabBar
self.tabBarController?.tabBar.hidden = true
}