how can i call drawrect cgrect cellforrowat and draw on a custom tableview?

You just need to make your data point arrays accessible as public properties:

class DrawWorkoutChart: UIView {

    private let ftp = 100

    var dataPointsX: [CGFloat] = []
    var dataPointsY: [CGFloat] = []

    override func draw(_ rect: CGRect) {
        super.draw(rect)
    }
}

In your custom Cell class you need a custom method to pass that data points to your view:

extension UIView {
    func fill(with view: UIView) {
        addSubview(view)
        NSLayoutConstraint.activate([
            leftAnchor.constraint(equalTo: view.leftAnchor),
            rightAnchor.constraint(equalTo: view.rightAnchor),
            topAnchor.constraint(equalTo: view.topAnchor),
            bottomAnchor.constraint(equalTo: view.bottomAnchor),
        ])
    }
}

class ErgWorkoutCell: UITableViewCell {

    static let identifier = String(describing: ErgWorkoutCell.self)

    lazy var chartView: DrawWorkoutChart = {
        let chart = DrawWorkoutChart()
        chart.translatesAutoresizingMaskIntoConstraints = false
        chart.backgroundColor = .black
        chart.clearsContextBeforeDrawing = true

        let height = chart.heightAnchor.constraint(equalToConstant: 500)
        height.priority = .defaultHigh
        height.isActive = true
        return chart
    }()

    func configure(dataPointsX: [CGFloat], dataPointsY: [CGFloat]) {
        chartView.dataPointsX = dataPointsX
        chartView.dataPointsY = dataPointsY
        chartView.setNeedsDisplay()
    }

    override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
        super.init(style: style, reuseIdentifier: reuseIdentifier)
        contentView.fill(with: chartView)
    }

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

Notice that I’m explicitly setting the view’s backgroundColor and clearsContextBeforeDrawing properties. This is important so that your your chart is cleared before draw(rect:) is called.

The configure method is where the magic happens. We pass in our data points and call setNeedsDisplay so that the view is redrawn.

Now in your cellForRowAt method you just need to pass in your data points:

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCell(withIdentifier: ErgWorkoutCell.identifier) as! ErgWorkoutCell
    cell.configure(
        dataPointsX: .random(count: 6, in: 0..<20),
        dataPointsY: .random(count: 6, in: 0..<100)
    )
    return cell
}

And this is just a method for generating arrays with random values:

extension Array where Element: SignedNumeric {

    static func random(count: Int, in range: Range<Int>) -> Self {
        return Array(repeating: 0, count: count)
            .map { _ in Int.random(in: range) }
            .compactMap { Element(exactly: $0) }
    }
}

CLICK HERE to find out more related problems solutions.

Leave a Comment

Your email address will not be published.

Scroll to Top