iOS 11导航栏高度自定义 [英] iOS 11 navigation bar height customizing

查看:152
本文介绍了iOS 11导航栏高度自定义的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

现在在iOS 11中,不会从 UINavigationBar 子类调用 sizeThatFits 方法。更改 UINavigationBar 的框架会导致毛刺和错误的插入。
那么,现在有关于如何自定义导航栏高度的任何想法吗?

Now in iOS 11, the sizeThatFits method is not called from UINavigationBar subclasses. Changing the frame of UINavigationBar causes glitches and wrong insets. So, any ideas how to customize navbar height now?

推荐答案

2018年1月7日更新

Updated 07 Jan 2018

此代码支持XCode 9.2,iOS 11.2

This code is support XCode 9.2, iOS 11.2

我遇到了同样的问题。以下是我的解决方案。我假设身高是66.

I had the same problem. Below is my solution. I assume that height size is 66.

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

Please choose my answer if it helps you.

创建CINavgationBar。 swift

Create 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类

Set Custom NavigationBar class

添加TestView +设置SafeArea

Add TestView + Set SafeArea

ViewController.swift

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

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。

Yellow is barbackgroundView. Black opacity is BarContentView.

我删除了BarContentView的backgroundColor。

And I removed BarContentView's backgroundColor.

就是这样。

这篇关于iOS 11导航栏高度自定义的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