Custom navigationItem.titleView not setting - ios

I am having troubles setting the self.navigationItem.titleView, could someone please help me catch my mistake.
import Foundation
class CustomNavigationController: UINavigationController
{
override func viewDidLoad() {
let logo = UIImage(named: "browse_back")
var hexColor = 0x21BBD4 as UInt
self.navigationBar.barTintColor = GeneralHelper.UIColorFromRGB(hexColor)
self.navigationItem.titleView = UIImageView(image: logo)
}
}
Here is my code for setting the titleView to an image.
When I run the application, the color of the navigation bar is being changed to the correct color, but the titleView image is not displaying.
I've tested to ensure the image does exist.
Thanks.

The managing UINavigationController object uses the navigation items
of the topmost two view controllers to populate the navigation bar
with content.
Source: UINavigationItem Class Reference
You have to set the titleView of the navigationItem of the controller that is the top most controller in the navigation stack managed by your custom navigation controller.

For those using a UILabel as your titleView
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
navigationItem.titleView?.sizeToFit()
}
Hope this works!

Related

How to add view on top of navigation bar

How to add view above navigation bar?
I have a custom navigation controller and I want to present a view above nav bar (like on the screen), so it should be visible on other ViewControllers
Would be great if the solution will be on storyboard.
Tried to add on UIWindow did't help.
Swift 4.2, Xcode 10+
Okay, from what I can tell (via your comment reply, though it still isn't 100% clear), the best solution to your question would be to make the navigation bar transparent, such that you can see any navigationController-presented view controllers underneath it. For this, I'd suggest the following extension to UIViewController:
extension UIViewController {
func setupTransparentNavigationBarWithBlackText() {
setupTransparentNavigationBar()
//Status bar text and back(item) tint to black
self.navigationController?.navigationBar.barStyle = .default
self.navigationController?.navigationBar.tintColor = .black
}
func setupTransparentNavigationBarWithWhiteText() {
setupTransparentNavigationBar()
//Status bar text and back(item) tint to white
self.navigationController?.navigationBar.barStyle = .blackTranslucent
self.navigationController?.navigationBar.tintColor = .white
}
func setupTransparentNavigationBar() {
self.navigationController?.navigationBar.setBackgroundImage(UIImage(), for: .default)
self.navigationController?.navigationBar.shadowImage = UIImage()
self.navigationController?.navigationBar.backgroundColor = .clear
self.navigationController?.navigationBar.isTranslucent = true
}
}
Using either of the first two methods in viewWillAppear of your UIViewController subclasses will let you make the navigation bar completely transparent with the statusBar text + wifi/battery indicators black or white as desired. From this, you can then display anything under the navigation bar by pinning your constraints to view.bounds.topAnchor. E.g. for a transparent navigation controller with white statusBar text:
class YourViewController: UIViewController {
override func viewWillAppear(_ animated: Bool) {
setupTransparentNavigationBarWithWhiteText()
}
}

Navigation Bar Overlaps Info

I am having a problem with my navigation Bars overlapping the Information on the top of the iPhone. I originally had the navigation bar as White/ Translucent and it didn't cause a problem. I feel that making it black would be better except for now it overlaps the Time, Battery and Data from the iPhone. How would I move the navigation bar down?
You need to create a custom navigationBar and then add the constraints that you want, but this is not something that should interrupt with the status bar usually. You could try to change the font size of your navigationBar text:
self.navigationController?.navigationBar.titleTextAttributes = [ NSAttributedStringKey.font: UIFont.systemFont(ofSize: 10)]
Update:
After some clarification, you donĀ“t want to move done the navigationBar, you just want to change the color of the statusBar (which contains all system icons on the top). Add these two rows in your viewDidLoad function to change the background color of you:
if let statusBar: UIView = UIApplication.shared.value(forKey: "statusBar") as? UIView {
statusBar.backgroundColor = .white
}
Just make this class parent class of your every viewController
For example you have a SignUpViewController class and currently your this view controller will be like this.
class SignUpViewController: UIViewController {
//Your all methods and properties are implemented here.
}
So just change the parent class of above class from UIViewController to below written class LargerNavigationBaseVC like this.
class SignUpViewController: LargerNavigationBaseVC {
//Your all methods and properties are implemented here.
}
class LargerNavigationBaseVC: UIViewController {
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
self.navigationItem.prompt = " "
}
}

How do I create a custom navigationController with image and name?

