[英]UITableViewCell changing UITableView's datasource
这对我来说非常有用,因为我一直在努力解决这个问题。 每次我尝试创建自定义UITableViewCell并在UITableView中使用它时,事情就会变得混乱。 我相信这是因为我用来填充单元格的函数,在这个例子中它的名字是fillPlayerCellWithPlayer:。
我有一个玩家联系人的NSArray作为我的UITableView的数据源。 我的想法是用每个PlayerContact属性填充单元格的内容,如UILabels和UIImageViews等。 通常的做法是在cellForRowAtIndexPath中填充这些属性,如: tablecell.playerNameLabel.text = player.playerName
等。 但为了方便起见,我将其实现如下,我将在后面说明如下:
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *cellIdentifier = @"PlayerCellID";
AddPlayerObjectCell *tablecell = (AddPlayerObjectCell *)[tableView dequeueReusableCellWithIdentifier:cellIdentifier];
NSArray * chosenPlayerArray = [self generatePlayersArrayForCategoryRow:selectedCategoryIndexRow];
NSMutableDictionary * dict = (NSMutableDictionary *)[chosenPlayerArray objectAtIndex:indexPath.row];
PlayerContact * player = (PlayerContact *)[dict objectForKey:@"sgfPlayer"];
[tablecell fillPlayerCellWithPlayer:player];
return tablecell;}
为了解释为什么我不使用常规练习方法,首先让我分享fillPlayerCellWithPlayer函数:
- (void) fillPlayerCellWithPlayer : (PlayerContact *) player {
[self createGestureRegocnizer];
myPlayer = player; //this sets the player as the private variable of AddPlayerObjectCell class
cellItemLabel.text = myPlayer.playerName;
cellItemSubLabel.text = myPlayer.playerTeam;
UIImage * img = [UIImage imageNamed:@"messi.JPG"];
cellItemImageView.image = img; }
- (void) createGestureRegocnizer{
UITapGestureRecognizer *gesture = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(handleTapFrom)];
gesture.delegate = self;
[self addGestureRecognizer:gesture];}
- (void) handleTapFrom{
NSString * imageName = @"unselected_user_icon.png";
NSString * imageNameSelected = @"selected_user_icon.png";
if(playerSelected){
playerSelected = NO;
myPlayer.playerSelected = playerSelected;
[cellItemSelectionImageView setImage:[UIImage imageNamed:imageName]];}
else{
playerSelected = YES;
myPlayer.playerSelected = playerSelected;
[cellItemSelectionImageView setImage:[UIImage imageNamed:imageNameSelected]];}}
正如您所看到的,当用户触摸单元格时, handleTapFrom
会触发,我可以更改myPlayer的playerSelected
属性,以便稍后我可以使用此信息来过滤我选择的玩家的主阵列。
我的一个问题是,每当我在玩家的桌面视图中滑动手指时,他们选择的选中标记就会变得像疯了一样。 我想这是由于我以错误的方式使用可重用单元逻辑引起的。 如果你们能给我一个正确的方法,我会非常高兴。
我的第二个问题对我来说更重要,因为如果你们说的是真的,我想在整个应用程序设计中使用它作为一般逻辑。 假设我将名为playersArray的NSArray传递给tableview作为数据源。 并且单元类更改了与其indexPath对应的playersArray对象。 在我的控制器类和可以访问playersArray的类中,观察到了这种变化。 这对我来说是个好消息,因为我不需要复制数组并相应地更改其内容。 你认为这对UITableViewCell更改其UITableView的DataSource内容是一个好习惯吗? 或者是UITableViewCell唯一可以根据需要显示单元格的工作? 我应该以其他方式实现吗? 像委托或其他什么,如果我想更新数据源?
非常感谢你提前。 无论如何,如果你们需要我,我可以更加清楚。
Aytunçİşseven
通常,您应该避免Cell正在持有数据模型并操纵它们。 您还应该避免多次创建和添加此手势识别器(如果您调用fillPlayerCellWithPlayer将会发生这种情况:并且重复使用该单元格)。 这将增加敲击识别器的数量,并且每个将触发敲击。 相反,你可以覆盖
- (void)setSelected:(BOOL)selected animated:(BOOL)animated
在UITableViewCell上处理您的选择。 每次更改UITableViewCell的选择状态时都会触发此操作。 您应该只更改单元格的视觉外观,因为单元格不应该保持播放器对象。
要处理选择播放器,只需实现UITableViewDelegate方法(在控制器上)
- (NSIndexPath *)tableView:(UITableView *)tableView willSelectRowAtIndexPath:(NSIndexPath *)indexPath
并在那里处理数据模型的操作。
原因是:
UITableViewCell是一个视图,遵循模型 - 视图 - 控制器模式(Appkit所基于的),视图应该只代表模型而不管理它。 控制器(实现UITableViewDelegate - 例如UIViewController)是这两者之间的连接器,应该是管理模型信息而不是您建议的视图的连接器。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.