2015-05-26 68 views
3

我創建使用iOS 8的自上漿細胞與改變高度

tableview.rowHeight = UITableViewAutomaticDimension;

具有自上漿UITableViewCells一個的tableview用於測試的創建單個UIView並將其與下面的約束添加至cell.contentView。 (使用磚石)

- (void)updateConstraints { 
    UIView *superview = self.contentView; 

    if (!_didSetupConstraints) { 
     [self.testView mas_makeConstraints:^(MASConstraintMaker *make) { 
      make.top.equalTo(superview); 
      make.height.equalTo(@10.0f); 
      make.left.equalTo(superview); 
      make.right.equalTo(superview); 
      make.bottom.equalTo(superview); 
     }]; 

     _didSetupConstraints = YES; 
    } 

    [super updateConstraints]; 
} 

當我選擇一行我喜歡改變所選單元格的高度。

- (void)setSelected:(BOOL)selected animated:(BOOL)animated { 
    [super setSelected:selected animated:animated]; 

    [self.testView mas_updateConstraints:^(MASConstraintMaker *make) { 
     if (selected) { 
      make.height.equalTo(@100); 
     } 
     else { 
      make.height.equalTo(@10); 
     } 
    }]; 

    [UIView animateWithDuration:0.3f animations:^{ 
     [super layoutIfNeeded]; 
    }]; 
} 

看來工作,但是,並出現以下錯誤的Xcode投訴:

Unable to simultaneously satisfy constraints.

那麼問題是contentView創造本身就是一個高度constaint(因爲contentView.translatesAutoresizingMaskIntoConstraints = YES;我通過這樣做每個默認值)。

所以當updateConstraints是第一次運行時,系統將在contentView等於10.0f

後來當setSelected...叫我改變我的testView的高度,創造一個高度約束所以那裏有testView.height(100.0f)之間的衝突contentView.height(10.0f)並且由於testView附加到contentView的底部(爲了使自定尺寸的單元工作),它給出了錯誤。

我試過設置contentView.translatesAutoresizingMaskIntoConstraints = NO;,但它似乎UITableViewCell無法真正找出一個適當的單元格大小。 (有時它太寬/太小)等。

什麼是適當的方式來實現自動調整大小的細胞,它們的高度可以動態變化?

+0

你有沒有設置'estimatedRowHeight'財產? – Michael

+0

我沒有設置estimatedRowHeight :)但只是測試,並沒有對高度限制衝突的問題有任何影響。 –

回答

0

這裏有兩個問題:

1.自動版式消息:Unable to simultaneously satisfy constraints.

這是由您更新您的自定義視圖的height約束造成的事實,但你不更新contentView「約束條件。由於您還將自定義視圖的bottom約束設置爲contentView bottom,因此係統無法同時滿足以下兩個約束條件:自定義視圖的高度不能超過100,並且同時連接到contentView的底部,而contentView的高度仍然爲10 。

對此的修復非常簡單。您爲contentView定義高度約束並將其設置爲您的自定義視圖的高度:

[self.contentView mas_makeConstraints:^(MASConstraintMaker *make) { 
    make.height.equalTo(self.testView); 
}]; 

這可解決問題。

2.更新單元格的高度

更新單元高度,因爲細胞的高度由UITableViewController而不是細胞本身處理是不那麼容易。當然,你可以改變你的單元格的高度,但只要UITableViewController不給細胞足夠的空間,你將看不到新的單元格高度。你會看到你現在更高的單元會覆蓋下一個單元。

所以,你需要一種方法來告訴UITableViewController,它應該更新單元格的高度。你可以通過撥打reloadRowsAtIndexPaths:withRowAnimation:來完成。重新加載單元格並且也很好地動畫。因此,細胞在某種程度上具有呼籲UITableViewController該方法。那裏的挑戰:A UITableViewCell沒有提及其UITableViewController(它不應該)。

你可以做的是子類UITableViewCell,並給它一個封閉性,它可以執行,只要它的高度已經改變:

class DynamicHeightTableViewCell: UITableViewCell { 
    var heightDidChange: (() -> Void)? 
    ... 

現在,當你在出列單元格的UITableViewControllerDataSource設置其關閉:

func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell { 
    let cell:UITableViewCell = tableView.dequeueReusableCellWithIdentifier("DynamicHeightTableViewCell", forIndexPath: indexPath) 
    if let customCell = cell as? DynamicHeightTableViewCell { 
     customCell.heightDidChange = { [weak cell, weak tableView] in 
      if let currentIndexPath = tableView?.indexPathForCell(cell!) { 
       tableView?.reloadRowsAtIndexPaths([currentIndexPath], withRowAnimation: .Automatic) 
      } 
     } 
    } 

    return cell 
} 

,然後在細胞改變其高度你只是執行關閉和細胞將重新加載:

func theFunctionWhereTheHeightChanges() { 

    // change the height 

    heightDidChange?() 
} 
+0

對我不起作用(reloadRowsAtIndexPaths會發生崩潰),並且將testView鏈接到contentView的約束也會觸發Autolayout衝突。 – Mikael