[cell viewWithTag:]中的标签始终返回为nil

时间:2015-01-07 08:31:32

标签: ios objective-c ios8

我在这个基本的东西上挣扎超过一天,它让我发疯!有趣的是,我在其他屏幕上有非常相似的东西,它工作得很好!我这样做了一千次,但从来没有经历过这么奇怪的事情。也许只是iOS 8中的这种行为?

在我非常简单的Prototype单元格中,我有两个带有标签102和103的标签。但是当我想为它们设置文本时,它们总是为零。

我已经仔细检查过标识符是否正确,并且该标记与Storyboard中的标记相同。

-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    NSString * identifier = @"secondReusableIdentifier";
    UITableViewCell *cell = (UITableViewCell *)[tableView dequeueReusableCellWithIdentifier:identifier];
    if (cell == nil){
        cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:identifier];
    }

    for (UIView *subview in [cell subviews]) {
        NSLog(@"subview: %lu", subview.tag); // prints 0
    }

    UILabel * label1 = (UILabel *)[cell viewWithTag:102]; // returns nil
    UILabel * label2 = (UILabel *)[cell viewWithTag:103]; // returns nil
    if (self.items.count) {
        MyObject *obj = [self.items objectAtIndex:indexPath.row];
        label1.text = obj.someProperty;
        fuelPrice2.text = obj.someOtherProperty;
        }
    }
    return cell;

任何建议都将不胜感激。

3 个答案:

答案 0 :(得分:2)

在您的代码中,您正在创建一个新单元格,它与您在Storyboard中的单元格不同。

更改此选项:这是旧方法,或者您通过代码或笔尖使用单元格时使用的方式,并且您不使用故事板。这段代码意味着。

      NSString * identifier = @"secondReusableIdentifier";
// If I have available a cell with this identifier: secondReusableIdentifier, let's go to use it.
UITableViewCell *cell = (UITableViewCell *)[tableView dequeueReusableCellWithIdentifier:identifier];
if (cell == nil){
 // If not, we create a new cell with this identifier. This methods is previous to storyboard, and this methods create a new cell, but does´t look in Storyboard if this identifier exist, or something like that.

    cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:identifier];
}

另一方面,当Apple推出故事板时,框架会以这种方式增长,这样就可以了:如果有一个单元格可以自由使用它,如果没有,它会在Storyboard中查找具有此标识符的单元格并创建一个带有此信息的新单元格。 (您也可以通过代码和nib文件使用此方法,但您必须在...之前注册该类。)。

 // Be sure than: "secondReusableIdentifier", it's its identifier in storyboard
  UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"secondReusableIdentifier" forIndexPath:indexPath];

答案 1 :(得分:1)

取而代之:

NSString * identifier = @"secondReusableIdentifier";
UITableViewCell *cell = (UITableViewCell *)[tableView dequeueReusableCellWithIdentifier:identifier];
if (cell == nil){
    cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:identifier];
}

UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"secondReusableIdentifier" forIndexPath:indexPath];
  

用于创建单元格将解决您的问题,因为它始终返回一个单元格。它要么重新使用现有单元格,要么创建一个新单元格,如果没有单元格则返回。

最重要的区别是,如果您没有为标识符注册类或nib,则forIndexPath:版本会崩溃。在这种情况下,较旧的(非forIndexPath :)版本返回nil。

您必须注册一个类或nib才能使用它。但是如果您在故事板中创建表格视图和单元格原型,则故事板加载器会负责注册您在故事板中定义的单元格原型。

希望这会有所帮助.. :)

答案 2 :(得分:0)

如果

for (UIView *subview in [cell subviews]) {
    NSLog(@"subview: %lu", subview.tag); // prints 0
}

打印0,为什么这样做?

UILabel * label1 = (UILabel *)[cell viewWithTag:102];
UILabel * label2 = (UILabel *)[cell viewWithTag:103];

因此,如果您使用IB创建了自定义单元格,则必须创建自定义类并使用它而不是简单的UITableViewCell