Создание кроссфейдов программно


у меня есть UIViewController вот и все мои UIViewsControllers расширить для повторного использования некоторых общих операций.

Я хочу настроить сегмент на этом "общем" UIViewController Так что все остальные UIViewControllers наследовать.

Я пытаюсь выяснить, как это сделать программно.

Я думаю, что вопрос также может быть, как мне установить segue для всех UIViewControllers не заходя в раскадровку и делать их вручную.

13 196

13 ответов:

по определению сегмент не может существовать независимо от раскадровки. Это даже есть в названии класса:UIStoryboardSegue. Вы не создаете сегменты программно - это среда выполнения раскадровки, которая создает их для вас. Обычно вы можете позвонить performSegueWithIdentifier: в коде контроллера вашего представления, но это зависит от того, что сегмент уже настроен в раскадровке для ссылки.

то, что я думаю, что вы спрашиваете, хотя, как вы можете создать метод в вашем общем контроллере представления (базовый класс), который будет переходить к новому контроллеру представления и будет наследоваться всеми производными классами. Вы можете сделать это, создав такой метод для вашего контроллера базового класса:

- (IBAction)pushMyNewViewController
{
    MyNewViewController *myNewVC = [[MyNewViewController alloc] init];

    // do any setup you need for myNewVC

    [self presentModalViewController:myNewVC animated:YES];
}

а затем в производном классе вызовите этот метод, когда будет нажата соответствующая кнопка или выбрана строка таблицы или что-то еще.

Я думал, что добавлю еще одну возможность. Одна из вещей, которые вы можете сделать, - это подключить две сцены в раскадровке с помощью segue, который не прикреплен к действию, а затем программно запустить segue внутри вашего контроллера вида. Способ, которым вы это делаете, заключается в том, что вам нужно перетащить значок владельца файла в нижней части сцены раскадровки, которая является сегментирующей сценой, и перетащить вправо к целевой сцене. Я добавлю изображение, чтобы помочь объяснить.

enter image description here

появится всплывающее окно для "ручного перехода". Я выбрал толчок как тип. Нажмите на маленький квадрат и убедитесь, что вы находитесь в инспекторе атрибутов. Присвойте ему идентификатор, который вы будете использовать, чтобы ссылаться на него в коде.

enter image description here

ОК, Далее я собираюсь перейти к использованию программного элемента кнопки панели. В 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.

http://developer.apple.com/library/ios/#documentation/UIKit/Reference/UIStoryboardSegue_Class/Reference/Reference.html#//apple_ref/occ/cl/UIStoryboardSegue

Я хотел бы добавить уточнение...

распространенное недоразумение, на самом деле то, что у меня было в течение некоторого времени, заключается в том, что раскадровка 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()
    }
    ...
}