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

Ios [cell viewWithTag:]中的标签始终返回为nil,ios,objective-c,ios8,Ios,Objective C,Ios8,我为这件基本的事情挣扎了一天多,它让我发疯!有趣的是,我在另一个屏幕上有非常相似的东西,它工作得很好!我已经做过一千次了,但从未经历过如此奇怪的事情。也许这只是iOS 8中的行为 在我非常简单的原型电池上,我有两个标签,标签是102和103。但是当我想给它们设置文本时,它们总是为零 我仔细检查了标识符是否正确,标记是否与脚本中的相同 -(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIn

我为这件基本的事情挣扎了一天多,它让我发疯!有趣的是,我在另一个屏幕上有非常相似的东西,它工作得很好!我已经做过一千次了,但从未经历过如此奇怪的事情。也许这只是iOS 8中的行为

在我非常简单的原型电池上,我有两个标签,标签是102和103。但是当我想给它们设置文本时,它们总是为零

我仔细检查了标识符是否正确,标记是否与脚本中的相同

-(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;
如有任何建议,将不胜感激。

如果

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

,因为您正在创建一个新单元格,它与脚本中的单元格不同

-(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;
改变这一点:这是旧的方式,或者当单元格是按代码或笔尖,而不使用故事板时使用的方式。这个代码的意思是

      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];
}
另一方面,当苹果公司发布故事板时,框架以这种方式增长:如果有一个无单元,就使用它,如果没有,就在故事板中查找具有此标识符的单元,并使用此信息创建一个新单元。(您也可以通过代码和nib文件使用此方法,但必须在…)之前注册该类

替换此:

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];
因为创建一个单元格将解决您的问题,因为它总是返回一个单元格。它或者重新使用现有的单元格,或者创建一个新的单元格,如果没有单元格,则返回

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

您必须注册一个类或nib才能使用它。但是,如果在情节提要中创建表视图和单元原型,则情节提要加载程序将负责注册在情节提要中定义的单元原型

-(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;

希望这有帮助:)

在原型单元内的故事板中,在哪里添加label1和label2?以及相应的标记。由于
UITableViewCell
一直在重复使用,因此您不能依赖该标记。您应该使用
UILabel
属性创建一个自定义的
UITableViewCell
类。但是,对于不同的项目,即使是在同一个应用程序中,但在不同的屏幕上,同样的事情对我来说已经很长时间了?无论如何,我会试试的,我会让你知道的,谢谢!尽管您可能已经这样做了一百万次,我也向您保证,您可能在故事板和代码中都有不同的重用标识符,因此值得仔细检查以确保它们确实相同。容易犯错误。我使用的是原型单元,所以不需要自定义类。。。它不应该打印0,这就是重点。如上所述,相同的方法适用于不同的UIViewController。它有效!但是怎么做呢?你能更深入地解释一下这里的重点是什么吗?好的,我将在我的回答中稍微解释一下。