faced such an issue that the navigation controller is always black even if I change the appearance to light.
Here is how I create it:
class TabBarController: UITabBarController {
override func viewDidLoad() {
super.viewDidLoad()
viewControllers = [
createViewController(for: AssetViewController(), title: NSLocalizedString("Assets", comment: ""), image: UIImage(systemName: "dollarsign.circle")!),
createViewController(for: WalletViewController(), title: NSLocalizedString("Wallets", comment: ""), image: UIImage(systemName: "wallet.pass")!),
]
}
func createViewController(for rootViewController: UIViewController, title: String, image: UIImage) -> UIViewController {
let navController = UINavigationController(rootViewController: rootViewController)
navController.tabBarItem.image = image
navController.navigationBar.prefersLargeTitles = true
rootViewController.navigationItem.title = title
return navController
}
ViewController:
class AssetViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
view.backgroundColor = .systemBackground
self.view = CustomView()
}
The other navigation controllers I build the same way, but they are 100% fine.
What could be the problem? Thanks.
Found the problem. I set the backgroundColor and afterward, I set the custom view. Should switch the order. Still weird why other VCs worked fine.
Related
I'm trying to display a custom button for the tab bar item in my Swift project.
I added a png file, called btn_new, to the Assets folder of the Xcode project and tried to display the custom button in the custom tabbar controller class. But I can only see a circle button with the default blue color and no custom image on it in my simulator.
this is the custom tabbar controller class.
import UIKit
class CustomTabBarController: UITabBarController {
var createEventViewController: CreateEventViewController!
override func viewDidLoad() {
super.viewDidLoad()
createEventViewController = CreateEventViewController()
self.delegate = self
self.tabBar.barTintColor = UIColor.customGreen()
}
func createListNC() -> UINavigationController {
let listVC = listViewController()
listVC.tabBarItem = UITabBarItem(title: "", image: UIImage(named: "btn_new"), tag: 0)
return UINavigationController(rootViewController: listVC)
}
func setUpTabbarItems() -> [UIViewController]{
return [createListNC()]
}
}
extension CustomTabBarController: UITabBarControllerDelegate {
func tabBarController(_ tabBarController: UITabBarController, shouldSelect viewController: UIViewController) -> Bool {
if viewController == tabBarController.viewControllers?[0] {
let vc = CreateEventViewController()
let nc = UINavigationController(rootViewController: vc)
nc.modalPresentationStyle = .popover
self.present(nc, animated: true, completion: nil)
return false
}
return true
}
}
I double-checked the name is called exactly "btn_new", so I was not sure why the button is not displayed. Not really sure but, one thing I am concerned about is that I did not set a size for this custom icon. Can anyone tell me how can I display the button image for the tabbar item?
In your CustomTabBarController viewDidload:
let buttonImage: UIImage! = UIImage(named:
"btn_new")!.withRenderingMode(.alwaysOriginal)
(tabBar.items![0] ).selectedImage = buttonImage
Goto Storyboard-> Select tabBarItem on VC(blue selected area)
How can I change the back button of a certain navigation controller. I have tried to use
override func viewDidLoad() {
super.viewDidLoad()
navigationItem.backBarButtonItem?.tintColor = UIColor.red
}
I know that if i use navigationController it will change the back button tint color on all of my view controllers.
Try this!!
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
self.navigationController?.navigationBar.tintColor = .red
}
override func willMove(toParent parent: UIViewController?) {
self.navigationController?.navigationBar.tintColor = // original color
}
}
Is it possible to create a clear UINavigationBar class with isTranslucent = false ?
One way to do this is to change properties of UINavigationController on the viewDidLoad method of your viewController as follows :
override func viewDidLoad() {
super.viewDidLoad()
if let nav = self.navigationController {
nav.navigationBar.setBackgroundImage(UIImage(), for: .default)
nav.navigationBar.shadowImage = UIImage()
nav.navigationBar.isTranslucent = true
}
}
I'm trying to change the title in Product but somehow the navigationItem is different. How come the navigationItem in Container is different compared to the one in Product?
class VC1: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
let controller = Container()
let navigation = UINavigationController(rootViewController: controller)
navigationController?.pushViewController(navigation, animated: true)
}
}
class Container: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
print(navigationItem)
navigationItem.title = "test"
let controller = Product()
controller.didMove(toParentViewController: self)
self.addChildViewController(controller)
view.addSubview(controller.view)
}
}
class Product: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
print(navigationItem)
navigationItem.title = "" // Doesn't remove the title
}
}
I'm just reading the documentation for navigationItem, and it says this:
This is a unique instance of UINavigationItem created to represent the view controller when it is pushed onto a navigation controller.
However, in your case, the embedded VC is not a direct child of a navigation controller.
So, I tried the following code and it worked. The key part is I overrode navigationItem to return the parent's navigation item if there is a parent view controller.
override var navigationItem: UINavigationItem {
if let parentItem = parent?.navigationItem {
return parentItem
} else {
return super.navigationItem
}
}
How to create programmatically tabs from any class extended by UIViewController:
class DashboardTabBarController: UITabBarController {
override func viewDidLoad() {
//here
}
...
}
UPDATE SWIFT 5
One example of how to create an UITabBarController programmatically could be like this:
First we create the UIViewControllers that will be the content for each tab of the tab bar interface. For this example we only create one very simple.
class Item1ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
view.backgroundColor = UIColor.green
self.title = "item1"
print("item 1 loaded")
}
}
Now, the UITabBarController:
We create the new instances of the UIViewControllers that we want to display in the tab bar. Then we create an icon for each instance we have created and then we create an array that contains all UIViewControllers that specify the content for each tab of the tab bar interface. The order of the view controllers in the array corresponds to the display order in the tab bar.
class DashboardTabBarController: UITabBarController, UITabBarControllerDelegate {
override func viewDidLoad() {
super.viewDidLoad()
delegate = self
}
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
let item1 = Item1ViewController()
let icon1 = UITabBarItem(title: "Title", image: UIImage(named: "someImage.png"), selectedImage: UIImage(named: "otherImage.png"))
item1.tabBarItem = icon1
let controllers = [item1] //array of the root view controllers displayed by the tab bar interface
self.viewControllers = controllers
}
//Delegate methods
func tabBarController(_ tabBarController: UITabBarController, shouldSelect viewController: UIViewController) -> Bool {
print("Should select viewController: \(viewController.title ?? "") ?")
return true;
}
}
If you are using storyboard for the viewcontrollers then you have to write like this in your tabbarcontroller class.
class CustomTabbarController : UITabBarController {
override func viewDidLoad() {
super.viewDidLoad()
let storyboard = UIStoryboard(name: "Main", bundle: nil)
let firstViewController = FirstViewController()
let navigationController = UINavigationController(rootViewController: firstViewController)
navigationController.title = "First"
navigationController.tabBarItem.image = UIImage.init(named: "map-icon-1")
viewControllers = [navigationController]
if let secondViewController = storyboard.instantiateViewController(withIdentifier: "SecondViewController") as? SecondViewController {
let navgitaionController1 = UINavigationController(rootViewController: secondViewController)
navgitaionController1.title = "Second"
navgitaionController1.tabBarItem.image = UIImage.init(named: "second-icon-1")
var array = self.viewControllers
array?.append(navgitaionController1)
self.viewControllers = array
}
}
}
private lazy var tabbarViewController: UITabBarController = {
let tabbarViewController = UITabBarController()
tabbarViewController.setViewControllers([startVC,
offerVC,
benefitsVC,
shopVC,
recipesVC], animated: true)
return tabbarViewController
}()
window?.rootViewController = tabbarViewController