iOS11以下自定义增高UINavigationBar后ViewController视图遮挡问题
解决iOS11以下增高导航栏后视图被遮挡的问题
嘿,这个问题我之前也踩过坑!iOS11+用prefersLargeTitles的时候系统会自动帮我们处理视图布局,但手动修改导航栏高度的低版本就需要我们自己调整了,下面给你几个可行的解决方案:
原因分析
iOS11以下,当你手动增大导航栏的frame后,系统并不会自动调整ViewController的视图布局——默认情况下VC的view是从屏幕最顶部开始绘制的,自然就会被增高后的导航栏挡住一部分。
解决方案1:调整edgesForExtendedLayout
这是最简单的方法,直接告诉系统不要让VC的视图延伸到导航栏下方:
override func viewDidLoad() { super.viewDidLoad() if #available(iOS 11.0, *) { // iOS11+已经通过prefersLargeTitles自动处理,无需额外设置 } else { // 只让视图延伸到底部,顶部从导航栏下方开始 edgesForExtendedLayout = .bottom } }
解决方案2:基于布局锚点手动约束(更灵活)
如果你的VC里有自定义的滚动视图或者内容视图,推荐用AutoLayout约束来绑定顶部位置,适配更精准:
override func viewDidLoad() { super.viewDidLoad() // 假设你的主内容视图是contentView contentView.translatesAutoresizingMaskIntoConstraints = false if #available(iOS 11.0, *) { contentView.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor).isActive = true } else { // iOS11以下用topLayoutGuide来对齐导航栏底部 contentView.topAnchor.constraint(equalTo: topLayoutGuide.bottomAnchor).isActive = true } // 别忘了设置其他约束(比如左右、底部) contentView.leadingAnchor.constraint(equalTo: view.leadingAnchor).isActive = true contentView.trailingAnchor.constraint(equalTo: view.trailingAnchor).isActive = true contentView.bottomAnchor.constraint(equalTo: view.bottomAnchor).isActive = true }
解决方案3:针对滚动视图调整内边距
如果你的VC里是UITableView/UICollectionView这类滚动视图,除了上面的约束,还可以手动调整内边距来避免内容被遮挡:
override func viewWillAppear(_ animated: Bool) { super.viewWillAppear(animated) self.navigationController!.setupNavigationWithMenu() if #available(iOS 11.0, *) { tableView.contentInsetAdjustmentBehavior = .automatic } else { guard let navBarHeight = navigationController?.navigationBar.frame.height else { return } // 给滚动视图顶部添加和导航栏高度一致的内边距 tableView.contentInset = UIEdgeInsets(top: navBarHeight, left: 0, bottom: 0, right: 0) tableView.scrollIndicatorInsets = tableView.contentInset } }
额外优化:导航栏布局稳定性
在你修改导航栏frame的代码里,建议加上autoresizingMask,避免屏幕旋转时导航栏布局错乱:
else { let bounds = self.navigationBar.bounds let newHeight = bounds.height + menuHeight self.navigationBar.frame = CGRect(x: 0, y: 0, width: bounds.width, height: newHeight) // 确保导航栏宽度自适应,顶部位置跟随状态栏 self.navigationBar.autoresizingMask = [.flexibleWidth, .flexibleTopMargin] }
你可以根据自己的页面结构选择最合适的方案,一般用方案1就能解决基础问题,如果有复杂的布局就用方案2或者3~
内容的提问来源于stack exchange,提问作者Fred Novack
相关产品推荐
相关产品推荐

