【问题标题】:How to use masonry create dynamic height cell,the layout is mix when scroll the tableview如何使用砌体创建动态高度单元格,滚动表格视图时布局混合
【发布时间】:2016-08-10 04:10:41
【问题描述】:

在 ViewController 中,我捕获单元格高度并在每个 indexPath 处设置行的动态高度

-(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{
     PFBubbleData *dataModel = (PFBubbleData *)self.dataSource[indexPath.row];
     PFBubbleLayout *layout = dataModel.layout;
     return layout.bubbleHeight;
}

并从单元队列中获取单元格并使用包含布局模型的 dataModel 对其进行更新

-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
     PFBubbleCell *cell = [tableView dequeueReusableCellWithIdentifier:@"PFBubbleCell"];
     [cell updateViewWithData:self.dataSource[indexPath.row]];
     return cell;
}

在创建cell的时候,给contentView添加子视图,(每个子视图在getMethod中已经创建好了,这里直接添加子视图)

-(instancetype)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier{
    LOG_METHOD
    self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
    if (self) {
        self.contentView.translatesAutoresizingMaskIntoConstraints = NO;

        self.contentView.backgroundColor = [UIColor colorWithRed:0.224 green:0.671 blue:1.000 alpha:1.000];

        [self.contentView addSubview:self.faceImageView];
        [self.contentView addSubview:self.containerView];
    }
    return self;
}

最后,当我将 dataModel 设置到单元格时,我会更新子视图,并使用砌体布局子视图

-(void)updateViewWithData:(id)dataEntity {
    LOG_METHOD
    self.dataModel = (PFBubbleData*)dataEntity;
    //update the subeViewFrame is Needed after the data changed
    [self.faceImageView setImage:self.dataModel.avatarImage];
    [self setupFrameAndConstraints];
}

砌体布局如下

-(void)setupFrameAndConstraints {
[self.contentView mas_makeConstraints:^(MASConstraintMaker *make) {
    make.edges.equalTo(self).insets(UIEdgeInsetsMake(0, 0, 0, 0));
}];

if (self.dataModel.bubbleDirection == PFBubbleDirection_Other) {
    //                self.avaterImageView.frame = CGRectMake(self.dataModel.layout.board_margin,
    //                                                        self.dataModel.layout.board_margin, 50, 50);
    //                self.containerView.frame = CGRectMake(CGRectGetMaxX(self.avaterImageView.frame) + self.dataModel.layout.board_margin,
    //                                                      CGRectGetMinY(self.avaterImageView.frame),
    //                                                      self.dataModel.layout.contentSize.width,
    //                                                      self.dataModel.layout.contentSize.height);

        [self.faceImageView mas_updateConstraints:^(MASConstraintMaker *make) {
            make.top.equalTo(self.contentView.mas_top).offset(contentMargin);
            make.left.equalTo(self.contentView.mas_left).offset(contentMargin);
            make.width.mas_equalTo(@(50));
            make.height.mas_equalTo(@(50));
        }];

        [self.containerView mas_updateConstraints:^(MASConstraintMaker *make) {
            make.top.equalTo(self.faceImageView.mas_top);
            make.left.equalTo(self.faceImageView.mas_right).offset(contentMargin);
            make.width.mas_equalTo(self.dataModel.layout.contentSize.width);
            make.bottom.mas_equalTo(self.contentView.mas_bottom).offset(-contentMargin);
        }];
    }else if(self.dataModel.bubbleDirection == PFBubbleDirection_Self){
    //                self.avaterImageView.frame = CGRectMake(self.frame.size.width - self.dataModel.layout.board_margin - 50,
    //                                                        self.dataModel.layout.board_margin, 50, 50);
    //
    //                self.containerView.frame = CGRectMake(CGRectGetMinX(self.avaterImageView.frame) - self.dataModel.layout.board_margin - self.dataModel.layout.contentSize.width,
    //                                                      CGRectGetMinY(self.avaterImageView.frame),
    //                                                      self.dataModel.layout.contentSize.width,
    //                                                      self.dataModel.layout.contentSize.height);

        [self.faceImageView mas_updateConstraints:^(MASConstraintMaker *make) {
            make.top.equalTo(self.contentView.mas_top).offset(contentMargin);
            make.right.equalTo(self.contentView.mas_right).offset(-contentMargin);
            make.width.mas_equalTo(@(50));
            make.height.mas_equalTo(@(50));
        }];

        [self.containerView mas_updateConstraints:^(MASConstraintMaker *make) {
            make.top.equalTo(self.faceImageView.mas_top);
            make.right.equalTo(self.faceImageView.mas_left).offset(-contentMargin);
            make.width.mas_equalTo(self.dataModel.layout.contentSize.width);
            make.bottom.mas_equalTo(self.contentView.mas_bottom).offset(-contentMargin);
        }];
    }
    [self setNeedsLayout];
    [self layoutIfNeeded];
}

它看起来像这样:

当我滚动表格查看日志时,如下所示:

【问题讨论】:

    标签: ios objective-c autolayout tableview masonry


    【解决方案1】:

    好的,我从未使用过砌体,但不要忘记 tableview 重用单元格,并且您在重用的单元格上调用 -(void)updateViewWithData:(id)dataEntity。所以你称它为第二次(或第三次,第四次)。

    所以你再次设置约束。

    设置一个标志(例如,您可以将第一次调用 -(void)updateViewWithData:(id)dataEntity 时设置为 true 的 id 命名为 layoutDone,并且在重复使用单元格时不要再次调用此函数。

    希望这会有所帮助。

    【讨论】:

      【解决方案2】:

      我认为问题在于cellForRowAtIndexPath。您可以尝试将数据源方法声明为

      -(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
           PFBubbleCell *cell = [tableView dequeueReusableCellWithIdentifier:@"PFBubbleCell"];
           if(cell) {
             cell = [[PFBubbleCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"PFBubbleCell"];
           }
           [cell updateViewWithData:self.dataSource[indexPath.row]];
           return cell;
      }
      

      【讨论】:

        猜你喜欢
        • 2013-05-16
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-06-15
        相关资源
        最近更新 更多