iOS 11导航栏高度自定义

78

在iOS 11中,sizeThatFits方法不再从UINavigationBar子类中调用。改变UINavigationBar的框架会导致故障和错误的插入。那么,现在有什么想法来自定义Navbar高度呢?


1
即使在 Beta 1 中报告的问题已经被修复,但这仍然是 Beta 2 中存在的问题:sizeThatFits 没有被 UINavigationBar 子类调用。 - ghr
1
在Beta 3中,调用了sizeThatFits,但似乎没有使用自定义高度。这个问题是否在发布说明中提到过? - Alex Medearis
1
对我来说,UINavigationBar被调整大小了,但视图仍然认为它是默认的44像素高度。因此,我的视图在自定义navigationBar下面绘制。附注:扩展边缘为“无”。 - Jeroen Bakker
1
是的,在beta 4中,自定义高度的导航栏仍然存在很多故障,尽管发布说明中声明:“导航栏现在应该看起来正确。(32076094)”。我建议提交一个重复的错误报告。 - karwag
2
UINavigationBar故意不再使用sizeThatFits来确定其大小,因为在iOS 11中具有大标题的动态更改导航栏高度。因此,我不知道除了构建自己的导航栏之外,在iOS 11中如何获得固定高度。我建议您提交增强请求,要求API影响iOS 11+的导航栏高度。 - Jordan H
显示剩余9条评论
11个回答

43

根据苹果开发者的说法(在此处这里这里),iOS 11中不支持更改导航栏高度。在这里他们建议采用解决方法,例如将一个视图放在导航栏下面(但不包括它),然后移除导航栏边框。结果在storyboard中会得到这样的效果:

enter image description here

在设备上看起来像这样:

enter image description here

现在你可以尝试另一篇答案中提供的解决方式:创建一个UINavigationBar的自定义子类,并将自定义的大的子视图添加到其中,重写sizeThatFitslayoutSubviews,然后将导航的顶控制器的 additionalSafeAreaInsets.top设置为差值customHeight - 44px,但是导航栏视图仍将保持默认的44px,尽管在视觉上一切看起来完美。我没有尝试重写setFrame,也许会奏效,但是正如苹果开发者在上面提到的一个链接中写道:"…同样也不支持更改由UINavigationController拥有的导航栏的框架(导航控制器将随时随地随心所欲地践踏您的框架更改)"。

在我的情况下,上述解决方法使视图呈现以下效果(调试视图以显示边框):

这里输入图片描述

如您所见,视觉效果相当不错,additionalSafeAreaInsets成功将内容向下推,大导航栏可见,但我在此栏中有一个自定义按钮,只有标准44像素导航栏下面的区域是可点击的(绿色区域在图中)。低于标准导航栏高度的触摸无法触及我的自定义子视图,因此我需要调整导航栏本身的大小,但苹果开发人员表示这是不支持的。


2
为了解决可点击区域的问题,请尝试在自定义UINavigationBar中添加以下重写方法:override func hitTest(_ point: CGPoint, with event: UIEvent?) -> UIView? { return subviews.reduce(super.hitTest(point, with: event)) { (result, subview) in return result ?? subview.hitTest(convert(point, to: subview), with: event) } }对于格式不当,我们表示抱歉。 - MarkII
7
苹果最新提供的项目不包括扩展导航栏。 - Weizhi
1
@Weizhi,你可以从Github下载旧版本:https://github.com/robovm/apple-ios-samples/tree/master/CustomizingUINavigationBar - Grubas
@Weizhi - 他们仍然包含代码,但是故事板场景已被移除。 - Gang Fang
由于Apple提供的示例现在是不完整的,@frangulan你能否提供一些代码,说明你实际上是如何实现这个功能的? - Don Miguel
@DonMiguel 我刚刚停止了对导航栏的调整,改用默认的导航栏设计我的应用程序。否则,我相信我必须实现自己的导航栏,这不值得。 - frangulyan

24

更新于2018年1月7日

此代码支持XCode 9.2,iOS 11.2。

我也遇到了同样的问题。以下是我的解决方案。我假设高度大小为66。

如果有帮助,请选择我的答案。

创建CINavgationBar.swift文件。

   import UIKit

@IBDesignable
class CINavigationBar: UINavigationBar {

    //set NavigationBar's height
    @IBInspectable var customHeight : CGFloat = 66

    override func sizeThatFits(_ size: CGSize) -> CGSize {

        return CGSize(width: UIScreen.main.bounds.width, height: customHeight)

    }

