我正在找出将数据从UITableViewCell
传递到UIableViewController
(或UIViewController
)的正确机制。
在stackoverflow中搜索我找到了不同的方法来做到这一点,最后我找到了一个运行良好的机制,但我不知道它是否是一个有效的方法。
这就是场景。首先,我创建了一个名为DataTableViewCell
的自定义单元格(与xib接口关联),扩展了UITableViewCell
。这个单元格有一些显示(和修改)数据的出口和一个名为index的成瘾属性,如下所示:
@property (nonatomic, copy) NSIndexPath* index;
此属性在cellForRowAtIndexPath
中的方法UITableViewController
方法内刷新:
- (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
实现该协议。这样,在单元格内(针对某些事件),我可以调用该方法并以正确的方式更新模型。
话虽如此,我还有一些问题要问:
关于街区,我这么想:
在单元格内创建一个属性块,如下所示:
@property (nonatomic, copy) void (^updateModelOnEvent)(DataItem* dataItem);
然后在cellForRowAtIndexPath
内的方法UITableViewController
方法内将该属性分配给这样的块代码(此代码与cell.index = indexPath;
处于同一级别):
// configure the cell with the current indexPath
cell.updateModelOnEvent = ^(DataItem* dataItem) {
[self.model insertObject:dataItem atIndex:indexPath.row];
};
可能是一个有效的替代方案吗?在这种情况下,我是否必须使用复制或保留策略?
提前谢谢。
答案 0 :(得分:10)
为什么不将[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 :(得分:0)