以编程方式创建导航控制器(Swift)

74

我一直试图以编程方式重新制作我的应用程序。(不使用故事板)

我快做完了,唯独手动创建导航控制器还没完成。

目前,我只有一个视图控制器。当然还有appDelegate。

导航控制器将在整个应用程序的所有页面中使用。

如果有人能帮我,或者发送一些适当的文档链接来以编程方式完成这个操作,那将非常感激。

编辑:

我忘了提到它是用Swift编写的。


1
可能是在iOS中以编程方式创建UINavigationController的重复问题。 - qwerty_so
请注意,在绝大多数情况下,您可以在Storyboard上完成它... https://dev59.com/SX7aa4cB1Zd3GeqPr5KN#22981726 然后,您可以关闭奇怪的按钮栏,它与以编程方式完成的效果“一样好”。 - Fattie
1
@ThomasKilian 这怎么算是重复了呢?另一个是Objective C,但这个是Swift啊? - user3390652
1
@user3390652,请查看编辑历史记录。当时提问者没有标记为Swift。 - qwerty_so
7个回答

115

在AppDelegate.swift中

Swift 1, 2:

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
   self.window = UIWindow(frame: UIScreen.mainScreen().bounds)
   var nav1 = UINavigationController()
   var mainView = ViewController(nibName: nil, bundle: nil) //ViewController = Name of your controller
   nav1.viewControllers = [mainView]
   self.window!.rootViewController = nav1
   self.window?.makeKeyAndVisible()
}

Swift 4+:和Swift 5+

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
   self.window = UIWindow(frame: UIScreen.main.bounds)
   let nav1 = UINavigationController()
   let mainView = ViewController(nibName: nil, bundle: nil) //ViewController = Name of your controller
   nav1.viewControllers = [mainView]
   self.window!.rootViewController = nav1
   self.window?.makeKeyAndVisible()
}

1
没事了,我意识到自己哪里出错了。将其改回 mainView 并执行 "var mainView = NameOfYourViewController()",然后它就可以工作了。非常感谢您的帮助! - MLyck
如果我想将它添加到已经有UITabBarController的视图中怎么办? - TomSawyer
@TomSawyer,在将控制器添加到选项卡栏之前,使用您的控制器创建UINavigationController对象,并使用该导航对象添加到UITabbarcontroller上。 - Jogendra.Com
1
你也可以使用 UINavigationController(rootViewController: _) 初始化器来代替将一个元素的数组分配给 viewControllers 属性。但这只是为了节省一行代码 :) - Kirill Dubovitskiy
这对我来说似乎是错误的(尽管我知道它可以工作,我已经使用过它)。self.window.rootViewController是UIViewController类型,在Swift对象中不应该被分配UINavigationController。 - muz the axe
显示剩余2条评论

22

类型 'AppDelegate' 的值没有成员 'window'

对于使用 SceneDelegate.swift 构建的较新项目,您可以在 SceneDelegate 中使用 'var window: UIWindow?' 替代已移除的 AppDelegate 中的 'var window'。

func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
    guard let windowScene = (scene as? UIWindowScene) else { return }

    window?.windowScene = windowScene
    window?.makeKeyAndVisible()

    let viewController = ViewController()
    let navViewController = UINavigationController(rootViewController: viewController)
    window?.rootViewController = navViewController
}

谢谢,我本来打算在单个视图控制器中设置导航栏,但是无法弄清它的约束。现在我知道这是错误的。它应该在AppDelegate或SceneDelegate中作为全局使用设置。 - Zhou Haibo

17

我建议您使用以下骨架开始编写AppDelegate:

1) 尽可能使用let

2) UINavigationController具有rootViewController属性。

func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
    let viewController = ViewController(nibName: nil, bundle: nil) //ViewController = Name of your controller
    let navigationController = UINavigationController(rootViewController: viewController)

    self.window = UIWindow(frame: UIScreen.mainScreen().bounds)
    self.window?.rootViewController = navigationController
    self.window?.makeKeyAndVisible()

    return true
}

9

这里是SceneDelegate类的另一种实现:

var window: UIWindow?

