I\'d like to add a button to a large title navigation bar like App Store\'s account button.
Flow Desired:
Found the answer on this Medium article by Tung Fam.
private let imageView = UIImageView(image: UIImage(named: "image_name"))
/// WARNING: Change these constants according to your project's design
private struct Const {
/// Image height/width for Large NavBar state
static let ImageSizeForLargeState: CGFloat = 40
/// Margin from right anchor of safe area to right anchor of Image
static let ImageRightMargin: CGFloat = 16
/// Margin from bottom anchor of NavBar to bottom anchor of Image for Large NavBar state
static let ImageBottomMarginForLargeState: CGFloat = 12
/// Margin from bottom anchor of NavBar to bottom anchor of Image for Small NavBar state
static let ImageBottomMarginForSmallState: CGFloat = 6
/// Image height/width for Small NavBar state
static let ImageSizeForSmallState: CGFloat = 32
/// Height of NavBar for Small state. Usually it's just 44
static let NavBarHeightSmallState: CGFloat = 44
/// Height of NavBar for Large state. Usually it's just 96.5 but if you have a custom font for the title, please make sure to edit this value since it changes the height for Large state of NavBar
static let NavBarHeightLargeState: CGFloat = 96.5
}
/**
Setup the image in navbar to be on the same line as the navbar title
*/
private func setupUI() {
navigationController?.navigationBar.prefersLargeTitles = true
title = "Large Title"
// Initial setup for image for Large NavBar state since the the screen always has Large NavBar once it gets opened
guard let navigationBar = self.navigationController?.navigationBar else { return }
navigationBar.addSubview(imageView)
// setup constraints
imageView.layer.cornerRadius = Const.ImageSizeForLargeState / 2
imageView.clipsToBounds = true
imageView.translatesAutoresizingMaskIntoConstraints = false
NSLayoutConstraint.activate([
imageView.rightAnchor.constraint(equalTo: navigationBar.rightAnchor, constant: -Const.ImageRightMargin),
imageView.bottomAnchor.constraint(equalTo: navigationBar.bottomAnchor, constant: -Const.ImageBottomMarginForLargeState),
imageView.heightAnchor.constraint(equalToConstant: Const.ImageSizeForLargeState),
imageView.widthAnchor.constraint(equalTo: imageView.heightAnchor)
])
}
override func viewDidLoad() {
super.viewDidLoad()
// setup Settings navigation bar button
setupUI()
}
And in case you want to hide/show the image when you navigate to children of this view controller:
/**
Show or hide the image from NavBar while going to next screen or back to initial screen
- parameter show: show or hide the image from NavBar
*/
private func showImage(_ show: Bool) {
UIView.animate(withDuration: 0.4) {
self.settingsImageView.alpha = show ? 1.0 : 0.0
}
}
override func viewWillDisappear(_ animated: Bool) {
super.viewWillDisappear(animated)
showImage(false)
}
override func viewWillAppear(_ animated: Bool) {
super.viewDidAppear(animated)
showImage(true)
}
If this helped you, you can check out the actual article and give the author a clap or two