如何在 iOS 中管理自定义单元格标签值?

Posted

技术标签:

【中文标题】如何在 iOS 中管理自定义单元格标签值?【英文标题】:How to manage custom cell label value in iOS? 【发布时间】:2015-02-27 14:26:57 【问题描述】:

我正在使用故事板构建一个 ios 应用程序。我使用了 UITableViewController,它有 6 个自定义单元格,每个单元格包含三个 IBOutlet 按钮和一个 IBOutlet 标签。

当用户点击一个特定自定义单元格中的任何按钮时,只有该特定单元格标签的值应该改变。

但是发生的情况是,每个自定义单元格中所有标签的值都发生了变化。

这是我的代码:

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

    static NSString *Cellidentifier1 = @"List";
    Cell *cell1 = [tableView dequeueReusableCellWithIdentifier:Cellidentifier1 forIndexPath:indexPath];
     cell1.selectionStyle = UITableViewCellSelectionStyleNone;
    // Configure the cell...

    long row = [indexPath row];

    cell1.First.tag=row;//button iboutlet in cell
    cell1.Second.tag=row;//button iboutlet in cell
    cell1.Third.tag=row;//button iboutlet in cell

    cell1.Level.tag=row;

    cell1.Level.text=Skill;//label iboutlet in cell

    return cell1;
 


-(IBAction)FirstAction:(id)sender

     Skill=@"first";
     [self.tableView reloadData];



-(IBAction)SecondAction:(id)sender

     Skill=@"Second";
     [self.tableView reloadData];




-(IBAction)ThirdAction:(id)sender

     Skill=@"Third";
     [self.tableView reloadData];


【问题讨论】:

您在单击第一个操作时设置技能,然后重新加载表格并将每个单元格设置为具有技能中的值。您需要一系列技能。 @MikeTaverne 感谢您的回复,这不是我想要做的,因此通过单击标签的那些单元格值更改了单元格中的按钮,但现在它在所有单元格中都在更改,但我希望在用户单击时在特定单元格中的按钮上,然后该特定单元格的值标签发生更改。 我猜在某些时候你会想要对技能数据做一些事情,而不是显示它。如果您只关注显示问题,那么当您实际尝试使用从用户那里收集的信息时,您会感到失望。为了避免这种失望,您需要考虑如何正确使用表视图。我在这里的回答可能会有所帮助:***.com/questions/28036277/… 【参考方案1】:

几个问题:

    您应该有一个模型来反映您的表格视图中的内容。具体来说,现在您只有一个 Skill 值,但您有六行。您想要维护一个包含值数组的模型,例如:

    @property (nonatomic, strong) NSMutableArray *values;
    

    - (void)viewDidLoad 
        [super viewDidLoad];
    
        self.values = [@[@"first", @"first", @"first", @"first", @"first", @"first"] mutableCopy];
    
    

    - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath 
    
        static NSString *Cellidentifier1 = @"List";
        Cell *cell = [tableView dequeueReusableCellWithIdentifier:Cellidentifier1 forIndexPath:indexPath];
    
        NSString *value = self.values[indexPath.row];
    
        cell.level.text = value;
    
        return cell;
    
    

    注意,不需要标签号。

    当您点击一个按钮时,您必须 (a) 确定表中对应的行; (b) 更新模型中的该行; (c) 重新加载表中的单行(这将在模型中查找值):

    - (void)updateCell:(UIView *)cell withValue:(NSString *)value 
        NSParameterAssert(cell);
    
        NSIndexPath *indexPath = [self.tableView indexPathForCell:(UITableViewCell *)cell];
        if (cell) 
            self.values[indexPath.row] = value;
            [self.tableView reloadRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationFade];
        
    
    
    - (IBAction)didTapFirstButton:(id)sender 
        [self updateCell:[[sender superview] superview] withValue:@"first"];
    
    
    - (IBAction)didTapSecondButton:(id)sender
        [self updateCell:[[sender superview] superview] withValue:@"second"];
    
    
    - (IBAction)didTapThirdButton:(id)sender
        [self updateCell:[[sender superview] superview] withValue:@"third"];
    
    

    注意,sender 是按钮。所以我通过抓取superview(这是单元格的内容视图)然后抓取它的superview(单元格本身)来获取表格视图单元格。如果您的视图层次结构不同,请酌情更改它,但希望这能说明这个想法。

