在prepareForSegue中分配给目标视图控制器属性的对象作为UITableViewCell出现

时间:2014-10-08 01:36:28

标签: ios objective-c uitableview

我正在尝试将视频控制器的属性设置为自定义对象(Restroom),但它会以UITableViewCell形式出现。

以下是触发segue的原始View Controller的代码。当用户选择列出洗手间的表视图中的单元格时,将调用userDidSelectRestroomNotification方法 - 然后应用程序将转到视图控制器,该控制器列出该洗手间的详细信息:

- (void)userDidSelectRestroomNotification:(NSNotification *)notification
{
    Restroom *selectedRestroom = (Restroom *)[notification object];

    [self performSegueWithIdentifier:@"ShowRestroomDetails" sender:selectedRestroom];
};

- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
    if ([segue.identifier isEqualToString:@"ShowRestroomDetails"])
    {
        RestroomDetailsViewController *restroomDetailsViewController = 
            (RestroomDetailsViewController*)segue.destinationViewController;

        restroomDetailsViewController.restroom = sender;
    }
}

以下是我的数据源中提供通知的代码:

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
    // post a notification when a selection is made
    NSNotification *notification = [NSNotification 
        notificationWithName:RRTableViewDidSelectRestroomNotification 
        object:[self restroomForIndexPath:indexPath]];

    [[NSNotificationCenter defaultCenter] postNotification:notification];
}

- (Restroom *)restroomForIndexPath:(NSIndexPath *)indexPath
{
    return [self.restroomsList objectAtIndex:[indexPath row]];
}

重点是,我在通知中发送Restroom个对象。

问题来自于RestroomDetailsViewController,我试图将标签的文本设置为我传递的Restroom对象的名称:

@interface RestroomDetailsViewController ()

@property (weak, nonatomic) IBOutlet UILabel *nameLabel;

@end

@implementation RestroomDetailsViewController

- (void)viewWillAppear:(BOOL)animated
{
    [super viewWillAppear:animated];

    self.nameLabel.text = self.restroom.name;
}

@end

它在self.nameLabel.text = self.restroom.name崩溃了。当我检查对象时,我发现我的self.restroom对象实际上是UITableViewCell。让我更加困惑的是,UITableViewCell似乎是用户选择触发segue的单元格 - 即在数据源中设置的单元格:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    NSParameterAssert([indexPath section] == 0);
    NSParameterAssert([indexPath row] < [_restroomsList count]);

    UITableViewCell *restroomCell = [tableView 
        dequeueReusableCellWithIdentifier:restroomCellReuseIdentifier];

    if(!restroomCell)
    {
        restroomCell = [[UITableViewCell alloc] 
            initWithStyle:UITableViewCellStyleDefault 
            reuseIdentifier:restroomCellReuseIdentifier];
    }

    restroomCell.textLabel.text = [[_restroomsList objectAtIndex:[indexPath row]] name];

    return restroomCell;
}

我不明白为什么会发生这种情况以及如何将restroom属性正确分配给Restroom对象。

2 个答案:

答案 0 :(得分:1)

为什么使用后期​​通知?

我在这里看不到使用通知的任何要求。带参数的简单函数可以完成工作。

尝试按照以下方式调用segue

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
  [self performSegueWithIdentifier:@"ShowRestroomDetails" sender:[self restroomForIndexPath:indexPath]];
}

- (Restroom *)restroomForIndexPath:(NSIndexPath *)indexPath
{  
return [self.restroomsList objectAtIndex:[indexPath row]];
}


 - (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
      Restroom *selectedRestroom = (Restroom *)sender;


    if ([segue.identifier isEqualToString:@"ShowRestroomDetails"])
    {
    RestroomDetailsViewController *restroomDetailsViewController = 
        (RestroomDetailsViewController*)segue.destinationViewController;

    restroomDetailsViewController.restroom = selectedRestroom ;
   }
}

答案 1 :(得分:0)

我理解在按下单元格时发布通知并不常见 - 但这就是我当前选择实现此应用程序的方式。

话虽这么说,这就是我最终让这个工作的原因(感谢@rdelmar的评论说要检查调用这些方法的顺序):

- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
    if ([segue.identifier isEqualToString:@"ShowRestroomDetails"])
    {
        if([sender isKindOfClass:[Restroom class]])
        {
            RestroomDetailsViewController *restroomDetailsViewController = (RestroomDetailsViewController*)segue.destinationViewController;

            restroomDetailsViewController.restroom = sender;
        }
    }
}

我发现在prepareForSegue方法之前按下单元格时会触发userDidSelectRestroomNotification方法。但是,我希望userDidSelectRestroomNotification实际上是触发prepareForSegue的方法,因为它会创建所需的Restroom对象。因此,我检查了prepareForSegue,确保传入的对象是Restroom实例。

所有这一切 - 我不知道这不是一个黑客而不是一个解决方案。