我想知道如何从模态视图控制器内部调用的方法更新呈现视图控制器的视图控制器property
?现在,我能想到的唯一方法是使用NSNotificationCenter
,虽然这适用于词典项目,但我无法弄清楚如何将它用于自定义对象。
例如,我的展示视图控制器HomewViewController
有一个名为PFObject
的解析homeSelections
,可以在模态显示的ModalViewController
属性中更新newSelections
(以及PFObject
)。在用户进行选择之后,我希望HomeViewController
homeSelections
也具有从模态视图控制器传递的最新数据。
感谢帮助 - 谢谢。
更新1 :这就是我现在所做的事情(注意我正在使用一个精简的示例来测试)
在ViewController
中(这是父/呈现视图控制器)
@interface ViewController ()
@property (strong, nonatomic) NSArray *totalRamen;
@end
@implementation ViewController
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
self.totalRamen = @[@"ramen1", @"ramen2", @"ramen3", @"moot"];
}
- (void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
NSLog(@"self.totalRamen: %@", self.totalRamen);
NSLog(@"Done");
}
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if ([segue.identifier isEqualToString:@"showModal"]){
ModalViewController *destinationVC = (ModalViewController *)segue.destinationViewController;
destinationVC.passedRamen = self.totalRamen;
}
}
- (IBAction)showModalAction:(UIButton *)sender
{
ModalViewController *destinaionViewController = [[ModalViewController alloc] init];
destinaionViewController.selectionCallback = ^(id selectedItem) {
self.totalRamen = (NSArray *)selectedItem;
NSLog(@"self.totalRAmen %@", self.totalRamen);
NSLog(@"done");
};
[self performSegueWithIdentifier:@"showModal" sender:self];
}
在ModalViewController
中(这是呈现的/模态视图控制器)
@interface ModalViewController : UIViewController
@property (strong, nonatomic) NSArray *passedRamen;
- (IBAction)dismissModal:(UIButton *)sender;
typedef void(^CallbackBlock)(id value);
@property (nonatomic, copy) CallbackBlock selectionCallback;
@end
- (void)viewWillAppear:(BOOL)animated{
[super viewWillAppear:animated];
NSLog(@"Passed ramen %@", self.passedRamen);
NSLog(@"Done");
self.passedRamen = @[@"moot is awesome"];
NSLog(@"new ramen: %@", self.passedRamen);
NSLog(@"%@", self.selectionCallback); //nil here
//call back
CallbackBlock selectionCallback = self.selectionCallback;
if (selectionCallback){
selectionCallback(self.passedRamen); //I want to send the newly updated self.passedRamen back
} else {
NSLog(@"No show"); //Means if isn't called
}
}
- (IBAction)dismissModal:(UIButton *)sender
{
[self dismissViewControllerAnimated:YES completion:nil];
}
答案 0 :(得分:4)
将回调块传递给呈现的视图控制器。这样,呈现的视图控制器就不知道有关呈现它的视图控制器的任何信息。更灵活,因为现在任何人可以呈现你的视图控制器,他们只是传递一个块!
PresentedViewController *vc = [[PresentedViewController alloc] init]; //or get your existing one
vc.selectionCallback = ^(id selectedItem) {
//update selected items here
};
//present vc here
typedef void(^CallbackBlock)(id value);
@property (nonatomic, copy) CallbackBlock selectionCallback;
- (void)somethingWasSelected:(id)selectedItem {
CallbackBlock selectionCallback = self.selectionCallback;
if (selectionCallback) selectionCallback(selectedItem);
}
谨防保留周期。该块由所呈现的视图控制器保留,因此对块中呈现的视图控制器的引用而不首先削弱它将产生泄漏。有关此问题的更多信息,请访问here。
答案 1 :(得分:0)
用户选择后,我想要HomeViewController homeSelections也有从模态视图传递的最新数据 控制器。
简单的方法是避免ModalViewController
更新HomeViewController
。打开通讯 - 拥有HomeViewController
查询ModalViewController
并在模式被解除时自行更新。
HomeViewController
已取决于ModalViewController
- 它必须知道ModalViewController
才能呈现它。因此,让它知道如何在适当的时间从newSelections
中读取ModalViewController
属性也没有什么害处。另一方面,ModalViewController
无需了解其信息的来源。为了完成工作,它不需要知道HomeViewController
。如果您无法告诉ModalViewController
有关HomeViewController
的任何内容,您可以轻松地使用来自其他视图控制器的ModalViewController
,如果出现这种需要的话。更重要的是,如果ModalViewController
更改,则无需更新HomeViewController
。
例如,您的HomeViewController
可能会(部分)看起来像这样:
- (void)showModalViewController
{
self.modalViewController = [[ModalViewController alloc] init]; // or otherwise get the modal controller
[self presentViewController:self.modalViewController
animated:YES
completion:];
}
- (void)dismissViewControllerAnimated:(BOOL)flag completion:(void (^)(void))completion
{
self.homeSelections = self.modalViewController.newSelections;
[super dismissViewControllerAnimated:flag completion:completion];
self.modalViewController = nil;
}