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

时间:2014-12-30 22:53:37

标签: ios objective-c uitableview xcode6

我是iOS开发的新手。目前正在通过Matthijs Hollemans的iOS Apprentice教程学习。我正在使用Xcode 6和Objective-C来制作教程应用程序。

在本书的第二篇教程中,他教导读者如何使用表格视图,导航控制器等构建待办事项列表应用程序。

一开始: 带有文本“Label”的自定义标签放置在表格的原型单元格中。在此时运行应用程序时,“标签”会按预期显示在应用程序中。

要在表格视图中显示自定义文字,他会要求读者设置标签的“标签”标识符,然后使用“标签”显示自定义文字,如下面的代码所示。这会导致异常行为。

这样做是在启动应用时显示“标签”。但是,在屏幕上滚动文本然后再返回屏幕时,会显示自定义文本。

要解决这个问题,我不是在Label上设置'Tag'标识符,而是在Table View Cell上设置它,尽管本书的作者特别警告不要这样做。我还必须从表视图中的Label中删除默认文本“Label”,以便自定义文本和“Label”不重叠。

这解决了这个问题,但现在我很困惑在使用表视图时设置'Tag'标识符时要遵循的正确协议是什么。是否应在表视图单元格或标签上设置“标记”?如果它应该在标签上设置那么我可能会遇到这个问题的原因是什么?

这是主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

2 个答案:

答案 0 :(得分:3)

我不熟悉本教程,但使用标签以这种方式识别单元格内的标签并不是一个好主意。

细胞应该知道它自己的标签。在单元格上有一个可以传递文本的方法,然后让单元格负责在单元格中显示文本,这样做要好得多。

通过这种方式使用标签,您可能希望对单元的内部实现了解太多,而且这很脆弱,可能会破坏。

所以我的答案是不在它们上面设置标签,并使用单元本身的正确配置方法。

已编辑添加

您可以下载用于配置单元格的简单版本的项目,而无需在此处使用代码https://bitbucket.org/abizern/so-27713743/get/543739690dc4.zip

答案 1 :(得分:2)

解决此问题的另一种方法是根本不处理视图标记,而是创建UITableViewCell的子类并使用此子类设计布局。当您在tableView: cellForRowAtIndexPath:中将单元格出列或在tableView:didSelectRowAtIndexPath中获取单元格时,请使用您的子类作为单元格。

例如,创建UITableViewCell的子类并为其指定标签作为属性。如果您使用的是xib或故事板,请将此标签作为插座附加。然后,您可以像访问任何其他财产一样直接访问该标签。