Выполнить функцию для вызова функции performSegueWithIdentifier из другого класса

Я потратил несколько часов на это, пытаясь разобраться в себе, но я сдаюсь!

У меня есть соглашение о мастер-детали, где экран ввода пользователя должен вызывать функцию другого класса для публикации в веб-службе. По завершении асинхронного вызова класс вызовет указанную функцию. В этом случае я просто тестирую, и все, что я хочу сделать, это вернуться на главный экран после того, как пользовательский ввод будет принят веб-службой.

Когда использование отбирает кнопку на экране ввода (SetLocationViewController), асинхронная операция вызывается в классе APIPostClass. После того, как он будет завершен, я хочу, чтобы SetLocationViewController перешел к MasterViewController.

В APIPostClass.m in (после завершения асинхронного завершения)

-(void)callWhenDone { NSLog(@"callWhenDone loaded."); SetLocationViewController *SLVClassInstance = [[SetLocationViewController alloc] init]; [SLVClassInstance doSegue]; } 

В SetLocationViewController.m

 -(void) doSegue { NSLog(@"doSegue loaded"); [self performSegueWithIdentifier:@"SetLocationViewControllerManualUnwind" sender:self]; } 

Вызов doSegue из действия на SetLocationViewController.m работает, поэтому я знаю, что мой segue в порядке, но указанное выше не работает. Я получаю причину ошибки: «Receiver () не имеет сеанса с идентификатором« SetLocationViewControllerManualUnwind »

Я предполагаю, что причина связана с инициализацией инициализации VC инициализации, но я не знаю ничего лучше. Таким образом, как я могу вызвать функцию в другом классе, как если бы ее вызывал собственный класс?

Создайте делегат, он будет намного более надежным и быстрым, чем Уведомления.

 @protocol APIPostDelegate <NSObject> @required -(void)OnRequestSucess; @end 

В APIPost добавьте новое свойство для делегата

 @interface APIPost : NSObject @property (weak) id<APIPostDelegate> delegate; 

В SetLocationViewController реализовано APIPostDelegate

SetLocationViewController.h

 SetLocationViewController :NSObject<APIPostDelegate> 

SetLocationViewController.m

 -(void)OnRequestSucess { [self doSegue]; } 

перед тем как сделать вызов метода на APIPost, назначьте себя для делегирования свойства.

 APIPost *apipost=[[APIPost alloc]init]; apipost.delegate=self; [apipost <your api method>]; 

APIPost.m

 [self.delegate OnRequestSucess]; 

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

Есть несколько способов сделать это: –

  1. Использовать Delegate
  2. Используйте NSNotification .
  3. Описанный выше Artur (для SplitViewController Only – iPad)

Вы должны использовать делегат всякий раз, когда это возможно, но это может быть не слишком прямолинейно. NSNotification более прямолинейна, но это не хорошая практика, а не хороший стиль программирования.

Я буду использовать только метод NSNotification, поскольку его проще реализовать.

В SetLocationViewController.m

 -(void)viewWillAppear:(BOOL)animated{ [super viewWillAppear:animated]; [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(doSegue) name:@"calldoSegue" object:nil]; } -(void)viewWillDisappear:(BOOL)animated{ [super viewWillDisappear:animated]; [[NSNotificationCenter defaultCenter]removeObserver:self name:@"calldoSegue" object:nil]; } -(void) doSegue { NSLog(@"doSegue loaded"); [self performSegueWithIdentifier:@"SetLocationViewControllerManualUnwind" sender:self]; } 

В APIPostClass.m

 -(void)callWhenDone { NSLog(@"callWhenDone loaded."); [[NSNotificationCenter defaultCenter]postNotificationName:@"calldoSegue" object:nil]; } 

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

Ответ здесь: Выполнение segue из другого класса

В моем APIPostClass.h я настраиваю контроллер вида:

 @interface APIPostClass : NSObject { SetLocationViewController *setLocationViewController; } @property(nonatomic, strong) SetLocationViewController *setLocationViewController; @end 

В моем APIPostClass.m я его синтезирую:

 @synthesize setLocationViewController; 

то вместо этого (как в моем вопросе):

 -(void)callWhenDone { NSLog(@"callWhenDone loaded."); SetLocationViewController *SLVClassInstance = [[SetLocationViewController alloc] init]; [SLVClassInstance doSegue]; } 

У меня есть:

 -(void)callWhenDone { NSLog(@"callWhenDone loaded"); [self.setLocationViewController doSegue]; } 

В методе SetLocationViewController.m метод segue остается неизменным:

 -(void) doSegue { NSLog(@"doSegue loaded"); [self performSegueWithIdentifier:@"SetLocationViewControllerManualUnwind" sender:self]; } 

Но когда я называю свой API, мне нужно «прикрепить» (простить мою терминологию) к контроллеру представления. Это то, что у меня было:

 - (IBAction)btnTestAPICall:(id)sender { NSLog(@"User tapped API button"); APIPostClass *APIPostClassInstance = [[APIPostClass alloc] init]; [APIPostClassInstance APICall: ... .... } 

Но это то, что работает после приведения всего вышеперечисленного:

 - (IBAction)btnTestAPICall:(id)sender { NSLog(@"User tapped API button"); APIPostClass *APIPostClassInstance= [[APIPostClass alloc] init]; UIViewController *currentVC=self; APIPostClassInstance.setLocationViewController = currentVC; [APIPostClassInstance APICall: ... ... 

Надеюсь, это поможет кому-то еще!