    override func layoutSubviews() {
        super.layoutSubviews()

        print("It called")

        self.tintColor = .black
        self.backgroundColor = .red



        for subview in self.subviews {
            var stringFromClass = NSStringFromClass(subview.classForCoder)
            if stringFromClass.contains("UIBarBackground") {

                subview.frame = CGRect(x: 0, y: 0, width: self.frame.width, height: customHeight)

                subview.backgroundColor = .green
                subview.sizeToFit()
            }

            stringFromClass = NSStringFromClass(subview.classForCoder)

            //Can't set height of the UINavigationBarContentView
            if stringFromClass.contains("UINavigationBarContentView") {

                //Set Center Y
                let centerY = (customHeight - subview.frame.height) / 2.0
                subview.frame = CGRect(x: 0, y: centerY, width: self.frame.width, height: subview.frame.height)
                subview.backgroundColor = .yellow
                subview.sizeToFit()

            }
        }


    }


}

设置故事板

在此输入图片描述

设置NavigationBar类

设置自定义NavigationBar类

添加TestView

在此输入图片描述

添加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。

这里输入图片描述

就是这样。


1
这个解决方案在iOS 11.2中似乎无效,因为导航栏会多次调用layoutSubviews(),导致应用程序冻结。 - Michael
1
我也遇到了同样的问题 @Michael - Krishna Kumar Thakur
10
这些变通方法非常粗糙,且很可能在不久的将来失效! - anemo
1
在 iPhone X 上,导航栏的高度会发生变化,但不再延伸到状态栏区域下方。有没有更新来使其在 iPhone X 上正常工作? - Jordan H
1
按类名搜索子视图非常脆弱。任何寻求稳健解决方案的人都应该避免使用此方法。 - InkGolem
显示剩余4条评论

10

这对我有效:

- (CGSize)sizeThatFits:(CGSize)size {
    CGSize sizeThatFit = [super sizeThatFits:size];
    if ([UIApplication sharedApplication].isStatusBarHidden) {
        if (sizeThatFit.height < 64.f) {
            sizeThatFit.height = 64.f;
        }
    }
    return sizeThatFit;
}

- (void)setFrame:(CGRect)frame {
    if ([UIApplication sharedApplication].isStatusBarHidden) {
        frame.size.height = 64;
    }
    [super setFrame:frame];
}

- (void)layoutSubviews
{
    [super layoutSubviews];

    for (UIView *subview in self.subviews) {
        if ([NSStringFromClass([subview class]) containsString:@"BarBackground"]) {
            CGRect subViewFrame = subview.frame;
            subViewFrame.origin.y = 0;
            subViewFrame.size.height = 64;
            [subview setFrame: subViewFrame];
        }
        if ([NSStringFromClass([subview class]) containsString:@"BarContentView"]) {
            CGRect subViewFrame = subview.frame;
            subViewFrame.origin.y = 20;
            subViewFrame.size.height = 44;
            [subview setFrame: subViewFrame];
        }
    }
}

9

新增: 这个问题在iOS 11 beta 6中已得到解决,所以下面的代码已经没有用了 ^_^


原始回答:

使用下面的代码来解决:

(我总是希望navigationBar.height + statusBar.height == 64,无论statusBar是否隐藏)

 @implementation P1AlwaysBigNavigationBar

- (CGSize)sizeThatFits:(CGSize)size {
    CGSize sizeThatFit = [super sizeThatFits:size];
    if ([UIApplication sharedApplication].isStatusBarHidden) {
        if (sizeThatFit.height < 64.f) {
            sizeThatFit.height = 64.f;
        }
    }
    return sizeThatFit;
}

- (void)setFrame:(CGRect)frame {
    if ([UIApplication sharedApplication].isStatusBarHidden) {
        frame.size.height = 64;
    }
    [super setFrame:frame];
}

- (void)layoutSubviews
{
    [super layoutSubviews];

    if (![UIApplication sharedApplication].isStatusBarHidden) {
        return;
    }

    for (UIView *subview in self.subviews) {
        NSString* subViewClassName = NSStringFromClass([subview class]);
        if ([subViewClassName containsString:@"UIBarBackground"]) {
            subview.frame = self.bounds;
        }else if ([subViewClassName containsString:@"UINavigationBarContentView"]) {
            if (subview.height < 64) {
                subview.y = 64 - subview.height;
            }else {
                subview.y = 0;
            }
        }
    }
}
@end

