Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/flutter/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ios 使用autolayout将运行时的子视图添加到配置了xib的UITableviewCell中_Ios_Objective C_Uitableview_Autolayout - Fatal编程技术网

Ios 使用autolayout将运行时的子视图添加到配置了xib的UITableviewCell中

Ios 使用autolayout将运行时的子视图添加到配置了xib的UITableviewCell中,ios,objective-c,uitableview,autolayout,Ios,Objective C,Uitableview,Autolayout,有一个UITableview子类,它有*.xib文件,其中配置了autolayout(如下图所示,在xib中,所有依赖项都配置为2标签样式)。该单元可以像通常的autolayout单元一样动态计算其高度 但有一种情况,根据接收到的数据,标签的数量可能会有所不同,这取决于模型中的数据 有没有办法使用现有的自动布局系统将多个标签(3,5,n)作为子视图添加到单元中?这一点很重要,因为在使用.xib时,单元格不应失去自行计算其大小的能力。最安全、最省力、最高效的方法是使用不同的Resure标识符注册

有一个UITableview子类,它有*.xib文件,其中配置了autolayout(如下图所示,在xib中,所有依赖项都配置为2标签样式)。该单元可以像通常的autolayout单元一样动态计算其高度

但有一种情况,根据接收到的数据,标签的数量可能会有所不同,这取决于模型中的数据

有没有办法使用现有的自动布局系统将多个标签(3,5,n)作为子视图添加到单元中?这一点很重要,因为在使用.xib时,单元格不应失去自行计算其大小的能力。最安全、最省力、最高效的方法是使用不同的Resure标识符注册.xib。最好扫描您的模型,找出并注册您需要的模型(注册过多会出错;反之则会导致即时崩溃)。在子类中,重写
-initWithStyle:reuseIdentifier:
,并在那里进行设置

有几种方法可以进行设置

  • IB heavy:创建具有最大标签数的单元格。将它们彼此附加,并使用单独的约束将每个约束附加到单元格内容视图的底部,并按优先级对约束进行排序,1000是附加到底部的标签,没有移除任何约束,优先级从底部向下。然后删除
    -initWithStyle:reuseIdentifier:
    中不需要的标签;它们的约束将被删除,从而使下一个最低优先级生效
  • 循环:对于任意数字,您可以在
    -initWithStyle:reuseIdentifier:
    --循环编号的resuse标识符可以是
    +stringWithFormat
    ,这将允许您使用
    -intValue
    获取数字。但这可能太可爱了,因此您可能希望尝试创建一个带有NumberOfLabels的方法
    -formatWithNumberOfLabels
    ,并检查
    -didSetup
    标志 编辑:选项2比我想象的要麻烦得多。此示例是编程的,但您应该能够看到如何将其应用于.xibs。在细胞的注射中:

    -(id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier {
    
        self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
    
        if (self) {
            [self.contentView setTranslatesAutoresizingMaskIntoConstraints:NO];
    
            NSMutableDictionary *layoutDictionary = [[NSMutableDictionary alloc] init];
            NSMutableString *visualFormatLanguageString = [[NSMutableString alloc] init];
    
            NSInteger numberOfLabels = reuseIdentifier.integerValue; //This is not that safe, using below class method is the only way to make it safe to do this.
    
            for (int i = 0; i <= numberOfLabels; i++) {
                if (i == 0) {
                    [visualFormatLanguageString appendString:@"V:|-20-"];
                } else {
                    [visualFormatLanguageString appendString:@"-8-"];
                }
    
                UILabel *labelX = [[UILabel alloc] init];
                [labelX setTranslatesAutoresizingMaskIntoConstraints:NO];
    
                int tag = 1000 + i;
                labelX.tag = tag;
    
                NSString *labelXString = [NSString stringWithFormat:@"Label%i", tag];
                [layoutDictionary setObject:labelX forKey:labelXString];
                [visualFormatLanguageString appendString:[NSString stringWithFormat:@"[%@]", labelXString]];
    
                [self.contentView addSubview:labelX];
            }
            [visualFormatLanguageString appendString:@"-20-|"];
            [self.contentView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:visualFormatLanguageString
                                                                           options:NSLayoutFormatAlignAllLeading
                                                                           metrics:nil
                                                                             views:layoutDictionary]];
        }
        return self;
    }
    
    + (NSString*)reuseStringForNumber:(NSInteger)reuseNumber {
        return [NSString stringWithFormat:@"%li",(long) reuseNumber];
    }
    
    -(id)initWithStyle:(UITableViewCellStyle)样式重用标识符:(NSString*)重用标识符{
    self=[super-initWithStyle:style-reuseIdentifier:reuseIdentifier];
    如果(自我){
    [self.contentView setTranslatesAutoresizingMaskIntoConstraints:否];
    NSMutableDictionary*layoutDictionary=[[NSMutableDictionary alloc]init];
    NSMutableString*visualFormatLanguageString=[[NSMutableString alloc]init];
    NSInteger numberOfLabels=reuseIdentifier.integerValue;//这不是那么安全,使用类下方法是确保安全的唯一方法。
    
    对于(int i=0;i)您所说的“现有自动布局系统”是什么意思?您是指2标签单元格中的约束吗?如果是,答案是否,您需要更改这些约束。在运行时,当您获得数据时,您需要以编程方式向单元格添加n个标签,并添加至少2n个约束(但可能更多)谢谢你的努力,你的答案被提高了。事实上,这种方式看起来很粗糙,尤其是“你期望的最大标签”。我通过重新设计控件解决了这个问题。每个标签现在都显示在一个单独的单元格中。所有逻辑都被移到了viewcontroller中。这很公平。但这并不是一个真正的黑客行为,我可能已经提出了比必要时更强烈的观点,因为我已经被烧坏了:任何需要给系统一个值的地方,以及,单独的,更早或更晚的地方给系统同样的值——或者说即时保证崩溃——本质上是危险的,但这是在表视图的API设计中。不过,感谢您的后续反馈,祝您好运。
    - (void)viewDidLoad {
        [super viewDidLoad];
    
        for (NSInteger i = 0; i < 4; i++) {
            [self.tableView registerClass:[MultiLabelTableViewCell class] forCellReuseIdentifier:[MultiLabelTableViewCell reuseStringForNumber:i]];
        }
    
        self.tableView.estimatedRowHeight = 44;
    }
    
    - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    
        NSInteger cellNumber = indexPath.row % 4;
    
        MultiLabelTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:[MultiLabelTableViewCell reuseStringForNumber:cellNumber] forIndexPath:indexPath];
    
        for (int i = 0; i <= cellNumber; i++) {
            int tag = 1000 + i;
            [(UILabel *)[cell.contentView viewWithTag:tag] setText:[NSString stringWithFormat:@"Cell %i, label %i", indexPath.row, i]];
        }
    
        return cell;
    }