我已将 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
}
如果您在应用程序场景清单中的信息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)
}
}