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


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.