My goal is to create a UI that looks like this
The only way that I could think of is to embed a navigationController on the UIViewController then add UIView
Storyboard
Code - ProfileViewController
class ProfileViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
navigationBarColor()
}
func navigationBarColor() {
navigationController?.navigationBar.backgroundColor = UIColor(red:0.91, green:0.04, blue:0.51, alpha:1.0)
navigationController?.navigationBar.shadowImage = UIImage()
navigationController?.navigationBar.setBackgroundImage(UIImage(), for: .default)
}
}
Result
Is my approach correct? or do I need to use a different method to achieve this result?
The best way to do this is to make the navigationBar invisible basically. Here is what I did to achieve the look you want:
Step 1:
Add the navigation controller and a view controller and hold control and drag from the navigation controller to the view controller and select root view controller(which i am pretty sure you have already done). Also, drag and drop a UIBarButtonItem onto the navigationBar in the view controller, not the navigationBar in the navigation controller.
Step 2:
Subclass the navigation controller and the view controller, in my example, mine are called CustomNavController.swift and MainVC.swift. In the storyboard, set them as the class of the controllers.
Step 3:
In the class you made for the view controller, set the code in the viewDidLoad to change the background color.
import Foundation
import UIKit
class MainVC: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
self.view.backgroundColor = UIColor(red: 231/255, green: 11/255, blue: 129/255, alpha: 1)
}
}
And in the navigation controller class, add this code.
import UIKit
class CustomNavController: UINavigationController {
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
self.navigationBar.setBackgroundImage(UIImage(), for: .default)
self.navigationBar.shadowImage = UIImage()
self.navigationBar.isTranslucent = true
self.navigationBar.tintColor = .white
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
override var preferredStatusBarStyle: UIStatusBarStyle {
return .lightContent
}
}
The Result:
Since you are using a navigation controller, you have to set the status bar style to lightContent in the navigation controller subclass like shown above. If you have other view controller that you want the status bar to be black in, you will have to implement the method preferredStatusBarStyle in the class and return .default unless, if the view controller has a navigation controller associated with it, the you would have to implement preferredStatusBarStyle in the navigation controller subclass like I showed in my example. If you have any questions feel free to leave a comment and I will answer when I can.
You can subclass navigation bar, but with that amount of size, i think it's not a good approach. What you are doing seems ok. It's a solution.
Your approach will work. To match your Sketch mockup as closely as possible, here are a few tips:
UINavigationBar's background color should be set using the barTintColor property. This will give the status bar the same background color.
Set the UINavigationBar's barStyle property to black. This will set the status bar's content color to white.
You might notice how the navigation bar's color is slightly different from the view you created beneath it. This is because UINavigationBar is translucent by default, so the background color has a reduced alpha value. You can set the UINavigationBar property isTranslucent to false to fix this.
An alternative approach (without UINavigationController) would involve creating a simple UIView to use as the status bar background, as shown here: https://stackoverflow.com/a/43264566/5223633.
First step, add this 3 lines of codes in your viewDidLoad methods of your controller class:
navigationController?.navigationBar.barTintColor = UIColor(red:0.91, green:0.04, blue:0.51, alpha:1.0)
navigationController?.navigationBar.tintColor = UIColor.white
UIApplication.shared.statusBarStyle = .lightContent
And then, select your info.plist file. When it's opened, add a row by right clicking on it. Give the key name:
View controller-based status bar appearance
and set it's value into:
NO
as boolean value.
see this info.plist screenshot example
Then run it.
You can create custom viewcontroller with Xib file after that load and add its view inside your navigation bar. Hide back button if required and update navigationBar height
accordingly
navigationItem.hidesBackButton = true
navigationController?.navigationBar.frame.size.height = 100
guard let yourCustomView = UINib(nibName: "yourCustomXib", bundle: nil).instantiate(withOwner: nil, options: nil).first as? YourCustomView else {
fatalError("Missing yourCustomXib")
}
navigationController?.navigationBar.addSubview(yourCustomView)

TableView shows under tabbar

I've got a UITableViewController embedded inside a Navigation and TabBar controller. When I set the background image using
override func viewWillAppear(animated: Bool) {
super.viewWillAppear(animated)
let backgroundImage = UIImage(named: "Background.png")
let imageView = UIImageView(image: backgroundImage)
self.tableView.backgroundView = imageView
}
the table appears under the TabBar that is translucent.
I can't use Insets or anything as the code above just sets background to the tableview.
I need something that sets background to the view and not the table to use Insets.
And the problem can be solve by using UIViewController(with tableView inside it) but I gotta use static cells so that is out of scope.

Customising the UITabBar.appearance in each View Controller [Swift]

I'm trying to set the tab bar to have a different background image on each view controller.
class CharacterVC: UIViewController {
var tabBarApparence = UITabBar.appearance()
override func viewDidLoad() {
super.viewDidLoad()
tabBarApparence.backgroundImage = UIImage(named: "BlueTB") //Loaded from Image Asset
}
This works fine and changes it to blue in that view, however when I go to the next view it stays the blue colour and doesn't change to the red colour which I programmed in with this code:
class AnonVC: UIViewController {
var tabBarApparence = UITabBar.appearance()
override func viewDidLoad() {
super.viewDidLoad()
tabBarApparence.backgroundImage = UIImage(named: "RedTabBar")
// addtional code here
}
I have an additional 2 view controllers, one should display the green version of the image and the other the purple version of the image.
Any suggestions which could fix this?
If you want to change appearance of TabBar in a view controller is very easy. You can this in function viewDidLoad or viewWillAppear. The code is the next:
// Set color of titles and icons in tabBar
self.tabBarController?.tabBar.tintColor = UIColor.redColor()
// Set color of background tabBar
self.tabBarController?.tabBar.barTintColor = UIColor.blueColor()
Replace code to viewWillAppear()
Better set backgroundImage to tabBar, not to UITabBar.appearance()

Resources