1
在for循环中,您的subview是一个UIView。之后你是如何做到subview.height的呢? - sudoExclaimationExclaimation
我为UIView编写了一个辅助类别。 - CharlieSu
仍然在iOS 11 beta 9中遇到此问题。使用这个解决方法可以解决问题。但希望他们能够修复它。谢谢@CharlieSu。 - Steffen Ruppel
1
我该如何将这个类设置为我的UINavigationController的导航栏? - Husein Behboudi Rad
这方面有Swift的示例吗?我想我需要使用子类化的UINavigationBar? - andromedainiative
我的self.subviews为空。 - krishnanunni

6

使用Swift 4进行简化。

class CustomNavigationBar : UINavigationBar {

    private let hiddenStatusBar: Bool

    // MARK: Init
    init(hiddenStatusBar: Bool = false) {
        self.hiddenStatusBar = hiddenStatusBar
        super.init(frame: .zero)
    }

    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }

    // MARK: Overrides
    override func layoutSubviews() {
        super.layoutSubviews()

        if #available(iOS 11.0, *) {
            for subview in self.subviews {
                let stringFromClass = NSStringFromClass(subview.classForCoder)
                if stringFromClass.contains("BarBackground") {
                    subview.frame = self.bounds
                } else if stringFromClass.contains("BarContentView") {
                    let statusBarHeight = self.hiddenStatusBar ? 0 : UIApplication.shared.statusBarFrame.height
                    subview.frame.origin.y = statusBarHeight
                    subview.frame.size.height = self.bounds.height - statusBarHeight
                }
            }
        }
    }
}

这段代码给我一个致命错误 fatalError("init(coder:) has not been implemented")。 - user7367398

5

除了覆盖-layoutSubviews-setFrame:之外,如果您不希望调整大小的导航栏隐藏内容,还应该查看新添加的UIViewController的additionalSafereaInsets属性(Apple Documentation)。


这很重要,仅更新导航栏背景高度将导致它与视图控制器中的内容重叠。我无法弄清楚的是如何正确使用addionalSafeAreaInsets,特别是如何允许iOS 10及以下版本不支持此属性。 - JoGoFo
这很重要,简单更新您的导航栏背景高度将导致它与视图控制器中的内容重叠。我无法弄清楚的是如何正确使用additionalSafeAreaInsets,特别是如何允许iOS 10及以下版本不支持此属性。 - JoGoFo

4
尽管在 beta 4 中已经修复了,但似乎导航栏的背景图片并不随实际视图缩放(您可以通过查看视图层次结构查证此事)。目前的解决方法是在自定义的 UINavigationBar 中重写 layoutSubviews,然后使用以下代码:
- (void)layoutSubviews
{
  [super layoutSubviews];

  for (UIView *subview in self.subviews) {
    if ([NSStringFromClass([subview class]) containsString:@"BarBackground"]) {
        CGRect subViewFrame = subview.frame;
        subViewFrame.origin.y = -20;
        subViewFrame.size.height = CUSTOM_FIXED_HEIGHT+20;
        [subview setFrame: subViewFrame];
    }
  }
}

如果您注意到了,实际上进度条的背景有一个偏移量为-20,以使其出现在状态栏后面,因此上述计算要加上这个偏移量。

你需要声明/实例化subviewFrame吗?还是直接编辑子视图的frame? - Marco Pappalardo
1
@MarcoPappalardo 修正了拼写错误,需要将其改为局部变量。 - strangetimes

3

在 Xcode 9 Beta 6 上我仍然遇到同样的问题。导航栏高度一直为 44 像素,并且被推到状态栏下面。

为了解决这个问题,我使用 @strangetimes 的代码(用 Swift 实现)创建了一个子类。

class NavigationBar: UINavigationBar {

  override func layoutSubviews() {
    super.layoutSubviews()

    for subview in self.subviews {
      var stringFromClass = NSStringFromClass(subview.classForCoder)
      print("--------- \(stringFromClass)")
      if stringFromClass.contains("BarBackground") {
        subview.frame.origin.y = -20
        subview.frame.size.height = 64
      }
    }
  }
}

我将工具栏放置在状态栏下方。

let newNavigationBar = NavigationBar(frame: CGRect(origin: CGPoint(x: 0,
                                                                       y: 20),
                                                         size: CGSize(width: view.frame.width,
                                                                      height: 64)
      )
    ) 

3

