0

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?

Rouzbeh
  • 39
  • 5

1 Answers1

0

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

backslash-f
  • 7,923
  • 7
  • 52
  • 80
  • 1
    I really appreciate your help. I'm still struggling with it, but I think you have shown me the answer and I can solve the problem with that – Rouzbeh Mar 03 '19 at 20:31
  • It may look simple, but there are loads of concepts there. Some struggling is expected. :) Anyway, I'm glad it was useful! It was my pleasure, really. If anything, keep posting your questions... Cheers! – backslash-f Mar 03 '19 at 21:17
  • dear @backslash-f, I have two other questions :) sorry to take your time 1- Finally I made it something like what you did, but same as you, my icons have a black background, while their background is transparent in the paintCode codes, could you tell me that how I can remove its background? 2- What is the best way that I can add the icon and label into an array as I did it in createOptionsArray() that I have shown it to you on the first page. thank you so much – Rouzbeh Mar 05 '19 at 02:25
  • Question #1 is easy, you just need to set a `clear color` for the `UIView background color` in `Interface Builder` (or programatically). Question #2: it really depends on how you want to architect your code. I personally wouldn't use an array, for instance. I've updated my answer with an implementation proposal that relies on `subclassing UIView` and an `option enum`. That to me looks like a more elegant solution... Take a look. – backslash-f Mar 05 '19 at 09:48
  • Dear @backslash-f, first of all, I have to thank you for all of your help. I'm really appreciated. Everything works perfectly now, except for one thing: I set `clear color` for the `UIView background color`, but nothing changes. The interesting thing is, in my app, after clicking on any row, it will show its icon in another view, in the new view, the icon doesn't have any background and it's clear! if I change the background color to red for example, it only shows it on the new view, not in the table view that is located, for some reason, changing background color is not working in tableview – Rouzbeh Mar 07 '19 at 04:03
  • Well, that‘s weird. The only thing I have to do is to set a clear background color for the UIView and that’s it. Also the behavior you described doesn’t seem correct. I would say double check your table view setup, perhaps comparing it with the example project I posted. – backslash-f Mar 07 '19 at 06:03
  • 1
    Thank you dear @backslash-f, I will double check the table view setup with your example. I really appreciate your help. – Rouzbeh Mar 08 '19 at 00:26