为所有 UIViewController 实例设置全局默认后退按钮显示模式
Posted
技术标签:
【中文标题】为所有 UIViewController 实例设置全局默认后退按钮显示模式【英文标题】:Set global default back button display mode for all UIViewController instances 【发布时间】:2020-10-05 12:49:41 【问题描述】:ios 14 引入了可配置的后退按钮模式。 例如。您可以在按钮上添加“返回”标签文本,但在紧凑的历史菜单中您仍然可以看到以前控制器的正确标题。
我正在寻找一种简单、愉快的方式来配置默认模式,因此运行时的所有 UIViewController 实例都将设置默认模式,例如 UINavigationItemBackButtonDisplayModeGeneric
我想知道是否有一种方法可以在不继承 UIViewController 的情况下做到这一点,或者记得始终手动配置 UIViewController 的每个实例
(通过viewController.navigationItem.backButtonDisplayMode = UINavigationItemBackButtonDisplayModeGeneric
)。
非常感谢任何不需要对数百个 UIViewController 实例进行大量重构的便捷方法!
【问题讨论】:
【参考方案1】:我认为没有子类化是不可能的,因为navigationItem
需要一个实例才能使用并且不能直接从扩展中修改
class GenericViewController: UIViewController
override func viewDidLoad()
super.viewDidLoad()
// your code here
viewController.navigationItem.backButtonDisplayMode = UINavigationItemBackButtonDisplayModeGeneric
在任何需要的地方使用它
class viewController: GenericViewController
这是一个非常好的方法,因为您可以控制实现它的内容以及不考虑它可能不在所有场景中存在的内容
【讨论】:
【参考方案2】:为了解决同样的问题,我使用了 swizzling 技术
import UIKit
private let swizzling: (UIViewController.Type, Selector, Selector) -> Void = forClass, originalSelector, swizzledSelector in
if let originalMethod = class_getInstanceMethod(forClass, originalSelector), let swizzledMethod = class_getInstanceMethod(forClass, swizzledSelector)
let didAddMethod = class_addMethod(forClass, originalSelector, method_getImplementation(swizzledMethod), method_getTypeEncoding(swizzledMethod))
if didAddMethod
class_replaceMethod(forClass, swizzledSelector, method_getImplementation(originalMethod), method_getTypeEncoding(originalMethod))
else
method_exchangeImplementations(originalMethod, swizzledMethod)
extension UIViewController
static func swizzle()
let originalSelector1 = #selector(viewDidLoad)
let swizzledSelector1 = #selector(swizzled_viewDidLoad)
swizzling(UIViewController.self, originalSelector1, swizzledSelector1)
@objc open func swizzled_viewDidLoad()
if let _ = navigationController
if #available(iOS 14.0, *)
navigationItem.backButtonDisplayMode = .generic
else
// Fallback on earlier versions
navigationItem.backButtonTitle = "Back"
swizzled_viewDidLoad()
并在application(_:didFinishLaunchingWithOptions:)
通话中
UIViewController.swizzle()
【讨论】:
以上是关于为所有 UIViewController 实例设置全局默认后退按钮显示模式的主要内容,如果未能解决你的问题,请参考以下文章
使用方法调配一次在所有 UIViewController 实例上更改 iOS13 上的 modalPresentationStyle
UIviewcontroller - 啥时候实例化视图属性?
将 UIViewController 设置为 UITableViewCell 中自定义 UIView 的委托