动态单元格高度自动布局IOS

时间:2015-05-31 20:17:18

标签: ios uitableview autolayout tableviewcell

我一直在学习本教程以实现动态单元格高度。 dynamic-table-view-cell-height但它只适用于ios 7,而不适用于ios 8.但它在iPAD上的ios 8中有效,所以我有点难以理解为什么它不能在iphone上工作。虽然我已经完全遵循了代码,但是教程和我实现它的方式之间存在一些差异,因为我对自动布局和表格不太了解,我不确定这是不是导致我的问题。

首先,在本教程中,tableView的尾部和前导边缘恰好等于0到superview。在我的实现中,我创建了比例约束,以便在多个不同的布局中扩展tableView。进一步解释:

这是我的TableView在多个不同设备上使用比例约束的图片。 enter image description here

为实现这一目标,我实现了以下约束: enter image description here

enter image description here

enter image description here

enter image description here

AutoLayout是否可能无法计算单元格高度,因为tableView具有动态高度?

我在实现和教程之间可以看到的第二个区别是数据源。我从调用SLQ3Lite数据库中获取数据,而本教程从xml提要中获取数据。我确信数据填充了单元格,因为当我在IPAD上查看我的实现时,我可以看到如下数据:enter image description here

但是在iphone上出现的是: 该表是可见的,但没有单元格写入表中。 enter image description here

当我使用调试器时,我可以看到正在从数据库中成功检索记录,但它们没有写入表中。

这是很长的代码(对不起)

    #import "favouritedViewController.h"
#import "DBManager.h"
#import "favouritedCell.h"

@interface favouritedViewController ()
@property (strong, nonatomic) IBOutlet UITableView *tableView;
@property (strong, nonatomic) NSArray *favourites;
@property (nonatomic, strong) DBManager *dbManager;
typedef void (^CompletionBlock)();

-(void)loadData;
-(void)reloadDataWithCompletions:(CompletionBlock)completionBlock;

@end

@implementation favouritedViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view.

    self.dbManager = [[DBManager alloc] initWithDatabaseFilename:@"tomhaisdb.sql"];

    self.tableView.delegate = self;
    self.tableView.dataSource = self;

    [self loadData];

}

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

-(void)loadData {
    NSString *query = @"select * from favourites";

    if (self.favourites != nil) {
        self.favourites = nil;
    }

    self.favourites = [[NSArray alloc] initWithArray:[self.dbManager loadDataFromDB:query]];

   /* [self reloadDataWithCompletions:^{
         self.tableView.backgroundColor = [UIColor colorWithRed:28.0f/255.0f green:30.0f/255.0f blue:35.0f/255.0f alpha:1];
    }];*/
    [self reloadTableViewContent];
}



/*-(NSInteger)numberOfSectionsInTableView:(UITableView *)tableView{
    return 1;
}*/

-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{
    return self.favourites.count;
}


-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
    return [self basicCellAtIndexPath:indexPath];
}

- (void)reloadTableViewContent {
    dispatch_async(dispatch_get_main_queue(), ^{
        [self.tableView reloadData];
        [self.tableView scrollRectToVisible:CGRectMake(0, 0, 1, 1) animated:NO];
    });
}

-(favouritedCell *)basicCellAtIndexPath:(NSIndexPath *)indexPath {
    favouritedCell *cell = [self.tableView dequeueReusableCellWithIdentifier:@"favouriteCell" forIndexPath:indexPath];
    [self configureBasicCell:cell atIndexPath:indexPath];
    return cell;
}

-(void)configureBasicCell:(favouritedCell *)cell atIndexPath:(NSIndexPath *)indexPath{
    NSInteger indexOfTomhaisText = [self.dbManager.arrColumnNames indexOfObject:@"tomhaisText"];
    NSString *tomhaisText = [[self.favourites objectAtIndex:indexPath.row] objectAtIndex:indexOfTomhaisText];
    [self setTomhaisForCell:cell item:tomhaisText];
    [self setAnswerForCell:cell item:tomhaisText]; // change this later
}

-(void)setTomhaisForCell:(favouritedCell *)cell item:(NSString *)item{
    [cell.favouriteText setText:item];
}

-(void)setAnswerForCell:(favouritedCell *)cell item:(NSString *)item{
    [cell.answer setText:item];
}

