JimmyLee
JimmyLee

Reputation: 569

How to update data and view of my customized cell subview?

I have a customized view to add on my cell containView.
But when I update my data, and I use reloadData to reload tableview.
The view doesn't change like nothing happening.
I want to add one item "A6" to my view.
What's wrong with me.
Have any idea to refresh the view? Thanks.

My view like following image.
The items update accroding to the infos array.

enter image description here

class ViewController: UIViewController {

    var alreadyLoadCell: Bool = false

    var initInfos = [Info(name: A1, color: UIColor.A1), Info(name: A2, color: UIColor.A2), Info(name: A3, color: UIColor.A3), Info(name: A4, color: UIColor.A4), Info(name: A5, color: UIColor.A5)]

    var updateInfos = [Info(name: A1, color: UIColor.A1), Info(name: A2, color: UIColor.A2), Info(name: A3, color: UIColor.A3), Info(name: A4, color: UIColor.A4), Info(name: A5, color: UIColor.A5), Info(name: A6, color: UIColor.A6)]         


    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {

        if indexPath.row == 0 {

            let customCell = tableView.dequeueReusableCell(withIdentifier: "CustomTableViewCell", for: indexPath) as! CustomTableViewCell

            if alreadyLoadCell == false {
                customCell.initCell(infos: initInfos)
                alreadyLoadCell = true
            }else{
                //TODO: reloadData to update cell
                customCell.updateCell(infos: updateInfos)
            }

            return customCell

        }

       return UITableViewCell()            
    }

}

class CustomTableViewCell: UITableViewCell {

    var testItemView: UIView?

    func initCell(infos: [Info]) {

        self.testItemView = createItemView(infos: infos)

        self.contentView.addSubview(testItemView!)

        testItemView?.snp.makeConstraints { (make) in
            make.left.equalTo(13)
            make.top.equalTo(10)
            make.right.equalTo(-13)
            make.height.equalTo(195)
            make.bottom.equalTo(-10)
        }

   }

   func updateCell(infos: [Info]) {

       self.testContainView = createItemView(infos: infos)
       //How to update successful?

   }


    func createItemView(infos: [Info]) -> UIView {

        let contentView = UIView()
        var serialNumber = 0
        var previousView: TitleView?

        for info in infos {

            let view = TitleView(assets: info, color: info.color)
            contentView.addSubview(view)
            switch serialNumber {
            case 0: //A1
                view.snp.makeConstraints { (make) in
                    make.left.equalTo(15)
                    make.width.equalTo(135)
                    make.top.equalToSuperview()
                }
                previousView = view
            case 1: //A2
                view.snp.makeConstraints { (make) in
                    make.right.equalToSuperview().offset(-15)
                    make.width.equalTo(135)
                    make.top.equalToSuperview()
                }
                previousView = view
            case 2: //A3
                view.snp.makeConstraints { (make) in
                    make.left.equalTo(15)
                    make.width.equalTo(135)                
                    make.top.equalTo((previousView?.snp.bottom)!).offset(5)
                }
                previousView = view
            case 3: //A4
                view.snp.makeConstraints { (make) in
                    make.right.equalToSuperview().offset(-15)
                    make.width.equalTo(135)
                    make.centerY.equalTo((previousView?.snp.centerY)!)
                }
                previousView = view
            case 4: //A5
                view.snp.makeConstraints { (make) in
                    make.left.equalTo(15)
                    make.width.equalTo(135) 
                    make.top.equalTo((previousView?.snp.bottom)!).offset(5)
                }
                previousView = view
            case 5: //A6
                view.snp.makeConstraints { (make) in
                    make.right.equalToSuperview().offset(-15)
                    make.width.equalTo(135)
                    make.centerY.equalTo((previousView?.snp.centerY)!)
                }
                previousView = view
            default:
                break
            }

            serialNumber += 1
        }

        return contentView
    }

}

Upvotes: 2

Views: 534

Answers (2)

user6400204
user6400204

Reputation:

It's not OK to recreate elements inside of reusable cell. That would affect the performance of the App itself. Imagine having 1000 cells with that layout and every time you scroll it recreates everything from the scratch.

You use the same function createItemView for update and init, which is not necessary.

Instead, create custom xib layout with all your elements and with your A6 element that is initially hidden. Connect all the elements from xib to your custom cell class. In that way you'll always have all the elements in the place, and you just need to update the values for infos.

So, inside of cellForRowAt function instead of calling init or update, just update the data like:

customCell.someLabel.text = "example text"

or

    if infos.count == 6 {
    
        // this could mean that you have A6 in your array
    
        customCell.A6.isHidden = false
        customCell.A6. // change A6 element as you wish
    
    } else {
     
        customCell.A6.isHidden = true

    }

Upvotes: 1

IvanovDeveloper
IvanovDeveloper

Reputation: 602

At first, before updating cell, you should remove from superview early initiated testItemView, because at updateCells method you are create new instance of testItemView and add for new created view constraints again.


I think this code should work for you, replace you updateCell method:

func updateCell(infos: [Info]) {
   testContainView.removeFromSuperView
   testContainView = createItemView(infos: infos)

   contentView.addSubview(testItemView!)

   testItemView?.snp.makeConstraints { (make) in
        make.left.equalTo(13)
        make.top.equalTo(10)
        make.right.equalTo(-13)
        make.height.equalTo(195)
        make.bottom.equalTo(-10)
    }
}

Upvotes: 1

Related Questions