SwiftUI -如何在SwiftUI中弹出特定视图?

mrfwxfqh  于 2023-05-27  发布在  Swift
关注(0)|答案(3)|浏览(155)

有没有办法在SwiftUI中实现popToViewController(vc)的等价物?例如,如果我有以下流程:
视图1->视图2->视图3->视图4
考虑到我们无法控制导航堆栈,我如何从View 4直接弹出到View 2?

7ivaypg9

7ivaypg91#

让它简单!!
UINavigationController添加扩展

extension UINavigationController {
func popToViewController(ofClass: AnyClass, animated: Bool = true) {
  if let vc = viewControllers.last(where: { $0.isKind(of: ofClass) }) {
    popToViewController(vc, animated: animated)
  }
}

添加下面的代码以转到特定的SwiftUI视图。你必须提到SampleView的位置。

navigationController.popToViewController(ofClass: HostingController<SampleView>.self)

就是这样!

qnyhuwrf

qnyhuwrf2#

// Do not change, it must be same with NavigationBarTitle
enum ViewIdentifiers: String {
    case homeView = "Home"
    case detailView = "Detail Page"
}    

struct HomeView: View {

 var body: some View {
   VStack {
      NavigationLink {
          DetailView()
      } label: {
         Text("Go To Detail")
     }
   }
   .navigationBarTitle(ViewIdentifiers.homeView.rawValue, displayMode: .inline)
 }
}

struct DetailView: View {

 var body: some View {
   VStack {
       Text("Detail")
         .onTapGesture { UIApplication.shared.popToView(ViewIdentifiers.homeView) }
   }
   .navigationBarTitle("Detail Page", displayMode: .inline)
 }
}

extension UIApplication {

  var keyWindow: UIWindow? {
    return UIApplication.shared.connectedScenes
        .filter { $0.activationState == .foregroundActive }
        .first(where: { $0 is UIWindowScene })
        .flatMap({ $0 as? UIWindowScene })?.windows
        .first(where: \.isKeyWindow)
  }
 

 func getNavigationController() -> UINavigationController? {
    guard let window = keyWindow else { return nil }
    guard let rootViewController = window.rootViewController else { return nil }
    guard let navigationController = findNavigationController(viewController: rootViewController) else { return nil }
    return navigationController
  }
  
  private func findNavigationController(viewController: UIViewController?) -> UINavigationController? {
    guard let viewController = viewController else {
        return nil
    }
    
    if let navigationController = viewController as? UINavigationController {
        return navigationController
    }
    
    for childViewController in viewController.children {
        return findNavigationController(viewController: childViewController)
    }
    
    return nil
 }

 func popToView(_ identifier: ViewIdentifiers) {
    guard let navigationController = getNavigationController() else {
        return
    }
    
    for vc in navigationController.children {
        if vc.navigationItem.title == identifier.rawValue {
            navigationController.popToViewController(vc, animated: true)
            break
        }
    }
  }

}
bxjv4tth

bxjv4tth3#

因为我正在用SwiftUI做一些功能的研发。我正面临着特定视图弹出的问题。研发之后我有了新发现。您可以使用它来弹出到特定的视图视图。
1.首先,您必须为UINavigationController创建一个扩展。检查下面提到的代码

import UIKit

extension UINavigationController {

    func popToViewController(ofClass: AnyClass, animated: Bool = true) {
        if let vc = viewControllers.filter({$0.isKind(of: ofClass)}).last {
            popToViewController(vc, animated: animated)
        }
    }

    func popViewControllers(viewsToPop: Int, animated: Bool = true) {
        if viewControllers.count > viewsToPop {
            let vc = viewControllers[viewControllers.count - viewsToPop - 1]
            popToViewController(vc, animated: animated)
        }
    }

    func popBack<T: UIViewController>(toControllerType: T.Type) {
        if var viewControllers: [UIViewController] = self.navigationController?.viewControllers {
            viewControllers = viewControllers.reversed()
            for currentViewController in viewControllers {
                if currentViewController .isKind(of: toControllerType) {
                    self.navigationController?.popToViewController(currentViewController, animated: true)
                    break
                }
            }
        }
    }
}

1.使用此代码获取UINavigationController示例。

let window = UIApplication.shared.connectedScenes
    .filter { $0.activationState == .foregroundActive }
    .map { $0 as? UIWindowScene }
    .compactMap { $0 }
    .first?.windows
    .filter { $0.isKeyWindow }
    .first
let navigation = window?.rootViewController?.children.first as? UINavigationController

1.获得UINavigationController示例后,您可以使用此代码轻松地弹出到特定视图。

navigation.popViewControllers(viewsToPop: 2)

相关问题