-(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{
    return [self heightForFavouriteCellAtIndexPath:indexPath];
}

-(CGFloat)heightForFavouriteCellAtIndexPath:(NSIndexPath *)indexPath{
    static favouritedCell *sizingCell = nil;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        sizingCell = [self.tableView dequeueReusableCellWithIdentifier:@"favouriteCell"];
    });

    [self configureBasicCell:sizingCell atIndexPath:indexPath];
    return [self calculateHeightForConfiguredSizingCell:sizingCell];
}

-(CGFloat)calculateHeightForConfiguredSizingCell:(UITableViewCell *)sizingCell{
    sizingCell.bounds = CGRectMake(0.0f, 0.0f, CGRectGetWidth(self.tableView.frame), CGRectGetHeight(sizingCell.bounds));
    [sizingCell setNeedsLayout];
    [sizingCell layoutIfNeeded];

    CGSize size = [sizingCell.contentView systemLayoutSizeFittingSize:UILayoutFittingCompressedSize];
    return size.height + 1.0f;
}

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

编辑1

enter image description here enter image description here enter image description here enter image description here enter image description here enter image description here

这是在ios 7上运行的图片(正在运行) enter image description here

这是日志输出

  

2015-06-01 18:43:40.855 Facts [62233:607]行数:2 2015-06-01   18:43:43.996事实[62233:607]布局之前的界限{{0,0},{256,82}}   2015-06-01 18:43:55.068 Facts [62233:607]布局前的内容视图   {{0,0},{256,82}} 2015-06-01 18:44:09.409事实[62233:607]界限   布局后{{0,0},{256,82}} 2015-06-01 18:44:12.843   事实[62233:607]布局前的内容视图{{0,0},{256,82}}   2015-06-01 18:44:21.462事实[62233:607]布局{{0,0}}之前的界限,   {256,82}} 2015-06-01 18:44:23.884 Facts [62233:607]内容视图   在布局{{0,0},{256,82}}之前2015-06-01 18:44:30.536   事实[62233:607]布局后的界限{{0,0},{256,82}} 2015-06-01   18:44:32.278事实[62233:607]布局前的内容视图{{0,0},   {256,82}}

从这段代码:

    -(CGFloat)calculateHeightForConfiguredSizingCell:(UITableViewCell *)sizingCell{
    sizingCell.bounds = CGRectMake(0.0f, 0.0f, CGRectGetWidth(self.tableView.frame), CGRectGetHeight(sizingCell.bounds));
    NSLog(@"Bounds before Layout %@", NSStringFromCGRect(sizingCell.bounds));
     NSLog(@"Content View before Layout %@", NSStringFromCGRect(sizingCell.contentView.bounds));
    [sizingCell setNeedsLayout];
    [sizingCell layoutIfNeeded];

    CGSize size = [sizingCell.contentView systemLayoutSizeFittingSize:UILayoutFittingCompressedSize];
    NSLog(@"Bounds after layout %@", NSStringFromCGRect(sizingCell.bounds));
    NSLog(@"Content View before Layout %@", NSStringFromCGRect(sizingCell.contentView.bounds));
    return size.height + 1.0f;
}

但是在ios8上,这就是我所看到的: enter image description here

这是输出:

  

2015-06-01 18:47:14.688 Facts [62306:81355636]布局前的界限   {{0,0},{256,44}} 2015-06-01 18:47:14.688事实[62306:81355636]   布局前的内容视图{{0,0},{256,44}} 2015-06-01 18:47:14.688   事实[62306:81355636]布局{{0,0},{256,44}}之后的界限   2015-06-01 18:47:14.688 Facts [62306:81355636]之前的内容视图   布局{{0,0},{256,44}}

ios7中的sizingCell正在读取单元格内容的正确边界,但在ios8中却没有。

2 个答案:

答案 0 :(得分:1)

我发现https://github.com/forkingdog/UITableView-FDTemplateLayoutCell库很有用。我已经尝试过但都没有工作。现在这个库动态计算UITableView行的高度。

答案 1 :(得分:0)

你做得太多了; Apple可以为您处理前导和尾随间距。

0 正好 正确要使用的正确数字,但是你固定到superview.margin,而不是superview。 Apple会根据设备将您的保证金调整为建议保证金。 (在4.7"更宽,在4&#34上更窄;。)

FYI,0倍任何乘数因子始终为0,因此您当前的约束不会达到预期的效果。

单元格高度关闭的原因是由于错误的框架(Interface Builder无法警告,因为没有为anyXany安装标签约束)。

IOS 7仍然可以解决单元格高度,但iOS 8 requires the cell height to be initially correct(可解决)。