Search code examples
iosuinavigationcontrollerswift3uinavigationbaruinavigationitem

Swift Custom Navigation Controller Class


Everyone who reads it, hello and thank you. I am writing an application like Viber or WhatsApp for iOS devices using Xcode 8.2.1 and Swift 3.0. I have a problem: I want my app has a navigation controller but not a simple one, I want it to be a custom one. There is a print screen from WhatsApp to be understanding, what I am trying to achieve:

Screenshot of WhatsApp chat with somebody

As we can see, this navigation controller has 3 buttons, label and image with avatar. I also want to change my color to green one. Due to do this I have created class:

import UIKit

class CustomNavigationController: UINavigationController {

    override func viewDidLoad() {
        super.viewDidLoad()
        self.navigationBar.barTintColor = UIColor.green


        let imageView = UIImageView(frame: CGRect(x: 0, y: 0, width: 39, height: 39))
        imageView.contentMode = .scaleAspectFit
        let image = UIImage(named: "logo")
        imageView.image = image
        navigationItem.titleView = imageView


    }
}

And it gives this result: enter image description here As you can see it is without picture. I know that if I add this code:

        let imageView = UIImageView(frame: CGRect(x: 0, y: 0, width: 39, height: 39))
        imageView.contentMode = .scaleAspectFit
        let image = UIImage(named: "logo")
        imageView.image = image
        navigationItem.titleView = imageView

to ViewController, image with logo will appear but I want complete class which I will connect somewhere (for example, in Interface Builder) and it will make a beautiful Navigation Controller with buttons, images and etc. Moreover, I can create a different class with another Navigation Controller and connect it to different screens, on which, for example, I will not need images, only buttons. So question is: how to make custom Navigation Controller class?

I will be really glad and thankful for any help, Thank You!


Solution

  • Now, I know the answer! It will be written for Swift 4.1.2. Each class inherited from UIViewController has a property self.navigationController?.navigationBar or navigationItem. You can create you own class like this:

    class CustomNavigationController: UIViewController {
    
        override func viewDidLoad() {
            super.viewDidLoad()
    
            let color = UIColor(red: 81 / 255, green: 155 / 255, blue: 22 / 255, alpha: 1.0)
            self.navigationController?.navigationBar.barTintColor = color
    
            let image = UIImage(named: "logo")
            let imageView = UIImageView(image: image)
            imageView.contentMode = .scaleAspectFit
            navigationItem.titleView = imageView
        }
    
        private func imageView(imageName: String) -> UIImageView {
            let logo = UIImage(named: imageName)
            let logoImageView = UIImageView(frame: CGRect(x: 0, y: 0, width: 35, height: 35))
            logoImageView.contentMode = .scaleAspectFit
            logoImageView.image = logo
            logoImageView.widthAnchor.constraint(equalToConstant: 35).isActive = true
            logoImageView.heightAnchor.constraint(equalToConstant: 35).isActive = true
            return logoImageView
        }
    
        func barImageView(imageName: String) -> UIBarButtonItem {
            return UIBarButtonItem(customView: imageView(imageName: imageName))
        }
    
        func barButton(imageName: String, selector: Selector) -> UIBarButtonItem {
            let button = UIButton(type: .custom)
            button.setImage(UIImage(named: imageName), for: .normal)
            button.frame = CGRect(x: 0, y: 0, width: 35, height: 35)
            button.widthAnchor.constraint(equalToConstant: 35).isActive = true
            button.heightAnchor.constraint(equalToConstant: 35).isActive = true
            button.addTarget(self, action: selector, for: .touchUpInside)
            return UIBarButtonItem(customView: button)
        }
    
    }
    

    Now you can inherit any of you UIViewControllers from this class CustomNavigationController and add ass much buttons, icons, change colors, logos and etc. as much as you want (of course, in normal range)! Like this:

    class ViewController: CustomNavigationController {
    
        override func viewDidLoad() {
            super.viewDidLoad()
    
            navigationItem.leftBarButtonItem = barImageView(imageName: "picture1")
    
            let firstImage = barImageView(imageName: "picture2")
            let secondButton = barButton(imageName: "picture3", selector: #selector(secondButtonPressed))
    
            navigationItem.rightBarButtonItems = [firstImage, secondButton]
        }
    
        @objc func secondButtonPressed() {
            print("Pressed")
        }
    
    }
    

    This is my solution, maybe not the best, but 100% works! Thank you!