【问题标题】:Set UINavigationBar height proportionally to screen size设置 UINavigationBar 高度与屏幕大小成比例
【发布时间】:2021-10-12 17:35:42
【问题描述】:

我在 UITabBarController 中有 5 个选项卡,每个选项卡都嵌入在 UINavigationController 中。我想将此选项卡的高度设置为屏幕的 8%,但我无法为 StoryBoard 设置约束,如果我尝试从代码中设置它,它会变黑并破坏 UI 控件。 我的 UINavigationController 的代码是这样的:


class NavBarController: UINavigationController {
    override func viewDidLayoutSubviews() {
        self.navigationBar.topItem?.titleView = UIImageView(image: UIImage(named: "image"))
        self.navigationBar.topItem?.titleView?.contentMode = .scaleAspectFit
        let gradient = CAGradientLayer()
        var bounds = self.navigationBar.bounds
        bounds.size.height += self.view.window?.windowScene?.statusBarManager?.statusBarFrame.height ?? 0
        bounds.origin.y -= self.view.window?.windowScene?.statusBarManager?.statusBarFrame.height ?? 0
        gradient.frame = bounds
        gradient.colors = [UIColor.black, UIColor.white]
        gradient.locations = [0.0, 1.0]
        self.navigationBar.setBackgroundImage(image(fromLayer: gradient), for: .default)
    }
    
    func image(fromLayer layer: CALayer) -> UIImage {
        UIGraphicsBeginImageContext(layer.frame.size)
        layer.render(in: UIGraphicsGetCurrentContext()!)
        let outputImage = UIGraphicsGetImageFromCurrentImageContext()
        UIGraphicsEndImageContext()
        return outputImage!
    }
}

我试过设置:

self.navigationBar.frame.size.height = (self.view.superview?.frame.height)! * 0.08
self.navigationBar.layoutIfNeeded()

在viewDidLayoutSubviews的开头,但它不起作用并且还破坏了渐变背景。有人能帮我吗?理想的解决方案是通过情节提要,但我不能简单地将 UINavigationItem 高度约束设置为其视图高度。

【问题讨论】:

  • 您是否尝试过通过覆盖layout()updateConstraints() 来执行此代码?我相信viewDidLayoutSubviews() 在渲染循环中为时已晚。您需要继承 UINavigationBar 并在您的自定义子类中进行覆盖。
  • @user1922718 不,我没有尝试过,因为我在渐变方面遇到了一些问题,但我会尝试一下。谢谢你。如何访问超级视图高度? self.navigationController.view.superview...?
  • 在任何视图上调用superview 都会为您提供其父视图,只要该视图位于视图层次结构中。所以你可以通过调用view.superview.frame.height 来获取超级视图的高度
  • @user1922718 我尝试了不同的方式,通过覆盖 layoutSubviews()、updateConstraints() 等,我也在控制器中再次尝试。没什么,我不能设置这个他妈的酒吧高度。
  • 您可以尝试的另一件事是子类UINavigationBar 并为frame 变量编写didSet 观察者。然后在调试器中设置断点,并记下每次更改此变量时以及在渲染循环中的哪个点。这将为您提供何时需要设置条形高度的线索。

标签: ios swift user-interface uikit


【解决方案1】:

在花了一些时间研究这个之后,我发现 UINavigationBar 在整个过渡过程中多次被赋予 44pts 的高度。由于 UIKit 坚持高度为 44,我决定使用自定义设置器的一些技巧。

class NavigationBar: UINavigationBar {
    private var _frame: CGRect!
    override var frame: CGRect {
        set {
            _frame = CGRect(origin: newValue.origin, size: CGSize(width: newValue.width, height: 22))
        }
        get {
            _frame
        }
    }
}

在这里,我将导航栏的高度强制为 22 pts。但是,编译运行后导航栏还是44。为什么?因为 UIKit 也设置了一个约束,将高度强制为 44。这意味着 AutoLayout 在布局时将高度恢复为 44。似乎这是苹果真的不希望你改变的东西。

【讨论】:

  • 谢谢,几分钟前我在文档中读到了同样的内容,我想我会创建自己的导航栏,因为我必须遵循一个模型。感谢您的宝贵时间
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-08-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多