这对于常规导航栏效果很好。如果您使用的是LargeTitle,则效果不佳,因为titleView的大小不会是固定的44个点高度。但对于常规视图,这应该足够。

像@frangulyan apple建议添加一个视图在navBar下面并隐藏细线(阴影图像)。以下是我想出的方法。我在navigationItem的titleView中添加了一个uiview,然后在其中添加了一个imageView。我删除了细线(阴影图像)。我添加的uiview与navBar的完全相同的颜色。我在那个视图里面添加了一个uiLabel,就这样。

enter image description here

这是3D图像。扩展视图在用户名标签后面,在导航栏下方。它是灰色的,下面有一条细线。只需将您的collectionView或其他内容锚定在细分隔线下方即可。

enter image description here

每行代码上面都有9个步骤的解释:
class ExtendedNavController: UIViewController {

    fileprivate let extendedView: UIView = {
        let view = UIView()
        view.translatesAutoresizingMaskIntoConstraints = false
        view.backgroundColor = .white
        return view
    }()

    fileprivate let separatorLine: UIView = {
        let view = UIView()
        view.translatesAutoresizingMaskIntoConstraints = false
        view.backgroundColor = .gray
        return view
    }()

    fileprivate let usernameLabel: UILabel = {
        let label = UILabel()
        label.translatesAutoresizingMaskIntoConstraints = false
        label.font = UIFont.systemFont(ofSize: 14)
        label.text = "username goes here"
        label.textAlignment = .center
        label.lineBreakMode = .byTruncatingTail
        label.numberOfLines = 1
        return label
    }()

    fileprivate let myTitleView: UIView = {
        let view = UIView()
        view.backgroundColor = .white
        return view
    }()

    fileprivate let profileImageView: UIImageView = {
        let imageView = UIImageView()
        imageView.translatesAutoresizingMaskIntoConstraints = false
        imageView.clipsToBounds = true
        imageView.backgroundColor = .darkGray
        return imageView
    }()

    override func viewDidLoad() {
        super.viewDidLoad()
        view.backgroundColor = .white

        // 1. the navBar's titleView has a height of 44, set myTitleView height and width both to 44
        myTitleView.frame = CGRect(x: 0, y: 0, width: 44, height: 44)

        // 2. set myTitleView to the nav bar's titleView
        navigationItem.titleView = myTitleView

        // 3. get rid of the thin line (shadow Image) underneath the navigationBar
        navigationController?.navigationBar.setValue(true, forKey: "hidesShadow")
        navigationController?.navigationBar.layoutIfNeeded()

        // 4. set the navigationBar's tint color to the color you want
        navigationController?.navigationBar.barTintColor = UIColor(red: 249.0/255.0, green: 249.0/255.0, blue: 249.0/255.0, alpha: 1.0)

        // 5. set extendedView's background color to the same exact color as the navBar's background color
        extendedView.backgroundColor = UIColor(red: 249.0/255.0, green: 249.0/255.0, blue: 249.0/255.0, alpha: 1.0)

        // 6. set your imageView to get pinned inside the titleView
        setProfileImageViewAnchorsInsideMyTitleView()

        // 7. set the extendedView's anchors directly underneath the navigation bar
        setExtendedViewAndSeparatorLineAnchors()

        // 8. set the usernameLabel's anchors inside the extendedView
        setNameLabelAnchorsInsideTheExtendedView()
    }

    override func viewWillDisappear(_ animated: Bool) {
        super.viewWillDisappear(true)

        // 9. **Optional** If you want the shadow image to show on other view controllers when popping or pushing
        navigationController?.navigationBar.setBackgroundImage(nil, for: .default)
        navigationController?.navigationBar.setValue(false, forKey: "hidesShadow")
        navigationController?.navigationBar.layoutIfNeeded()
    }

    func setExtendedViewAndSeparatorLineAnchors() {

        view.addSubview(extendedView)
        view.addSubview(separatorLine)

        extendedView.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor).isActive = true
        extendedView.leadingAnchor.constraint(equalTo: view.leadingAnchor).isActive = true
        extendedView.trailingAnchor.constraint(equalTo: view.trailingAnchor).isActive = true
        extendedView.heightAnchor.constraint(equalToConstant: 29.5).isActive = true

