Skip to content

Instantly share code, notes, and snippets.

@bubudrc
Last active April 23, 2022 22:13
Show Gist options
  • Save bubudrc/d1ffa55995260df4481cd520a67dc25b to your computer and use it in GitHub Desktop.
Save bubudrc/d1ffa55995260df4481cd520a67dc25b to your computer and use it in GitHub Desktop.
This gist shows how to create a custom titleView to use correctly in any UINavigationController (UINavigationItem)
// CustomitleView
//
// Created by Marcelo Perretta on 21/04/2022.
//
import UIKit
class CustomTitleView: UIView {
private let elementsDistance: CGFloat = 5.0
private let iconSize: CGFloat = 25.0
private lazy var icon: UIImageView = {
let downloadableImage = UIImageView()
downloadableImage.contentMode = .scaleAspectFill
downloadableImage.clipsToBounds = true
downloadableImage.backgroundColor = .tertiarySystemBackground
downloadableImage.translatesAutoresizingMaskIntoConstraints = false
return downloadableImage
}()
private lazy var title: UILabel = {
let label = UILabel()
label.numberOfLines = 1
label.translatesAutoresizingMaskIntoConstraints = false
return label
}()
// MARK: - Life cycle
override init (frame: CGRect) {
super.init(frame: frame)
self.translatesAutoresizingMaskIntoConstraints = true
self.addSubviews()
}
convenience init () {
self.init(frame: .zero)
}
required init(coder aDecoder: NSCoder) {
fatalError("TitleView does not support NSCoding")
}
private func addSubviews() {
addSubview(icon)
addSubview(title)
}
func setTitleView(with iconName: String, andTitle title: String) {
icon.image = UIImage(string: iconName)
title.text = title
title.sizeToFit()
setNeedsUpdateConstraints()
}
// MARK: - Layout
override func updateConstraints() {
removeConstraints(self.constraints)
NSLayoutConstraint.activate([
icon.heightAnchor.constraint(equalToConstant: iconSize),
icon.widthAnchor.constraint(equalToConstant: iconSize),
icon.leadingAnchor.constraint(equalTo: self.leadingAnchor),
icon.centerYAnchor.constraint(equalTo: centerYAnchor),
title.leadingAnchor.constraint(equalTo: icon.trailingAnchor, constant: elementsDistance),
title.trailingAnchor.constraint(equalTo: self.trailingAnchor),
title.topAnchor.constraint(equalTo: topAnchor),
title.bottomAnchor.constraint(equalTo: bottomAnchor)
])
super.updateConstraints()
}
override func sizeThatFits(_ size: CGSize) -> CGSize {
// +8.0 - distance between image and text
let width = icon.bounds.width + title.bounds.width + elementsDistance
let height = max(icon.bounds.height, title.bounds.height)
return CGSize(width: width, height: height)
}
}
// How to use it
// on ViewController
import UIKit
class TestVC: UIViewController {
private lazy var customTitleView: CustomTitleView = {
return CustomTitleView()
}()
override func viewDidLoad() {
super.viewDidLoad()
navigationItem.titleView = customTitleView
customTitleView.setTitleView(with: "My Icon", andTitle: "My Title")
customTitleView.sizeToFit()
self.navigationController?.navigationBar.setNeedsLayout()
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment