繁体   English   中英

UITableViewCell的扩展,在iOS中包含长内容

[英]The UITableViewCell's expansion with long long content in iOS

1.当单元格内的内容过长时,单元格展开,或者再缩小,UITableView将滚动到单元格位置的背面。

2.我希望单元回滚到开始扩展的地方。

我的代码:

    ((PartnershipsTableViewCell *)cell).commentSpreadButtonClickHandler = ^() {
       // just call - (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
        [weakSelf.tableView beginUpdates];
        [weakCell configUI];
        [weakSelf.tableView endUpdates];

        // if here use "[weakSelf.tableView reloadData]", 
        // it can be correct, 
        // Unless on the first cell which have the expansion button.
    };

然后更新uitableview单元格的高度。 但是结果不是我想要的

- (void)configUI {
    if ([self.baseModel isKindOfClass: [UserWorldDynamicModel class]]) {
        self.model = (id)self.baseModel;
    }
    [self setupValue];
}

- (void)setupValue {
    // setup the property value, and update the constraints with masonry
}


// the button : read less or read more
- (void)setSpreadButton {
    NSString *text = self.model.isContentOpen ? @"read less" : @"read more";
    if (!self.spreadButton) {
        self.spreadButton = [MYSUtil createButtonWithTitle: text target: self sel: @selector(spreadButtonClick:) image: nil font: Font14 color: DarkBlueTextColor cornerRadius: 0];
        self.spreadButton.contentHorizontalAlignment = UIControlContentHorizontalAlignmentLeft;
    }
    if (self.model.shouldShowSpreadButton) {
        if (!self.spreadButton.superview) {
            [self.whiteBackgroudView addSubview: self.spreadButton];
        }
        [self.spreadButton setTitle: text forState: UIControlStateNormal];
        self.spreadButton.selected = [self.model.isSpreadState intValue];
        self.spreadButton.frame = CGRectMake(CGRectGetMinX(self.contentLabel.frame), CGRectGetMaxY(self.contentLabel.frame), 80, 30);
        self.tempView = self.spreadButton;
    } else {
        if (self.spreadButton.superview) {
            [self.spreadButton removeFromSuperview];
        }
    }
}

    // calculate the height of the label and compare it with the fixed value
    NSMutableAttributedString *string = [self createMutableAttibuteStringWithNSString: text withFont: font];
    self.contentLabel.attributedText = string;

    // here calculate maxContentLabelHeight with
    CGFloat maxContentLabelHeight = self.contentLabel.font.pointSize * (numberOfLines + 1) + 16;

    // here calculate the NSMutableAttributedString's height
    YYTextContainer *container = [YYTextContainer containerWithSize:CGSizeMake(width, MAXFLOAT)];
    YYTextLayout *textLayout = [YYTextLayout layoutWithContainer:container text: string];
    CGSize size = textLayout.textBoundingSize;
    CGFloat height = size.height;

    // then compare the NSMutableAttributedString's height with the fixed value. if true, show the spreadButton
    if (height > maxContentLabelHeight) {
        self.model.shouldShowSpreadButton = YES;
        // storage the real height and temp height, use to calculate the tableView's contentOffset, when cell from expansion state to shrinking state in block.
        self.model.contentHeight = height;
        self.model.tempContentHeight = maxContentLabelHeight;
    }

    // if height > maxContentLabelHeight and the property "isContentOpen" of the viewModel, the height value is maxContentLabelHeight, Or not, the height value is height
    if (!self.model.isContentOpen && height > maxContentLabelHeight) {
        height = maxContentLabelHeight;
    }

    // no matter cell is expansion state or shrinking state, reset label's frame.
    self.contentLabel.frame = CGRectMake(x, CGRectGetMaxY(self.headerImageView.frame) + Margin_Top, width, height);

readMore / readLess块

在mainView上的tableView reloadData之前,记录它的contentOffset,用于计算需要滚动的tableView的位置。 像这样:

 CGPoint point = weakSelf.tableView.contentOffset;

reloadData:在mainQueue上刷新tableView。 reloadData完成后,将tableView滚动到展开的位置。 当tableView从展开状态变为收缩状态,并且展开状态的高度大于屏幕高度的70%时,滚动tableView(70%是ma条件,可以根据您的条件进行更改)

- (UITableViewCell *)tableView:(UITableView *) tableView cellForRowAtIndexPath: (NSIndexPath *) indexPath {
    // here is your code
    PartnershipsTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier: cellIdentifierString];
    [cell config];
    ((PartnershipsTableViewCell *)cell).spreadButtonClickHandler = ^() {
        CGPoint point = weakSelf.tb.contentOffset;
        [weakSelf.tb reloadData];
        if (!baseModel.isContentOpen && baseModel.contentHeight > SCREEN_HEIGHT * 0.7) {
            point.y -= baseModel.contentHeight - baseModel.tempContentHeight;
            dispatch_async(dispatch_get_main_queue(), ^{
                weakSelf.tb.contentOffset = point;
            });
        }
    };
    return cell;
}


- (CGFloat)tableView:(UITableView *) tableView heightForRowAtIndexPath:(NSIndexPath *) indexPath {
    return 70;
}

在我的问题中,当在代码中使用follow方法时,我发现了另一个有趣的问题。 如果您的单元格发生了很大的变化,尤其是单元格的高度。 当使用方法[tableView reloadData]时,最好不要使用follow方法。

 - (CGFloat)tableView:(UITableView *)tableView estimatedHeightForRowAtIndexPath:(NSIndexPath *)indexPath {
        return 70;
  }

然后使用[tableView reloadData]方法刷新UI,tableView将滚动到任何位置,因此我将其删除。 因为,此方法用于估计单元格的高度,然后用于估计tableView的contentSize,如果估计和实际之间的高度差较大,请使用方法[tableView reloadData],将导致tableView滚动到任何位置。(不要问我怎么知道,这对我来说是一个痛苦的过程。

我已经解决了这个问题,给自己和每一个人留下一些笔记,并希望我的解决方案也能对您有所帮助。

感谢@pckill和@Theorist,没有您的建议,我无法完美地解决我的问题,非常感谢。

@Theorist我已经重新编写了代码。 也许,现在的可读性更好。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM