调整UITableViewCell的高度

时间:2014-12-31 09:11:11

标签: ios objective-c uitableview

我想根据UITableViewCell中存储的文本调整NSString高度,使其具有多行 - {{1}的内容}多次更改,因此我无法预定义单元格的高度

然而,我尝试了以下内容,因为您可以从附加的图像中查看,此代码会产生奇怪的结果,其中单元格太大:

NSString

-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath*)indexPath { static NSString *CellIdentifier = @"Cell"; UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier]; if (cell == nil) { cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier]; } cell.textLabel.font = [UIFont fontWithName:@"Helvetica" size:16]; cell.textLabel.lineBreakMode = NSLineBreakByWordWrapping; cell.textLabel.numberOfLines = 0; [cell setSelectionStyle:UITableViewCellSelectionStyleGray]; cell.textLabel.text = tableString; return cell; } - (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath { CGSize labelSize = CGSizeMake(200.0, 20.0); if ([termDefintion length] > 0) labelSize = [tableString sizeWithFont: [UIFont boldSystemFontOfSize: 14.0] constrainedToSize: CGSizeMake(labelSize.width, 800) lineBreakMode: NSLineBreakByWordWrapping]; return labelSize.height; } - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView { return 1; } - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { return 1; } 是NSString,其内容会多次更改。以下是两个屏幕截图,您可以看到上方和下方的空间太大 - http://bramhall.me/cell-1.png& http://bramhall.me/cell-2.png

是否有更有效的方法来获得正确的结果?

3 个答案:

答案 0 :(得分:0)

在故事板中为您的标签添加约束

-(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{
    if ([TypeOfCell[indexPath.row] isEqualToString: @"Checklist"]) {
        if(!self.uitableviewcell){
            self. self.uitableviewcell = [self.tableView dequeueReusableCellWithIdentifier:@"cell identifies "];
        }

        //Configure the cell
        [cell.lblName setText:[names  objectAtIndex:indexPath.row]];
        [cell.lbl setFont:[UIFont fontWithName:@"HelveticaNeue-Bold" size:16]];
        //Layout the cell
        [self.cell layoutIfNeeded];
        //Get the height for the cell
        CGFloat heightTask = [self.checklistView.contentView systemLayoutSizeFittingSize:UILayoutFittingCompressedSize].height;

        return heightTask + 1;
    }
}

答案 1 :(得分:0)

这有点令人沮丧,但它绝对可行。有几种方法可以做到这一点,但我选择的默认方法是按以下方式设置:

  1. 在代码中创建我的所有单元格。这给了我更好地控制一切的好处。这不一定是更好,但我更喜欢它,因为它使整个过程对我来说更直观。
  2. 创建一对这样的方法(我无法正确设置格式,但第一种方法是 CLASS 方法,第二种方法是 INSTANCE 方法):

    • (CGFloat的)heightNeededForObject:(ID)objectUsedToConfigureCell;
    • (无效)configureForObject:(ID)objectUsedToConfigureCell;
  3. 创建私有类方法,返回我想要的间距,字体大小等值。

  4. 完成所有这些后,UITableViewController中的代码变得微不足道。基本上,您可以获得配置所需的数据并将其传递给单元格,询问它所需的高度,或者要求它为数据配置自己。

    以下是一个示例实现:

    // UITableViewController
    - (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
        PFObject *item = self.items[indexPath.row];
        return [ItemTableViewCell heightNeededForItem:item];
    }
    - (ItemTableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
        ItemTableViewCell *cell  = [tableView dequeueReusableCellWithIdentifier:@"cell" forIndexPath:indexPath];
        PFObject *item           = self.items[indexPath.row];
        [cell configureForItem:item];
        return cell;
    }
    
    
    // UITableViewCell Subclass
    
    // Header file
    #import <UIKit/UIKit.h>
    @interface ItemTableViewCell : UITableViewCell {
    
    }
    
    #pragma mark - 
    #pragma mark - Public Class Methods
    + (CGFloat)heightNeededForItem:(PFObject *)item;
    
    #pragma mark -
    #pragma mark - Public Instance Methods
    - (void)configureForItem:(PFObject *)item;
    
    @end
    
    // Implementation file
    // Header import
    #import "ItemTableViewCell.h"
    
    @interface ItemTableViewCell () {
    
    }
    
    #pragma mark -
    #pragma mark - UI Controls
    @property (strong, nonatomic) UILabel *detailLabel;
    
    @end
    @implementation ItemTableViewCell
    
    #pragma mark -
    #pragma mark - Initialization
    - (instancetype)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier {
        self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
        if (self != nil) {
            self.selectionStyle = UITableViewCellSelectionStyleNone;
            [self setupUserInterface];
        }
        return self;
    }
    
    #pragma mark -
    #pragma mark - Public Class Methods
    + (CGFloat)heightNeededForItem:(PFObject *)item {
        NSString *detailString = item[@"property"];
        CGFloat availableWidth = // perhaps just the screen width; maybe more advanced logic here (e.g., if using cell accessories)
    
        UIFont *detailFont     = [self detailLabelFont];
        CGSize detailSize      = [detailString boundingRectWithSize:CGSizeMake(availableWidth, MAXFLOAT)
                                                            options:NSStringDrawingUsesLineFragmentOrigin
                                                         attributes:@{NSFontAttributeName: detailFont}
                                                            context:nil].size;
    
        return [self topBottomMargin] + detailSize.height + [self topBottomMargin];
    }
    
    #pragma mark -
    #pragma mark - "Methodized" Class Properties
    + (CGFloat)leftRightMargin {
        return 16.0f;
    }
    + (CGFloat)detailLabelFontSize {
        if (IS_IPHONE_4 || IS_IPHONE_5) {
            return 14.0f;
        } else if (IS_IPHONE_6) {
            return 17.0f;
        } else if (IS_IPHONE_6PLUS) {
            return 20.0f;
        } else {
            return 24.0f;
        }
    }
    + (CGFloat)topBottomMargin {
        return 16.0f;
    }
    + (UIFont *)detailLabelFont {
        return [UIFont systemFontOfSize:[self detailLabelFontSize]];
    }
    
    #pragma mark -
    #pragma mark - Public Instance Methods
    - (void)configureForItem:(PFObject *)item {
        // This could be very advanced...
        self.detailLabel.text = item[@"property"];
    }
    
    #pragma mark -
    #pragma mark - UI Setup
    - (void)setupUserInterface {
        [self createControls];
        [self setupControls];
        [self layoutControls];
    }
    - (void)createControls {
        self.detailLabel    = [[UILabel alloc] init];
    }
    - (void)setupControls {        
        self.detailLabel.font   = [ItemTableViewCell detailLabelFont];
        // This is necessary for a pure auto layout scenario
        [self.detailLabel setTranslatesAutoresizingMaskIntoConstraints:NO];
    }
    - (void)layoutControls {
        [self.contentView addSubview:self.detailLabel];
        [self.contentView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|-(margin)-[label]-(margin)-|"
                                                                                 options:0
                                                                                 metrics:@{@"margin"    : @([ItemTableViewCell leftRightMargin])}
                                                                                   views:@{@"label"     : self.detailLabel}]];
        [self.contentView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|-(margin)-[detail]-(margin)-|"
                                                                                 options:0
                                                                                 metrics:@{@"margin"    : @([ItemTableViewCell topBottomMargin])}
                                                                                   views:@{@"detail"    : self.detailLabel}]];
    }
    @end
    

    仅供参考:IS_IPHONE_4IS_IPHONE_5IS_IPHONE_6IS_IPHONE_6PLUS是在单身辅助类中定义的宏。

    我希望这段代码有意义。我实际上削减了一个有{2}的子类,它有2个标签(主要和细节),但我认为这将是一个更好的教学工具,使它更简单。你可以让细胞本身变得复杂,我已经这样做了。您可以在任何配置中使用多个标签/视图,此设置允许单元处理其所有布局和配置。

    我甚至使用这种方法计算出特定数据集所需的最大高度,然后将其用于所有单元格以保持一致性(而不是让每个单元格具有不同的高度,这在某些情况下看起来很糟糕例)。但是,您必须小心,因为在UITableViewCell中迭代数据集会产生大量不必要的调用。

答案 2 :(得分:0)

您计算高度的方法是错误的,因为您在cellForRowAtIndexPath方法中将可设置的字体大小设置为16,并使用字体大小14计算单元格高度。这是第一个值得注意的问题。另一个是用于计算高度的宽度。这就是你的高度计算错误的原因。

见下面的代码,它可以帮助您计算确切的高度:

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{ 
       UITableViewCell *cell = [self tableView:tableView cellForRowAtIndexPath:indexPath];

       CGSize maximumLabelSize = CGSizeMake(cell.textLabel.frame.size.width,9999);
       CGSize expectedLabelSize = [cell.textLabel.text sizeWithFont:cell.textLabel.font constrainedToSize:maximumLabelSize lineBreakMode:cell.textLabel.lineBreakMode];

       return MAX(set default cell height if needed, expectedLabelSize.height + (some padding if you want to add));   
}  

如果您有任何问题,请告诉我....