Search code examples
iosswiftiphoneswift5

Is there any way to resize UIImageView inside UITableViewCell


I'm trying to add image inside of UITableViewCell with UIImageView, and really added "normally", but when i change the size of UIImageView. I get this error message:

[LayoutConstraints] Unable to simultaneously satisfy constraints. Probably at least one of the constraints in the following list is one you don't want. Try this: (1) look at each constraint and try to figure out which you don't expect; (2) find the code that added the unwanted constraint or constraints and fix it. ( "<NSLayoutConstraint:0x600001a30b40 UIImageView:0x7fad5ed0fd90.height == 90 (active)>", "<NSLayoutConstraint:0x600001a30b90 V:|-(0)-[UIStackView:0x7fad5ed10360] (active, names: '|':Music.MusicsCell:0x7fad5ed0ec20'cellId' )>", "<NSLayoutConstraint:0x600001a30d70 UIStackView:0x7fad5ed10360.bottom == Music.MusicsCell:0x7fad5ed0ec20'cellId'.bottom (active)>", "<NSLayoutConstraint:0x600001a31270 'UISV-canvas-connection' UIStackView:0x7fad5ed10360.top == UIImageView:0x7fad5ed0fd90.top
(active)>", "<NSLayoutConstraint:0x600001a312c0 'UISV-canvas-connection' V:[UIImageView:0x7fad5ed0fd90]-(0)-| (active, names: '|':UIStackView:0x7fad5ed10360 )>", "<NSLayoutConstraint:0x600001a314f0 'UIView-Encapsulated-Layout-Height' Music.MusicsCell:0x7fad5ed0ec20'cellId'.height == 90.5 (active)>" )

Will attempt to recover by breaking constraint

but i've tried many things, like simple things, just image with background and size, example:

let imageView: UIImageView = UIImageView()
imageView.size(size: CGSize(width: 40, height: 40))
imageView.backgroundColor = .purple
imageView.layer.cornerRadius = 6
imageView.clipsToBounds = true

and I don't know what I have to disappear this warning message. Follow the code below:

MusicsVC (UITableViewController):

class MusicsVC: UITableViewController {
    let cellId = "cellId"
    
    override func viewDidLoad() {
        super.viewDidLoad();
        
        tableView.register(MusicsCell.self, forCellReuseIdentifier: cellId)
    }
}

extension MusicsVC {
    override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return 5;
    }
    
    override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: cellId, for: indexPath) as! MusicsCell
    
        return cell;
    }
}

UITableViewCell:

class MusicsCell: UITableViewCell {

    let tituloLabel: UILabel = .textLabel(text: "Teste", fontSize: 16);
    
    override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
        super.init(style: style, reuseIdentifier: reuseIdentifier)

        let imageView: UIImageView = UIImageView()
        imageView.size(size: CGSize(width: 60, height: 60))
        imageView.layer.cornerRadius = 6
        imageView.clipsToBounds = true
        
        imageView.load(url: "https://studiosol-a.akamaihd.net/uploadfile/letras/fotos/d/7/4/2/d74238794c3024afbcba997e444fd2cb.jpg")
        
        let stackView = UIStackView(arrangedSubviews: [
            imageView,
            tituloLabel
        ])
        
        stackView.spacing = 12
        
        addSubview(stackView)
        stackView.inset(view: stackView, insets: UIEdgeInsets(top: 6, left: 12, bottom: 6, right: 12))
    }
    
    required init?(coder: NSCoder) {
        fatalError()
    }
}

Solution

  • I suppose do you want this, but your code is a little bit confused to know what you really you want... Declare your table view, and add constraints :

    class ViewController: UIViewController {
    
    let tableView = UITableView()
    let cellId = "cellId"
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        view.backgroundColor = .white
        
        tableView.delegate = self
        tableView.dataSource = self
        tableView.register(MusicsCell.self, forCellReuseIdentifier: cellId)
        tableView.translatesAutoresizingMaskIntoConstraints = false
        
        view.addSubview(tableView)
        tableView.topAnchor.constraint(equalTo: view.topAnchor).isActive = true
        tableView.leadingAnchor.constraint(equalTo: view.safeAreaLayoutGuide.leadingAnchor).isActive = true
        tableView.trailingAnchor.constraint(equalTo: view.safeAreaLayoutGuide.trailingAnchor).isActive = true
        tableView.bottomAnchor.constraint(equalTo: view.bottomAnchor).isActive = true
     }
    }
    

    now delegate and datasource

    extension ViewController: UITableViewDelegate, UITableViewDataSource {
    
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return 5
    }
    
    func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
        return 72 // 60 image view height + 6x2 padding from top and bottom = 72
    }
    
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: cellId, for: indexPath) as! MusicsCell
        
        return cell;
     }
    }
    

    and this how your cell looks like:

    class MusicsCell: UITableViewCell {
    
    let tituloLabel: UILabel = {
        let label = UILabel()
        label.text = "Testo"
        label.font = .systemFont(ofSize: 16, weight: .regular)
        label.translatesAutoresizingMaskIntoConstraints = false
        return label
    }()
    
    let myImageView: UIImageView = {
        let iv = UIImageView()
        iv.contentMode = .scaleAspectFill
        iv.layer.cornerRadius = 6
        iv.clipsToBounds = true
        iv.translatesAutoresizingMaskIntoConstraints = false
        
        return iv
    }()
    
    override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
        super.init(style: style, reuseIdentifier: reuseIdentifier)
    
        guard let url = URL(string: "https://studiosol-a.akamaihd.net/uploadfile/letras/fotos/d/7/4/2/d74238794c3024afbcba997e444fd2cb.jpg") else {return}
        myImageView.downloadImage(from: url) // this is my extension to load image from url, you can use yours
        
        contentView.addSubview(myImageView)
        myImageView.topAnchor.constraint(equalTo: contentView.topAnchor, constant: 6).isActive = true
        myImageView.leadingAnchor.constraint(equalTo: contentView.leadingAnchor, constant: 12).isActive = true
        myImageView.widthAnchor.constraint(equalToConstant: 60).isActive = true
        myImageView.heightAnchor.constraint(equalToConstant: 60).isActive = true
        
        contentView.addSubview(tituloLabel)
        tituloLabel.topAnchor.constraint(equalTo: myImageView.topAnchor).isActive = true
        tituloLabel.leadingAnchor.constraint(equalTo: myImageView.trailingAnchor, constant: 10).isActive = true
        tituloLabel.trailingAnchor.constraint(equalTo: contentView.trailingAnchor).isActive = true
        tituloLabel.bottomAnchor.constraint(equalTo: myImageView.bottomAnchor).isActive = true
    }
    
    required init?(coder: NSCoder) {
        fatalError()
     }
    }
    

    and this is the result

    enter image description here