您的第一个问题将通过minimumInteritemSpacing
在 OuterCell 中设置 innerCollectionView 来解决。所以 innerCollectionView 的定义变成了这样:
let innerCollectionView : UICollectionView = {
let layout = UICollectionViewFlowLayout()
layout.scrollDirection = .horizontal
layout.minimumLineSpacing = 0
layout.minimumInteritemSpacing = 0
let cv = UICollectionView(frame :.zero , collectionViewLayout: layout)
cv.translatesAutoresizingMaskIntoConstraints = false
cv.backgroundColor = .orange
layout.estimatedItemSize = CGSize(width: cv.frame.width, height: 1)
cv.isPagingEnabled = true
cv.showsHorizontalScrollIndicator = false
return cv
}()
第二个问题通过在 OuterCell 的 post 属性的 didSet 中添加对 reloadData 和 layoutIfNeeded 的调用来解决,如下所示:
var post: Post? {
didSet {
if let numLikes = post?.numLikes {
likesLabel.text = "\(numLikes) Likes"
}
if let numComments = post?.numComments {
commentsLabel.text = "\(numComments) Comments"
}
innerCollectionView.reloadData()
self.layoutIfNeeded()
}
}
您所看到的与单元重用有关。如果您滚动到第一项上的黄色边框文本,然后向下滚动,您可以看到这一点。你会看到其他人也在黄色边框的文本上(尽管现在至少有正确的文本)。
编辑
作为奖励,这里是一种记住细胞状态的方法。
首先,您需要跟踪位置何时发生变化,因此在 OuterCell.swft 中添加一个新协议,如下所示:
protocol OuterCellProtocol: class {
func changed(toPosition position: Int, cell: OutterCell)
}
然后将该协议的委托的实例变量添加到 OuterCell 类,如下所示:
public weak var delegate: OuterCellProtocol?
然后最后您需要添加以下方法,该方法在滚动完成时调用,计算新位置并调用委托方法让它知道。像这样:
func scrollViewDidEndDecelerating(_ scrollView: UIScrollView) {
if let index = self.innerCollectionView.indexPathForItem(at: CGPoint(x: self.innerCollectionView.contentOffset.x + 1, y: self.innerCollectionView.contentOffset.y + 1)) {
self.delegate?.changed(toPosition: index.row, cell: self)
}
}
这就是每个单元格检测集合视图单元格何时更改并通知委托人。让我们看看如何使用这些信息。
OutterCellCollectionViewController 将需要跟踪其集合视图中每个单元格的位置,并在它们变得可见时更新它们。
因此,首先使 OutterCellCollectionViewController 符合 OuterCellProtocol,以便在其中一个时通知它
class OutterCellCollectionViewController: UICollectionViewController, UICollectionViewDelegateFlowLayout, OuterCellProtocol {
然后添加一个类实例变量以将单元格位置记录到 OuterCellCollectionViewController,如下所示:
var positionForCell: [Int: Int] = [:]
然后添加所需的 OuterCellProtocol 方法来记录单元格位置的变化,如下所示:
func changed(toPosition position: Int, cell: OutterCell) {
if let index = self.collectionView?.indexPath(for: cell) {
self.positionForCell[index.row] = position
}
}
最后更新 cellForItemAt 方法以设置单元格的委托并使用新的单元格位置,如下所示:
override func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "OutterCardCell", for: indexPath) as! OutterCell
cell.post = posts[indexPath.row]
cell.delegate = self
let cellPosition = self.positionForCell[indexPath.row] ?? 0
cell.innerCollectionView.scrollToItem(at: IndexPath(row: cellPosition, section: 0), at: .left, animated: false)
print (cellPosition)
return cell
}
如果您设法正确完成所有设置,它应该在您向上和向下滚动列表时跟踪位置。