Возможно ли использовать существующий ViewController с PerformSegueWithIdentifier? - PullRequest
16 голосов
/ 29 ноября 2011

Я использую метод performSegueWithIdentifier:sender:, чтобы программно открыть новый ViewController из файла раскадровки.Это работает как талисман.

Но каждый раз, когда вызывается этот метод, создается новый ViewController.Можно ли использовать существующий ViewController, если он существует?Я не нахожу ничего об этой проблеме (apple-doc, Stack Overflow, ...).

Проблема заключается в следующем: на созданном ViewController пользователь установил некоторые элементы формы, и если ViewController будет вызван снова, элементы формы имеют начальные настройки: (

Любая помощь будет оценена.

Редактировать: я ценю многие ответы. Между тем я не знаком спроект и не могу проверить ваши ответы.

Ответы [ 7 ]

12 голосов
/ 28 января 2014

Используйте shouldPerforSegueWithIdentifier , чтобы разрешить выполнение перехода или отменить переход и вручную добавить свой ViewController.Сохраните указатель в prepareForSegue .

... header

@property (strong, nonatomic) MyViewController *myVC;

... реализация

-(BOOL) shouldPerformSegueWithIdentifier:(NSString *)identifier sender:(id)sender{
    if([identifier isEqualToString:@"MySegueIdentifier"]){
        if(self.myVC){
            // push on the viewController
            [self.navigationController pushViewController:self.myVC animated:YES];
             // cancel segue
            return NO; 
        }
    }
    // allow the segue to perform
    return YES;
}


-(void) prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
    if([segue.identifier isEqualToString:@"MySegueIdentifier"]){
        // this will only be called the first time the segue fires for this identifier
        // retian a pointer to the view controller
        self.myVC = segue.destinationViewController;
    }
}
8 голосов
/ 29 февраля 2012

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

Например:

UIStoryboardSegue* aSegue = [[UIStoryboardSegue alloc] initWithIdentifier:@"yourSegueIdentifier" source:self destination:self.existingViewController]
[self prepareForSegue:aSegue sender:self];
[aSegue perform];
2 голосов
/ 11 декабря 2012

Следующий код делает Singleton View контроллером. Добавьте их в вашу реализацию контроллера представления назначения, тогда segue будет использовать тот же vc.

static id s_singleton = nil;
+ (id) alloc {
    if(s_singleton != nil)
        return s_singleton;
    return [super alloc];
}
- (id) initWithCoder:(NSCoder *)aDecoder {
    if(s_singleton != nil)
        return s_singleton;
    self = [super initWithCoder:aDecoder];
    if(self) {
        s_singleton = self;
    }
    return self;
}
0 голосов
/ 10 января 2016

Если это стандартное универсальное приложение master-detail (которое использует UISplitViewController), то это может быть достигнуто путем реализации shouldPerform следующим образом:

- (BOOL)shouldPerformSegueWithIdentifier:(NSString *)identifier sender:(id)sender{
    if([identifier isEqualToString:@"showDetail"]){
        if(self.detailViewController){
            NSIndexPath *indexPath = [self.tableView indexPathForSelectedRow];
            Event *object = [self.fetchedResultsController objectAtIndexPath:indexPath];
            self.detailViewController.detailItem = object;
            return NO;
        }
    }
    return [super shouldPerformSegueWithIdentifier:identifier sender:sender];
}
0 голосов
/ 30 января 2013

Вам потребуется превратить Viewcontroller в одноэлементный класс.

0 голосов
/ 09 февраля 2012

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

MyController *controller = [storedControllers valueForKey:@"controllerName"];

if (!controller)
{
    controller = [[UIStoryboard storyboardWithName:@"MainStoryboard_iPhone" bundle:NULL] instantiateViewControllerWithIdentifier:@"MyControllerIdentifierOnTheStoryboard"];

    [storedControllers setValue:controller forKey:@"controllerName"];
}

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

Надеюсь, это поможет.

0 голосов
/ 29 ноября 2011

Создать свойство для контроллера.

@property (nonatomic, weak) MyController controller;

И использовать какую-нибудь ленивую инициализацию в performSegueWithIdentifier:sender

if (self.controller == nil)
{
self.controller = [MyController alloc] init]
...
}

В этом случае, если контроллер уже создан, он будет использован повторно.

...