【问题标题】:collectionView.reloadsection not reloading cellcollectionView.reloadsection 不重新加载单元格
【发布时间】:2020-06-16 05:49:18
【问题描述】:

所以我使用组合布局来自动调整单元格的大小。这就是我创建布局部分的方式。然后我在 UICollectionViewCompositionalLayout(sectionProvider:) 中返回它。

    }

private func whatsNewSection() -> NSCollectionLayoutSection {
    let itemSize = NSCollectionLayoutSize(widthDimension: .fractionalWidth(1), heightDimension: .estimated(80))
    let item = NSCollectionLayoutItem(layoutSize: itemSize)

    let group = NSCollectionLayoutGroup.vertical(layoutSize: itemSize, subitems: [item])

    let section = NSCollectionLayoutSection(group: group)
    section.contentInsets = NSDirectionalEdgeInsets(top: 0, leading: 24, bottom: 24, trailing: 24)
    section.boundarySupplementaryItems = [
        .init(layoutSize: .init(widthDimension: .fractionalWidth(1), heightDimension: .absolute(50)), elementKind: UICollectionView.elementKindSectionHeader, alignment: .top)
    ]

    return section
}

所以这个部分看起来像这样。

现在我有 2 个 nib 文件,每个文件都有自己的类。部分标题只有一个标签和一个按钮。让我们忽略标题,因为问题出在 WhatsNewCell 上。类文件看起来像这样。

class WhatsNewCell: UICollectionViewCell {
  static let reuseIdentifier  = String(describing: WhatsNewCell.self)
  var delegate: WhatsNewCellDelegate?

  @IBOutlet weak var appVersionLabel: UILabel!
  @IBOutlet weak var appUpdateLabel: UILabel!
  @IBOutlet weak var moreButton: UIButton!


  override func awakeFromNib() {
    super.awakeFromNib()
    moreButton.addTarget(self, action: #selector(handleMore), for: .touchUpInside)
  }

  @objc private func handleMore() {
    self.moreButton.setTitle("", for: .normal)
    self.appUpdateLabel.numberOfLines = 0

    delegate?.moreButtonClick()
  }
}

好的,版本标签和更新标签在堆栈视图中。当用户单击按钮时,我更改更新标签的行数。现在我创建了一个名为 WhatsNewCellDelegate 的委托,以便能够从我的控制器重新加载我的集合视图。这就是我在控制器中重新加载集合视图的方式。当我初始化一个单元格时,我确实将单元格委托设置为我的控制器。

extension AppDetailCollectionVC: WhatsNewCellDelegate {
func moreButtonClick() {
   //collectionView.collectionViewLayout.invalidateLayout()

    collectionView.performBatchUpdates({
        //collectionView.reloadData()
        collectionView.reloadSections(IndexSet(integer: 2))
    }, completion: nil)
}

}

现在当我调用重新加载数据时它可以工作,但当我调用重新加载部分时它不起作用。我必须按两次更多按钮才能使用重新加载部分。我也尝试使用 invalidateLayout() ,但它使我的一些单元格消失了。看看下面的屏幕截图。

这是当我使用 invalidateLayout() 单击更多按钮时的样子。

所以我不知道发生了什么。我如何能够重新加载该部分而不必按两次更多按钮。非常感谢您的帮助。

【问题讨论】:

  • 简单地说 - 您的单元格存储的信息在另一个单元格出列时不会持久保存。此外,它不会被重置。您必须将有关“更多”的信息存储在您的控制器中,并始终在您的单元格上更新它。

标签: swift uicollectionview


【解决方案1】:

尝试在没有performBatchUpdates 的情况下在主线程上运行它?

DispatchQueue.main.async {
    collectionView.reloadSections(IndexSet(integer: 2))
}

【讨论】:

  • 我刚试过。我仍然需要单击更多按钮两次才能看到单元格重新加载。
【解决方案2】:

所以我让它工作了。我必须在我的模型中添加一个属性。像这样的。

var shouldShowFullDetails: Bool = false

然后我不得不做这样的事情。

func moreButtonClick() {
    model?.shouldShowFullDetails = true

    self.collectionView.reloadItems(at: [IndexPath(item: 0, section: 1)])
}

然后在我的单元格文件中我必须做这样的事情。

  class WhatsNewCell: UICollectionViewCell {
  static let reuseIdentifier  = String(describing: WhatsNewCell.self)
  var delegate: WhatsNewCellDelegate?

  @IBOutlet weak var appVersionLabel: UILabel!
  @IBOutlet weak var appUpdateLabel: UILabel!
  @IBOutlet weak var moreButton: UIButton!

  var model: Model? {
    didSet {
        configureCell()
    }
  }

  override func awakeFromNib() {
    super.awakeFromNib()

    moreButton.addTarget(self, action: #selector(handleMore), for: .touchUpInside)
  }

  @objc func handleMore() {
    delegate?.moreButtonClick()
  }

  private func configureCell() {
    guard let model = model else { return }

    if app.shouldShowFullReleaseNotes {
        appUpdateLabel.numberOfLines = 0
    } else {
        appUpdateLabel.numberOfLines = 3
      }
  }
}

【讨论】:

    【解决方案3】:

    如果你这样做会发生什么?

    extension AppDetailCollectionVC: WhatsNewCellDelegate {
        func moreButtonClick() {
             collectionView.collectionViewLayout.invalidateLayout()
        }
    }
    

    【讨论】:

    • 它让我的一些细胞消失了,我不知道为什么。查看屏幕截图,看看我使用 invalidateLayout() 时会发生什么。
    【解决方案4】:

    我想当你第一次重新加载部分时,collectionView 会创建新的 Cell 和 self.appUpdateLabel.numberOfLines 取初始值 0。 您可以在awakeFromNib 中添加断点并点击更多按钮进行检查。

    尝试添加方法 @objc private func handleMore()self.invalidateIntrinsicContentSize()

    正如 Luis Ramirez 提到的,您应该为单元格使用一些外部配置。

    或者如果在这个集合视图中只有一个类型为WhatsNewCell 的单元格,你可以这样做:

    class WhatsNewCell: UICollectionViewCell {
        private static var shouldShowDetails = false
    
    
      override func awakeFromNib() {
        super.awakeFromNib()
        if Self.shouldShowDetails {
            self.moreButton.setTitle("", for: .normal)
            self.appUpdateLabel.numberOfLines = 0
        } else {
            self.moreButton.addTarget(self, action: #selector(handleMore), for: .touchUpInside)
        }
      }
    
        @objc private func handleMore() {
            Self.shouldShowDetails = true
            ....
        }
    }
    

    【讨论】:

      猜你喜欢
      • 2021-03-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-11-07
      • 2013-06-23
      相关资源
      最近更新 更多