Ios 添加到自定义UICollectionViewCell时出现意外的CAShapeLayer行为

Ios 添加到自定义UICollectionViewCell时出现意外的CAShapeLayer行为,ios,swift,xcode,uikit,Ios,Swift,Xcode,Uikit,我想弄清楚这件事已经有一段时间了,但我已经找遍了。我一直在尝试将CAShapeLayer添加到自定义UICollectionViewCell中,但它要么没有绘制,要么只是有时绘制。我决定用以下代码简化我要解决的问题: class ViewController: UICollectionViewController, UICollectionViewDelegateFlowLayout { let cellId = "cell" let dataSou

我想弄清楚这件事已经有一段时间了,但我已经找遍了。我一直在尝试将CAShapeLayer添加到自定义UICollectionViewCell中,但它要么没有绘制,要么只是有时绘制。我决定用以下代码简化我要解决的问题:

class ViewController: UICollectionViewController, UICollectionViewDelegateFlowLayout {
    
    let cellId = "cell"
    let dataSource: [UIColor] = [.blue, .purple, .brown, .green, .red]

    override func viewDidLoad() {
        super.viewDidLoad()
        collectionView.isPagingEnabled = true
        collectionView.register(CellSubclass.self, forCellWithReuseIdentifier: cellId)
    }
    
    override func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
        return dataSource.count
    }
    
    override func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
        let cell = collectionView.dequeueReusableCell(withReuseIdentifier: cellId, for: indexPath) as! CellSubclass
        cell.backgroundColor = dataSource[indexPath.item]
        return cell
    }
    
    func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
        return CGSize(width: view.frame.width, height: view.frame.height)
    }
}

class CellSubclass: UICollectionViewCell {
    
    let circle = CAShapeLayer()
    
    override init(frame: CGRect) {
        super.init(frame: frame)
        circle.frame = bounds

        let circleCenter = self.center
        let path = UIBezierPath(arcCenter: circleCenter, radius: 100, startAngle: 0, endAngle: 2*CGFloat.pi, clockwise: true)
        circle.path = path.cgPath
        circle.fillColor = UIColor.gray.cgColor
        layer.addSublayer(circle)
    }
    
    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
}
我有以下UICollectionViewController的流布局

let layout = UICollectionViewFlowLayout()
layout.scrollDirection = .horizontal
layout.minimumLineSpacing = 0
let home = ViewController(collectionViewLayout: layout)
基于我所看到的其他StackOverflow问题,人们建议在初始化时将shape子层添加到自定义UICollectionViewCell中。但是,当我运行此代码时,会得到以下输出:

如果您能帮助您了解如何修复此行为,以便自定义单元格的每个实例都有自己的形状,我们将不胜感激。

更改

    let circleCenter = self.center


init()
期间,您的单元类不知道其大小

通过在
layoutSubviews()
中设置图层路径,您的运气会更好:

注意:如果单元大小改变(如设备旋转),这也会使圆居中

    let circleCenter = CGPoint(x:self.bounds.midX, y:self.bounds.midY)
class CellSubclass: UICollectionViewCell {
    
    let circle = CAShapeLayer()
    
    override init(frame: CGRect) {
        super.init(frame: frame)
        
        circle.fillColor = UIColor.gray.cgColor
        layer.addSublayer(circle)
    }
    
    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
    
    override func layoutSubviews() {
        super.layoutSubviews()

        circle.frame = bounds
        let circleCenter = CGPoint(x: bounds.midX, y: bounds.midY)
        let path = UIBezierPath(arcCenter: circleCenter, radius: 100, startAngle: 0, endAngle: 2*CGFloat.pi, clockwise: true)
        circle.path = path.cgPath
    }
}