簡體   English   中英

如何為隱藏在 UITableViewCell 中的 UIStackView 設置動畫?

[英]How to animate UIStackView hiding inside UITableViewCell properly?

我想為 StackView 的 TableViewCell 的子視圖設置動畫。 當我隱藏 StackView 時,TableViewCell 高度不會更新。 google了之后發現應該調用tableView.beginUpdatestableView.endUpdates來通知tableView單元格有變化。 問題是隱藏動畫和 tableview 的變化不同步。

這是 tableview 單元格的視圖層次結構

內容視圖 - 容器視圖(用於卡片陰影) - 容器堆棧視圖 - [標簽和開關的堆棧視圖] & [StudentStackView 用於 StudentView 的容器]

如何以正確的方式同步單元格高度並隱藏動畫?

這是 github 存儲庫: GitHub

應用程序的 Gif: UIStackView 動畫與單元格高度不同步

您使用beginUpdates()/endUpdates()是正確的。 確保您沒有將someArrangedSubview.isHidden = true/false放在動畫塊中,因為表視圖和堆棧視圖將相應地處理動畫。 當表視圖開始更新操作時,堆棧視圖將調整您沒有刪除的任何排列的子視圖的大小以填充單元格的整個空間(即使您對排列的子視圖有高度限制)。 就我而言,每次我想通過刪除排列的子視圖來折疊單元格時,單元格內容都會跳動——所以我在我希望保持靜態* 的視圖和可折疊視圖之間添加了一個虛擬視圖。 靜態視圖不會調整大小,虛擬視圖將根據需要展開/折疊。 希望這可以幫助。

*靜態,因為我不希望視圖在動畫時移動。

 `public func setup(classRoom: ClassRoom, toggleInProcess: @escaping () -> (), toggled: @escaping () -> ()) {
        containerStackView.addArrangedSubview(studentStackView)
        self.nameLabel.text = classRoom.name
        self.activeSwitch.isOn = classRoom.isActive
        self.studentStackView.isHidden = !self.activeSwitch.isOn // Let him know his hide/unhide. 
        for student in classRoom.students {
            let studentView = StudentView()
            studentView.nameLabel.text = student.name
            studentStackView.addArrangedSubview(studentView)
        }
        activeSwitch.addTarget(self, action: #selector(toggleShowStudents(show:)), for: .valueChanged)
        self.toggleInProcess = toggleInProcess
        self.toggled = toggled
        setupShadow()
    }`


`  @objc func toggleShowStudents(show: Bool) {
        UIView.animate(withDuration: 0.3, animations: {
            self.studentStackView.isHidden = !self.activeSwitch.isOn
            self.toggleInProcess()
            self.containerView.layoutIfNeeded()
        }) { _ in
            self.toggled()
        }
    }`

您的 studentStackView 在函數setup分配值時也知道他的隱藏/取消隱藏狀態。

我將此留作評論,但對於遇到此行為的其他任何人,根本原因是 UILabel 在折疊之前正在擴展以填充可見區域。

這可以通過執行以下兩件事來解決:

  1. 在 UILabel 正下方,插入一個空白 UIView
  2. 將 UILabel 的 Content Hugging Priority 調整為“Required”

通過這兩個調整,而不是 UILabel 擴展以填充可見區域,而是 UIView 擴展。 從視覺上看,這看起來好像單元格剛剛折疊。

tableView.beginUpdatestableView.endUpdates是當您將要修改行數或行的選定狀態時應調用的函數。

您應該嘗試 reloadData 或reloadrowsatindexpaths ,它們應該負責單元格高度的調整。

您最好使用 performSelector API 來執行此操作,以免在cellForRowAt調用堆棧中引起遞歸。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM