1

这可能很简单,但我被困住了!

基本上我有一个父子视图控制器,我试图将数据从子节点传递给父节点。

//子VC接口

@protocol ANSearchGetawayFilterDelegate
    -(void)selectedCell:(NSString *)cellTitle;
@end

@interface ANSearchGetawayFilterViewController : UIViewController <UITableViewDelegate,     UITableViewDataSource, UISearchBarDelegate>
{
   NSString* cellTitle;
}
@property (nonatomic, assign) id<ANSearchGetawayFilterDelegate> delegate;

@end

//子VC实现

@implementation ANSearchGetawayFilterViewController
@synthesize delegate = _delegate;

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
    UITableViewCell *selectedCell = [tableView cellForRowAtIndexPath:indexPath];
    cellTitle = selectedCell.textLabel.text;
    [[self  delegate] selectedCell:cellTitle];

    [self dismissModalViewControllerAnimated:YES];
}

//父VC接口

#import "ANSearchGetawayFilterViewController.h"

@interface ANGetawayFilterViewController : UIViewController <ANSearchGetawayFilterDelegate>
{
    NSString* _cellText;
}

//父VC实现

   - (id)initWithNibName:(NSString*)nibNameOrNil bundle:(NSBundle*)nibBundleOrNil
    {
        self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
        if (self)
        {
            // Custom initialization
            ANSearchGetawayFilterViewController *search = [[ANSearchGetawayFilterViewController alloc] init];
            search.delegate = self;
        }
        return self;
    }

//delegate method

    -(void)selectedCell:(NSString *)cellTitle
    {
        _cellText = cellTitle;
        NSLog(@"cell text %@", _cellText);
    } 

委托方法永远不会被调用,什么时候 NSLog _cellText 其他地方它出现为空......我做错了什么?谢谢!

4

5 回答 5

2

您很可能会创建一个新实例,用于ANSearchGetawayFilterViewController演示它而不是在其上配置委托。

当你打电话

ANSearchGetawayFilterViewController *search = [[ANSearchGetawayFilterViewController alloc] init];
search.delegate = self;

您创建了一个实例,ANSearchGetawayFilterViewController然后正确设置了委托,您从未将这个实例存储在ANSearchGetawayFilterViewController任何地方。所以稍后当你来展示它时,你再次打电话

ANSearchGetawayFilterViewController *search = [[ANSearchGetawayFilterViewController alloc] init];

这为您提供了一个完全不同的实例,然后您需要再次配置它。例如

ANSearchGetawayFilterViewController *search = [[ANSearchGetawayFilterViewController alloc] init];
ANSearchGetawayFilterViewController *search1 = [[ANSearchGetawayFilterViewController alloc] init];

NSLog(@"%d", search1 == search);

#=> 0

修复更新您的代码

- (BOOL)textFieldShouldBeginEditing:(UITextField*)textField;
{
    BOOL shouldBeginEditing = YES; 
    NSLog(@"text field should begin editing"); 

    ANSearchGetawayFilterViewController *myANSearchGetawayFilterViewController = [[[ANSearchGetawayFilterViewController alloc] init] autorelease]; 
    myANSearchGetawayFilterViewController.delegate = self;    // <--- configure the delegate

    [self presentModalViewController:myANSearchGetawayFilterViewController animated:YES];
    [self closeAllPickers]; 
    return shouldBeginEditing; 
}

我不会将其设为 ivar,因为您可能会暂时显示此 viewController 只是为了选择一些数据然后将其删除,因此丢弃它并每次创建一个新数据可能是安全的。

于 2012-05-29T22:44:14.563 回答
0

相反,委托方法正在被调用(因此是NSLog())。但是,_cellText 是 (null),因为传入的值是 nil,ergo selectedCell.textLabel.text

于 2012-05-29T22:37:42.850 回答
0

首先,您确定-selectedCell正在调用该方法吗?

-tableViewDidSelectRow您可以通过在...之前或之后放置一个 NSLog() 来做到这一点

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
    ...
    NSLog(@"TABLEVIEW DID SELECT ROW BEFORE -> %@ <-", cellTitle);
    [[self  delegate] selectedCell:cellTitle];
    NSLog(@"TABLEVIEW DID SELECT ROW DELEGATE CALLED");
    ...
}

此外,您可能想做一些清理工作(可选)

首先,您的初始化方法正在泄漏。使用委托将设置ANGetawayFilterViewController为父类的属性,或者在设置委托后释放它。

其次,在 中-tableViewDidSelectRow,您的代码假定委托具有-selectedCell编码的方法。如果您没有实现该方法,那么应用程序将导致崩溃。您可以通过检查委托是否可以防止这种情况-respondsToSelector...

if ([self.delegate respondsToSelector:@selector(selectedCell:)]) {
    [self.delegate selectedCell:cellTitle];
}

第三,委托调用的方法通知 parentViewController 不遵循委托方法使用的一般模式,除了-numberOfRowsInSection( UITableViewDelegate)。您的方法也应该包含实际ANFilterGetawayViewController实例:

- (void) filterGetawayViewController:(ANSearchGetawayFilterViewController *) controller didSelectCellWithTitle:(NSString *) title {

    ...

}

它可以这样调用:

[self.delegate filterGetawayViewController:self didSelectCellWithTitle:cellTitle];
于 2012-05-29T22:38:50.777 回答
0

你在用ARC吗?因为当 init 函数结束时,你的对象(以及它对委托的引用)被清理了。如果将搜索变量设为全局变量(在标题中定义并在代码中初始化)会发生什么?

于 2012-05-29T22:49:10.107 回答
0

假设您使用的是 ARC:

您需要@property为您的ANSearchGetawayFilterViewController实例保留一个。ARC 将在调用委托方法时释放它。做这样的事情。

@property (strong, nonatomic) ANSearchGetawayFilterViewController *search;
...
@synthesize search = _search;

- (id)initWithNibName:(NSString*)nibNameOrNil bundle:(NSBundle*)nibBundleOrNil
{
    self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
    if (self)
    {
        // Custom initialization
        self.search = [[ANSearchGetawayFilterViewController alloc] init];
        self.search.delegate = self;
    }
    return self;
}

与您的问题无关,但最佳做法是在调用之前检查委托是否实际实现了您期望的方法,如下所示:

if ([self.delegate respondsToSelector:@selector(selectedCell:)]) {
    [self.delegate selectedCell:cellTitle];
}
于 2012-05-29T22:50:40.803 回答