从 A push 到 B, 从B push 到C, 从C返回直接到A
最佳方案
思路: 在B跳转C后将B从栈中删除
最佳时机: B 跳转 C的push动画完成之后移除
import UIKit
extension UINavigationController {
/// remove spacial UIViewController
///
/// - Parameter aClass: UIViewController Class
func removeViewController(_ aClass: AnyClass) {
viewControllers.removeAll(where: { $0.isKind(of: aClass) })
}
/// Push a UIViewController and remove a UIViewController class in the current stack when the push animation finished
/// - Parameters:
/// - controller: A UIViewController instance that will be pushed
/// - removeClass: The UIViewController class that needs to be removed, default is nil
func push(_ controller: UIViewController, removeClass: AnyClass? = nil) {
CATransaction.setCompletionBlock { [unowned self] in
// 移除栈中的当前Controller
if let removeClass = removeClass {
self.navigationController?.removeViewController(removeClass)
}
}
CATransaction.begin()
pushViewController(controller, animated: true)
CATransaction.commit()
}
}
示例:
import UIKit
@main
class AppDelegate: UIResponder, UIApplicationDelegate {
var window: UIWindow?
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
window = UIWindow(frame: UIScreen.main.bounds)
window?.backgroundColor = .white
let naviController = UINavigationController(rootViewController: AViewController())
window?.rootViewController = naviController
window?.makeKeyAndVisible()
return true
}
}
import UIKit
class AViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
view.backgroundColor = .brown
title = "AController"
}
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
let vc = BViewController()
navigationController?.pushViewController(vc, animated: true)
}
}
import UIKit
class BViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
view.backgroundColor = .red
title = "BController"
}
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
let vc = CViewController()
navigationController?.push(vc, removeClass: BViewController.self)
}
}
import UIKit
class CViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
title = "CController"
view.backgroundColor = .orange
}
}