繁体   English   中英

将数据从UITableViewCell传递到UITableViewController的食谱

[英]Recipes to pass data from UITableViewCell to UITableViewController

我正在寻找将数据从UITableViewCell传递到UIableViewController (或UIViewController )的正确机制。

在stackoverflow内搜索时,我发现了执行此操作的不同方法,最后我找到了一种运行良好的机制,但我不知道这是否是有效的方法。

这是方案。 首先,我创建了一个自定义单元格(与xib接口相关联),名为DataTableViewCell ,它扩展了UITableViewCell 此单元格具有一些出口以显示(和修改)数据以及称为index的成瘾属性,如下所示:

@property (nonatomic, copy) NSIndexPath* index;

此属性在UITableViewController cellForRowAtIndexPath方法内部刷新:

- (UITableViewCell *)tableView:(UITableView *)tv cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    DataTableViewCell *cell = (DataTableViewCell*)[tv dequeueReusableCellWithIdentifier:kCellTableIdentifier];
    if (cell == nil)
    {
        [[NSBundle mainBundle] loadNibNamed:@"DataTableViewCell" owner:self options:nil];     
        cell = (DataTableViewCell*)self.dataTableViewCellOutlet;
    }

    // configure the cell with data
    // do stuff here...

    // configure the cell with the current indexPath
    cell.index = indexPath;    

    return cell;
}

由于可以更改单元格中的值,因此我需要将数据传递给UITableViewController以更新模型。 为此,我决定使用委托机制。 因此,我使用以下方法创建了一个协议:

- (void)updateData:(DataItem*)dataItem atIndexPath:(NSIndexPath*)index;

UITableViewController实现该协议。 这样,在单元中(针对某些事件),我可以调用该方法并以正确的方式更新模型。

话虽如此,我有一些问题要问:

  1. 这是将数据从单元传递到控制器的正确机制吗?
  2. 使用像单元格中的一种用法这样的索引属性是否正确?
  3. 使用保留策略而不是复制策略是否相同? 有什么区别?
  4. 由于我发现的解决方案可能非常诡异,是否可以使用block代替?

关于积木,我是这样想的:

在单元格中,创建一个属性块,如下所示:

@property (nonatomic, copy) void (^updateModelOnEvent)(DataItem* dataItem);

然后在UITableViewController的方法cellForRowAtIndexPath方法内部,将该属性分配给这样的块代码(此代码位于cell.index = indexPath;的同一级别):

// configure the cell with the current indexPath
cell.updateModelOnEvent = ^(DataItem* dataItem) {

    [self.model insertObject:dataItem atIndex:indexPath.row];
};

可能是有效的替代方法? 在这种情况下,我是否必须使用复制或保留策略?

先感谢您。

为什么不只将[UITableView indexPathForCell:]与委托一起使用?

MyViewController.h

@interface MyViewController : UITableViewController <MyTableViewCellDelegate>

@end

MyViewController.m

@implementation MyViewController

// methods...

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {

   NSString *reuseIdentifier = @"MyCell";
   MyTableViewCell *cell = (id)[tableView dequeueReusableCellWithIdentifier:reuseIdentifier];

   if (cell == nil)
       cell = [[[MyTableViewCell alloc] initWithMyArgument:someArgument reuseIdentifier:reuseIdentifier] autorelease];

    [cell setDelegate:self];

    // update the cell with your data

    return cell;
}

- (void)myDelegateMethodWithCell:(MyTableViewCell *)cell {

    NSIndexPath *indexPath = [self.tableView indexPathForCell:cell];

    // update model
}

@end

MyTableViewCell.h

@protocol MyTableViewCellDelegate;

@interface MyTableViewCell : UITableViewCell

@property (assign, nonatomic) id <MyTableViewCellDelegate> delegate;

- (id)initWithMyArgument:(id)someArgument reuseIdentifier:(NSString *)reuseIdentifier;

@end


@protocol MyTableViewCellDelegate <NSObject>

@optional

- (void)myDelegateMethodWithCell:(MyTableViewCell *)cell;

@end

MyTableViewCell.m

@implementation MyTableViewCell

@synthesize delegate = _delegate;

- (id)initWithMyArgument:(id)someArgument reuseIdentifier:(NSString *)reuseIdentifier {

    self = [super initWithStyle:UITableViewCellStyleDefault reuseIdentifier:reuseIdentifier];

    if (self) {
        // custom setup
    }

    return self;
}

- (void)prepareForReuse {
    [super prepareForReuse];

    self.delegate = nil;
}

- (void)someActionHappened {

    if ([self.delegate respondsToSelector:@selector(myDelegateMethodWithCell:)])
        [self.delegate myDelegateMethodWithCell:self];
}

@end
  1. 要修改单元格,您应该修改数据模型并重新加载表数据。 没有其他的。
  2. 不必具有单元格的indexPath
  3. 在您的情况下,使用保留或复制策略是相同的。 复制使新对象具有相同的状态。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM