iOS 11 - 无法更改导航栏高度
Posted
技术标签:
【中文标题】iOS 11 - 无法更改导航栏高度【英文标题】:iOS 11 - Unable to change Navigation Bar height 【发布时间】:2018-03-01 16:47:11 【问题描述】:我正在开发一个应用程序,我刚刚升级到 Xcode 9 / Swift 4,还将我的 iPhone 升级到了 ios 11。 该应用程序是在我安装 iOS 11 时安装的,并且在我从 Xcode 运行它之前一切看起来都很好。现在我被默认的 NavBar 高度困住了。
我用来更改高度的代码不再有效:
class CustomNavControllerVC: UINavigationController
let navBarHeight : CGFloat = 64.0
let navbarBackButtonColor = UIColor(red: 247/255, green: 179/255, blue: 20/255, alpha: 1)
override func viewDidLoad()
super.viewDidLoad()
print("CustomNavControllerVC > viewDidLoad")
override func viewDidLayoutSubviews()
print("CustomNavControllerVC > viewDidLayoutSubviews")
super.viewDidLayoutSubviews()
navigationBar.frame.size.height = navBarHeight
navigationBar.tintColor = navbarBackButtonColor
override func didReceiveMemoryWarning()
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
// In my VCs
override func viewDidLoad()
customizeNavBar()
func customizeNavBar()
let navbarBackItem = UIBarButtonItem()
navbarBackItem.title = "Înapoi"
navigationItem.backBarButtonItem = navbarBackItem
let navbarImageView = UIImageView(frame: CGRect(x: 0, y: 0, width: 55, height: 20))
navbarImageView.contentMode = .scaleToFill
let navbarLogo = UIImage(named: "NavBarLogo.png")
navbarImageView.image = navbarLogo
navigationItem.titleView = navbarImageView
到目前为止,我在这个问题上唯一能找到的是:
iOS 11 navigation bar height customizing
iOS11 customize navigation bar height
How to correctly set UINavigationBar height in iOS 11
但不幸的是,提供的信息无济于事。
有什么想法/建议吗?
【问题讨论】:
为什么不能使用自定义视图而不是UINavigationBar
?
openradar.appspot.com/32912789 UIKit 团队似乎从未打算让UINavigationBar
支持自定义高度。如果你想扩大导航栏的大小,我会使用苹果在这里推广的技术:developer.apple.com/library/content/samplecode/NavBar/…
@mukesh_lokare - 最初 NavBar 应该具有标准高度,中间有徽标图像,所以我决定使用标准 NavBarController。 30 个屏幕和很多类之后,有人认为它必须具有自定义高度,所以我决定使用该方法。
@beyowulf - 我看到了,但我希望有一个解决方案。我将使用提供的技术,看看会发生什么。
很遗憾我们被 Apple 无能的开发人员所拖累。看起来唯一要做的就是忘记 NavController,再一次只是 DIY。
【参考方案1】:
2017.10.6 更新
我遇到了同样的问题。下面是我的解决方案。我假设高度大小是 66。
我的解决方案在 iOS 10、11 上运行良好。
如果对你有帮助,请选择我的答案。
创建 NavgationBar.swift
import UIKit
class NavigationBar: UINavigationBar
//set NavigationBar's height
var customHeight : CGFloat = 66
override func sizeThatFits(_ size: CGSize) -> CGSize
return CGSize(width: UIScreen.main.bounds.width, height: customHeight)
override func layoutSubviews()
super.layoutSubviews()
frame = CGRect(x: frame.origin.x, y: 0, width: frame.size.width, height: customHeight)
// title position (statusbar height / 2)
setTitleVerticalPositionAdjustment(-10, for: UIBarMetrics.default)
for subview in self.subviews
var stringFromClass = NSStringFromClass(subview.classForCoder)
if stringFromClass.contains("BarBackground")
subview.frame = CGRect(x: 0, y: 0, width: self.frame.width, height: customHeight)
subview.backgroundColor = .yellow
stringFromClass = NSStringFromClass(subview.classForCoder)
if stringFromClass.contains("BarContent")
subview.frame = CGRect(x: subview.frame.origin.x, y: 20, width: subview.frame.width, height: customHeight - 20)
subview.backgroundColor = UIColor(red: 20/255, green: 20/255, blue: 20/255, alpha: 0.4)
设置故事板
设置自定义 NavigationBar 类
添加 TestView + 设置 SafeArea
ViewController.swift
import UIKit
class ViewController: UIViewController
var navbar : UINavigationBar!
@IBOutlet weak var testView: UIView!
override func viewDidLoad()
super.viewDidLoad()
//update NavigationBar's frame
self.navigationController?.navigationBar.sizeToFit()
print("NavigationBar Frame : \(String(describing: self.navigationController!.navigationBar.frame))")
//Hide Statusbar
override var prefersStatusBarHidden: Bool
return true
override func viewDidAppear(_ animated: Bool)
super.viewDidAppear(false)
//Important!
if #available(iOS 11.0, *)
//Default NavigationBar Height is 44. Custom NavigationBar Height is 66. So We should set additionalSafeAreaInsets to 66-44 = 22
self.additionalSafeAreaInsets.top = 22
override func didReceiveMemoryWarning()
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
SecondViewController.swift
import UIKit
class SecondViewController: UIViewController
override func viewDidLoad()
super.viewDidLoad()
// Do any additional setup after loading the view.
// Create BackButton
var backButton: UIBarButtonItem!
let backImage = imageFromText("Back", font: UIFont.systemFont(ofSize: 16), maxWidth: 1000, color:UIColor.white)
backButton = UIBarButtonItem(image: backImage, style: UIBarButtonItemStyle.plain, target: self, action: #selector(SecondViewController.back(_:)))
self.navigationItem.leftBarButtonItem = backButton
self.navigationItem.leftBarButtonItem?.setBackgroundVerticalPositionAdjustment(-10, for: UIBarMetrics.default)
override var prefersStatusBarHidden: Bool
return true
@objc func back(_ sender: UITabBarItem)
self.navigationController?.popViewController(animated: true)
//Helper Function : Get String CGSize
func sizeOfAttributeString(_ str: NSAttributedString, maxWidth: CGFloat) -> CGSize
let size = str.boundingRect(with: CGSize(width: maxWidth, height: 1000), options:(NSStringDrawingOptions.usesLineFragmentOrigin), context:nil).size
return size
//Helper Function : Convert String to UIImage
func imageFromText(_ text:NSString, font:UIFont, maxWidth:CGFloat, color:UIColor) -> UIImage
let paragraph = NSMutableParagraphStyle()
paragraph.lineBreakMode = NSLineBreakMode.byWordWrapping
paragraph.alignment = .center // potentially this can be an input param too, but i guess in most use cases we want center align
let attributedString = NSAttributedString(string: text as String, attributes: [NSAttributedStringKey.font: font, NSAttributedStringKey.foregroundColor: color, NSAttributedStringKey.paragraphStyle:paragraph])
let size = sizeOfAttributeString(attributedString, maxWidth: maxWidth)
UIGraphicsBeginImageContextWithOptions(size, false , 0.0)
attributedString.draw(in: CGRect(x: 0, y: 0, width: size.width, height: size.height))
let image = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
return image!
override func didReceiveMemoryWarning()
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
黄色是barbackgroundView。黑色不透明度是 BarContentView。
并且我删除了 BarContentView 的 backgroundColor。
就是这样。
【讨论】:
谢谢。我试试看。 谢谢。但是安全区的顶部没有更新。安全区域的顶部仍然是 44px。你有解决方案吗?设置导航栏高度后,我不知道如何更新安全区域的顶部。 @VictorRay 你能分享你的代码吗?我在我的项目中使用此代码。我想帮助你 ios 11.2 打破了这一点 在我的情况下,视觉外观工作正常,但我在那些额外的 22 个像素中放置的任何控件都不会对触摸输入做出反应。我有一个跨越“边框”的大按钮,比如从顶部 25px 开始,在底部 60px 结束。我尝试点击它,只有在顶部 44px(默认条形高度)内的点击会通过并被接收。以上是关于iOS 11 - 无法更改导航栏高度的主要内容,如果未能解决你的问题,请参考以下文章