我是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
答案 0 :(得分:3)
我不熟悉本教程,但使用标签以这种方式识别单元格内的标签并不是一个好主意。
细胞应该知道它自己的标签。在单元格上有一个可以传递文本的方法,然后让单元格负责在单元格中显示文本,这样做要好得多。
通过这种方式使用标签,您可能希望对单元的内部实现了解太多,而且这很脆弱,可能会破坏。
所以我的答案是不在它们上面设置标签,并使用单元本身的正确配置方法。
已编辑添加
您可以下载用于配置单元格的简单版本的项目,而无需在此处使用代码https://bitbucket.org/abizern/so-27713743/get/543739690dc4.zip
答案 1 :(得分:2)
解决此问题的另一种方法是根本不处理视图标记,而是创建UITableViewCell的子类并使用此子类设计布局。当您在tableView: cellForRowAtIndexPath:
中将单元格出列或在tableView:didSelectRowAtIndexPath
中获取单元格时,请使用您的子类作为单元格。
例如,创建UITableViewCell的子类并为其指定标签作为属性。如果您使用的是xib或故事板,请将此标签作为插座附加。然后,您可以像访问任何其他财产一样直接访问该标签。