Search code examples
iosswiftviewuiviewuiimageview

Center UIImegaeView in CollectionViewCell


I Try to create a collectionView cell with an image at the center of it

My class looks like:

import Foundation
import UIKit

class MenuCell: UICollectionViewCell{
    

    let image:UIImageView = {
        
        let i = UIImageView()
        i.image = (UIImage(named: "mainMenu"))
        i.contentMode = .scaleAspectFit
        return i
        
    }()
    
    override init(frame: CGRect) {
        super.init(frame: frame)
        

    }
    
    required init?(coder: NSCoder) {
        fatalError()
    }
    
    func setupCell(){
        addSubview(image)

        let centerXConst = NSLayoutConstraint(item: image, attribute: .centerX, relatedBy: .equal, toItem: self.contentView, attribute: .centerY, multiplier: 1.0, constant: 0.0)
        let centerYConst = NSLayoutConstraint(item: image, attribute: .centerY, relatedBy: .equal, toItem: self.contentView, attribute: .centerY, multiplier: 1.0, constant: 0.0)
        
    
        image.addConstraints([centerXConst, centerYConst])
        NSLayoutConstraint.activate([image.centerYAnchor.constraint(equalTo: self.contentView.centerYAnchor), image.centerXAnchor.constraint(equalTo: contentView.centerXAnchor)])


    }
    
}

But when I run it it gives me an error

When added to a view, the constraint's items must be descendants of that view (or the view itself). This will crash if the constraint needs to be resolved before the view hierarchy is assembled. Break on

As I see, I add constrant normally.

UPD: Change code of func. Doesnt wotk =(

func setupCell(){
    contentView.addSubview(image)

    let centerXConst = NSLayoutConstraint(item: image, attribute: .centerX, relatedBy: .equal, toItem: self.contentView, attribute: .centerX, multiplier: 1.0, constant: 0.0)
    let centerYConst = NSLayoutConstraint(item: image, attribute: .centerY, relatedBy: .equal, toItem: self.contentView, attribute: .centerY, multiplier: 1.0, constant: 0.0)

    NSLayoutConstraint.activate([centerXConst, centerYConst])


}

Solution

  • As I see, I add constrant normally.

    Well, you see it wrong. You are pinning the image view to the cell content view, but you are not putting the image view in the content view. You need to. Change

    addSubview(image)
    

    To

    contentView.addSubview(image)
    

    Also, as has been pointed out in a comment, it makes no sense to pin a center x to a center y. Correct as follows:

    let centerXConst = NSLayoutConstraint(item: image, attribute: .centerX, relatedBy: .equal, toItem: self.contentView, attribute: .centerX, multiplier: 1.0, constant: 0.0)
    let centerYConst = NSLayoutConstraint(item: image, attribute: .centerY, relatedBy: .equal, toItem: self.contentView, attribute: .centerY, multiplier: 1.0, constant: 0.0)
    

    Plus you have forgotten to tell the image view not to translate its autoresizing mask into constraints.

    Finally, do not both add and activate constraints. Activating adds, and you obviously do not know which view to add the constraints to. So delete this line:

    image.addConstraints([centerXConst, centerYConst])