将属性从Modal View Controller传递给Parent

时间:2014-06-07 18:53:11

标签: ios objective-c cocoa-touch uiviewcontroller modalviewcontroller

我有一个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

5 个答案:

答案 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:...]

代表是一个更好的方式,但是: - )