Rouzbeh
Rouzbeh

Reputation: 39

Add custom class to UIView in the UITableView

I have made some icon with the paint code app:

class addIconView: UIView {
    override func draw(_ rect: CGRect) {
      TodayIcon.draw(frame: rect)
    }
 }

I also add the configuration of the cells in another class:

class OptionsTableCell {
    var icon: UIView
    var label: String

    init(icon: UIView, label: String) {
        self.icon = icon
        self.label = label
    }
}

Then I added a UIView in the prototype cell in a TableView. I used this array to update icons of the cell:

var optionsArray: [OptionsTableCell] = []

func createOptionsArray() -> [OptionsTableCell] {

    var cell: [OptionsTableCell] = []

    let addIcon = OptionsTableCell(icon: addIconView(), label: "Add")

    cell.append(addIcon)

    return cell
}

I just added addIconView() to update the icon of the cell. I think it's wrong.

How can I update the custom class of an UIView to change the icon inside it?

Upvotes: 0

Views: 373

Answers (1)

backslash-f
backslash-f

Reputation: 8193

Instead of using a generic UIView in the cell, subclass it into a new class that encapsulates the types of icons to be displayed. Consider this example:

UIView subclass that encapsulates the icon logic around PaintCode. Notice the Option enum and the @IBDesignable property (allows for live-rendering in Interface Builder):

import UIKit

@IBDesignable class OptionsView: UIView {

    // MARK: - Properties

    // Allowed options.
    enum Option {
        case star, tree
    }

    // Option that should currently be displayed. Default is .star (for no particular reason).
    var currentOption: Option = .star {
        didSet {
            setNeedsDisplay() // Force redrawing.
        }
    }

    // MARK: - Lifecycle

    override func draw(_ rect: CGRect) {
        drawIcon(rect)
    }
}

// MARK: - Private

private extension OptionsView {

    /// Logic to decide which icon to display.
    func drawIcon(_ rect: CGRect) {
        switch currentOption {
        case .star:
            StyleKit.drawStarIcon(frame: rect)
        case .tree:
            StyleKit.drawTreeIcon(frame: rect)
        }
    }
}

Storyboard configuration: custom UITableViewController + custom UITableViewCell with the custom UIView (notice the class attribute of type OptionsView):

setup

Connect the UILabel and the OptionsView to your CustomCell. Implementation example (notice the var option):

import UIKit

class CustomCell: UITableViewCell {

    // MARK: - Public  Properties

    // Option that should currently be displayed. Default is .star (for no particular reason).
    var option: OptionsView.Option = .star {
        didSet {
            iconView.currentOption = option
            updateLabelText()
        }
    }

    // MARK: - Private Properties

    @IBOutlet private weak var iconView: OptionsView!
    @IBOutlet private weak var label: UILabel!
}

// MARK: - Private

private extension CustomCell {

    func updateLabelText() {
        switch option {
        case .star:
            label.text = "Star"
        case .tree:
            label.text = "Tree"
        }
    }
}

Finally, in your custom UITableViewController:

import UIKit

class TableViewController: UITableViewController {

    // MARK: - Table view data source

    override func numberOfSections(in tableView: UITableView) -> Int {
        return 1 // Hardcoded in this example.
    }

    override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return 40 // Hardcoded in this example.
    }

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

        if let customCell = tableView.dequeueReusableCell(withIdentifier: "customCell", for: indexPath) as? CustomCell {

            // Logic around which option to display
            if indexPath.row < 20 {
                customCell.option = .star
            } else {
                customCell.option = .tree
            }

            return customCell
        }

        // Fallback.
        return UITableViewCell()
    }
}

Final result:

example

Refer to this project for the entire code (sixth test):
https://github.com/backslash-f/paintcode-tests

Upvotes: 0

Related Questions