Як я можу програмно завантажувати розкадровку з класу?


183

Моя проблема полягає в тому, що я шукав спосіб використовувати і розкадровку, і xib . Але я не можу знайти належного способу завантаження та показу розкадровки програмно. Проект розпочали розробку з xib, і зараз дуже важко вкладати всі Xib файли в розкадровку. Тому я шукав спосіб зробити це в коді, як і alloc, init, pushдля viewControllers. У моєму випадку у мене є лише один контролер у раскадровці:, у UITableViewControllerякому є статичні комірки з деяким вмістом, який я хочу показати. Якщо хтось знає правильний спосіб роботи як з xib, так і з раскадровкою без величезного рефакторингу, я буду вдячний за будь-яку допомогу.

Відповіді:


370

У своїй дошці розкадрів перейдіть до інспектора атрибутів та встановіть ідентифікатор контролера перегляду. Потім ви можете представити цей контролер перегляду за допомогою наступного коду.

UIStoryboard *sb = [UIStoryboard storyboardWithName:@"MainStoryboard" bundle:nil];
UIViewController *vc = [sb instantiateViewControllerWithIdentifier:@"myViewController"];
vc.modalTransitionStyle = UIModalTransitionStyleFlipHorizontal;
[self presentViewController:vc animated:YES completion:NULL];

65
[sb instantiateInitialViewController]зручно, якщо ви хочете запустити на контролері подання зображення за замовчуванням.
— веселий

Джеймс, дякую! Я досить довго шукав, намагаючись зрозуміти, як уявити погляд на дошку розгортки. Ваша відповідь (і питання Кококо) є найбільш освіжаючим.
— bejonbee

У коді Джеймса Біта потрібно повторно використовувати цей UIViewControler * vc, якщо він перемикається вперед і назад за допомогою поточного контролера перегляду. Я виявив важкий спосіб, що VC приклеюється навколо і підключається до ручки розкадровки, поки користувач не натисне кнопку на новому вікні перегляду, і тепер витік пам’яті з цим викинутим vc від попередніх запитів цього коду.
— SWoo

11
У разі, якщо хтось хоче знати, як це зробити в делегаті програми, ви замінюєте [self presentViewcontroller]логіку цими рядками у такому порядку: 1) self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];2) self.window.rootViewController = vc;та 3) [self.window makeKeyAndVisible];. Ви, ймовірно, також можете позбутися modalTransitionStyleлінії, оскільки це не модальний перехід від делегата додатка.
— lewiguez

FYI, якщо ви хочете "натиснути" на нову розкадровку замість того, щоб модально з'являтися, подивіться на відповідь chaithraVeeresh.
— Адам Джонс

76

Швидкий 3

let storyboard = UIStoryboard(name: "Main", bundle: nil)
let vc = storyboard.instantiateViewController(withIdentifier: "viewController")
self.navigationController!.pushViewController(vc, animated: true)

Швидкий 2

let storyboard = UIStoryboard(name: "Main", bundle: nil)
let vc = storyboard.instantiateViewControllerWithIdentifier("viewController")
self.navigationController!.pushViewController(vc, animated: true)

Необхідна умова

Призначте ідентифікатор розгортки для вашого контролера перегляду.

Ідентифікатор розгортки

IB> Показати інспектора посвідчення особи> Особистість> Ідентифікаційний аркуш

Швидкий (спадщина)

let storyboard = UIStoryboard(name: "Main", bundle: nil)
let vc = storyboard.instantiateViewControllerWithIdentifier("viewController") as? UIViewController
self.navigationController!.pushViewController(vc!, animated: true)

Редагувати: Swift 2 запропонував у коментарі Fred A.

якщо ви хочете користуватися без навігаційного контролера, ви повинні використовувати наступне:

    let Storyboard  = UIStoryboard(name: "Main", bundle: nil)
    let vc = Storyboard.instantiateViewController(withIdentifier: "viewController")
    present(vc , animated: true , completion: nil)

1
У Swift 2 вам не потрібно додавати "як? UIViewController", компілятор визначає це автоматично
— Frédéric Adda

2
або ви можете просто зробити self.storyboardі об'єднати line1 & 2
— Honey

17

У атрибутовому інспекторі дайте ідентифікатор цього контролера перегляду, і наведений нижче код працює для мене

UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"MainStoryboard" bundle:nil];
DetailViewController *detailViewController = [storyboard instantiateViewControllerWithIdentifier:@"DetailViewController"];
[self.navigationController pushViewController:detailViewController animated:YES];

5

Спробуйте це

UIStoryboard *mainStoryboard = [UIStoryboard storyboardWithName:@"Main" bundle:nil];
UIViewController *vc = [mainStoryboard instantiateViewControllerWithIdentifier:@"Login"];

[[UIApplication sharedApplication].keyWindow setRootViewController:vc];

Використовуйте це, якщо ви не використовуєте UINavigationController, як показано в інших відповідях
— latenitecoder

2

у швидкій
NavigationController та pushController, яку ви можете замінити

present(vc, animated:true , completion: nil)

1

Для швидких 3 і 4 ви можете це зробити. Доброю практикою є встановлення назви Storyboard рівним StoryboardID.

enum StoryBoardName{
   case second = "SecondViewController"
}
extension UIStoryBoard{
   class func load(_ storyboard: StoryBoardName) -> UIViewController{
      return UIStoryboard(name: storyboard.rawValue, bundle: nil).instantiateViewController(withIdentifier: storyboard.rawValue)
   }
}

а потім ви можете завантажити свою дошку розгортки у свій ViewController так:

class MyViewController: UIViewController{
     override func viewDidLoad() {
        super.viewDidLoad()
        guard let vc = UIStoryboard.load(.second) as? SecondViewController else {return}
        self.present(vc, animated: true, completion: nil)
     }

}

Коли ви створюєте нову дошку розкадрування, просто встановіть те саме ім’я на StoryboardID та додайте ім'я Storyboard у вашій перерахунку " StoryBoardName "


0

Ви завжди можете перейти праворуч до кореневого контролера:

UIStoryboard* storyboard = [UIStoryboard storyboardWithName:@"Main" bundle:nil];
UIViewController *vc = [storyboard instantiateInitialViewController];
vc.modalTransitionStyle = UIModalTransitionStyleFlipHorizontal;
[self presentViewController:vc animated:YES completion:NULL];

0

Розширення нижче дозволить завантажити Storyboardі пов’язане з ним UIViewController. Приклад: Якщо у вас є UIViewControllerіменований ModalAlertViewControllerі табло з назвою "ModalAlert", наприклад

let vc: ModalAlertViewController = UIViewController.loadStoryboard("ModalAlert")

Завантажить як Storyboardі, так UIViewControllerі vcбуде типу ModalAlertViewController. Примітка Припускає, що ідентифікаційний аркуш аркуша розкадрування має те саме ім'я, що і розкладочне, і те, що розміщено як « Контролер початкового перегляду» .

extension UIViewController {
    /// Loads a `UIViewController` of type `T` with storyboard. Assumes that the storyboards Storyboard ID has the same name as the storyboard and that the storyboard has been marked as Is Initial View Controller.
    /// - Parameter storyboardName: Name of the storyboard without .xib/nib suffix.
    static func loadStoryboard<T: UIViewController>(_ storyboardName: String) -> T? {
        let storyboard = UIStoryboard(name: storyboardName, bundle: nil)
        if let vc = storyboard.instantiateViewController(withIdentifier: storyboardName) as? T {
            vc.loadViewIfNeeded() // ensures vc.view is loaded before returning
            return vc
        }
        return nil
    }
}
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.