使用AutoLayout在UITableView中dynamic的单元格高度

我一直在试图让这个教程dynamic-cell-height在ios8上工作好几天,并且不知道是怎么回事。 它可以在iphone上使用ios7,它可以在iPAD上的ios7和ios8上运行,但是它不能在ios8上使用iphone。

我认为问题在于如何以及何时在单元格内创build标签。

我在控制器中有以下代码:

- (void)viewDidLoad { [super viewDidLoad]; // Do any additional setup after loading the view. self.dbManager = [[DBManager alloc] initWithDatabaseFilename:@"tomhaisdb.sql"]; [self loadData]; } -(void)viewWillAppear:(BOOL)animated{ [super viewWillAppear:animated]; [self deselectAllRows]; } -(void)deselectAllRows{ for (NSIndexPath * indexPath in [self.tableView indexPathsForSelectedRows]) { [self.tableView deselectRowAtIndexPath:indexPath animated:NO]; } } - (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]; } - (void)reloadTableViewContent { dispatch_async(dispatch_get_main_queue(), ^{ [self.tableView reloadData]; [self.tableView scrollRectToVisible:CGRectMake(0, 0, 1, 1) animated:NO]; }); } /*-(NSInteger)numberOfSectionsInTableView:(UITableView *)tableView{ return 1; }*/ #pragma mark - UITableViewDataSource -(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{ NSLog(@"Number of rows: %d", self.favourites.count); return self.favourites.count; } -(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{ return [self basicCellAtIndexPath:indexPath]; } -(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]; } #pragma mark - UITableViewDelegate -(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{ /* if ([[[UIDevice currentDevice]systemVersion]floatValue] >= 8.0) { return UITableViewAutomaticDimension; } else{*/ 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)); 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; } -(CGFloat)tableView:(UITableView *)tableView estimatedHeightForRowAtIndexPath:(NSIndexPath *)indexPath{ return 155.0f; } 

并在自定义标签单元格使用我有以下几点:

  @implementation favouriteLabel - (void)setBounds:(CGRect)bounds { [super setBounds:bounds]; // If this is a multiline label, need to make sure // preferredMaxLayoutWidth always matches the frame width // (ie orientation change can mess this up) if (self.numberOfLines == 0 && bounds.size.width != self.preferredMaxLayoutWidth) { self.preferredMaxLayoutWidth = self.bounds.size.width; NSLog(@"Label Bounds before update constraints %@", NSStringFromCGRect(self.bounds)); [self setNeedsUpdateConstraints]; NSLog(@"Label Bounds after update constraints %@", NSStringFromCGRect(self.bounds)); } } @end 

我认为我的问题在于创build标签时的原因是因为在ios 7中,我得到的输出如下所示:

 2015-06-01 20:07:10.563 Facts[63322:607] Label Bounds before update constraints {{0, 0}, {216, 2}} 2015-06-01 20:07:10.563 Facts[63322:607] Label Bounds after update constraints {{0, 0}, {216, 2}} 2015-06-01 20:07:10.563 Facts[63322:607] Label Bounds before update constraints {{0, 0}, {217, 40}} 2015-06-01 20:07:10.563 Facts[63322:607] Label Bounds after update constraints {{0, 0}, {217, 40}} >2015-06-01 20:07:10.564 Facts[63322:607] Bounds after layout {{0, 0}, {256, 82}} 2015-06-01 20:07:10.564 Facts[63322:607] Content View before Layout {{0, 0}, {256, 82}} 2015-06-01 20:07:10.564 Facts[63322:607] Bounds before Layout {{0, 0}, {256, 82}} 2015-06-01 20:07:10.564 Facts[63322:607] Content View before Layout {{0, 0}, {256, 82}} 2015-06-01 20:07:10.565 Facts[63322:607] Bounds after layout {{0, 0}, {256, 82}} 2015-06-01 20:07:10.565 Facts[63322:607] Content View before Layout {{0, 0}, {256, 82}} 2015-06-01 20:07:10.569 Facts[63322:607] Label Bounds before update constraints {{0, 0}, {216, 74.5}} 2015-06-01 20:07:10.569 Facts[63322:607] Label Bounds after update constraints {{0, 0}, {216, 74.5}} 2015-06-01 20:07:10.569 Facts[63322:607] Label Bounds before update constraints {{0, 0}, {217, 40}} 2015-06-01 20:07:10.570 Facts[63322:607] Label Bounds after update constraints {{0, 0}, {217, 40}} 

但是在ios8中,输出是不同的。

 2015-06-01 20:18:06.049 Facts[63396:81689795] Bounds before Layout {{0, 0}, {256, 44}} 2015-06-01 20:18:06.049 Facts[63396:81689795] Content View before Layout {{0, 0}, {320, 44}} 2015-06-01 20:18:06.131 Facts[63396:81689795] Label Bounds before update constraints {{0, 0}, {216, 0}} 2015-06-01 20:18:06.131 Facts[63396:81689795] Label Bounds after update constraints {{0, 0}, {216, 0}} 2015-06-01 20:18:06.131 Facts[63396:81689795] Label Bounds before update constraints {{0, 0}, {217, 4.5}} 2015-06-01 20:18:06.131 Facts[63396:81689795] Label Bounds after update constraints {{0, 0}, {217, 4.5}} 

在ios7中,标签似乎是先创build的,然后是单元格边界,然后再次调整标签的大小。 但在ios8中,我们首先看到内容视图输出,然后才看到标签的输出。

对不起,我不能更好地解释它。 对我来说这是一个神秘的东西如何使它的表,所以我真的坚持为什么它在ios7中,而不是在ios8

任何帮助最赞赏。 我已经在这里写了这个问题: dynamic单元格高度自动布局IOS但是我想我在这个问题上扔了一个关于自动布局的红鲱鱼。

该框架被放错了答案标签。 由于没有为任何Xany安装标签,因此警告在Interface Builder中不可见。

由于约束不等于预期的高度,停止自动布局正确解决iOS 8的单元格高度。

快速修复是为anyXany勾选其已安装的框。 你会看到警告显示。 select答案标签,select编辑器 – >自动布局问题 – >更新框架,你很好去!

更新:

标签最初出现的原因,不需要重新加载,是因为anyXany框勾选了。 苹果认为有安装的限制,并且初始高度是正确的,无需重新加载或滚动。

当方框未勾选时,限制在标签的布局过程中被添加得太晚以至于具有正确的初始高度。

我build议留下单元格的标签安装(任何大小类),因为单元格的约束不会改变,具体取决于性状。

(当tableView约束发生变化时,单元格的约束条件不应该是有条件的,如果有单元格,它将总是具有相同的约束条件,而不考虑大小等级。