正确的方法将标签设置为TableView中的所有单元格 [英] Correct way to setting a tag to all cells in TableView

查看:167
本文介绍了正确的方法将标签设置为TableView中的所有单元格的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在 tableView 中使用了一个按钮,按下时我得到 indexPath.row 。但它只能在没有滚动的情况下在屏幕上显示单元格时才能正常工作。

I'm using a button inside a tableView in which I get the indexPath.row when is pressed. But it only works fine when the cells can be displayed in the screen without scroll.

一旦tableView可以我可以滚动浏览桌面视图,返回的 indexPath.row 是一个错误的值,我注意到最初设置了20个对象,例如 Check 只打印了9次没有20。

Once the tableView can be scrolleable and I scrolls throught the tableview, the indexPath.row returned is a wrong value, I noticed that initially setting 20 objects, for example Check is just printed 9 times no 20.

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
   UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
   if (cell == nil) {
       cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];

       lBtnWithAction = [[UIButton alloc] initWithFrame:CGRectMake(liLight1Xcord + 23, 10, liLight1Width + 5, liLight1Height + 25)];
       lBtnWithAction.tag = ROW_BUTTON_ACTION;
       lBtnWithAction.titleLabel.font = luiFontCheckmark;
       lBtnWithAction.tintColor = [UIColor blackColor];
       lBtnWithAction.autoresizingMask = UIViewAutoresizingFlexibleLeftMargin;
       [cell.contentView addSubview:lBtnWithAction];
   }
   else 
   { 
       lBtnWithAction = (UIButton *)[cell.contentView viewWithTag:ROW_BUTTON_ACTION];
   }

//Set the tag
lBtnWithAction.tag = indexPath.row;
//Add the click event to the button inside a row
[lBtnWithAction addTarget:self action:@selector(rowButtonClicked:) forControlEvents:UIControlEventTouchUpInside];

//This is printed just 9 times (the the number of cells that are initially displayed in the screen with no scroll), when scrolling the other ones are printed
NSLog(@"Check: %li", (long)indexPath.row);

return cell;
}

使用点击的索引执行某些操作:

To do something with the clicked index:

-(void)rowButtonClicked:(UIButton*)sender
{
    NSLog(@"Pressed: %li", (long)sender.tag);
}

Constants.h

Constants.h

#define ROW_BUTTON_ACTION 9

什么是正确的方法在 rowButtonClicked 中获取 indexPath.row 或在我的<$ c中包含大量单元格时设置标记$ c> tableView ?

What is the correct way to get the indexPath.row inside rowButtonClicked or setting a tag when I have a lot of of cells in my tableView?

推荐答案

我对这类问题的解决方法是不使用标签以这种方式。这是对标签的完全滥用(在我看来),并且很可能会引发麻烦(正如您所发现的那样),因为细胞被重复使用。

My solution to this kind of problem is not to use a tag in this way at all. It's a complete misuse of tags (in my opinion), and is likely to cause trouble down the road (as you've discovered), because cells are reused.

通常,正在解决的问题是:单元格中的一个界面与用户进行交互(例如,点击一个按钮),现在我们想要知道该单元格当前对应的行我们可以对相应的数据模型做出回应。

Typically, the problem being solved is this: A piece of interface in a cell is interacted with by the user (e.g. a button is tapped), and now we want to know what row that cell currently corresponds to so that we can respond with respect to the corresponding data model.

我在我的应用程序中解决这个问题的方法是,当按下按钮或其他任何东西时,我收到一个控制事件或者从它委托事件,从界面的那一部分(按钮或其他)走向视图层次结构,直到我来到单元格,然后调用表视图的 indexPath(for :) ,它接受一个单元格并返回相应的索引路径。控制事件或委托事件总是将接口对象作为参数包含在内,因此很容易从该对象到单元格以及从那里到行。

The way I solve this in my apps is, when the button is tapped or whatever and I receive a control event or delegate event from it, to walk up the view hierarchy from that piece of the interface (the button or whatever) until I come to the cell, and then call the table view's indexPath(for:), which takes a cell and returns the corresponding index path. The control event or delegate event always includes the interface object as a parameter, so it is easy to get from that to the cell and from there to the row.

因此,例如:

UIView* v = // sender, the interface object
do {
    v = v.superview;
} while (![v isKindOfClass: [UITableViewCell class]]);
UITableViewCell* cell = (UITableViewCell*)v;
NSIndexPath* ip = [self.tableView indexPathForCell:cell];
// and now we know the row (ip.row)






[注意一种可能的替代方法是使用自定义单元子类,在该子类中有一个特殊属性,您可以将行存储在 cellForRowAt中。但在我看来这完全没必要,因为 indexPath(for :) 为您提供完全相同的信息!另一方面,页眉/页脚没有 indexPath(for :) ,所以在这种情况下我使用存储节号的自定义子类,如这个例子(参见 viewForHeaderInSection 的实现)。]


[NOTE A possible alternative would be to use a custom cell subclass in which you have a special property where you store the row in cellForRowAt. But this seems to me completely unnecessary, seeing as indexPath(for:) gives you exactly that same information! On the other hand, there is no indexPath(for:) for a header/footer, so in that case I do use a custom subclass that stores the section number, as in this example (see the implementation of viewForHeaderInSection).]

这篇关于正确的方法将标签设置为TableView中的所有单元格的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