将属性从模态视图控制器传递给父级
Posted
技术标签:
【中文标题】将属性从模态视图控制器传递给父级【英文标题】:Pass property from Modal View Controller to Parent 【发布时间】:2014-06-07 18:53:10 【问题描述】:我有一个 tableview 作为父视图控制器和一个子模态视图控制器。在模态视图控制器中,当用户点击一行时,我想设置父级的属性“过滤器”。但是,它只是返回 null。
如何将 NSString 过滤器属性传递回其父视图?我应该在 didSelectRowAtIndexPath 方法中实例化父视图控制器吗?
更新:使用 Delegates 解决,关注 this tutorial。
下面是模态视图控制器的代码:
#import "FilterViewController.h"
#import "ContactsTableViewController.h"
@interface FilterViewController ()
@end
@implementation FilterViewController
- (void)viewDidLoad
[super viewDidLoad];
self.filterTable.dataSource = self;
self.filterTable.delegate = self;
[self performSelector:@selector(retrieveFilteredEvents)];
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
return [self.filterEvents count];
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
static NSString *cellIdentifier = @"filterTableCell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier];
NSDictionary *tempDict = [self.filterEvents objectAtIndex:indexPath.row];
self.eventTitle = [tempDict objectForKey:@"eventType"];
cell.textLabel.text = self.eventTitle;
return cell;
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
NSDictionary *tempDict = [self.filterEvents objectAtIndex:indexPath.row];
NSString *string = [tempDict objectForKey:@"eventType"];
ContactsTableViewController *contactVC = [[ContactsTableViewController alloc] init];
contactVC.filter = string;
[self dismissViewControllerAnimated:YES completion:nil];
[[NSNotificationCenter defaultCenter] postNotificationName:@"updateParent" object:nil];
#pragma mark - Helper Methods
- (IBAction)done:(id)sender
[self dismissViewControllerAnimated:YES completion:nil];
-(void)retrieveFilteredEvents
PFQuery *retrieveEvents = [PFQuery queryWithClassName:@"eventTypes"];
[retrieveEvents orderByAscending:@"eventOrder"];
[retrieveEvents findObjectsInBackgroundWithBlock:^(NSArray *objects, NSError *error)
if (!error)
self.filterEvents = [[NSArray alloc] initWithArray:objects];
[self.filterTable reloadData];
];
@end
【问题讨论】:
按照 Ankush Agrawal 和 CrimsonChris 的建议使用委托解决。协议方法有点过头了,但我会回来练习。谢谢大家!! 【参考方案1】:有多种方法可以解决这个问题。我认为最简单的方法是在您的父类中设置一个属性,该属性会在您每次更新子类时更改。
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
NSDictionary *tempDict = [self.filterEvents objectAtIndex:indexPath.row];
NSString *string = [tempDict objectForKey:@"eventType"];
self.parentViewController.filter = string;
[self dismissViewControllerAnimated:YES completion:nil];
[[NSNotificationCenter defaultCenter] postNotificationName:@"updateParent" object:nil];
另一种选择是使用委托。这可能是一种更简洁的解决方案,但对初学者不太友好。
http://iosdevelopertips.com/objective-c/the-basics-of-protocols-and-delegates.html
【讨论】:
self.parentViewController 不允许我访问 filter 属性。可能是因为模态视图控制器嵌入在导航控制器中?【参考方案2】:你在这里做什么:
ContactsTableViewController *contactVC = [[ContactsTableViewController alloc] init];
contactVC.filter = string;
正在实例化一个全新的控制器,它与提供您的FilterViewController
的实际控制器无关。
尝试使用它来访问呈现@987654323@ 的视图控制器:
ContactsTableViewController *contactVC = (ContactsTableViewController*)self.presentingController;
contactVC.filter = string;
希望这会有所帮助。
【讨论】:
【参考方案3】:Alloc init 为您提供了一个全新的对象,而不是对您现有对象的引用。有几种方法可以引用您的表格视图。我推荐委托,这是一种灵活的方法,即使您以不同于模态的方式呈现视图,它也将继续有效。
【讨论】:
【参考方案4】:创建协议
@protocol PassSomeData
-(void)childViewController:(UIViewController *)viewController passedSomeData:(id)data;
@end
在子视图控制器中创建一个委托
@interface ViewControllerThatIsPresentedModally :UIViewController
@property(nonatomic,assign) id<PassSomeData>delegate;
@end
在呈现模态的视图控制器的prepareForSegue
中写下这个
UIViewController *vc = [segue destinationViewController];
if ([vc isKindOfClass:[ViewControllerTahIsPresentedModally class])
[((ViewControllerThatIsPresentedModally *)vc) setDelegate:self];
当您的用户点击允许收集某些数据的内容时 你会的
[self.delegate viewController:self passedSomeData:yourData];
你在父视图控制器中的方法会被你的数据调用
您的呈现视图控制器需要符合 PassedSomeData 协议并实现给定的方法
【讨论】:
如果您使用 ARC,请使用 weak 而不是为您的委托属性分配,这是您应该使用的。 在这方面遇到了真正的困难。当我发布您写的最后一条消息时,我收到错误“No known instance for selector 'viewController:passedSomeData:' 我想我不确定我需要在呈现视图控制器中实现的方法是什么。 @kerbelda 解决您的问题的“代表”的定义完全像这样......!【参考方案5】:如果它是一个简单的属性集,你可以这样做
[self.parentViewController performSelector:@selector(setSomething:) withObject:...]
或
[self.presentingViewController performSelector:@selector(setSomething:) withObject:...]
不过,委托是一种更好的方式 :-)
【讨论】:
以上是关于将属性从模态视图控制器传递给父级的主要内容,如果未能解决你的问题,请参考以下文章