我有一个tableview作为带有子模态视图控制器的父视图控制器。在模态视图控制器中,当用户点击一行时,我想设置父级的属性'过滤器。'但是,它只是返回null。
如何将NSString过滤器属性传递回其父视图?我应该在didSelectRowAtIndexPath方法中实例化父视图控制器吗?
更新:使用代表解决,然后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
答案 0 :(得分:3)
你在这做什么:
ContactsTableViewController *contactVC = [[ContactsTableViewController alloc] init];
contactVC.filter = string;
正在实例化一个与呈现FilterViewController
的实际控制器无关的全新控制器。
请尝试使用此代码来访问呈现FilterViewController
的视图控制器:
ContactsTableViewController *contactVC = (ContactsTableViewController*)self.presentingController;
contactVC.filter = string;
希望这有帮助。
答案 1 :(得分:3)
有多种方法可以解决这个问题。我认为最简单的方法是在父类中设置一个属性,每次更新子级时都会更改。
-(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
答案 2 :(得分:2)
Alloc init为您提供了一个全新的对象,而不是对您现有对象的引用。有几种方法可以获得对表视图的引用。我推荐代表团,它是一种灵活的方法,即使你以不同于模态的方式呈现你的观点,它仍将继续有效。
答案 3 :(得分:2)
创建协议
@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协议并实现给定的方法
答案 4 :(得分:0)
如果它是一个简单的属性集,你可以做
[self.parentViewController performSelector:@selector(setSomething:) withObject:...]
或
[self.presentingViewController performSelector:@selector(setSomething:) withObject:...]
代表是一个更好的方式,但是: - )