Возможно ли передавать данные с помощью popViewControllerAnimated?
Я столкнулся с интересной проблемой, у меня есть главный ViewController, позвонивший ему в MainVC с помощью navigationController, и я делаю performSegueWithIdentifier от него до Mine второго ViewController, чтобы назвать его SecVC. поэтому, когда я пытаюсь выполнить popViewControllerAnimated, я хочу передать некоторые данные из SecVC в MainVc.. Я знаю, что могу сделать это с помощью appDelegate Param или с классом одиночных игр, но мой вопрос: могу ли я сделать это с более элегантным решением? например, я использую prepareForSegue и использую локальные пармерометры.
Спасибо...
Ответы
Ответ 1
Лучший способ сделать это - использовать делегат.
//SecVCDelegate.h
#import <Foundation/Foundation.h>
@protocol SecVSDelegate <NSObject>
@optional
- (void)secVCDidDismisWithData:(NSObject*)data;
@end
//SecVC.h
#import <UIKit/UIKit.h>
#import "SecVSDelegate.h"
@interface SecVC : UIViewController
/** Returns the delegate */
@property (nonatomic, assign) id<SecVSDelegate> delegate;
@end
//SecVC.M
...
- (void) dealloc
{
...
delegate = nil
...
}
Когда вы будете popViewControllerAnimated, сразу после него (или до него) вы делаете это
if(_delegate && [_delegate respondsToSelector:@selector(secVCDidDismisWithData:)])
{
[_delegate secVCDidDismisWithData:myDataObject];
}
И в MainVC вы должны быть уверены, что реализуете функцию делегата
//MainVC.m
- (void)secVCDidDismisWithData
{
//do whatever you want with the data
}
Чтобы избежать каких-либо предупреждений, вы должны сказать, что класс MainVC реализует делегат следующим образом:
//MainVC.h
#import "SecVCDelegate.h"
...
@interface MainVC : UIViewController <SecVCDelegate>
...
secVCInstance.delegate = self;
[self.navigationController pushViewController:secVCInstance];
...
Ответ 2
Хотя я согласен с тем, что лучшим вариантом является использование Делегат,
но если кто-то ищет что-то другое, он может использовать NSNotificationCenter в качестве альтернативы.
В viewDidLoad MainVC:
- (void)viewDidLoad
{
[super viewDidLoad];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(recvData:)
name:@"SecVCPopped"
object:nil];
}
И добавьте метод recvDatastrong > в MainVC.m
- (void) recvData:(NSNotification *) notification
{
NSDictionary* userInfo = notification.userInfo;
int messageTotal = [[userInfo objectForKey:@"total"] intValue];
NSLog (@"Successfully received data from notification! %i", messageTotal);
}
Теперь в SecVC, перед появлением, добавьте эту строку
NSMutableDictionary* userInfo = [NSMutableDictionary dictionary];
[userInfo setObject:[NSNumber numberWithInt:messageTotal] forKey:@"total"];
NSNotificationCenter* nc = [NSNotificationCenter defaultCenter];
[nc postNotificationName:@"SecVCPopped" object:self userInfo:userInfo];
Ответ 3
Я бы сделал это одним из следующих способов, но я не уверен, достаточно ли он достаточно...
-
В SecVC добавьте @property MainVC *mainVC;
Используйте [self.mainVC setSomeValue:...];
перед вызовом [self.navigationController popViewControllerAnimated:...];
-
Используйте [self.navigationController viewControllers]; чтобы узнать MainVC *mainVC
, и вызовите [mainVC setSomeValue:...];
перед строкой кода, которая появляется в ViewController
.
Это то, что вы хотите?
Ответ 4
Я просто установил протокол в отключенном представлении (пример в Swift):
protocol ExampleTableViewControllerDismissDelegate {
func didDismiss(withData: Any)
}
var delegate: SearchableTableViewControllerDismissDelegate?
Затем вы можете вызвать это, когда вы отклоняете/выставляете свое мнение следующим образом
self.navigationController?.popViewController(animated: true)
delegate?.didDismiss(withData: Any)
Затем, когда представление отклонено (родительский элемент в иерархии), мы можем соответствовать делегату и по существу получить обратный вызов с данными после того, как представление было отклонено.
//MARK: ExampleTableViewControllerDismissDelegate
func didDismiss(withData: Any) {
//do some funky stuff
}
И не забудьте подписаться на делегат в родительском представлении, используя
viewController.delegate = self
Ответ 5
Существует другой способ передачи данных между представлениями, включая popViewControllerAnimated, и с глобальным экземпляром var, поэтому если вы измените этот параметр Var в своем подробном представлении и после popViewControllerAnimated, вы можете вызывать новые данные в методе viewWillAppear.
Первый шаг - объявить глобальный var в main.h
NSMutableArray * layerList;
И теперь вам нужно вызвать его в подробном представлении.
SecondView.m
extern NSString *layerList;
SecondView.h
-(void)back{
layerList = @"Value to send";
[self.navigationController popViewControllerAnimated:YES];
}
Теперь вы можете использовать информацию в главном представлении после обнаружения действия pop.
FirstView.m
extern NSString *layerList;
FirstView.h
-(void)viewWillAppear:(BOOL)animated{
NSLog(@"This is what I received: %@",layerList);
}