Використання кількох раскадровки в iOS


78

Моє завдання - створити додаток із вкладками, тоді подання для кожної з вкладок будуються в окремих розкадровках.

Знімок екрану розкадровки

Моя основна дошка - це вкладка.

Потім я створюю вторинну розкадрування (розкадровка №2) з 2 контролерами перегляду. Перший контролер перегляду (також позначений як початковий) має кнопку, і переходить (модальний) до 2-го перегляду.Контролер першого перегляду

Мені вдалося завантажити подання, підкласуючи та перевизначивши loadView з розкадрування No2. loadView замінити

Ось вихід тренажера.

Тренажер

При натисканні на кнопку "натисніть мене", я отримую EXC_BAD_ACCESS. Segue не працює, здається, друга раскадровка завантажується не повністю.

Хтось намагався це зробити раніше і налагодити роботу? Є відео з YouTube від SkillMaster.net, але він не демонструє, чи працює друга людина під вторинною розкадровкою. відео тут: http://youtu.be/D4_twoYvB4M

Дякуємо за будь-який внесок та допомогу!

Знімки екрана:


20
я не впевнений, що це теж хороша практика, але я хочу: 1. НЕ мати однієї великої / роздутої розкадровки 2. важко об’єднати код (у нас мало кодерів працює і
фіксується

Можливо, ви можете спробувати просто використовувати файли .xib, які ми використовували до iOS5? Їх не слід занадто важко поєднувати з розкадровками.
Том ван дер Вердт,

я хотів би знати, чи можемо ми використовувати Storyboard для цього. XIB точно буде працювати.
Daddycat Tan Yin Див.

5
+1000 за ідею розбиття XML-файлів для конфлікту великих конфліктів
Pierre de LESPINAY

Кілька розкадрувань можуть мати сенс, коли ви створюєте лінійку продуктів, а не окремий продукт. У цьому випадку у вас є одна раскадровка для основного / ванільного продукту та одна розкадровка для кожного індивідуального продукту
Кирило Гамазков,

Відповіді:


82

Це найкращі статті, які я бачив на багатьох раскадровках.

Цей хлопець не тільки розповідає, як створити нову розкадровку в коді, він ще

  • рекомендує на практиці кілька раскадровки (більш модульний код)
  • обговорює, коли використовувати xibs проти раскадровки (xibs утримують подання, сторборди базуються на контролерах)
  • пропонує клас для зв’язування розкадрувань із секціями на github

Зверніть увагу, що цей останній момент важливий, тому що ключовим недоліком кількох розкадрувань є те, що ви, як правило, не можете зв’язати їх із сегментами, але бібліотека robs дозволяє це з невеликим обманом

Також дивіться обговорене тут


44

Оператор відредагував своє запитання, включивши відповідь:

UIStoryboard* storyboard = [UIStoryboard storyboardWithName:@"HelpStoryboard" bundle:nil];
UIViewController* initialHelpView = [storyboard instantiateInitialViewController];

initialHelpView.modalPresentationStyle = UIModalPresentationFormSheet;
[self presentModalViewController:initialHelpView animated:YES];

Звичайно, те, звідки ви телефонуєте з цього, є значущим, оскільки у вас може бути 2 розкадровки та стек їх перегляду в пам'яті. Тож, мабуть, найкраще, якщо ви зателефонуєте цьому коду з-за меж контролерів перегляду інших розкадрувань.


2
це запитання було видалено з SO :-(. У будь-якому випадку, куди ви думаєте, де б ви поставили цей фрагмент у цьому випадку використання? Я стикаюся з такою ж ситуацією, і я не можу зрозуміти, де б я міг підключитись, UITabbarControllerщоб створити екземпляр правильна розкадровка для кожної вкладки. Чи був tabBarController:shouldSelectViewController:би відповідним делегат ?
Жан-Денис Муйс

2
Я використовую вищезазначений підхід, але не з панеллю вкладок. Я помістив цей код у метод дії, вказаний селектором для кнопки. В основному, код такий самий, як і у prepForSegue до того, як я перемістив сцену, що переймається, у свою розкадрування. Однією помилкою, яку я зробив спочатку, було те, що основний вигляд моєї нової розкадровки було вбудовано в UINavigationController - і після його налаштування я спробував представити подання замість контролера навігації.
Ревінь

19

Я вивчив підхід RBStoryboardLink, запропонований Rhubarb. Ця реалізація замінює властивості контролера подання, що виглядає дивним. Я вважаю, що знайшов спосіб уникнути цього. Ось демонстраційний проект .

Навігаційні контролери

Контролери навігації можуть просто встановити контролер подання, на який посилаються, як корінь. Реалізація такого контролера перегляду може виглядати так:

@interface ExternNavigationController : UINavigationController

@property (strong, nonatomic) NSString *storyboardName;
@property (strong, nonatomic) NSString *sceneIdentifier;

@end

@implementation ExternNavigationController

- (void)awakeFromNib
{
    NSAssert(self.storyboardName, @"storyboardName is required");

    UIStoryboard *storyboard = [UIStoryboard storyboardWithName:self.storyboardName bundle:nil];
    UIViewController *vc = self.sceneIdentifier
        ? [storyboard instantiateViewControllerWithIdentifier:self.sceneIdentifier]
        : [storyboard instantiateInitialViewController];

    self.viewControllers = @[vc];
}

@end

Перегляньте контролери

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

@interface ExternStoryboardSegue : UIStoryboardSegue

@end

@implementation ExternStoryboardSegue

- (id)initWithIdentifier:(NSString *)identifier source:(UIViewController *)source destination:(ExternViewController *)destination
{
    NSAssert(destination.storyboardName, @"storyboardName is required");

    UIStoryboard *storyboard = [UIStoryboard storyboardWithName:destination.storyboardName bundle:nil];
    UIViewController *vc = destination.sceneIdentifier
        ? [storyboard instantiateViewControllerWithIdentifier:destination.sceneIdentifier]
        : [storyboard instantiateInitialViewController];

    return [super initWithIdentifier:identifier source:source destination:vc];
}

- (void)perform
{
    [[self.sourceViewController navigationController] pushViewController:self.destinationViewController animated:YES];
}

@end

ExternViewController використовується як заповнювач і містить необхідні для властивостей заміщення (storyboardName та sceneIdentifier).

@interface ExternViewController : UIViewController

@property (strong, nonatomic) NSString *storyboardName;
@property (strong, nonatomic) NSString *sceneIdentifier;

@end

@implementation ExternViewController

@end

Нам потрібно встановити ці властивості та спеціальний клас для контролера перегляду заповнювачів. А також зв’язати контролер перегляду з ExternStoryboardSegue.

Знімок екрана IB


1
Я намагався поліпшити це за допомогою кращого рішення github.com/jeremygrenier/JGLinkedStoryboard
Jeremy Grenier

16

З одного зі своїх файлів XIB я переходжу до більш складної частини графічного інтерфейсу, і для цієї частини я використовую Storyboard. Тож кнопка в моєму XIB перейде до розкадрування. Я маю для цього такий код:

UIStoryboard* storyboard = [UIStoryboard storyboardWithName:@"MyStoryboardIdentifier" bundle:nil];
UIViewController* myStoryBoardInitialViewController = [storyboard instantiateInitialViewController];

[self.navigationController pushViewController:myStoryBoardInitialViewController animated:YES];

Це успішно перенесе мою StoryBoard на вигляд. Наведений вище код викликається за допомогою кнопки "Touch Up Inside".


9

Починаючи з Xcode 7 (і перенесеного назад на iOS8), тепер ви можете мати посилання на розкадровки. Про це було згадано на цій сесії WWDC 2015 (про них починають говорити близько першої години). В основному все , що вам потрібно зробити , це вибрати ViewController, який ви хочете перемістити в окрему розкадрування і натисніть на editor-> Refactor розкадровки ... . Дайте йому ім’я та вуаля:

введіть тут опис зображення

Зверніть увагу: якщо у вас були VC, які перенесені на нову раскадровку, і на них немає посилань поза нею (якою вона повинна бути), вам слід видалити їхні посилання з main.storyboard (розслабтеся, вони залишаться в новоствореній розкадровці, видалення лише посилань на них).


7

Документи Apple говорять, що у вас може бути кілька раскадровки. На жаль, вони не вдаються до реальних деталей, як це зробити. Як ви з’ясували, Interface Builder вам не допоможе, тому вам доведеться робити це в коді. Це працює подібно до завантаження файлів XIB:

[UIStoryboard storyboardWithName:@”MyNewStoryboard” bundle:myBundle]

Сказавши це, якщо ви не "хочете одну велику / роздуту раскадровку", як ви сказали у своєму коментарі, тоді XIB дійсно є правильним шляхом. Ця «величина» - це перевага: всі переходи між ВК розкладаються в одному місці. Наявність кількох розкадрів насправді полягає в тому, що ви можете підтримувати безліч різних і не пов’язаних між собою потоків через ваш додаток: наприклад, одну розкадровку для складного конфігураційного потоку, а іншу - для основного потоку користувачів.


25
Найбільша проблема - це коли ви працюєте в команді старше 3 років, де об’єднання однієї розкадровки - це кошмар.
Brian Liang

2
Я можу уявити, що це проблема. Є досить багато шорстких країв з розкадровкою; Ваша точка - ще одна.
Тім

4
Вам не потрібно відмовлятися від усього комфорту, який надають розкадровки, щоб уникнути злиття кошмарів. Просто ізолюйте різні незалежні області та призначте кожній окрему розкадрування. Ви все ще матимете всю магію розкадрувань для всіх внутрішніх переходів. Додаток із вкладками ідеально підходить для цього сценарію. Екран налаштувань теж. Навіть якщо ви єдиний розробник, все одно може бути доречним розділити свою розкадрування на кілька незалежних частин.
KPM

2

Я виявив, що якщо у вас є іменований сегмент у другій розкадровці, який ви хочете використовувати у виклику для виконанняSegueWithIdenitfier: ви повинні встановити поле "Ідентифікатор раскадровки" на вкладці "Ідентичність" у вихідному ViewController.

Наприклад, якщо ви надали VC під назвою "ViewController1" із секцією під назвою "segue1" іншому VC, встановіть для "Storyboard ID" "ViewController1" будь-яке значення (скажімо "viewC1" або щось інше), а потім у ViewController1.m ви можете використовувати [self performSegueWithIdentifier: @ "segue1" sender: self].


2

Xcode 8.2.1

Ви можете посилатися на контролер перегляду у зовнішній розкадровці.

відносини від TabBarController до посилання на розкадровки

перетягніть підключення від UITabBarControllerдо зовнішнього довідника розкадрування, додайте його як відношення "контролери перегляду". У основній розкадровці це відображається як "Елемент / квадрат", але у зовнішній розкадровці слід додати a UITabBarItemта визначити назву та зображення / вкладки для вкладки.

введіть тут опис зображення

Інспектор атрибутів, коли Storyboard Referenceвибрано.

Вам також потрібно буде вказати зовнішньому контролеру "ID розкадрування" в його розкадровці (тут не показано) , а в посиланні вказати його ім'я.


1

Для досягнення цього завдання виконайте наступні кроки:

Крок 1 : Пошук Storyboard Referenceкомпонентів in (див. Знімок екрана)

Крок 2 : Виберіть нове посилання на розкадровки. (Довідковий знімок екрана)

Крок 3 : Вкажіть нову назву розкадровки та ідентифікатор початкового ідентифікатора контролера перегляду (Refer Screen Shot)

введіть тут опис зображення

Побудуйте та запустіть. Це спрацює.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.