我正在尝试为导航栏创建自定义titleView。我可以在导航控制器中嵌入的根视图控制器中设置titleView。
当我将第二个视图控制器推到堆栈上并尝试为该视图控制器设置titleView时,它不起作用。 titleView快速出现并消失。当我回到上一个视图控制器时,此titleView迅速出现,现在也消失了。
有人知道为什么会这样,或者如何正确设置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
}
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
if segue.identifier == "Show" {
let controller = segue.destinationViewController as! SecondViewController
controller.titleView = titleView
}
}
}
第二个视图控制器:
class SecondViewController: UIViewController {
var titleView: UIView?
override func viewDidLoad() {
super.viewDidLoad()
if let titleView = titleView {
navigationItem.titleView = titleView
}
}
}
我找到了解决方案。我将addTitleView()方法从FirstViewController复制到SecondViewController,并在viewDidLoad()中将它们都调用了。这完全符合我的期望。由于某种原因,它无法将titleView作为属性向前传递并将其分配给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
}
}
第二个视图控制器:
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
}
}
我的解决方案很简单,并且有效:
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)
}
}
使用Xcode的视图调试器,您会发现titleView.bounds.origin不为零。如何使其再次发生,分两个步骤:1. UIViewController A和B; A具有自定义navigationItem.titleView
,B将navigationBar
隐藏在其viewWillAppear()
中;当B弹出时,A.viewWillAppear()setNavigationBar(隐藏:false,动画:true)2.抬起手,取消用户驱动的popViewController
。然后您会发现A的navigationBar
为空白。
我遇到了同样的问题,但是以上解决方案都没有为我解决。我的问题是我将translatesAutoresizingMaskIntoConstraints
设置为false
。我想这会导致出现/消失,因为需要将其设置为true
才能将视图内部限制在导航栏中。