UINavigationBar有意思的用法

今天在看iOS guide,突然发现了一些有意思的用法,特此记录一下。

导航栏提示

这里使用导航栏的prompt属性,可以在导航栏的上方添加提示。

1
navigationItem.prompt = "Test next viewController's prompt"

这里官方指出使用这个属性时在iOS7中会有一个bug(在iOS8中修复),如果在viewDidAppear之前设置会导致the top guide不能正确地重新计算尺寸,导致导航栏会重叠你的内容。因此使用prompt属性时在-viewDidAppear中设置就好。

导航栏拓展

在导航栏下方拓展一个view,并且这个view作为导航栏的一部分。

  • 配置拓展view

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    override func willMove(toWindow newWindow: UIWindow?) {
    super.willMove(toWindow: newWindow)
    // 利用图层阴影绘制位于视图的最底部一条1像素的细线
    layer.shadowOffset = CGSize(width: 0, height: CGFloat(1) / UIScreen.main.scale)
    layer.shadowRadius = 0
    /**
    导航栏下面的细线是自适应的,它的属性会根据它的内容发生变化,这里需要多次实验找到更好值去匹配自己的内容
    */
    layer.shadowColor = #colorLiteral(red: 0, green: 0, blue: 0, alpha: 1).cgColor
    layer.shadowOpacity = 0.25
    }
  • 配置导航栏

    1
    2
    3
    4
    5
    6
    // isTranslucent为false时,它将使用拓展view不透明的背景颜色
    navigationController!.navigationBar.isTranslucent = false
    // shadowImage设置一个透明的图片,backgroundImage
    设置一个1像素的图片,取消掉导航栏自身下面的细线
    navigationController!.navigationBar.shadowImage = UIImage(named: "TransparentPixel")
    navigationController!.navigationBar.setBackgroundImage(#imageLiteral(resourceName: "Pixel"), for: .default)

导航栏返回按钮

  • 创建一个不可拉伸的图片

    1
    2
    3
    4
    5
    // 此时设置的导航栏的tintColor属性不会影响这个图片,这个图片显示自身颜色
    var image = UIImage(named: "Menu")
    // 固定左侧 且不可拉伸
    image = image!.resizableImage(withCapInsets: .init(top: 0, left: image!.size.width - 1, bottom: 0, right: 0))
  • appearance绑定

    1
    2
    let appearance = UIBarButtonItem.appearance(whenContainedInInstancesOf: [CustomBackButtonNavController.self])
    appearance.setBackgroundImage(image!, for: .normal, barMetrics: .default)

    这个方法只能在iOS9及其之后使用

  • 创建一个空的UIBarButtonItem去隐藏默认返回按钮的标题,

    • 这里不需要额外提供target和action
    • 设置标题时不要传一个空字符串,传一个带空格的字符串。空字符串会在7的系统上有一个导致图片水平压缩的bug。

      1
      2
      3
      let backButtonItem = UIBarButtonItem(title: " ", style: .plain, target: nil, action: nil)
      navigationItem.backBarButtonItem = backButtonItem