Как программно установить начальный view controller в Storyboard?
Программная установка начального контроллера через AppDelegate
Проблема, которую вы описываете, очень распространена. Решение заключается в том, чтобы вручную загрузить Storyboard, создать экземпляр нужного View Controller и установить его как rootViewController для окна приложения. Вот пошаговое руководство.
Шаг 1: Настройка Storyboard
Убедитесь, что у ваших View Controllers в Storyboard заданы Storyboard ID. Для этого:
- Откройте Storyboard
- Выберите нужный View Controller
- В инспекторе Identity Inspector (правая панель) найдите поле Storyboard ID
- Задайте уникальные идентификаторы, например:
LoginViewControllerIDиMainViewControllerID
Шаг 2: Код в AppDelegate
Вот полный рабочий код для Swift 5+:
import UIKit
@main
class AppDelegate: UIResponder, UIApplicationDelegate {
var window: UIWindow?
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
// Создаем окно с размерами экрана
window = UIWindow(frame: UIScreen.main.bounds)
// Загружаем Storyboard
let storyboard = UIStoryboard(name: "Main", bundle: nil)
// Проверяем, авторизован ли пользователь
let isLoggedIn = UserDefaults.standard.bool(forKey: "isLoggedIn")
var initialViewController: UIViewController
if isLoggedIn {
// Если пользователь авторизован — показываем главный экран
initialViewController = storyboard.instantiateViewController(withIdentifier: "MainViewControllerID")
} else {
// Если нет — экран логина
initialViewController = storyboard.instantiateViewController(withIdentifier: "LoginViewControllerID")
}
// Устанавливаем начальный контроллер
window?.rootViewController = initialViewController
window?.makeKeyAndVisible()
return true
}
}
Шаг 3: Важные моменты
- Storyboard ID должны точно совпадать с теми, что вы указали в Storyboard
- Уберите стрелку начального контроллера из Storyboard, иначе будет конфликт
- Если используете SceneDelegate (iOS 13+), код нужно поместить туда, а не в AppDelegate
Альтернатива: Работа через SceneDelegate (iOS 13+)
import UIKit
class SceneDelegate: UIResponder, UIWindowSceneDelegate {
var window: UIWindow?
func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
guard let windowScene = (scene as? UIWindowScene) else { return }
window = UIWindow(windowScene: windowScene)
let storyboard = UIStoryboard(name: "Main", bundle: nil)
let isLoggedIn = UserDefaults.standard.bool(forKey: "isLoggedIn")
let identifier = isLoggedIn ? "MainViewControllerID" : "LoginViewControllerID"
let initialVC = storyboard.instantiateViewController(withIdentifier: identifier)
window?.rootViewController = initialVC
window?.makeKeyAndVisible()
}
}
Этот подход даёт полный контроль над тем, какой экран показывается первым, и идеально подходит для сценариев с авторизацией, онбордингом или A/B тестированием.
<<Использование NavigationController как контейнера
Другой популярный подход — не менять rootViewController, а использовать UINavigationController, который будет программно заменять свой корневой контроллер. Это удобно, если у вас уже есть навигация между экранами.
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
window = UIWindow(frame: UIScreen.main.bounds)
let storyboard = UIStoryboard(name: "Main", bundle: nil)
let isLoggedIn = UserDefaults.standard.bool(forKey: "isLoggedIn")
let initialVC: UIViewController
if isLoggedIn {
initialVC = storyboard.instantiateViewController(withIdentifier: "MainViewControllerID")
} else {
initialVC = storyboard.instantiateViewController(withIdentifier: "LoginViewControllerID")
}
// Оборачиваем в NavigationController
let navigationController = UINavigationController(rootViewController: initialVC)
window?.rootViewController = navigationController
window?.makeKeyAndVisible()
return true
}
Плюсы этого подхода:
- Сохраняет стандартную навигацию (back button, push/pop)
- Легко добавить анимацию перехода между экранами
- Удобно, если в будущем понадобится показывать разные стеки контроллеров
Выберите тот способ, который лучше подходит под архитектуру вашего приложения. Оба решения рабочие и используются в production-проектах.
Ответов пока нет.
Войдите чтобы оставить ответ
Блоги
Как быстро выучить Python и найти первую работу: Сроки, советы и реальные примеры