2017-10-05 70 views
0

在問題標題中提到的場景中,在更改段時,理想情況下UITableView應該重新加載,因此UITableViewCell也應該重新加載。問題是,所有內容都像標籤文本一樣更新。但是,如果我在一個細分受衆羣中擴展了細胞的子視圖,那麼在細分受衆羣發生變化後,它仍然會展開。
段索引變更功能:帶UITableView的UISegmentControl - UITableViewCell佈局在更改段時保持不變

@IBAction func segmentOnChange(sender: UISegmentControl) 
{ 
    // Few lines 
    // self.tableMenu.reloadData() 
} 

截圖1:

enter image description here

截圖2:

enter image description here

所以理想情況下,在截圖2中,購物車視圖應該已被摺疊。

更新:

顯示/隱藏視圖:

func showHideCartView(sender: UIButton) 
    { 
     let cell = self.tableMenu.cellForRow(at: IndexPath(row: 0, section: Int(sender.accessibilityHint!)!)) as! RestaurantMenuItemCell 
     if sender.tag == 1 
     { 
      // Show cart view 
      cell.buttonArrow.tag = 2 
      cell.viewAddToCart.isHidden = false 
      cell.constraint_Height_viewAddToCart.constant = 50 
      cell.buttonArrow.setImage(UIImage(named: "arrowUp.png"), for: .normal) 
     } 
     else 
     { 
      // Show cart view 
      cell.buttonArrow.tag = 1 
      cell.viewAddToCart.isHidden = true 
      cell.constraint_Height_viewAddToCart.constant = 0 
      cell.buttonArrow.setImage(UIImage(named: "arrowDown.png"), for: .normal) 
     } 

     self.tableMenu.reloadData() 
    } 

的cellForRowAtIndexPath:

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { 
     let cell = tableView.dequeueReusableCell(withIdentifier: "RestaurantMenuItemCell", for: indexPath) as! RestaurantMenuItemCell 
     cell.selectionStyle = .none 
     let menuItem = self.menuItems[indexPath.section] 
     cell.imageViewMenuItem.image = UIImage(named: "[email protected]") 
     cell.labelName.text = menuItem.name 
     cell.labelDescription.text = menuItem.description 
     cell.labelPrice.text = String(format: "$%i", menuItem.price!) 
     cell.buttonArrow.accessibilityHint = String(format: "%i", indexPath.section) 
     cell.buttonArrow.addTarget(self, action: #selector(self.showHideCartView(sender:)), for: .touchUpInside) 

     return cell 
    } 
+0

如何擴展表格單元格?意味着在heightForRowAtIndexPath方法中管理? – iPatel

+0

這應該有一個簡單的解決方法..檢查你的模型,這決定了一個單元格是否擴展或不..你必須重置它的段更改 –

+0

@iPatel:通過約束。我已經設置estimatedRowHeight = 150和rowHeight = UITableViewAutomaticDimension – Nitish

回答

1

既然你依靠發送按鈕的標籤,以確定是否細胞應在展開或摺疊狀態顯示,你需要確保當段改變,該標籤的所有單元格buttonArrow也改變爲1.

除非發生這種情況,否則單元格將被重用,並且由於buttonArrow的標記設置爲2,因此它將顯示爲展開。

+0

我現在已經採取了處理該模型屬性。 – Nitish

0

這裏發生了什麼事,當你點擊任何行那麼這將是擴大基礎在showHideCartView方法和之後,當真正的第一個條件n您正在更改保留上一行高度的段索引,因爲您正在重複使用單元格因此,當您更改段索引時,必須設置每行的正常高度。

對於採用的indexPath對象像

var selectedIndexPath: NSIndexPath? 

待辦事項如果是showHideCartView方法

func showHideCartView(sender: UIButton) { 
    selectedIndexPath = NSIndexPath(row: 0, section: Int(sender.accessibilityHint!)!)) // you can change row and section as per your requirement. 

//// Your other code 
} 

設置selectedIndexPath然後應用以下邏輯每當你正在改變段索引。

@IBAction func segmentOnChange(sender: UISegmentControl) 
{ 
     if indexPath = selectedIndexPath { // check selectedIndexPath is not nil 
      let cell = self.tableMenu.cellForRow(at: indexPath) as! RestaurantMenuItemCell 
      cell.buttonArrow.tag = 1 
      cell.viewAddToCart.isHidden = true 
      cell.constraint_Height_viewAddToCart.constant = 0 
      cell.buttonArrow.setImage(UIImage(named: "arrowDown.png"), for: .normal) 
     } 

    selectedIndexPath = nil // assign nil to selectedIndexPath 
    // Few lines 

    self.tableMenu.reloadData() // Reload your tableview 

} 
1

正在重用細胞,看你cellForRowAt執行第一行:

let cell = tableView.dequeueReusableCell(withIdentifier: "RestaurantMenuItemCell", for: indexPath) as! RestaurantMenuItemCell 

這意味着,一個的tableView不創建一個新的小區,也不重繪,除非必要的給定indexPath。但是,在代碼中,通過在單元的子視圖上設置一些高度約束和isHidden標誌來展開單元。現在,一旦你在一個新的區段重新加載表格,tableView將使用已經渲染的單元格來儘可能高效地重新加載表格。但是,這意味着儘管您將更改單元格中的數據,除非您明確摺疊它,但它會保持展開狀態(因爲之前您已將約束設置爲展開高度)。

當您更改段時,您需要重置展開狀態。現在讓我們來詳細說明一下,因爲我相信你目前的解決方案有一個隱藏的bug:

首先,因爲我說你離開單元格,萬一表格中有很多項目,你滾動通過它們,擴展單元很可能會在表格視圖中的某處稍後重用。所以看起來好像有一些隨機項目也被擴展了。

因此,我建議您提供一些模型,以記住哪些單元格應該展開,然後使用此模型中的信息更新每個單元格的狀態,然後將它們返回到您的cellForRowAt中。該模型可以是一個簡單的整數值數組,這些數值可以表示被展開的單元格的索引 - 例如,如果數組中有索引3,則意味着應該展開第3行的單元格。然後,當您將行中的行排列爲cellForRowAt,indexPath時,您應該在返回之前在該單元上設置約束條件。這樣你可以刪除我提到的錯誤。此外,當你改變數據段時,你可以從數組中刪除所有索引來表示不應該擴展任何單元(在調用tableView.reloadData()之前執行)。

相關問題