func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {

    if let windowScene = scene as? UIWindowScene {

        let window = UIWindow(windowScene: windowScene)    
        let navController = UINavigationController()
        let viewController = ViewController()

        navController.viewControllers = [viewController]            
        window.rootViewController = navController
        self.window = window
        window.makeKeyAndVisible()
    }
}

如何使其与TabBarController配合使用,以便显示标题? - Lukasz D
我不完全确定你在问什么。你只需要像这样将UITabBarController添加为rootViewController -> window.rootViewController = MyTabBarController() - Linus

3
尝试这个。它将指导您如何使用导航控制器。 iOS中以编程方式创建UINavigationController

AppDelegate.h

    #import <UIKit/UIKit.h>
    #import "LoginViewController.h"

    @interface AppDelegate : UIResponder <UIApplicationDelegate>

    @property (strong, nonatomic) UIWindow *window;
    @property (strong,nonatomic) UINavigationController *navigationController;
    @property (strong,nonatomic) LoginViewController *loginVC;

    @end

AppDelegate.m

    #import "AppDelegate.h"
    #import "LoginViewController.h"

    @implementation AppDelegate

  - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
  {
    self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
    // Override point for customization after application launch.

   self.loginVC = [[LoginViewController alloc]initWithNibName:nil bundle:nil];
   self.loginVC.title = @"Login Page";

   self.navigationController = [[UINavigationController alloc]initWithRootViewController:self.loginVC];

   self.window.rootViewController = self.navigationController;
   [self.window makeKeyAndVisible];
  }

当你想要推送另一个视图控制器时,只需使用以下代码来移动到另一个视图控制器。

- (IBAction)pushMyProfileView:(id)sender
{
    self.myProfileVC = [[MyProfileViewController alloc]initWithNibName:nil bundle:nil];
    [appDelegate.navigationController pushViewController:self.myProfileVC animated:YES];
}

嘿,非常感谢您的回复!我知道这完全是我的错,我只是把它添加为标签并忘记提到它。但我正在使用Swift编码。不幸的是,我不知道如何将那段代码翻译成Swift。 - MLyck
1
答案应该是用 Swift。 - Umair Afzal
@UmairAfzal 好的,如果你需要的话,我很快就会发布更新的Swift代码。 - Hardik Shekhat
@HardikShekhat,实际上我确实需要,请参考我的问题。http://stackoverflow.com/questions/37606778/how-to-navigate-all-views-of-application-using-navigation-controller-in-ios-usin/37606892#37606892 - Umair Afzal
1
@UmairAfzal 我会在那里发布有关Swift的答案。 - Hardik Shekhat

0

这可能有点过度,但我发现自己经常这样做,所以我扩展了UIViewController并创建了一个embedInNavigationController方法。现在我只需要调用viewController.embedInNavigationController。

extension UIViewController {

func embedInNavigationController() -> UINavigationController {
    return UINavigationController(rootViewController: self)
   }
}

-3
 self.window = UIWindow(frame: UIScreen.main.bounds) 
 let storyboard = UIStoryboard(name: "Main", bundle: nil) 
 let storyboard_Secondary = UIStoryboard(name: "Secondary", bundle: nil) 
 var initialViewController = UIViewController() 

 let aUser = CommonMethods.loadCustomObject("\(Constants.kUserProfile)") as? User  
 if aUser?.respCode == 1 { 
    initialViewController = storyboard_Secondary.instantiateViewController(withIdentifier: "MainTabVC")
    UIApplication.shared.statusBarStyle = .lightContent
    let navigationController = UINavigationController(rootViewController: initialViewController)
    navigationController.isNavigationBarHidden = true
    self.window!.rootViewController = navigationController
    self.window!.makeKeyAndVisible() 
}

2
这个答案不是通用的,依赖于语言中没有的一个类。这个答案也没有展示导入那个类,也没有说明那个类来自哪里或如何获取它。完全可以在不使用CommonMethods的情况下重写它,从而减少代码行数并得到更通用的答案。这里还有一些不必要的样式代码,对于NavigationController的正常工作来说并不需要。 - miles_b

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接