2017-10-28 153 views
0

我有一個UITableViewUITableViewCell有一個動態的UILabel這將根據我從數據庫中獲得的數據添加。UITableViewCell高度動態子視圖swift

我使用類似

let testing = ["A", "B", "C", "D"] // This array is dynamic data 
self.dictionaryTableView.estimatedRowHeight = 44 
self.dictionaryTableView.rowHeight = UITableViewAutomaticDimension 

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { 
    let cell = tableView.dequeueReusableCell(withIdentifier: "vocabCell", for: indexPath) 
    var y = 0 
    for var i in 0..<self.testing.count { 
     let lbl = UILabel(frame: CGRect(x: 0, y: y, width: 50, height: 25)) 
     lbl.text = self.testing[i] 
     lbl.numberOfLines = 0 
     cell.addSubview(lbl) 
     y += 20  
    } 
    return cell 
} 

UITableViewCell高度不會自動伸展來顯示所有內容的細胞。請幫助 下面是結果 enter image description here

編輯我加約束在UITableView中的cellForRowAtIndexPath中的UILabel,約束正在努力(我知道,當我花費了單元格高度),但細胞高度不全自動STRETCH時出

var bottomAnchor: NSLayoutYAxisAnchor = NSLayoutYAxisAnchor() 
for var i in 0..<self.testing.count { 
    let lbl = UILabel() 
    lbl.text = self.testing[i] 
    lbl.numberOfLines = 0 
    lbl.translatesAutoresizingMaskIntoConstraints = false 

    cell.addSubview(lbl) 
    lbl.leftAnchor.constraint(equalTo: cell.leftAnchor, constant: 16).isActive = true 
    lbl.widthAnchor.constraint(equalTo: cell.widthAnchor).isActive = true 
    lbl.heightAnchor.constraint(equalToConstant: 25).isActive = true 

    if i == 0 { 
     lbl.topAnchor.constraint(equalTo: cell.topAnchor).isActive = true 
    } else { 
     lbl.topAnchor.constraint(equalTo: bottomAnchor).isActive = true 
    } 
    bottomAnchor = lbl.bottomAnchor 
} 
return cell 

非常感謝

+0

爲什麼要添加多個標籤? 我的意思是你可以插入下一行字符 – SPatel

+0

@ user3783161循環裏面cellForRowAt是不是一個好主意,你可以添加標籤,故事板的意見。你有沒有使用你的疑問? –

+0

https://stackoverflow.com/a/30300870/8779236看這回答 –

回答

0

我找到了答案here

我加了一個約束,以我的UITableViewCell底部用下面的代碼,它的工作,但我不知道這條線究竟做了什麼(我也不知道這個參數)

任何人都可以幫我解釋此代碼

let bottomSpaceConstraint: NSLayoutConstraint = NSLayoutConstraint(item: lbl, attribute: NSLayoutAttribute.bottomMargin, relatedBy: NSLayoutRelation.equal, toItem: cell.contentView, attribute: NSLayoutAttribute.bottomMargin, multiplier: 1, constant: -8) 
cell.contentView.addConstraint(bottomSpaceConstraint) 
1

使用此代碼。

