我想在导航栏的中间放置一个比导航栏本身大的图像。到目前为止,我尝试将 UIView 与 UIImageView 一起使用,并且效果很好,正如您在此处看到的:
但是,只要我推另一个控制器并弹出我的 ImageView 就会再次裁剪为 NavigationBar 的大小。
到目前为止,我的 iOS 11 代码:
override func viewDidLoad() {
super.viewDidLoad()
let logo = UIImage(named: "Logo")
let titleView = UIView(frame: CGRect(x: 0, y: 0, width: 60, height: 60))
let imageView = UIImageView(image: logo)
imageView.frame = CGRect(x: 0, y: 0, width: titleView.frame.width, height: titleView.frame.height)
titleView.addSubview(imageView)
imageView.contentMode = .scaleAspectFit
imageView.image = logo
navigationItem.titleView = titleView
}
Run Code Online (Sandbox Code Playgroud)
编辑:目前有一个临时解决方案,它使用观察者覆盖导致问题的视图的 clipsToBounds 属性:链接(为此向@trungduc 大喊)
我找到了你遇到这个问题的原因。这是因为有一个名为 name 的私有视图_UINavigationBarContentView。它是 的子视图UINavigationBar。navigationItem.titleView包含在这个视图中。
第一次,当你改变的时候navigationItem.titleView。_UINavigationBarContentView.clipsToBounds是false。但是当您按下另一个控制器并弹出后,_UINavigationBarContentView.clipsToBounds是true。这就是为什么titleView被裁剪的原因。
所以我有一个临时解决方案。每次viewController出现时,找到该视图并更改_UINavigationBarContentView.clipsToBounds为false和 布局titleView。
override func viewDidAppear(_ animated: Bool) {
for view : UIView in (navigationController?.navigationBar.subviews)! {
view.clipsToBounds = false;
}
navigationItem.titleView?.layoutIfNeeded()
}
override func viewWillAppear(_ animated: Bool) {
for view : UIView in (navigationController?.navigationBar.subviews)! {
view.clipsToBounds = false;
}
navigationItem.titleView?.layoutIfNeeded()
}
Run Code Online (Sandbox Code Playgroud)
我尝试过并且有效。但我认为你不应该这样做,因为这是私人观点。也许苹果不想让我们用它做任何事。
希望我的建议能对你有所帮助。祝你好运 ;)
解决方案
添加观察者_UINavigationBarContentView.clipsToBounds,每次更改为 时false,设置为true并更新布局titleView
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
let logo = UIImage(named: "Logo")
let titleView = UIView(frame: CGRect(x: 0, y: 0, width: 60, height: 60))
let imageView = UIImageView(image: logo)
imageView.frame = CGRect(x: 0, y: 0, width: titleView.frame.width, height: titleView.frame.height)
titleView.addSubview(imageView)
imageView.contentMode = .scaleAspectFit
imageView.image = logo
navigationItem.titleView = titleView
navigationController?.navigationBar.subviews[2].addObserver(self, forKeyPath: "clipsToBounds", options: [.old, .new], context: nil)
}
override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) {
if (navigationController?.navigationBar.subviews[2].isEqual(object))! {
DispatchQueue.main.async {
self.navigationController?.navigationBar.subviews[2].clipsToBounds = false
self.navigationItem.titleView?.layoutIfNeeded()
}
}
}
deinit {
navigationController?.navigationBar.subviews[2].removeObserver(self, forKeyPath: "clipsToBounds")
}
Run Code Online (Sandbox Code Playgroud)
有关更多详细信息和更简单的信息,您可以在此处查看我的演示https://github.com/trungducc/stackoverflow/tree/big-title-navigation-bar