无法快速导航到根视图控制器(Home)

问题描述 投票:0回答:1

我已将 NavigationControllerScene 添加到 ViewController 并使其成为故事板中的初始视图控制器

代码:如果我使用下面的代码,点击testBtn无法转到ViewController1。为什么?我想显示带有侧菜单和底部选项卡的 ViewController,这就是我编写这样的代码的原因。在 Appdelegate 和 Scenedelagate 中添加了相同的代码

为什么无法从 ViewController 导航到 ViewController1?

这是我的信息.plist

import UIKit

class ViewController: UIViewController {

override func viewDidLoad() {
    super.viewDidLoad()
    setUpNavigationBar(with: "Viewcontroller", isBackNeed: false)
}


@IBAction func testBtn(_ sender: UIButton){
    // added same code in Appdelegate and scenedelagete as well
    let home = Helper.getVcObject(vcName: .ViewController1, StoryBoardName: .Main) as! ViewController1
    let menu = Helper.getVcObject(vcName: .MenuViewController, StoryBoardName: .Main) as! MenuViewController
    let nav = MainNavigationController(rootViewController: home)
    let sideMenu = SideMenuController(contentViewController: nav, menuViewController: menu)
    Helper.replaceRootView(for: sideMenu)
    
}
}

以及我的一些自定义方法:

let keyWindow = UIApplication.shared.connectedScenes
.filter({$0.activationState == .foregroundActive})
.compactMap({$0 as? UIWindowScene})
.first?.windows
.filter({$0.isKeyWindow}).first

enum StoryBoardNameCase: String {
case Main = "Main"

}

enum VCNameCase: String {
case MenuViewController = "MenuViewController"
case ViewController1 = "ViewController1"
}

class Helper {

static func getVcObject(vcName:VCNameCase, StoryBoardName:StoryBoardNameCase) -> UIViewController{
    
    let storyBoard: UIStoryboard = UIStoryboard(name: StoryBoardName.rawValue, bundle: nil)
    let vc = storyBoard.instantiateViewController(withIdentifier: vcName.rawValue)
    
    return vc
}

static func replaceRootView(for rootViewController: UIViewController, animated: Bool = true, completion: (() -> Void)? = nil) {
    if animated {
        UIView.transition(with: keyWindow ?? UIWindow(), duration: 0.5, options: .transitionCrossDissolve, animations: {
            let oldState: Bool = UIView.areAnimationsEnabled
            UIView.setAnimationsEnabled(false)
            keyWindow?.rootViewController = rootViewController
            keyWindow?.makeKeyAndVisible()
            UIView.setAnimationsEnabled(oldState)
        }, completion: { (finished: Bool) -> () in
            completion?()
        })
    } else {
        keyWindow?.rootViewController = rootViewController
        keyWindow?.makeKeyAndVisible()
    }
}

编辑:AppDelegate:代码也在SceneDelegate中添加了相同的代码

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
    // Override point for customization after application launch.
    
    let home = Helper.getVcObject(vcName: .ViewController1, StoryBoardName: .Main) as! ViewController1
    let menu = Helper.getVcObject(vcName: .MenuViewController, StoryBoardName: .Main) as! MenuViewController
    let nav = MainNavigationController(rootViewController: home)
    let sideMenu = SideMenuController(contentViewController: nav, menuViewController: menu)
    Helper.replaceRootView(for: sideMenu)
    
    SideMenuController.preferences.basic.menuWidth = UIScreen.main.bounds.width * 0.8
    
    return true
}

场景委托代码:

 func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) 
{
    // Use this method to optionally configure and attach the UIWindow `window` to the provided UIWindowScene `scene`.
    // If using a storyboard, the `window` property will automatically be initialized and attached to the scene.
    // This delegate does not imply the connecting scene or session are new (see `application:configurationForConnectingSceneSession` instead).
        
    let home = Helper.getVcObject(vcName: .ViewController1, StoryBoardName: .Main) as! ViewController1
    let menu = Helper.getVcObject(vcName: .MenuViewController, StoryBoardName: .Main) as! MenuViewController
    let nav = MainNavigationController(rootViewController: home)
    let sideMenu = SideMenuController(contentViewController: nav, menuViewController: menu)
    Helper.replaceRootView(for: sideMenu)
    
    SideMenuController.preferences.basic.menuWidth = UIScreen.main.bounds.width * 0.8
    
}
swift uinavigationcontroller root
1个回答
0
投票

如果您在应用程序场景清单中的信息plist中使用,您应该在SceneDelegate中定义根视图控制器:

因此,您将 LoginViewController 定义为 SceneDelegate 上的 rootViewController

class SceneDelegate: UIResponder, UIWindowSceneDelegate {
    var window: UIWindow?
    func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
        guard let scene = (scene as? UIWindowScene) else { return }
        self.window = UIWindow(windowScene: scene)
        window?.rootViewController = yourLoginVC
        window?.makeKeyAndVisible()
    }

    func initNewMainVC(rootVC: UIViewController) {
        window?.rootViewController = rootVC
        window?.makeKeyAndVisible()
    }
}

在你的班级:


static func replaceRootView(for rootViewController: UIViewController, animated: Bool = true, completion: (() -> Void)? = nil) {
    let scene = UIApplication.shared.connectedScenes.first
        if let sceneDelegate: SceneDelegate = (scene?.delegate as? SceneDelegate) {
            sceneDelegate.initNewMainVC(rootVC: rootViewController)
        }
}

但是如果你从 AppDelegate 使用:

您应该将 SceneDelegate 上定义的所有内容定义到 Appdelegate 并将其设置在 appdelegate 上:


static func replaceRootView(for rootViewController: UIViewController, animated: Bool = true, completion: (() -> Void)? = nil) {
        if let appDelegate = UIApplication.shared.delegate as? AppDelegate {
            appDelegate.initNewMainVC(rootVC: rootViewController)
        }
}
© www.soinside.com 2019 - 2024. All rights reserved.