无法在 UICollectionViewCell 中锚定 UIImageVIew(以编程方式)

Posted

技术标签:

【中文标题】无法在 UICollectionViewCell 中锚定 UIImageVIew(以编程方式)【英文标题】:Unable to Anchor UIImageVIew in UICollectionViewCell (programmatically) 【发布时间】:2020-08-05 02:23:04 【问题描述】:

在 Playground 中指定一个视图,但似乎无法弄清楚为什么 UIIMageView 被放置在 UICollectionViewCell 的中心。

相关代码:

class BookCell: UICollectionViewCell 
    
    static let identifier = "bookCell"
    
    override init(frame: CGRect) 
        super.init(frame: .zero)
        self.layer.cornerRadius = 12
        self.backgroundColor = .brown
        addAllSubviews()
        addAllConstraints()
    
    
    required init?(coder: NSCoder) 
        fatalError("init(coder:) has not been implemented")
    
    
    lazy var cover: UIImageView = 
        let imageview = UIImageView()
        imageview.translatesAutoresizingMaskIntoConstraints = false
        var largeImage = UIImage(named: "medium.jpg")
        imageview.image = largeImage
        imageview.contentMode = .scaleAspectFit
        //imageview.contentMode = .scaleToFill
        return imageview
    ()
    
    func coverConstraints()
        NSLayoutConstraint.activate([
            cover.leadingAnchor.constraint(equalTo: self.safeAreaLayoutGuide.leadingAnchor, constant: 0),
            
            /**widthConstraint*/
            NSLayoutConstraint(item: cover,
                               attribute: .width,
                               relatedBy: .equal,
                               toItem: self,
                               attribute: .width,
                               multiplier: 1.0, constant: 0.0),

            /**heightConstraint*/
            NSLayoutConstraint(item: cover,
                               attribute: .height,
                               relatedBy: .equal,
                               toItem: self,
                               attribute: .height,
                               multiplier: 0.75, constant: 0.0)
        ])
    
    
    
    let wordLabel: UILabel = 
        let label = UILabel()
        label.translatesAutoresizingMaskIntoConstraints = false
        label.text = "test"
        return label
    ()
    
    func wordLabelConstraints() 
        NSLayoutConstraint.activate([
            wordLabel.leadingAnchor.constraint(equalTo: leadingAnchor),
            wordLabel.trailingAnchor.constraint(equalTo: trailingAnchor),
            wordLabel.topAnchor.constraint(equalTo: cover.bottomAnchor, constant: 2)
        ])
    

    // MARK: - Add Subviews
    func addAllSubviews() 
        self.addSubview(cover)
        self.addSubview(wordLabel)
    
    
    // MARK: - SubViews Constraints
    func addAllConstraints() 
        coverConstraints()
        wordLabelConstraints()
    

BookCell 然后在 UICollectionViewController 中使用,如下所示:

class ViewController: UIViewController 

    fileprivate let collectionView: UICollectionView = 
        let layout = ColumnFlowLayout()
        let cv = UICollectionView(frame: .zero, collectionViewLayout: layout)
        cv.backgroundColor = .blue
        cv.translatesAutoresizingMaskIntoConstraints = false
        return cv
    ()

    var data: [Int] = Array(0..<10)

    override func loadView() 
        super.loadView()
        view.addSubview(collectionView)
        
        NSLayoutConstraint.activate([
            collectionView.topAnchor.constraint(equalTo: view.topAnchor),
            collectionView.bottomAnchor.constraint(equalTo: view.bottomAnchor),
            collectionView.leadingAnchor.constraint(equalTo: view.leadingAnchor, constant: 16),
            collectionView.trailingAnchor.constraint(equalTo: view.trailingAnchor, constant: -16)
        ])

    

    override func viewDidLoad() 
        super.viewDidLoad()
        self.collectionView.dataSource = self
        self.collectionView.delegate = self
        self.collectionView.register(BookCell.self, forCellWithReuseIdentifier:     BookCell.identifier)
        self.collectionView.alwaysBounceVertical = true
        self.collectionView.backgroundColor = .yellow
    

结果:

我注意到使用 scaleToFill 而不是scaleAspectFit 会导致图像覆盖单元格的整个宽度。结果(见下图)符合我的目标,但......见下面的问题

问题:

    使用scaleToFill 将图像固定到 UICollectionViewCell 的边缘(前导和尾随)的唯一方法。如果有,这是为什么呢? 我还尝试将 UIImageView 添加到 UIStackView,我相信我得到了相同的结果。 请注意,我对通过 Storyboard 执行此操作不感兴趣。

感谢您提供反馈

【问题讨论】:

【参考方案1】:

还有一个选项:.scaleAspectFill,但可能会裁剪您的图片内容。

The option to scale the content to fill the size of the view.
Some portion of the content may be clipped to fill the view’s bounds.

考虑获取图像大小比(宽/高),你有一个基于superview的固定宽度,而高度将基于图像比例。

【讨论】:

以上是关于无法在 UICollectionViewCell 中锚定 UIImageVIew(以编程方式)的主要内容,如果未能解决你的问题,请参考以下文章

无法在 xib 文件中选择 UICollectionViewCell

UICollectionViewCell 无法识别?

无法在 UITableViewCell 中聚焦 UICollectionViewCell

在 UICollectionViewCell 的情况下无法同时满足约束

UICollectionViewCell 中的自动布局宽度常量无法正常工作

无法将 UILabel 添加到 UICollectionViewCell