为所有UIViewController实例设置全局默认后退按钮显示模式

问题描述

iOS 14引入了可配置的后退按钮模式。 例如。您可以在按钮上显示“后退”标签文本,但是在紧凑的历史记录菜单中,您仍然可以看到以前控制器的正确标题

我正在寻找一种配置认模式的简便方法,因此在运行时,所有UIViewController实例都将设置认模式,例如UINavigationItemBackButtondisplayModeGeneric

我想知道是否有一种方法可以不对UIViewController进行子类化,或者记得始终手动配置每个UIViewController实例 (通过viewController.navigationItem.backButtondisplayMode = UINavigationItemBackButtondisplayModeGeneric)。

任何不需要大量重构数百个UIViewController实例的便捷方法,将不胜感激!

解决方法

我认为没有子类是不可能的,因为navigationItem需要一个实例,并且不能直接从扩展中修改

class GenericViewController: UIViewController {
override func viewDidLoad() {
    super.viewDidLoad()
    // your code here  
    viewController.navigationItem.backButtonDisplayMode = UINavigationItemBackButtonDisplayModeGeneric
  }
}

并在需要的地方使用它

class viewController: GenericViewController

这是一个非常好的方法,因为您可以控制实现它的方式以及不考虑可能并非在所有场景中都存在的方式

,

为解决相同的问题,我使用了模糊处理技术

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,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()

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...