【讨论】:

嗨@Rob你能帮我吗?我想增加在特定单元格中单击的按钮的大小,并尝试在单击按钮时更新按钮的CGRect,但这不起作用。 答案有点复杂(这取决于你的 iOS 版本、是否使用自动布局、按钮是否配置为将其框架转换为约束等) .最好在新的 Stack Overflow 问题中布置所有细节。【参考方案2】:

首先你要做的就是在选择行时使用委托方法selectRowAtIndexPath然后可以使用indexPath选择的行按钮...

func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath)

 

选择行时,将执行所需的行按钮功能

【讨论】:

【参考方案3】:

试试下面的代码。

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

    static NSString *Cellidentifier1 = @"List";
    Cell *cell1 = [tableView dequeueReusableCellWithIdentifier:Cellidentifier1 forIndexPath:indexPath];
     cell1.selectionStyle = UITableViewCellSelectionStyleNone;
    // Configure the cell...

    long row = [indexPath row];

    cell1.First.tag=row;//button iboutlet in cell
    cell1.Second.tag=row;//button iboutlet in cell
    cell1.Third.tag=row;//button iboutlet in cell

    cell1.Level.tag=row;

    cell1.Level.text=Skill;//label iboutlet in cell
[cell1.First addTarget:self action:@selector(FirstAction:) forControlEvents:UIControlEventTouchUpInside];
[cell1.Second addTarget:self action:@selector(SecondAction:) forControlEvents:UIControlEventTouchUpInside];
[cell1.Third addTarget:self action:@selector(ThirdAction:) forControlEvents:UIControlEventTouchUpInside];

    return cell1;
 

【讨论】:

感谢@Dipel 我应用了您的代码,但结果相同。【参考方案4】:

在您的 IBOutlet 方法中添加此项以查找行的 indexPath

CGPoint hitPoint = [sender convertPoint:CGPointZero toView:self.tableView];
NSIndexPath *hitIndex = [self.tableView indexPathForRowAtPoint:hitPoint];

您只想在指定的indexPath处重新加载该单元格的文本,而不是重新加载整个表格视图

要仅重新加载一个单元格,请执行 此操作而不是 [self.tableView reloadData];

[self.tableView reloadRowsAtIndexPaths:@[hitIndex] withRowAnimation:UITableViewRowAnimationNone];

【讨论】:

【参考方案5】:

有几种方法可以做到这一点。但是,通过查看您的代码,我会确保您从您选择的单元格中获得正确的 indexPath。假设您已经设置了目标操作,您可以像这样重写您的 IBAction 方法:

-(IBAction)firstAction:(UIButton *)sender
    int row = sender.tag;
    NSIndexPath *indexPath = [NSIndexPath indexPathForItem:row inSection:0];
    Cell *cell = [self.tableView cellForRowAtIndexPath:indexPath];
    Skill = @"first";
    [self.tableView reloadRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationNone];

这将获得正确的单元格和索引路径。仅更新该单元格的标签,然后重新加载它。

【讨论】:

感谢回复@Alex int row = sender.tag;在这里它给出了错误属性 'tag' not found on object of type '__strong id' 您必须将方法签名中的 id 更改为 UIButton * ,即 -(IBAction)firstAction:(UIButton *)sender,因为 id 没有标签 不要只更新单元格上的标签。更新支持 tableview 的模型(这意味着更改模型以便跟踪表中每一行的状态),然后重新加载单元格。这很关键。如果您只更新单元格标签,如果单元格滚动到视图之外并被重新用于表格的另一行,您将失去用户所做的事情。

以上是关于如何在 iOS 中管理自定义单元格标签值?的主要内容,如果未能解决你的问题,请参考以下文章

如何在swift ios中的自定义TableView单元格中显示多个字符串值到多个标签?

如何固定表格视图中自定义单元格文本字段的标签值?

具有动态标签高度的 IOS Tableview 自定义单元格

填充 UITableViewController 时,自定义单元格中的标签为空

iOS:如何从 tableview 的自定义单元格中的 UITextField 访问值

IOS:在某些类中使用自定义单元格