func tableView(tableView: UITableView, estimatedHeightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat { 
    return UITableViewAutomaticDimension 
} 
+0

1.不需要大於或等於標籤高度的限制。 2.這些並不是所有必要的步驟。 – FreeNickname

+0

這已經過時,因爲問題中的代碼示例已經設置了'self.dictionaryTableView.rowHeight = UITableViewAutomaticDimension'。 – Mischa

+0

我已經試過但沒有任何工作 – user3783161

1

還有,你需要在你的實現來解決兩件事情:

  1. 創建你的tableView(_:, cellForRowAt:)出隊它的佈局。

    出於效率原因,表格視圖重複使用當用戶滾動時一遍又一遍地重複相同的單元格。這就是爲什麼你使用這個奇怪的「出隊」功能,而不是簡單地實例化一個新的單元。

    let cell = tableView.dequeueReusableCell(withIdentifier: "vocabCell", for: indexPath) 
    

    將始終嘗試返回剛剛滾動出視圖的已用單元。只有當沒有可用的循環單元時(例如,當出現第一對單元格時),表格視圖將創建單元格的新實例。

    細胞回收是你爲什麼應該從不tableView(_:, cellForRowAt:)內創建你的細胞佈局的原因,例如通過添加標籤。當單元格被重新使用時,另一個標籤將被添加到您之前添加的標籤的頂部,當它再次被重新使用時,您將最終得到三個重疊的標籤等。

    同樣適用於約束。如果在不刪除現有約束的情況下向tableView(_:, cellForRowAt:)中的某個單元添加約束,則在用戶滾動時會添加越來越多的約束,這很可能導致嚴重的約束衝突。

    取而代之,在之前設置您的單元格的佈局。有幾種方法來實現這一目標:

    • 如果使用UITableViewController故事板裏面,你可以創建動態原型並直接在故事板鋪陳細胞。例如,您可以將標籤拖放到原型單元格中,並在自定義子類中爲其創建出口。

    • 您可以爲您的單元格創建XIB文件,在Interface Builder中打開它並在其中創建佈局。再次,您需要創建一個帶有適當插座的UITableViewCell子類並將其與您的XIB文件相關聯。

    • 您可以創建一個UITableViewCell子類,並在代碼中純粹設置您的佈局,例如在單元的初始化程序中。

  2. 您需要使用自動佈局。

    如果您在Interface Builder中創建佈局,只需添加必要的約束條件即可。如果您在代碼中創建您的佈局,您需要將translatesAutoresizingMaskIntoConstraints屬性設置爲false爲您要限制所有的意見,例如:

    lbl.translatesAutoresizingMaskIntoConstraints = false 
    

    在您的特定佈局,則需要在左邊來約束標籤,右側,頂部和底部與你的細胞的相應邊緣contentView

    如果您不知道如何操作,請閱讀Apple的Auto Layout Guide。 (這通常是一個更好的主意,在界面生成器,而不是代碼來做到這一點。)如何「在UITableView的自動佈局動態單元佈局&可變行高度」使用

    非常詳細的介紹,可以發現here

+0

我添加了約束(請參閱編輯),但不工作,有什麼問題 – user3783161

+1

在我的代碼中有一些其他錯誤,我一開始就忽略了。我更新了我的答案,並添加了有關如何解決此問題的詳細說明。 – Mischa

+0

感謝您的詳細信息,只是有一個問題。如果我在出隊之前設置單元格佈局,如何創建動態UILabel原因我不知道需要使用多少個標籤 – user3783161

1

您可以使用UITableView部分來呈現數據,而不是以編程方式添加視圖。這裏的例子:

class ViewController: UITableViewController { 

    private var dataSectionOne = ["Data 1", "Data 2"] 
    // This can be your dynamic data. 
    // Once the data changed, called tableView.reloadData() to update the view. 
    private var dataSectionTwo = ["A", "B", "C"] 

    override func viewDidLoad() { 
     super.viewDidLoad() 
     tableView.rowHeight = UITableViewAutomaticDimension 
     tableView.estimatedRowHeight = 44 
    } 

    override func numberOfSections(in tableView: UITableView) -> Int { 
     return 2 
    } 

    override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { 
     if section == 0 { 
      return dataSectionOne.count 
     } else if section == 1 { 
      return dataSectionTwo.count 
     } 
     return 0 
    } 

    override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { 
     let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath) 
     if indexPath.section == 0 { 
      cell.textLabel?.text = dataSectionOne[indexPath.row] 
     } else if indexPath.section == 1 { 
      cell.textLabel?.text = dataSectionTwo[indexPath.row] 
     } 
     return cell 
    } 

} 

結果:

Demo

+0

感謝您的建議。我的表格視圖有動態部分,每個部分都有我想用UILabel存檔的數據 – user3783161