这对我来说真的很有用,因为我一直在努力解决这个问题。每次我尝试创建自定义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
属性,以便稍后我可以使用此信息过滤我的主阵列以供选定的玩家使用
我的一个问题是,每当我在玩家的桌面视图中滑动手指时,他们选择的选中标记就会变得像疯了一样。我想这是由于我以错误的方式使用可重用单元逻辑引起的。如果你们能给我一个正确的方法,我会非常高兴。
我的第二个问题对我来说更重要,因为如果你们说的是真的,我想在整个app设计中将它作为一般逻辑使用。假设我将名为playersArray的NSArray传递给tableview作为数据源。并且单元类更改了与其indexPath对应的playersArray对象。在我的控制器类和可以访问playersArray的类中,观察到了这种变化。这对我来说是个好消息,因为我不需要复制数组并相应地更改其内容。你认为这对UITableViewCell更改其UITableView的DataSource内容是一个好习惯吗?或者是UITableViewCell唯一可以根据需要显示单元格的工作?我应该以其他方式实现吗?像委托或其他什么,如果我想更新数据源?
非常感谢您提前。无论如何,如果你们需要我,我可以更加清楚。
Aytunçİşseven
答案 0 :(得分:2)
通常,您应该避免Cell正在持有数据模型并操纵它们。你也应该避免创建&多次添加此手势识别器(如果您调用fillPlayerCellWithPlayer将会发生这种情况:并且重复使用该单元格)。这将增加敲击识别器的数量,并且每个将触发敲击。相反,你可以覆盖
- (void)setSelected:(BOOL)selected animated:(BOOL)animated
在UITableViewCell上并在那里处理您的选择。每次更改UITableViewCell的选择状态时都会触发此操作。您应该只更改单元格的视觉外观,因为单元格不应该保持播放器对象。
要处理选择播放器,只需实现UITableViewDelegate方法(在控制器上)
- (NSIndexPath *)tableView:(UITableView *)tableView willSelectRowAtIndexPath:(NSIndexPath *)indexPath
并在那里处理数据模型的操作。
原因是:
UITableViewCell是一个视图,遵循模型 - 视图 - 控制器模式(Appkit所基于的),视图应该只代表模型而不管理它。控制器(实现UITableViewDelegate - 例如UIViewController)是这两者之间的连接器,应该是管理模型信息而不是你建议的视图的连接器。