如何创建具有与iOS7和iOS8兼容的动态高度的UITableViewCell?

时间:2014-11-04 20:06:58

标签: ios objective-c uitableview xcode6 heightforrowatindexpath

我正在创建一个我想在iOS7和iOS8下运行的应用程序,它具有可变的表格单元格高度。在iOS7中,我用来定义一个原型单元格,然后在heightForRowAtIndexPath中使用它来根据放入标签的文本大小来计算高度。

这在使用Xcode 6时似乎不再起作用。我今天创建了一个小测试应用程序,看看我是否疯了(也许我是)。我开始没有定义heightForRowAtIndexPath。当我使用iOS7和iOS8设备测试它时,它的行为有所不同。在iOS8设备中,它自动确定单元格高度并正常工作。在iOS7中,单元格返回所有相同的高度。对于iOS7,它不会对具有可变文本的单元格进行自动高度调整,仅适用于iOS8。

所以......我想......嗯...在iOS8下我可以使用自动布局来确定高度,只为iOS7实现heightForRowAtIndexPath ...

好的,所以...我尝试添加heightForRowAtIndexPath。在iOS7下,它崩溃了方法systemLayoutSizeFittingSize。我玩了几个小时,我做的一切似乎都改变了这一点。这是非常简单的代码。

这是UITableViewController代码:

//
//  TestTableViewController.m
//  testTables
//

#import "TestTableViewController.h"
#import "Cell1.h"

@interface TestTableViewController ()

@property (nonatomic, strong) Cell1 *cellPrototype;

@end

@implementation TestTableViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    [self.tableView registerNib:[UINib nibWithNibName:@"Cell1" bundle:nil] forCellReuseIdentifier:@"Cell1"];
}

- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

#pragma mark - Table view data source

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
    // Return the number of sections.
    return 1;
}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
    // Return the number of rows in the section.
    return 10;
}

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {

    self.cellPrototype = [self.tableView dequeueReusableCellWithIdentifier:@"Cell1"];
    self.cellPrototype.label1.text = [self cellContents:indexPath];

    [self.cellPrototype layoutIfNeeded];
    CGSize size = [self.cellPrototype systemLayoutSizeFittingSize:UILayoutFittingCompressedSize];
    return size.height;

}


- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    Cell1 *cell = [tableView dequeueReusableCellWithIdentifier:@"Cell1" forIndexPath:indexPath];

    cell.label1.text = [self cellContents:indexPath];
    return cell;
}

- (NSString*)cellContents:(NSIndexPath *)indexPath  {

    if (indexPath.row == 0) {
        return @"one line";
    }
    else if (indexPath.row == 1) {
        return @"two lines I think will result from this piece of text that goes over";
    }
    else if (indexPath.row == 2) {
        return @"three lines I think will result from this piece of text that goes over and then even extends a little more again";
    }
    else {
        return @"three lines I think will result from this piece of text that goes over and then even extends a little more again, and then extends over more and more lines like it will go on forever and never end but in fact it does end right here.";
    }

}

@end

这是单元格标题(.m文件中没有任何内容):

//
//  Cell1.h
//  testTables
//
#import <UIKit/UIKit.h>

@interface Cell1 : UITableViewCell
@property (weak, nonatomic) IBOutlet UILabel *label1;

@end

这是细胞的xib。如您所见,它并不复杂: enter image description here

那么......这种旧方法不再起作用吗?如何获得可在两个iOS中运行的可变高度单元格?

1 个答案:

答案 0 :(得分:1)

此处详细说明了您所描述的许多警告。 Automatic Preferred Max Layout Width is not available on iOS versions prior to 8.0

在iOS 8之前,需要手动设置preferredMaxLayoutWidth。如果它不太可能改变,可以在任何地方设置此属性,但我的首选解决方案是使用自动设置preferredMaxLayoutWidth的子类UILabel。

您的子类UILabel将覆盖layoutSubviews,以使其preferredMaxLayoutWidth始终与其宽度相同。

- (void)layoutSubviews {
    self.preferredMaxLayoutWidth = self.bounds.size.width;
    [super layoutSubviews];
}