        separatorLine.topAnchor.constraint(equalTo:  extendedView.bottomAnchor).isActive = true
        separatorLine.leadingAnchor.constraint(equalTo: view.leadingAnchor).isActive = true
        separatorLine.trailingAnchor.constraint(equalTo: view.trailingAnchor).isActive = true
        separatorLine.heightAnchor.constraint(equalToConstant: 0.5).isActive = true
    }

    func setProfileImageViewAnchorsInsideMyTitleView() {

        myTitleView.addSubview(profileImageView)

        profileImageView.topAnchor.constraint(equalTo: myTitleView.topAnchor).isActive = true
        profileImageView.centerXAnchor.constraint(equalTo: myTitleView.centerXAnchor).isActive = true
        profileImageView.widthAnchor.constraint(equalToConstant: 44).isActive = true
        profileImageView.heightAnchor.constraint(equalToConstant: 44).isActive = true

        // round the profileImageView
        profileImageView.layoutIfNeeded()
        profileImageView.layer.cornerRadius = profileImageView.frame.width / 2
    }

    func setNameLabelAnchorsInsideTheExtendedView() {

        extendedView.addSubview(usernameLabel)

        usernameLabel.topAnchor.constraint(equalTo: extendedView.topAnchor).isActive = true
        usernameLabel.leadingAnchor.constraint(equalTo: view.leadingAnchor).isActive = true
        usernameLabel.trailingAnchor.constraint(equalTo: view.trailingAnchor).isActive = true
    }
}

navigationController?.navigationBar.setValue(true, forKey: "hidesShadow") 被认为是私有的,会被苹果审核拒绝吗? - Itai Spector
我在我的一个实时应用中使用它,从来没有遇到任何问题。 - Lance Samaria
@ItaiSpector 你不用担心。 - Lance Samaria

2
这是我使用的方法。如果您将UISearchBar作为标题或其他修改栏内容大小的视图,则必须相应地更新值,才能适用于普通内容(44.0 px)。请注意,由于某些原因,此方法可能会失效,请自行决定是否使用。
这是具有硬编码高度为90.0px的导航栏,在iOS 11和旧版本上均可使用。对于iOS 11之前的版本,您可能需要为UIBarButtonItem添加一些插入来使其外观保持一致。
class NavBar: UINavigationBar {

    override init(frame: CGRect) {
        super.init(frame: frame)

        if #available(iOS 11, *) {
            translatesAutoresizingMaskIntoConstraints = false
        }
    }

    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }

    override func sizeThatFits(_ size: CGSize) -> CGSize {
        return CGSize(width: UIScreen.main.bounds.width, height: 70.0)
    }

    override func layoutSubviews() {
        super.layoutSubviews()

        guard #available(iOS 11, *) else {
            return
        }

        frame = CGRect(x: frame.origin.x, y:  0, width: frame.size.width, height: 90)

        if let parent = superview {
            parent.layoutIfNeeded()

            for view in parent.subviews {
                let stringFromClass = NSStringFromClass(view.classForCoder)
                if stringFromClass.contains("NavigationTransition") {
                    view.frame = CGRect(x: view.frame.origin.x, y: frame.size.height - 64, width: view.frame.size.width, height: parent.bounds.size.height - frame.size.height + 4)
                }
            }
        }

        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: 90)
                subview.backgroundColor = .yellow
            }

            stringFromClass = NSStringFromClass(subview.classForCoder)
            if stringFromClass.contains("BarContent") {
                subview.frame = CGRect(x: subview.frame.origin.x, y: 40, width: subview.frame.width, height: subview.frame.height)

            }
        }
    }
}

如何将其添加到 UINavigationController 的子类中:

class CustomBarNavigationViewController: UINavigationController {

    init() {
        super.init(navigationBarClass: NavBar.self, toolbarClass: nil)
    }

    override init(nibName nibNameOrNil: String?, bundle nibBundleOrNil: Bundle?) {
        super.init(nibName: nibNameOrNil, bundle: nibBundleOrNil)
    }

    override init(rootViewController: UIViewController) {
        super.init(navigationBarClass: NavBar.self, toolbarClass: nil)

        self.viewControllers = [rootViewController]
    }

    required public init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }

}

我遇到了一个错误 -> 致命错误:init(coder :)尚未实现: - Shawn Baek
如果您正在使用那个,请使用编码器实现init。 - Jelly
谢谢回复。但是安全区域的顶部没有更新。安全区域的顶部仍然是44像素。如何在设置导航栏高度后更新安全区域的顶部。 - Shawn Baek
你可以尝试在UIView上使用safeAreaInsets属性来更新你的安全区域。 - Jelly

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接