简体   繁体   English

iOS表格视图-在单元格或标签上设置标签?

[英]iOS Table View - Set tag on cell or label?

I'm a newbie to iOS development. 我是iOS开发的新手。 Currently learning by following tutorials from iOS Apprentice by Matthijs Hollemans. 当前正在按照Matthijs Hollemans的iOS Apprentice教程进行学习。 I'm using Xcode 6 and Objective-C to make the tutorial apps. 我正在使用Xcode 6和Objective-C制作教程应用程序。

In the book's second tutorial, he teaches his readers how to build a to-do-list app with table views, navigation controllers, etc. 在本书的第二篇教程中,他教他的读者如何使用表视图,导航控制器等构建待办事项应用程序。

In the beginning: A custom Label with the text "Label" is placed in the prototype cell of the table. 首先,在表的原型单元格中放置一个带有文本“ Label”的自定义标签。 On running the app at this point, "Label" shows up in the app, as expected. 此时,在运行该应用程序时,将按预期在应用程序中显示“标签”。

To display custom text in the table view, he asks the readers to set the 'Tag' identifier for the Label and then display custom text using the 'Tag' as shown in the code below. 为了在表格视图中显示自定义文本,他要求读者设置标签的“标签”标识符,然后使用“标签”显示自定义文本,如下代码所示。 This leads to abnormal behaviour. 这会导致异常行为。

What this does is that it displays "Label" on launching the app. 它的作用是在启动应用程序时显示“标签”。 However, on scrolling the text off the screen and then back on the screen, the custom text shows up. 但是,从屏幕上滚动文本然后再回到屏幕上时,将显示自定义文本。

To resolve this, instead of setting the 'Tag' identifier on the Label, I set it on the Table View Cell, in spite of the Author of the book specifically warning against doing this. 为了解决这个问题,尽管书的作者特别警告不要这样做,但我没有在标签上设置“标签”标识符,而是在表视图单元格上进行了设置。 I also had to remove the default text "Label" from the Label in the table view so that the custom text and "Label" don't overlap. 我还必须从表视图的“标签”中删除默认文本“标签”,以使自定义文本和“标签”不重叠。

This fixed the problem, but now I'm confused as to what is the correct protocol to follow for setting the 'Tag' identifier when it comes to using table views. 这解决了问题,但是现在我对于使用表视图时设置“ Tag”标识符应遵循的正确协议感到困惑。 Should the 'Tag' be set on Table View Cell or the Label? 应该在表格视图单元格还是标签上设置“标签”? If it should be set on the Label then what could be the reason for me to run into this problem? 如果应该在标签上设置它,那么我可能会遇到这个问题的原因是什么?

Here's the code for the main ViewController.m 这是主ViewController.m的代码

#import "ViewController.h"
#import "ChecklistItem.h"

@interface ViewController ()

@end

@implementation ViewController

{
    NSMutableArray * _items;
}

- (void)viewDidLoad {

    [super viewDidLoad];

    _items = [[NSMutableArray alloc] initWithCapacity:20];

    ChecklistItem * item;

    item = [[ChecklistItem alloc]init];
    item.text = @"Walk the dog";
    item.checked = NO;
    [_items addObject:item];

    item = [[ChecklistItem alloc]init];
    item.text = @"Brush teeth";
    item.checked = NO;
    [_items addObject:item];

    item = [[ChecklistItem alloc]init];
    item.text = @"Prepare breakfast";
    item.checked = NO;
    [_items addObject:item];

    item = [[ChecklistItem alloc]init];
    item.text = @"Soccer practice";
    item.checked = NO;
    [_items addObject:item];

    item = [[ChecklistItem alloc]init];
    item.text = @"Eat ice cream";
    item.checked = NO;
    [_items addObject:item];

}

- (void)didReceiveMemoryWarning {

    [super didReceiveMemoryWarning];

}

//data source method no.1 to get the number of rows in section for the table view
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {

    return [_items count];

}

- (void)configureCheckmarkForCell:(UITableViewCell *)cell withChecklistItem:(ChecklistItem *) item {

    //if the item is checked, display checkmark
    if (item.checked) {

        cell.accessoryType = UITableViewCellAccessoryCheckmark;

    } else {

        cell.accessoryType = UITableViewCellAccessoryNone;

    }

}


- (void)configureTextForCell:(UITableViewCell *)cell withChecklistItem:(ChecklistItem *) item {

    UILabel * label = (UILabel *)[cell viewWithTag:1000];
    label.text = item.text;

}


//data source mathod no.2 to get the cell to display the row in the given index path
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {

    UITableViewCell * cell = [tableView dequeueReusableCellWithIdentifier:@"ChecklistItem"];

    ChecklistItem * item = _items[indexPath.row];

    [self configureTextForCell:cell withChecklistItem:item];
    [self configureCheckmarkForCell:cell withChecklistItem:item];

    return cell;

}


//delegate method to handle taps on rows
- (void) tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {

    UITableViewCell * cell = [tableView cellForRowAtIndexPath:indexPath];

    ChecklistItem * item = _items[indexPath.row];

    [item toggleChecked];

    [self configureCheckmarkForCell:cell withChecklistItem:item];

    [tableView deselectRowAtIndexPath:indexPath animated:YES];

}

@end

I'm not familiar with the tutorial, but using tags to identify labels within cells this way is not a good idea. 我对本教程不熟悉,但是以这种方式使用标签标识单元格中的标签不是一个好主意。

The cell should know about it's own label. 单元格应该知道它自己的标签。 It's far better to just have a method on the cell that you can pass the text to, and then let the cell take care of displaying the text in the cell. 最好是在单元格上有一个可以传递文本的方法,然后让该单元格负责在单元格中显示文本。

By using the tag in this way, you are expecting to know too much about the internal implementation of the cell, and this is brittle and is likely to break. 通过以这种方式使用标记,您期望对单元的内部实现了解太多,这很脆弱并且很可能会中断。

So my answer is to set the tag on neither of them, and to use a proper configuration method of the cell itself. 因此,我的答案是在这两个标签上均未设置标签,并使用单元格本身的正确配置方法。

Edited to add 编辑添加

You can download a simple version of a project for configuring a cell, without using tags here https://bitbucket.org/abizern/so-27713743/get/543739690dc4.zip 您可以在不使用标签的情况下下载用于配置单元的项目的简单版本https://bitbucket.org/abizern/so-27713743/get/543739690dc4.zip

An alternative way to solve this is to not deal with a view tag at all, but create a subclass of UITableViewCell and design your layout with this subclass. 解决此问题的另一种方法是根本不处理视图标签,而是创建UITableViewCell的子类并使用此子类设计布局。 When you dequeue the cell in tableView: cellForRowAtIndexPath: or get the cell in tableView:didSelectRowAtIndexPath , use your subclass for the cell. 当您使tableView: cellForRowAtIndexPath:的单元出队时,或获取tableView:didSelectRowAtIndexPath的单元时,请对该单元使用子类。

For example, create a subclass of UITableViewCell and give it a label as a property. 例如,创建UITableViewCell的子类并为其提供标签作为属性。 If you're using xib's or storyboard, attach this label as an outlet. 如果您使用的是xib或情节提要,请将此标签粘贴为插座。 Then you can access that label directly as you would any other property. 然后,您可以像访问其他任何属性一样直接访问该标签。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM