Làm cách nào để tôi lập trình thiết lập InitialViewController
cho Storyboard? Tôi muốn mở bảng phân cảnh của mình sang một chế độ xem khác tùy thuộc vào một số điều kiện có thể thay đổi từ khởi chạy đến khởi chạy.
Làm cách nào để tôi lập trình thiết lập InitialViewController
cho Storyboard? Tôi muốn mở bảng phân cảnh của mình sang một chế độ xem khác tùy thuộc vào một số điều kiện có thể thay đổi từ khởi chạy đến khởi chạy.
Câu trả lời:
Làm thế nào để không có bộ điều khiển xem ban đầu giả
Đảm bảo tất cả các bộ điều khiển xem ban đầu có ID Storyboard.
Trong bảng phân cảnh, bỏ chọn thuộc tính "Là trình điều khiển xem ban đầu" từ trình điều khiển chế độ xem đầu tiên.
Nếu bạn chạy ứng dụng của mình vào thời điểm này, bạn sẽ đọc:
Failed to instantiate the default view controller for UIMainStoryboardFile 'MainStoryboard' - perhaps the designated entry point is not set?
Và bạn sẽ nhận thấy rằng thuộc tính cửa sổ của bạn trong đại biểu ứng dụng hiện không.
Trong cài đặt của ứng dụng, đi đến mục tiêu của bạn và Info
tab. Có giá trị rõ ràng của Main storyboard file base name
. Trên General
tab, xóa giá trị cho Main Interface
. Điều này sẽ loại bỏ cảnh báo.
Tạo cửa sổ và trình điều khiển xem ban đầu mong muốn trong application:didFinishLaunchingWithOptions:
phương thức của đại biểu ứng dụng :
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
self.window = [[UIWindow alloc] initWithFrame:UIScreen.mainScreen.bounds];
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"MainStoryboard" bundle:nil];
UIViewController *viewController = // determine the initial view controller here and instantiate it with [storyboard instantiateViewControllerWithIdentifier:<storyboard id>];
self.window.rootViewController = viewController;
[self.window makeKeyAndVisible];
return YES;
}
didFinishLaunchingWithOptions
được gọi khi ứng dụng được khởi động trong một quy trình mới. Nếu bạn vào màn hình chính và quay lại ứng dụng, phương pháp này sẽ không được gọi lại. (Trừ khi iOS chấm dứt do hạn chế về bộ nhớ.) Hãy thử dừng ứng dụng và khởi chạy lại từ IDE của bạn. Nếu vấn đề vẫn tiếp tục, hãy đăng vấn đề lên SO và tôi rất sẵn lòng giúp đỡ, bạn ạ.
self.window = UIWindow(frame: UIScreen.mainScreen().bounds) var storyboard = UIStoryboard(name: "Main", bundle: nil) var viewController: UIViewController = // self.window!.rootViewController = viewController self.window!.makeKeyAndVisible()
Đối với tất cả những người yêu thích Swift ngoài kia, đây là câu trả lời của @Travis được dịch sang SWIFT :
Làm những gì @Travis giải thích trước mã C Mục tiêu. Sau đó,
func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
self.window = UIWindow(frame: UIScreen.mainScreen().bounds)
let mainStoryboard: UIStoryboard = UIStoryboard(name: "Main", bundle: nil)
var exampleViewController: ExampleViewController = mainStoryboard.instantiateViewControllerWithIdentifier("ExampleController") as! ExampleViewController
self.window?.rootViewController = exampleViewController
self.window?.makeKeyAndVisible()
return true
}
Các ExampleViewController
sẽ là bộ điều khiển xem ban đầu mới mà bạn muốn hiển thị.
Các bước giải thích:
Thưởng thức và vui vẻ lập trình!
Bạn có thể lập trình thiết lập rootViewControll của cửa sổ chính trong (BOOL)application:(UIApplication *)application willFinishLaunchingWithOptions:(NSDictionary *)launchOptions
ví dụ:
- (BOOL)application:(UIApplication *)application willFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
if (shouldShowAnotherViewControllerAsRoot) {
UIStoryboard *storyboard = self.window.rootViewController.storyboard;
UIViewController *rootViewController = [storyboard instantiateViewControllerWithIdentifier:@"rootNavigationController"];
self.window.rootViewController = rootViewController;
[self.window makeKeyAndVisible];
}
return YES;
}
init()
/ deinit()
chu kỳ, nhưng không thực hiện viewDidLoad()
hoặc khởi tạo đúng cách IBOutlet
-s. Hãy chắc chắn rằng mã của bạn đã sẵn sàng cho nó.
Swift 3: Cập nhật mã của @ victor-sigler
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
self.window = UIWindow(frame: UIScreen.main.bounds)
// Assuming your storyboard is named "Main"
let mainStoryboard: UIStoryboard = UIStoryboard(name: "Main", bundle: nil)
// Add code here (e.g. if/else) to determine which view controller class (chooseViewControllerA or chooseViewControllerB) and storyboard ID (chooseStoryboardA or chooseStoryboardB) to send the user to
if(condition){
let initialViewController: chooseViewControllerA = mainStoryboard.instantiateViewController(withIdentifier: "chooseStoryboardA") as! chooseViewControllerA
self.window?.rootViewController = initialViewController
)
}else{
let initialViewController: chooseViewControllerB = mainStoryboard.instantiateViewController(withIdentifier: "chooseStoryboardB") as! chooseViewControllerB
self.window?.rootViewController = initialViewController
)
self.window?.makeKeyAndVisible(
return true
}
Bạn có thể đặt Bộ điều khiển gốc điều hướng làm bộ điều khiển xem chính. Ý tưởng này có thể sử dụng để đăng nhập tự động theo yêu cầu ứng dụng.
UIStoryboard *mainStoryboard = [UIStoryboard storyboardWithName:@"Main" bundle: nil];
UIViewController viewController = (HomeController*)[mainStoryboard instantiateViewControllerWithIdentifier: @"HomeController"];
UINavigationController navController = [[UINavigationController alloc] initWithRootViewController:viewController];
self.window.rootViewController = navController;
if (NSFoundationVersionNumber > NSFoundationVersionNumber_iOS_6_1) {
// do stuff for iOS 7 and newer
navController.navigationBar.barTintColor = [UIColor colorWithRed:88/255.0 green:164/255.0 blue:73/255.0 alpha:1.0];
navController.navigationItem.leftBarButtonItem.tintColor = [UIColor colorWithRed:88/255.0 green:164/255.0 blue:73/255.0 alpha:1.0];
navController.navigationBar.tintColor = [UIColor whiteColor];
navController.navigationItem.titleView.tintColor = [UIColor whiteColor];
NSDictionary *titleAttributes =@{
NSFontAttributeName :[UIFont fontWithName:@"Helvetica-Bold" size:14.0],
NSForegroundColorAttributeName : [UIColor whiteColor]
};
navController.navigationBar.titleTextAttributes = titleAttributes;
[[UIApplication sharedApplication] setStatusBarStyle:UIStatusBarStyleLightContent];
}
else {
// do stuff for older versions than iOS 7
navController.navigationBar.tintColor = [UIColor colorWithRed:88/255.0 green:164/255.0 blue:73/255.0 alpha:1.0];
navController.navigationItem.titleView.tintColor = [UIColor whiteColor];
}
[self.window makeKeyAndVisible];
Dành cho người dùng StoryboardSegue
UIStoryboard *mainStoryboard = [UIStoryboard storyboardWithName:@"Main" bundle: nil];
// Go to Login Screen of story board with Identifier name : LoginViewController_Identifier
LoginViewController *loginViewController = (LoginViewController*)[mainStoryboard instantiateViewControllerWithIdentifier:@“LoginViewController_Identifier”];
navigationController = [[UINavigationController alloc] initWithRootViewController:testViewController];
self.window.rootViewController = navigationController;
[self.window makeKeyAndVisible];
// Go To Main screen if you are already Logged In Just check your saving credential here
if([SavedpreferenceForLogin] > 0){
[loginViewController performSegueWithIdentifier:@"mainview_action" sender:nil];
}
Cảm ơn
Mở mainstoryboard, chọn chế độ xem mà bạn muốn bắt đầu trước, sau đó mở Tiện ích -> Thuộc tính. Bên dưới "Trình điều khiển xem", bạn thấy nút radio "Là trình điều khiển xem ban đầu". Chỉ cần chọn nó.
--- Đối với câu hỏi sửa đổi:
Có thể bạn có thể thử điều này: viết một phương thức trong phần ViewDidLoad của chế độ xem ban đầu của bạn và khi phương thức này chạy khi khởi chạy ứng dụng, phương thức sẽ kích hoạt một phân biệt cho một khung nhìn khác.
Chuyển 5
Nếu bạn không có ViewContoder được đặt làm ViewContoder ban đầu trong bảng phân cảnh, bạn cần thực hiện 2 điều:
Cuối cùng, bây giờ bạn có thể thêm mã của mình vào SceneDelegate:
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).
guard let windowScene = (scene as? UIWindowScene) else { return }
window = UIWindow(windowScene: windowScene)
let storyboard = UIStoryboard(name: "Main", bundle: nil)
// Make sure you set an Storyboard ID for the view controller you want to instantiate
window?.rootViewController = storyboard.instantiateViewController(withIdentifier: identifier)
window?.makeKeyAndVisible()
}
Failed to instantiate the default view controller for UIMainStoryboardFile 'Main' - perhaps the designated entry point is not set
cảnh báo tôi gặp phải sau khi tôi quyết định khởi tạo mã VC ban đầu của mình. Một điểm quan trọng, khi @ rs7 nói "xóa trường tên bảng phân cảnh", chúng có nghĩa là toàn bộ hàng của bảng, không chỉ nội dung của chính trường đó.
Bạn có thể đặt initial view controller
bằng Trình tạo giao diện cũng như lập trình.
Dưới đây là cách tiếp cận được sử dụng cho lập trình.
Mục tiêu-C:
self.window = [[UIWindow alloc] initWithFrame:UIScreen.mainScreen.bounds];
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"MainStoryboard" bundle:nil];
UIViewController *viewController = [storyboard instantiateViewControllerWithIdentifier:@"HomeViewController"]; // <storyboard id>
self.window.rootViewController = viewController;
[self.window makeKeyAndVisible];
return YES;
Swift:
self.window = UIWindow(frame: UIScreen.mainScreen().bounds)
let mainStoryboard: UIStoryboard = UIStoryboard(name: "Main", bundle: nil)
var objMainViewController: MainViewController = mainStoryboard.instantiateViewControllerWithIdentifier("MainController") as! MainViewController
self.window?.rootViewController = objMainViewController
self.window?.makeKeyAndVisible()
return true
Tôi đã tạo một lớp định tuyến để xử lý điều hướng động và giữ sạch lớp AppDelegate, tôi hy vọng nó cũng sẽ giúp ích cho người khác.
//
// Routing.swift
//
//
// Created by Varun Naharia on 02/02/17.
// Copyright © 2017 TechNaharia. All rights reserved.
//
import Foundation
import UIKit
import CoreLocation
class Routing {
class func decideInitialViewController(window:UIWindow){
let userDefaults = UserDefaults.standard
if((Routing.getUserDefault("isFirstRun")) == nil)
{
Routing.setAnimatedAsInitialViewContoller(window: window)
}
else if((userDefaults.object(forKey: "User")) != nil)
{
Routing.setHomeAsInitialViewContoller(window: window)
}
else
{
Routing.setLoginAsInitialViewContoller(window: window)
}
}
class func setAnimatedAsInitialViewContoller(window:UIWindow) {
Routing.setUserDefault("Yes", KeyToSave: "isFirstRun")
let mainStoryboard: UIStoryboard = UIStoryboard(name: "Main", bundle: nil)
let animatedViewController: AnimatedViewController = mainStoryboard.instantiateViewController(withIdentifier: "AnimatedViewController") as! AnimatedViewController
window.rootViewController = animatedViewController
window.makeKeyAndVisible()
}
class func setHomeAsInitialViewContoller(window:UIWindow) {
let userDefaults = UserDefaults.standard
let decoded = userDefaults.object(forKey: "User") as! Data
User.currentUser = NSKeyedUnarchiver.unarchiveObject(with: decoded) as! User
if(User.currentUser.userId != nil && User.currentUser.userId != "")
{
let mainStoryboard: UIStoryboard = UIStoryboard(name: "Main", bundle: nil)
let homeViewController: HomeViewController = mainStoryboard.instantiateViewController(withIdentifier: "HomeViewController") as! HomeViewController
let loginViewController: UINavigationController = mainStoryboard.instantiateViewController(withIdentifier: "LoginNavigationViewController") as! UINavigationController
loginViewController.viewControllers.append(homeViewController)
window.rootViewController = loginViewController
}
window.makeKeyAndVisible()
}
class func setLoginAsInitialViewContoller(window:UIWindow) {
let mainStoryboard: UIStoryboard = UIStoryboard(name: "Main", bundle: nil)
let loginViewController: UINavigationController = mainStoryboard.instantiateViewController(withIdentifier: "LoginNavigationViewController") as! UINavigationController
window.rootViewController = loginViewController
window.makeKeyAndVisible()
}
class func setUserDefault(_ ObjectToSave : Any? , KeyToSave : String)
{
let defaults = UserDefaults.standard
if (ObjectToSave != nil)
{
defaults.set(ObjectToSave, forKey: KeyToSave)
}
UserDefaults.standard.synchronize()
}
class func getUserDefault(_ KeyToReturnValye : String) -> Any?
{
let defaults = UserDefaults.standard
if let name = defaults.value(forKey: KeyToReturnValye)
{
return name as Any
}
return nil
}
class func removetUserDefault(_ KeyToRemove : String)
{
let defaults = UserDefaults.standard
defaults.removeObject(forKey: KeyToRemove)
UserDefaults.standard.synchronize()
}
}
Và trong AppDelegate của bạn gọi đây
self.window = UIWindow(frame: UIScreen.main.bounds)
Routing.decideInitialViewController(window: self.window!)
Một giải pháp khác với việc sử dụng Swift 3 và Swift 4 để tránh ép buộc là như thế này
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
self.window = UIWindow(frame: UIScreen.main.bounds)
let storyboard = UIStoryboard(name: "Main", bundle: nil)
guard let viewController = storyboard.instantiateViewController(withIdentifier: "YourViewController") as? YourViewController else {
return false
}
self.window?.rootViewController = viewController
self.window?.makeKeyAndVisible()
return true
}
Và dưới đây là sử dụng với UINavigationController
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
self.window = UIWindow(frame: UIScreen.main.bounds)
let storyboard = UIStoryboard(name: "Main", bundle: nil)
guard let viewController = storyboard.instantiateViewController(withIdentifier: "YourViewController") as? YourViewController else {
return false
}
let navigationController = UINavigationController(rootViewController: viewController)
self.window?.rootViewController = navigationController
self.window?.makeKeyAndVisible()
return true
}
Trong AppDelegate.swift
bạn có thể thêm mã sau đây:
let sb = UIStoryboard(name: "Main", bundle: nil)
let vc = sb.instantiateViewController(withIdentifier: "YourViewController_StorboardID")
self.window?.rootViewController = vc
self.window?.makeKeyAndVisible()
Tất nhiên, bạn cần triển khai logic của mình, dựa trên tiêu chí nào bạn sẽ chọn bộ điều khiển chế độ xem phù hợp.
Ngoài ra, đừng quên thêm danh tính (chọn bảng phân cảnh -> Cảnh điều khiển -> Hiển thị trình kiểm tra danh tính -> gán StorboardID).
CẬP NHẬT TRẢ LỜI cho iOS 13 và đại biểu cảnh:
đảm bảo trong tệp info.plist của bạn, bạn đi vào Bản kê cảnh ứng dụng -> Cấu hình cảnh -> Vai trò phiên ứng dụng -> Mục 0 và cũng xóa tham chiếu đến bảng phân cảnh chính ở đó. Nếu không, bạn sẽ nhận được cảnh báo tương tự về việc không khởi tạo từ bảng phân cảnh.
Ngoài ra, di chuyển mã từ đại biểu ứng dụng sang cảnh phương thức ủy nhiệm cảnh (_: willConnectTo: tùy chọn :), vì đây là lúc các sự kiện vòng đời được xử lý.
Vài ngày trước tôi đã gặp phải tình huống tương tự. Một mẹo rất đơn giản đã giải quyết vấn đề này. Tôi đặt ẩn bộ điều khiển xem ban đầu của tôi trước khi launch2. Nếu bộ điều khiển xem ban đầu là bộ điều khiển phù hợp, nó được đặt thành hiển thị trong viewDidLoad. Khác, một segue được thực hiện để điều khiển xem mong muốn. Nó hoạt động hoàn hảo trong iOS 6.1 trở lên. Tôi chắc chắn rằng nó hoạt động trên các phiên bản iOS trước đó.
Cảm ơn đã sửa đổi điều này như sau trong AppDelegate:
func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
//Some code to check value of pins
if pins! == "Verified"{
print(pins)
self.window = UIWindow(frame: UIScreen.mainScreen().bounds)
let mainStoryboard: UIStoryboard = UIStoryboard(name: "HomePage", bundle: nil)
let exampleViewController: UINavigationController = mainStoryboard.instantiateViewControllerWithIdentifier("SBHP") as! UINavigationController
self.window?.rootViewController = exampleViewController
self.window?.makeKeyAndVisible()
}else{
print(pins)
self.window = UIWindow(frame: UIScreen.mainScreen().bounds)
let mainStoryboard: UIStoryboard = UIStoryboard(name: "Main", bundle: nil)
let exampleViewController: UINavigationController = mainStoryboard.instantiateViewControllerWithIdentifier("SBUser") as! UINavigationController
self.window?.rootViewController = exampleViewController
self.window?.makeKeyAndVisible()
}
Đã tìm thấy giải pháp đơn giản - không cần xóa "kiểm tra trình điều khiển xem ban đầu" khỏi bảng phân cảnh và chỉnh sửa tab Thông tin dự án và sử dụng makeKeyAndVisible
, chỉ cần đặt
self.window.rootViewController = rootVC;
trong
- (BOOL) application:didFinishLaunchingWithOptions:
rootVC
từ instantiateViewControllerWithIdentifier
, có đúng không?
let mainStoryboard = UIStoryboard(name: "Main", bundle: nil)
let vc = mainStoryboard.instantiateViewController(withIdentifier: "storyBoardid") as! ViewController
let navigationController = UINavigationController(rootViewController: vc)
UIApplication.shared.delegate.window?.rootViewController = navigationController
Một cách khác là trình bày viewContoder,
let mainStoryboard = UIStoryboard(name: "Main", bundle: nil)
let vc = mainStoryboard.instantiateViewController(withIdentifier: "storyBoardid") as! ViewController
self.present(vc,animated:true,completion:nil)
Trước tiên, bạn cần tạo đối tượng của bảng phân cảnh của mình, sau đó thay đổi root (nếu cần), sau đó bạn tham chiếu bộ điều khiển chế độ xem cụ thể được đẩy bộ điều khiển chế độ xem hiện tại (nếu bạn thay đổi root), nó chỉ trình bày bộ điều khiển chế độ xem mới mà bạn có thể
Swift 4, Xcode 9
trong tệp AppDelegate.swift
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
let storyboard = UIStoryboard(name: "Main", bundle: nil)
let firstVC = storyboard.instantiateViewController(withIdentifier: "firstViewController") as! firstViewController
self.window?.rootViewController = firstVC
}
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
self.window = UIWindow(frame: UIScreen.main.bounds)
let storyboard = UIStoryboard(name: "Main", bundle: nil)
if (PreferenceHelper.getAccessToken() != "") {
let initialViewController = storyboard.instantiateViewController(withIdentifier: "your View Controller Identifier")
self.window?.rootViewController = initialViewController
} else {
let initialViewController = storyboard.instantiateViewController(withIdentifier: "your View Controller identifier")
self.window?.rootViewController = initialViewController
}
self.window?.makeKeyAndVisible()
return true
}
/*
use your view Controller identifier must use it doubles quotes**strong text**
Swift 5 trở lên # tạo bộ điều khiển xem tuyến đường bằng mã đơn giản này. Nếu bạn đang sử dụng xcode 11 trở lên, lần đầu tiên khởi động var window: UIWindow?
trong AppDelegate
let rootVC = mainStoryboard.instantiateViewController(withIdentifier: "YOURCONTROLLER") as! YOURCONTROLLER
navigationController.setNavigationBarHidden(true, animated: true)
UIApplication.shared.windows.first?.rootViewController = UINavigationController.init(rootViewController: rootVC)
UIApplication.shared.windows.first?.makeKeyAndVisible()
Nếu bạn không muốn thay đổi applicationDidFinish, bạn có thể thực hiện mẹo sau:
Đặt Bộ điều khiển điều hướng làm bộ điều khiển xem ban đầu và gán cho nó một lớp tùy chỉnh 'MyNavlationContoder'. Sau đó, bạn có thể điều chỉnh bộ điều khiển xem gốc của nó trong viewDidLoad - nó sẽ ghi đè lên bộ điều khiển xem gốc mà bạn đã đặt trong bảng phân cảnh của mình.
class MyNavigationController: UINavigationController {
override func viewDidLoad() {
super.viewDidLoad()
if !isLoggedIn() {
viewControllers = [R.storyboard.authentication.loginView()!]
}
}
private func isLoggedIn() -> Bool {
return false
}
}