子视图没有添加到一些 UICollectionViewCells 和闪烁以编程方式

问题描述

我正在尝试使用集合视图制作自定义图像滑块。我希望它可以重复使用。所以我制作了单独的自定义类,其中所有 collectionView 的东西。然后从 UIViewController 调用该类,如下面的代码所示。而我的 UICollectonViewCell 只包含 imageView。

问题在于第二个单元格。 imageView 没有被添加,在第三个单元格上,它也会闪烁。我试图调试这些问题,但不能。

ImageSlider 类和 UICollectionViewCell 类在最后,带有集合视图的东西:

class ImageSlider: UIView {
    var imgArr = [UIImage(named: "one.jpg"),UIImage(named: "3.jpg"),UIImage(named: "two.jpg"),UIImage(named: "4.jpg")]
    var sliderCollection : UICollectionView = {
        let widthRatio : Float = 16.0
        let heightRatio : Float = 9.0
        let collecionWidth = UIScreen.main.bounds.width - 30
        let layout = UICollectionViewFlowLayout()
        let collectionView = UICollectionView(frame: CGRect(x: 15,y: 100,width: collecionWidth,height: CGFloat((Float(collecionWidth)*heightRatio)/widthRatio)),collectionViewLayout: layout)
        layout.scrollDirection = .horizontal
        layout.minimumLinespacing = 0
        layout.minimumInteritemSpacing = 0
        collectionView.backgroundColor = .systemOrange
        collectionView.isPagingEnabled = true
//        collectionView.isScrollEnabled = true
        collectionView.register(ImageSliderCell.self,forCellWithReuseIdentifier: "ImageSliderCell")
        return collectionView
    }()
    
    
}

extension ImageSlider: UICollectionViewDelegate,UICollectionViewDataSource,UICollectionViewDelegateFlowLayout {
    func collectionView(_ collectionView: UICollectionView,numberOfItemsInSection section: Int) -> Int {
        return imgArr.count
    }
    
    func collectionView(_ collectionView: UICollectionView,cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
        let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "ImageSliderCell",for: indexPath) as! ImageSliderCell
        
        cell.imgView.image = imgArr[indexPath.item]
//        cell.imgView.contentMode = .scaleAspectFit
        print("cell frame : ","(\(cell.frame.width),\(cell.frame.height)")
        print("imgView frame : ","(\(cell.imgView.frame.width),\(cell.imgView.frame.height)")
        return cell
    }
    
    func collectionView(_ collectionView: UICollectionView,layout collectionViewLayout: UICollectionViewLayout,sizeforItemAt indexPath: IndexPath) -> CGSize {
        return CGSize(width: collectionView.frame.width,height: collectionView.frame.height)
    }
    
}

class ImageSliderCell: UICollectionViewCell {
    var imgView = UIImageView()
    
//    override func awakeFromNib() {
//        self.addSubview(imgView)
//    }
    
    override init(frame: CGRect) {
        super.init(frame: frame)
        imgView.frame = frame
        self.addSubview(imgView)
    }
    
    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
}

这是 ViewController,我在其中调用 ImageSlider() 类。

class ImageSliderVC: UIViewController,UICollectionViewDelegate {
    
    let imageSlider = ImageSlider()
    
    override func viewDidLoad() {
        super.viewDidLoad()
        self.view.addSubview(imageSlider.sliderCollection)
        imageSlider.sliderCollection.delegate = imageSlider
        imageSlider.sliderCollection.dataSource = imageSlider
        imageSlider.sliderCollection.reloadData()
    }
}

解决方法

看起来它不能不受约束地工作,因为 UICollectionViewCell 可以用零帧创建,并将其转换为单元格内的 imageView。您需要向 imageView 添加约束以使其可见。

extension UIView {
    
    func centerX(inView view: UIView,constant: CGFloat = 0) {
        translatesAutoresizingMaskIntoConstraints = false
        centerXAnchor.constraint(equalTo: view.centerXAnchor,constant: constant).isActive = true
    }
    
    func centerY(inView view: UIView,constant: CGFloat = 0) {
        translatesAutoresizingMaskIntoConstraints = false
        centerYAnchor.constraint(equalTo: view.centerYAnchor,constant: constant).isActive = true
    }
    
    func setDimensions(height: CGFloat,width: CGFloat) {
        translatesAutoresizingMaskIntoConstraints = false
        heightAnchor.constraint(equalToConstant: height).isActive = true
        widthAnchor.constraint(equalToConstant: width).isActive = true
    }
    
    func setHeight(_ height: CGFloat) {
        translatesAutoresizingMaskIntoConstraints = false
        heightAnchor.constraint(equalToConstant: height).isActive = true
    }
}

class ImageSliderCell: UICollectionViewCell {
    var imgView = UIImageView()
    
    
    override init(frame: CGRect) {
        super.init(frame: frame)
  
        self.addSubview(imgView)
        // not sure about the right size of image ...
        imgView.setDimensions(height: 100.0,width: 100.0)
    }
    
    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
}