Создание кроссфейдов программно
у меня есть UIViewController
вот и все мои UIViewsControllers
расширить для повторного использования некоторых общих операций.
Я хочу настроить сегмент на этом "общем" UIViewController
Так что все остальные UIViewControllers
наследовать.
Я пытаюсь выяснить, как это сделать программно.
Я думаю, что вопрос также может быть, как мне установить segue
для всех UIViewControllers
не заходя в раскадровку и делать их вручную.
13 ответов:
по определению сегмент не может существовать независимо от раскадровки. Это даже есть в названии класса:
UIStoryboardSegue
. Вы не создаете сегменты программно - это среда выполнения раскадровки, которая создает их для вас. Обычно вы можете позвонитьperformSegueWithIdentifier:
в коде контроллера вашего представления, но это зависит от того, что сегмент уже настроен в раскадровке для ссылки.то, что я думаю, что вы спрашиваете, хотя, как вы можете создать метод в вашем общем контроллере представления (базовый класс), который будет переходить к новому контроллеру представления и будет наследоваться всеми производными классами. Вы можете сделать это, создав такой метод для вашего контроллера базового класса:
- (IBAction)pushMyNewViewController { MyNewViewController *myNewVC = [[MyNewViewController alloc] init]; // do any setup you need for myNewVC [self presentModalViewController:myNewVC animated:YES]; }
а затем в производном классе вызовите этот метод, когда будет нажата соответствующая кнопка или выбрана строка таблицы или что-то еще.
Я думал, что добавлю еще одну возможность. Одна из вещей, которые вы можете сделать, - это подключить две сцены в раскадровке с помощью segue, который не прикреплен к действию, а затем программно запустить segue внутри вашего контроллера вида. Способ, которым вы это делаете, заключается в том, что вам нужно перетащить значок владельца файла в нижней части сцены раскадровки, которая является сегментирующей сценой, и перетащить вправо к целевой сцене. Я добавлю изображение, чтобы помочь объяснить.
появится всплывающее окно для "ручного перехода". Я выбрал толчок как тип. Нажмите на маленький квадрат и убедитесь, что вы находитесь в инспекторе атрибутов. Присвойте ему идентификатор, который вы будете использовать, чтобы ссылаться на него в коде.
ОК, Далее я собираюсь перейти к использованию программного элемента кнопки панели. В viewDidLoad или где-то еще я создам элемент кнопки на панели навигации с этим кодом:
UIBarButtonItem *buttonizeButton = [[UIBarButtonItem alloc] initWithTitle:@"Buttonize" style:UIBarButtonItemStyleDone target:self action:@selector(buttonizeButtonTap:)]; self.navigationItem.rightBarButtonItems = @[buttonizeButton];
ОК, обратите внимание что селектор является buttonizeButtonTap:. Поэтому напишите метод void для этой кнопки, и в этом методе вы вызовете segue следующим образом:
-(void)buttonizeButtonTap:(id)sender{ [self performSegueWithIdentifier:@"Associate" sender:sender]; }
параметр sender необходим для идентификации кнопки при вызове prepareForSegue. prepareForSegue-это метод фреймворка, в котором вы создадите экземпляр своей сцены и передадите ему любые значения, которые ему понадобятся для выполнения своей работы. Вот как выглядит мой метод:
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender { if ([[segue identifier] isEqualToString:@"Associate"]) { TranslationQuizAssociateVC *translationQuizAssociateVC = [segue destinationViewController]; translationQuizAssociateVC.nodeID = self.nodeID; //--pass nodeID from ViewNodeViewController translationQuizAssociateVC.contentID = self.contentID; translationQuizAssociateVC.index = self.index; translationQuizAssociateVC.content = self.content; } }
ок, только что проверил его и он работает. Надеюсь, это поможет вы.
Я использую этот код, чтобы создать экземпляр моего пользовательского подкласса segue и запустить его программно. Кажется, это работает. Что-нибудь не так с этим? Я озадачен, читая все другие ответы, говорящие, что это невозможно сделать.
UIViewController *toViewController = [self.storyboard instantiateViewControllerWithIdentifier:@"OtherViewControllerId"]; MyCustomSegue *segue = [[MyCustomSegue alloc] initWithIdentifier:@"" source:self destination:toViewController]; [self prepareForSegue:segue sender:sender]; [segue perform];
думаю, это ответ и принято, но я просто хотел бы добавить еще несколько деталей к нему.
что я сделал, чтобы решить проблему, когда я бы представил login-view в качестве первого экрана, а затем хотел перейти к приложению, если логин был правильным. Я создал сегмент от контроллера login-view до контроллера root view и дал ему идентификатор, такой как"myidentifier".
затем после проверки всех кодов входа в систему, если логин был правильным, я бы позвонил
[self performSegueWithIdentifier: @"myidentifier" sender: self];
мое самое большое недоразумение состояло в том, что я попытался поставить segue на кнопку и как бы прервать segue, как только он был найден.
вы должны связать ваш код
UIStoryboard
что вы используете. Убедитесь, что вы идете в YourViewController в своемUIStoryboard
, нажмите на границу вокруг него, а затем установите егоidentifier
поле вNSString
что вы называете в вашем коде.UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"MainStoryboard" bundle:nil]; YourViewController *yourViewController = (YourViewController *) [storyboard instantiateViewControllerWithIdentifier:@"yourViewControllerID"]; [self.navigationController pushViewController:yourViewController animated:YES];
для контроллеров, которые в раскадровке.
jhilgert00 это то, что вы искали?
-(IBAction)nav_goHome:(id)sender { UIViewController *myController = [self.storyboard instantiateViewControllerWithIdentifier:@"HomeController"]; [self.navigationController pushViewController: myController animated:YES]; }
или...
[self performSegueWithIdentifier:@"loginMainSegue" sender:self];
ну, вы можете создать, а также может подкласс UIStoryBoardSegue . подклассы в основном используются для предоставления пользовательской анимации перехода.
вы можете посмотреть видео с конференции WWDC 2011 представляем раскадровки. его также можно найти в youtube.
Я хотел бы добавить уточнение...
распространенное недоразумение, на самом деле то, что у меня было в течение некоторого времени, заключается в том, что раскадровка segue запускается
prepareForSegue:sender:
метод. Это не. Раскадровка segue будет выполнять, независимо от того, реализовали ли выprepareForSegue:sender:
метод для этого (отходящего от) контроллера вида.я узнал это от превосходного пола Хегарти iTunesU лекции. Мои извинения, но, к сожалению, не могу вспомнить, какой лекция.
Если вы подключаете сегмент между двумя контроллерами вида в раскадровке, но не реализуете
prepareForSegue:sender:
метод, segue будет по-прежнему переходить к целевому контроллеру представления. Однако он будет переходить к этому контроллеру представления неподготовленным.надеюсь, что это помогает.
раскадровка сегменты не должны быть созданы за пределами раскадровки. Вам нужно будет подключить его, несмотря на недостатки.
UIStoryboardSegue Ссылка четко указано:
вы не создаете объекты segue напрямую. Вместо этого раскадровка среда выполнения создает их, когда необходимо выполнить переход между двумя вид контроллеры. Вы все еще можете инициировать сегмент программно с помощью performSegueWithIdentifier:отправитель: метод UIViewController если вы хотеть. Вы можете сделать это, чтобы инициировать сегмент из источника, который был добавлен программными средствами и, следовательно, не доступны в Построителе интерфейс.
вы все еще можете программно указать раскадровке представить контроллер вида с помощью segue с помощью
presentModalViewController:
илиpushViewController:animated:
вызовы, но вам понадобится экземпляр раскадровки.можно назвать
UIStoryboard
s метод класса, чтобы получить именованную раскадровку с пакетом nil для основного пачка.
storyboardWithName:bundle:
во-первых, предположим, что у вас есть два разных вида в раскадровке, и вы хотите перейти с одного экрана на другой, поэтому выполните следующие действия:
1). Определите все свои представления с помощью файла класса, а также идентификатора раскадровки в Identity inspector.
2). Убедитесь, что вы добавили навигационный контроллер в первый вид. Выберите его в раскадровке, а затем редактор > встроить в > навигационный контроллер
3). В первом классе импортируйте "secondClass.h"
#import "ViewController.h #import "secondController.h"
4). Добавьте эту команду в IBAction, который должен выполнить segue
secondController *next=[self.storyboard instantiateViewControllerWithIdentifier:@"second"]; [self.navigationController pushViewController:next animated:YES];
5).
@"second"
- это класс контроллера secondview, идентификатор раскадровки.
Я перепроектировал и сделал реализацию с открытым исходным кодом (re)сегментов UIStoryboard:https://github.com/acoomans/Segway
с этой библиотекой вы можете определить сегменты программно (без раскадровки).
надеюсь, что это может помочь.
пару проблем, на самом деле:
во-первых, в этом проекте, который вы загрузили для нас, segue не несет идентификатор "segue1":
идентификатор
вы должны заполнить этот идентификатор, если вы еще этого не сделали.
во-вторых, когда вы переходите от табличного представления к табличному представлению, вы вызываете initWithNibName для создания контроллера представления. Вы действительно хотите использовать instantiateViewControllerWithIdentifier.
вот пример кода
Creating a segue programmatically
:class ViewController: UIViewController { ... // 1. Define the Segue private var commonSegue: UIStoryboardSegue! ... override func viewDidLoad() { ... // 2. Initialize the Segue self.commonSegue = UIStoryboardSegue(identifier: "CommonSegue", source: ..., destination: ...) { self.commonSegue.source.showDetailViewController(self.commonSegue.destination, sender: self) } ... } ... override func prepare(for segue: UIStoryboardSegue, sender: Any?) { // 4. Prepare to perform the Segue if self.commonSegue == segue { ... } ... } ... func actionFunction() { // 3. Perform the Segue self.prepare(for: self.commonSegue, sender: self) self.commonSegue.perform() } ... }