I am trying to create a custom titleView for a navigation bar. I am able to set the titleView in the root view controller that is embedded in a navigation controller.
When I push the second view controller onto the stack and try to set the titleView for this view controller it does not work. The titleView quickly appears and disappears. When I go back to the previous view controller this titleView quickly appears and disappears now also.
Does anyone know why this is happening or how to set the titleView correctly without flashing and disappearing?
class FirstViewController: UIViewController {
var titleView: UIView!
override func viewDidLoad() {
super.viewDidLoad()
addTitleView()
}
func addTitleView() {
titleView = UIView(frame: CGRect(x: 0, y: 0, width: 150, height: 44))
let companyLabel = UILabel(frame: CGRect(x: 0, y: 3, width: 150, height: 11))
companyLabel.text = "CPS Dashboard"
companyLabel.textColor = UIColor.grayColor()
companyLabel.textAlignment = .Center
companyLabel.font = UIFont.systemFontOfSize(9)
titleView.addSubview(companyLabel)
let titleLabel = UILabel(frame: CGRect(x: 0, y: 16, width: 150, height: 18))
titleLabel.text = "Dashboard"
titleLabel.textColor = UIColor.blackColor()
titleLabel.textAlignment = .Center
titleLabel.font = UIFont.systemFontOfSize(15)
titleView.addSubview(titleLabel)
navigationItem.titleView = titleView
}
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
if segue.identifier == "Show" {
let controller = segue.destinationViewController as! SecondViewController
controller.titleView = titleView
}
}
}
The second viewcontroller:
class SecondViewController: UIViewController {
var titleView: UIView?
override func viewDidLoad() {
super.viewDidLoad()
if let titleView = titleView {
navigationItem.titleView = titleView
}
}
}
I found a solution. I copied addTitleView() method from FirstViewController into SecondViewController, and called both of them in viewDidLoad(). This worked exactly as I wanted it to. For some reason it was not working to pass the titleView forward as a property and assigning it to navigationItem.titleView.
class FirstViewController: UIViewController {
var titleView: UIView!
override func viewDidLoad() {
super.viewDidLoad()
addTitleView()
}
func addTitleView() {
titleView = UIView(frame: CGRect(x: 0, y: 0, width: 150, height: 44))
let companyLabel = UILabel(frame: CGRect(x: 0, y: 3, width: 150, height: 11))
companyLabel.text = "CPS Dashboard"
companyLabel.textColor = UIColor.grayColor()
companyLabel.textAlignment = .Center
companyLabel.font = UIFont.systemFontOfSize(9)
titleView.addSubview(companyLabel)
let titleLabel = UILabel(frame: CGRect(x: 0, y: 16, width: 150, height: 18))
titleLabel.text = "Dashboard"
titleLabel.textColor = UIColor.blackColor()
titleLabel.textAlignment = .Center
titleLabel.font = UIFont.systemFontOfSize(15)
titleView.addSubview(titleLabel)
navigationItem.titleView = titleView
}
}
The second viewcontroller:
class SecondViewController: UIViewController {
var titleView: UIView!
override func viewDidLoad() {
super.viewDidLoad()
addTitleView()
}
func addTitleView() {
titleView = UIView(frame: CGRect(x: 0, y: 0, width: 150, height: 44))
let companyLabel = UILabel(frame: CGRect(x: 0, y: 3, width: 150, height: 11))
companyLabel.text = "CPS Dashboard"
companyLabel.textColor = UIColor.grayColor()
companyLabel.textAlignment = .Center
companyLabel.font = UIFont.systemFontOfSize(9)
titleView.addSubview(companyLabel)
let titleLabel = UILabel(frame: CGRect(x: 0, y: 16, width: 150, height: 18))
titleLabel.text = "Dashboard"
titleLabel.textColor = UIColor.blackColor()
titleLabel.textAlignment = .Center
titleLabel.font = UIFont.systemFontOfSize(15)
titleView.addSubview(titleLabel)
navigationItem.titleView = titleView
}
}
My solution is simple, and it works:
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
if let tv = navigationItem.titleView {
print("transform", tv.transform)) // is always identity
let bounds = tv.bounds
print("bounds", bounds) // its origin may not be zero.
tv.bounds = CGRect(origin: .zero, size: bounds.size)
print("new bounds", tv.bounds)
}
}
Using Xcode's view debugger, you will find that titleView.bounds.origin is not zero.
How to let it happen again , two steps: 1. UIViewController A and B; A has custom navigationItem.titleView
, B hides navigationBar
in its viewWillAppear()
; when B poped, A.viewWillAppear() setNavigationBar(hidden: false, animated: true) 2. user-driven popViewController
is canceled by lifting your hand.
Then you will found, A's navigationBar
is blank.
I was having this same issue, but none of the above solutions fixed it for me. My issue was that I was setting translatesAutoresizingMaskIntoConstraints
to false
. I imagine this caused the appearing/disappearing because it needs to be set to true
in order to constrain the view internally to the navigation bar.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.