在 iOS14 通过 backButtonDisplayMode 来管理你的后退按钮

4,417 阅读3分钟

原文链接: sarunw.com/posts/new-w…

作者: @sarunw

在 iOS14,长按后退按钮会显示一个导航历史的菜单。我们已经在前一篇文章中讨论了这个问题和解决方案。虽然在那篇文章中的解决方案能够实际运行,但我很高兴 Apple 在 iOS14 beta 3 中添加了一个新的 NavigationItem 属性来解决这个问题。

建议在阅读本文章之前先阅读一下前一篇文章来了解问题所在,这样你就会明白为什么 Apple 要添加这个新的属性了。

导航历史

backButtonDisplayMode

这个新的属性是 backButtonDisplayMode ,他被用来控制后退按钮如何展示他的 title

@available(iOS 14.0, *)
open var backButtonDisplayMode: UINavigationItem.BackButtonDisplayMode

他的类型是 UINavigationItem.BackButtonDisplayMode

public enum BackButtonDisplayMode : Int {
    /// Default mode, uses an appropriate title, followed by a generic title (typically 'Back'), then no title.
    case `default` = 0

    /// Generic titles only. Ignores .title and .backButtonTitle (but *not* .backBarButtonItem.title).
    case generic = 1

    /// Don't use a title, just the back button indicator image.
    case minimal = 2
}

Sources of back button title

由于 backButtonDisplayMode 定义了后退按钮的 title 的来源,那我们来看一下现在有哪些方式能决定后退按钮的 title

A view controller title or navigation item title

backButtonTitlebackBarButtonItem 没有被指明时,一个 ViewControllertitlenavigationItem.title 会被用作后退按钮的 title。(译者注:两者是同级的,同时设置时后执行的则为 ViewControllertitle

class AViewController: UIViewController {
    override func viewDidLoad() {
        title = "Title A" 
        // or 
        navigationItem.title = "Title A"
    }
}

A view controller title or navigation item title-1

A view controller title or navigation item title-2

Back button title

你可以通过 navigationItem.backButtonTitle 来直接设置后退按钮的 title。他会覆盖你设置的 UIViewController.titleUIViewController.navigationItem.title

class AViewController: UIViewController {
    override func viewDidLoad() {
        title = "Title A" 
        navigationItem.backButtonTitle = "backButtonTitle A"
    }
}

back-button-title-1

back-button-title-2

Back bar button item

在这些设置 title 的方法中,优先级最高的是 navigationItem.backBarButtonItem。这会覆盖任何你设置过的 titlenavigationItem.backButtonTitlenavigationItem.backBarButtonItem

class AViewController: UIViewController {
    override func viewDidLoad() {
        title = "Title A" 
        navigationItem.backButtonTitle = "backButtonTitle A"
        navigationItem.backBarButtonItem = UIBarButtonItem(title: "backBarButtonItem A", style: .plain, target: nil, action: nil)
    }
}

back-bar-button-item-1

back-bar-button-item-2

BackButtonDisplayMode.default

这就是在 iOS14 以前你所见到的后退按钮的样式。他右边显示的 title 就是你在导航历史中会见到的标题。

BackButtonDisplayModel.generic

这个模式使用 Back(返回) 来作为你的后退按钮的 title。但在导航历史中他会使用 titlenavigationItem.titlenavigationItem.backButtonTitle 来作为标题。

class AViewController: UIViewController {
    override func viewDidLoad() {
        title = "Title A" 
        // or 
        navigationItem.title = "Title A"
        navigationItem.backButtonDisplayMode = .generic
    }
}

但后退按钮使用的是"Back"(返回)

上述规则同样适用与 navigationItem.backButtonTitle,但是这不会影响你通过navigationItem.backBarButtonItem 设置的标题。

class AViewController: UIViewController {
    override func viewDidLoad() {
        title = "Title A" 
        navigationItem.backButtonTitle = "backButtonTitle A"
        navigationItem.backBarButtonItem = UIBarButtonItem(title: "backBarButtonItem A", style: .plain, target: nil, action: nil)
        navigationItem.backButtonDisplayMode = .generic
    }
}

BackButtonDisplayModel.minimal

这个模式不会在后退按钮的右侧显示一个 title,只会有一个箭头图标。导航历史中依然会使用titlenavigationItem.titlenavigationItem.backButtonTitle 来作为标题。就像.generic 一样,他不会影响你通过 navigationItem.backBarButtonItem 设置的标题。

class AViewController: UIViewController {
    override func viewDidLoad() {
        title = "Title A" 
        navigationItem.backButtonTitle = "backButtonTitle A"
        navigationItem.backButtonDisplayMode = .minimal
    }
}

Summary

标题来源BackButtonDisplayMode后退按钮 Title导航历史标题
title, navigationItem.title or navigationItem.backButtonTitledefault标题来源 or 位置不够时使用 Back(返回)标题来源
title, navigationItem.title or navigationItem.backButtonTitlegeneric"Back"(返回)标题来源
title, navigationItem.title or navigationItem.backButtonTitleminimal标题来源
navigationItem.backBarButtonItemdefault标题来源 or 位置不够时使用 Back(返回)标题来源
navigationItem.backBarButtonItemgeneric标题来源 or 位置不够时使用 Back(返回)标题来源
navigationItem.backBarButtonItemminimal标题来源 or 位置不够时使用 Back(返回)标题来源

Conclusion

backButtonDisplayMode 是一个在 iOS14 加入的不错的 API,我们现在能更好的控制后退按钮的 title 样式。

下面的代码会使 ViewController 的标题为 "Title A",后退按钮后没有 title,导航历史中的标题显示为"Title in history stack A"。

class AViewController: UIViewController {
    override func viewDidLoad() {
        title = "Title A"
        navigationItem.backButtonTitle = "Title in history stack A"
        navigationItem.backButtonDisplayMode = .minimal
    }
}

这比我们在前一篇文章文章中做的 hack 看起来清爽了许多。

Related Resources