【问题标题】:CollectionView Cells are not visibleCollectionView 单元格不可见
【发布时间】:2020-01-29 13:47:28
【问题描述】:

使用 Swift 5.1.3、iOS13.3,

我正在尝试将水平 CollectionViewController 显示为 ChildView 控制器。

问题:所有单元格都是不可见的!

代码中的打印语句(在下面的评论中显示了很多 !!!!!!!!)

Test.CardHeaderCell: 0x7fa563709370; baseClass = UICollectionViewCell; frame = (1059 23; 343 279); hidden = YES; layer = <CALayer: 0x6000024de080>>

代码如下:

override func viewDidLoad() {
    // ...

    let cardsHorizontalController = CardsHorizontalController()
    self.addChild(cardsHorizontalController)
    self.view.addSubview(cardsHorizontalController.view)
    self.didMove(toParent: cardsHorizontalController)
    cardsHorizontalController.view.translatesAutoresizingMaskIntoConstraints = false
    cardsHorizontalController.view.topAnchor.constraint(equalTo: self.view.topAnchor, constant: 70.0).isActive = true
    cardsHorizontalController.view.heightAnchor.constraint(equalToConstant: 390.0).isActive = true
    cardsHorizontalController.view.widthAnchor.constraint(equalToConstant: UIScreen.main.bounds.width).isActive = true
}

这是水平控制器

class CardsHorizontalController: HorizontalSnappingController, UICollectionViewDelegateFlowLayout {

    let cellId = "horizontalCardID"

    override func viewDidLoad() {
        super.viewDidLoad()

        collectionView.backgroundColor = .green

        collectionView.register(CardHeaderCell.self, forCellWithReuseIdentifier: cellId)

        if let layout = collectionViewLayout as? UICollectionViewFlowLayout {
            layout.scrollDirection = .horizontal
        }

        collectionView.showsHorizontalScrollIndicator = true
        collectionView.showsVerticalScrollIndicator = false

        // do the insets here instead of the optional "insetForSectionAt" delegate-method
        // i.e. this helps to get the scrolled cells aligned in the middle of the screen once 1 cell wide scrolled...
        collectionView.contentInset = .init(top: 65.0, left: 16.0, bottom: 0.0, right: 16.0)
    }

    func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
        return .init(width: view.frame.width - 32.0, height: 279.0)
    }

    override func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
        return 17
    }

    override func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
        let cell = collectionView.dequeueReusableCell(withReuseIdentifier: cellId, for: indexPath)

        // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        print(cell)
        // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

        return cell
    }

}

还有细胞:

class CardHeaderCell: UICollectionViewCell {

    let imageView = UIImageView(cornerRadius: 10.0)

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

        // blur view
        imageView.backgroundColor = UIColor(red: 0.086, green: 0.086, blue: 0.086, alpha: 0.35)
        let visualEffectView = UIVisualEffectView(frame: imageView.frame)
        visualEffectView.effect = UIView.customBlurEffect()
        visualEffectView.autoresizingMask = UIView.AutoresizingMask(rawValue: UIView.AutoresizingMask.flexibleWidth.rawValue | UIView.AutoresizingMask.flexibleHeight.rawValue)
        imageView.addSubview(visualEffectView)

        let stackView = VerticalStackView(arrangedSubviews: [
            imageView
        ], spacing: 12.0)
        addSubview(stackView)
        stackView.fillSuperview(padding: .init(top: 0.0, left: 0.0, bottom: 0.0, right: 0.0))
    }

    required init?(coder aDecoder: NSCoder) {
        fatalError()
    }   
}

为了完整起见,这里是其余的自定义类...

class HorizontalSnappingController: UICollectionViewController {

    init() {
        let layout = BetterSnappingLayout()
        layout.scrollDirection = .horizontal
        super.init(collectionViewLayout: layout)
        collectionView.decelerationRate = .fast
    }

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

}
class BetterSnappingLayout: UICollectionViewFlowLayout {

    override func targetContentOffset(forProposedContentOffset proposedContentOffset: CGPoint, withScrollingVelocity velocity: CGPoint) -> CGPoint {

        guard let collectionView = collectionView else {
            return super.targetContentOffset(forProposedContentOffset: proposedContentOffset, withScrollingVelocity: velocity)
        }

        let nextX: CGFloat

        if proposedContentOffset.x <= 0 || collectionView.contentOffset == proposedContentOffset {
            nextX = proposedContentOffset.x
        } else {
            nextX = collectionView.contentOffset.x + (velocity.x > 0 ? collectionView.bounds.size.width : -collectionView.bounds.size.width)
        }

        let targetRect = CGRect(x: nextX, y: 0, width: collectionView.bounds.size.width, height: collectionView.bounds.size.height)

        var offsetAdjustment = CGFloat.greatestFiniteMagnitude

        let horizontalOffset = proposedContentOffset.x + collectionView.contentInset.left

        let layoutAttributesArray = super.layoutAttributesForElements(in: targetRect)

        layoutAttributesArray?.forEach({ (layoutAttributes) in
            let itemOffset = layoutAttributes.frame.origin.x
            if fabsf(Float(itemOffset - horizontalOffset)) < fabsf(Float(offsetAdjustment)) {
                offsetAdjustment = itemOffset - horizontalOffset
            }
        })

        return CGPoint(x: proposedContentOffset.x + offsetAdjustment, y: proposedContentOffset.y)
    }

}
class VerticalStackView: UIStackView {

    init(arrangedSubviews: [UIView], spacing: CGFloat = 0, alignment: UIStackView.Alignment = .center) {
        super.init(frame: .zero)

        arrangedSubviews.forEach({addArrangedSubview($0)})

        self.spacing = spacing
        self.alignment = alignment
        self.axis = .vertical
    }

    required init(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }

}

【问题讨论】:

  • 尝试添加let cell = collectionView.dequeueReusableCell(withReuseIdentifier: cellId, for: indexPath) as! CardHeaderCell并在cellForRowAt方法的单元格内容视图中添加单元格项目
  • 我刚刚做到了。但没有变化。细胞仍然不可见!
  • collectionView的delegate和datasource应该连接
  • @Kisham Bhatiya:您能否更具体地说明一下代表的位置(即我的上述哪些课程)以及如何分配代表?我纯粹在代码中工作(没有故事板)
  • 先试试viewDidLoad()self.didMove(toParent: cardsHorizontalController)改成cardsHorizontalController.didMove(toParent: self)

标签: swift uicollectionview uikit uicollectionviewcell


【解决方案1】:

我终于找到了解决办法:

VerticalStackView 类有一个默认的对齐属性.center

当我将 .center 替换为 .fill 作为默认值时 - 一切都按预期工作!

VerticalStackView 的用法保持不变(即适用对齐的默认值):

let stackView = VerticalStackView(arrangedSubviews: [
    imageView
], spacing: 12.0)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-04-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-11-27
    相关资源
    最近更新 更多