1

This is probably some misconception on my side but I can't see why this doesn't work.

I have created a UITableViewCell subclass, like this:

class MenuCell: UITableViewCell {

var mcImage: String
var mcLabel: String

init(mcImage: String, mcLabel: String) {
    self.mcImage = mcImage
    self.mcLabel = mcLabel

    super.init(style: .default, reuseIdentifier: "reuseIdentifier")

    setupView()
}

required init?(coder aDecoder: NSCoder) {
    fatalError("init(coder:) has not been implemented")
}

func setupView() {
    let mcImageView   = UIImageView()
    let mcLabelView   = UILabel()

    mcImageView.image         = UIImage(systemName: mcImage)
    mcLabelView.text          = mcLabel

    // Rest of setup (font, colors, positions...)

    addSubview(mcImageView)
    addSubview(mcLabelView)
}}

If in my ViewController I write:

var firstCell = MenuCell(mcImage: "plus.circle", mcLabel: "Some text")

It creates the object and works perfectly, I can access my object properties, but why can't I set a property like this:

firstCell.mcImage = "plus.circle"   // This doesn't work

It just ignores me, but however I can set any UITableViewCell property:

firstCell.accessoryType = .none   // This works
Jawad Ali
  • 13,556
  • 3
  • 32
  • 49
Alvaro
  • 182
  • 2
  • 13
  • hold a reference to `UIImageView` and set its `.image` property directly using `UIImage(systemName: "plus.circle")` rather than setting `mcImage` property – Sandeep Bhandari May 26 '20 at 18:33
  • It **does** work, it changes the value of the property but it does not necessarily change the image because property and image (view) are not related. – vadian May 26 '20 at 18:35

1 Answers1

2

Well it will set the value of mcImage to "plus.circle" but you cant see the impact ... because you are not calling setupView() after assigning it a value ... in setupView() function you are using this value to create imageView with this image

You can edit your class like this

     class MenuCell: UITableViewCell {

         private let mcImageView   = UIImageView()
         private let mcLabelView   = UILabel()


            var mcImage: String {
                didSet{
                    self.mcImageView.image  = UIImage(systemName: mcImage)
                }
            }
        var mcLabel: String {
            didSet{
                self.mcLabelView.text = mcLabel
            }
        }

    init(mcImage: String, mcLabel: String) {
        self.mcImage = mcImage
        self.mcLabel = mcLabel


        super.init(style: .default, reuseIdentifier: "reuseIdentifier")
        addSubview(mcImageView)
        addSubview(mcLabelView)
        setupView()
    }
    func setupView() {


        // Rest of setup (font, colors, positions...)


    }
override func prepareForReuse() {
        super.prepareForReuse()
        mcImageView.image = nil
        mcLabelView.text = ""
    }

        }

So that every time you set value of image string ... it will refresh your view

Jawad Ali
  • 13,556
  • 3
  • 32
  • 49
  • 1
    calling `setupView` again and again will simply add UIImageViews again and again, why cant you simply hold a strong reference to UIImageView and set its `.image` property rather, this is a terrible advice – Sandeep Bhandari May 26 '20 at 18:31
  • yeah i havent seen that .. updated my code .. thank you for suggestion – Jawad Ali May 26 '20 at 18:37
  • 1
    Yup much better :) hence +1. BTW user will comeback and say cells are not updated properly on scrolling so to avoid future issues also if required mention `prepareForReuse` and clear images :) – Sandeep Bhandari May 26 '20 at 18:38
  • 1
    Thanks both of you. I can see it clearly now. About _prepareForReuse_, thanks for pointing. In this case it was a static TableView with just a few rows, but I'll keep the note for the future :) – Alvaro May 26 '20 at 18:46