UICollectionView 中水平滚动的单元格消失

Posted

技术标签:

【中文标题】UICollectionView 中水平滚动的单元格消失【英文标题】:Cells disappearing with horizontal scrolling in UICollectionView 【发布时间】:2017-05-19 22:29:52 【问题描述】:

我被这个奇怪的问题困扰了一段时间,似乎无法弄清楚。

设置

AUICollectionView B是A的UICollectionViewCells

C 是一个UICollectionView,当用户在 B 中点击时作为 B 的子视图添加

+------------------------------+
|A                             |
|                              |
| +----------+    +----------+ |
| |B         |    |B         | |
| |----------|    |          | |
| |          |    |          | |
| |C         |    |          | |
| +----------+    +----------+ |
+------------------------------+

问题

当初始化 C 的 UICollectionViewFlowLayout 滚动方向属性为 .horizontal滚动经过第二个单元格,C 的单元格消失了。

作为奖励C 本身从 UI 中消失了:用户再次能够点击单元格,该单元格执行所有在 C 的通常移除时完成的操作。当再次点击以正常重新显示它时,触发了在 C 的显示上触发的操作,但 C 仍然在视觉上无处可寻。

当滚动方向设置为.vertical时不会出现此问题。

有没有人遇到过类似的问题或任何关于这里发生了什么的线索?

提前致谢。


编辑实际实施

(B)

import UIKit

class CollectionViewCell: UICollectionViewCell 

    //...

    private let cellId = "cellId"

    private lazy var label: UILabel = 

        return CollectionViewCell._label()
    ()

    fileprivate lazy var gallery: UICollectionView = 

        return CollectionViewCell._gallery()
    ()

    //...

    override init(frame: CGRect) 
        super.init(frame: frame)

        isOpaque = true
        clipsToBounds = true
        layer.borderWidth = 1.5
        layer.cornerRadius = 8

        // ...
    

    required init?(coder aDecoder: NSCoder) 
        fatalError("init(coder:) has not been implemented")
    

    private func onSwitchDisplayGallery(_ isDiplaying: Bool) 

        switch isDiplaying 

        case true:

            addSubview(label)
            label.topAnchor.constraint(equalTo: topAnchor).isActive = true
            label.leftAnchor.constraint(equalTo: leftAnchor).isActive = true
            label.widthAnchor.constraint(equalTo: widthAnchor).isActive = true
            label.heightAnchor.constraint(equalToConstant: frame.height / 5.25).isActive = true

            gallery.register(NestedCollectionViewCell.self, forCellWithReuseIdentifier: cellId)
            gallery.delegate = self
            addSubview(gallery)
            gallery.topAnchor.constraint(equalTo: label.bottomAnchor).isActive = true
            gallery.bottomAnchor.constraint(equalTo: bottomAnchor).isActive = true
            gallery.widthAnchor.constraint(equalTo: widthAnchor).isActive = true
            gallery.heightAnchor.constraint(equalTo: heightAnchor, constant: -frame.height / 5.25).isActive = true

        case false:

            print("removed cv")
            // ...
        
    

    //...


extension CollectionViewCell: UICollectionViewDelegateFlowLayout 

    func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize 

        return gallery.frame.size
    



private extension CollectionViewCell 

    class func _gallery() -> UICollectionView 

        let layout = UICollectionViewFlowLayout()

        layout.minimumInteritemSpacing = 0
        layout.minimumLineSpacing = 0
        layout.scrollDirection = .horizontal

        let cv = UICollectionView(frame: .zero, collectionViewLayout: layout)

        cv.isPagingEnabled = true
        cv.showsHorizontalScrollIndicator = false
        cv.translatesAutoresizingMaskIntoConstraints = false
        return cv
    

    class func _label() -> UILabel 

        let label = UILabel()

        label.font = UIFont(name: "Montserrat-Regular", size: 15)
        label.textColor = .white
        label.translatesAutoresizingMaskIntoConstraints = false
        return label
    

(C)

import UIKit

class NestedCollectionViewCell: UICollectionViewCell 

    private let containerView = NestedCollectionViewCell._containerView()

    override init(frame: CGRect) 
        super.init(frame: frame)

        isOpaque = true
        clipsToBounds = true
        backgroundColor = .white

        addSubview(containerView)
        containerView.centerXAnchor.constraint(equalTo: centerXAnchor).isActive = true
        containerView.centerYAnchor.constraint(equalTo: centerYAnchor).isActive = true
        containerView.widthAnchor.constraint(equalTo: widthAnchor).isActive = true
        containerView.heightAnchor.constraint(equalTo: heightAnchor).isActive = true

        //...
    

    required init?(coder aDecoder: NSCoder) 
        fatalError("init(coder:) has not been implemented")
    


private extension NestedCollectionViewCell 

    class func _containerView() -> UIImageView 

        let view = UIImageView()

        view.contentMode = .scaleAspectFill
        view.translatesAutoresizingMaskIntoConstraints = false
        return view
    


编辑 2 我试过尼克的回答here。

当滚动方向设置为.vertical时,一切正常。

当设置为.horizontalC 时不显示单元格...

【问题讨论】:

你能显示你的代码吗?你在用锚吗?还是你使用了故事板? @kbunarjo:一切都是通过锚点以编程方式完成的,是的。请参阅编辑后的答案和实施。 【参考方案1】:

愚蠢,愚蠢的菜鸟错误。如果其他人像我一样需要眼镜,请留在这里:)

集合视图没有水平约束...

addSubview(gallery)
gallery.topAnchor.constraint(equalTo: label.bottomAnchor).isActive = true
gallery.bottomAnchor.constraint(equalTo: bottomAnchor).isActive = true

将其更正为

addSubview(gallery)
gallery.topAnchor.constraint(equalTo: label.bottomAnchor).isActive = true
gallery.leftAnchor.constraint(equalTo: leftAnchor).isActive = true

修复它(显然)。

【讨论】:

以上是关于UICollectionView 中水平滚动的单元格消失的主要内容,如果未能解决你的问题,请参考以下文章

计算 iOS 中水平 UICollectionView 的动态单元格高度

在 Table View Controller 中水平滚动 UITableView

具有多个部分的 UICollectionView

对 SwiftUI 中水平滚动视图内的列表不起作用的操作

带有 pagingEnabled 的 UICollectionView 滚动动作控件

在 tableview 中水平滚动以及正常的垂直滚动