UITableViewCell gets reused and shows wrong drawing in UIView

人走茶凉 提交于 2021-02-11 12:14:30

问题


I've been having this problem for weeks and I think I am not able to solve it.

I have a tableView which has custom tableViewCells and they are filled with data. The tableViewCell has two UILabels and one UIView.

The problem appears when I scroll several times the drawings on the UIViews are overlapped one with another, I think they are redrawn. I know that this behavior is because of the reuse of the cells but I can't even locate the origin of the problem.

UIViews show perfectly when opening the app

UIViews get overlapped after scrolling

My UITableView's cellForRowAtIndexPath is:

func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
    let CellIdentifier = "Cell"

    let cell: CustomTableViewcell = self.tableView.dequeueReusableCellWithIdentifier(CellIdentifier, forIndexPath: indexPath) as! CustomTableViewcell
                                  //self.tableView.dequeueReusableCellWithIdentifier(CellIdentifier) as! CustomTableViewcell

    cell.prepareForReuse()

    self.createUIForCell(cell)
    self.configureCell(cell, indexPath: indexPath)

    print("\t\(parsedData[indexPath.row].stationName): \(parsedData[indexPath.row].freeBikes)")

    return cell
}

func createUIForCell(cell: CustomTableViewcell) {

    cell.distanceLabel.textColor      = UIColor.whiteColor()
    cell.distanceLabel.backgroundColor = UIColor.clearColor()
    cell.bikeStationLabel.textColor   = UIColor.whiteColor()
    cell.bikeStationLabel.backgroundColor = UIColor.clearColor()
}

func configureCell(cell: CustomTableViewcell, indexPath: NSIndexPath) {

    let stations = parsedData[indexPath.row]

    if indexPath.row % 2 == 0 {
        cell.stackView.arrangedSubviews.first!.backgroundColor = cellBackgroundColor1
        cell.progressView.backgroundColor = cellBackgroundColor2
    } else {
        cell.stackView.arrangedSubviews.first!.backgroundColor = cellBackgroundColor2
        cell.progressView.backgroundColor = cellBackgroundColor1
    }

    cell.progressView.getWidth(stations.freeBikes, freeDocks: stations.freeDocks)

    cell.getLocation(stations.latitude, longitude: stations.longitude)
    cell.getParameters(stations.freeBikes, freeDocks: stations.freeDocks)
    cell.bikeStationLabel.text  = stations.stationName

    if stations.distanceToLocation != nil {
        if stations.distanceToLocation! < 1000 {
            cell.distanceLabel.text = String(format: "%.f m", stations.distanceToLocation!)
        } else {
            cell.distanceLabel.text = String(format: "%.1f km", stations.distanceToLocation! / 1000)
        }
    } else {
        cell.distanceLabel.text = ""
    }
}

For the before mentioned UIVIew inside my custom cell I have created a separated class for it to handle the drawing and it looks like this:

import UIKit

class ProgressViewBar: UIView {

var freeBikes = 0
var freeDocks = 0
var text: UILabel? = nil
var text2: UILabel? = nil

func getWidth(freeBikes: Int, freeDocks: Int) {

    self.freeBikes = freeBikes
    self.freeDocks = freeDocks
}

override func drawRect(rect: CGRect) {

    let path = UIBezierPath(roundedRect: CGRect(x: 0, y: 0, width: rect.width * (CGFloat(freeBikes) / (CGFloat(freeBikes) + CGFloat(freeDocks))), height: frame.height), cornerRadius: 0)
    let shapeLayer = CAShapeLayer()
    shapeLayer.path = path.CGPath
    shapeLayer.strokeColor = UIColor.whiteColor().CGColor
    shapeLayer.fillColor = UIColor.whiteColor().CGColor

    self.layer.addSublayer(shapeLayer)

    drawText(rect)
}

func drawText(rect: CGRect) {


    if freeBikes != 0 {
        text?.removeFromSuperview()
        text = UILabel(frame: CGRect(x:  2, y: 0, width: 20, height: 20))
        text!.text = String("\(freeBikes)")
        text!.textAlignment = NSTextAlignment.Left
        text!.font = UIFont(name: "HelveticaNeue-Thin", size: 17)
        text!.backgroundColor = UIColor.clearColor()
        text!.textColor = UIColor(red: 1/255, green: 87/255, blue: 155/255, alpha: 1)

        self.addSubview(text!)
    }

    text2?.removeFromSuperview()
    text2 = UILabel(frame: CGRect(x: rect.width * (CGFloat(freeBikes) / (CGFloat(freeBikes) + CGFloat(freeDocks))) + 2, y: 0, width: 20, height: 20))
    text2!.text = String("\(freeDocks)")
    text2!.textAlignment = NSTextAlignment.Left
    text2!.font = UIFont(name: "HelveticaNeue-Thin", size: 17)
    text2!.backgroundColor = UIColor.clearColor()
    text2!.textColor = UIColor.whiteColor()
    self.addSubview(text2!)
}
}

The view needs two parameters to be drawn and I pass them using the func getWidth(freeBikes: Int, freeDocks: Int) method calling it from the `ViewController. If any other piece of code is needed you can look at the repo.


回答1:


The problem is that when reusing the cell you call drawRect once again and don't clear the already drawn rect. Clear it before drawing another one.



来源:https://stackoverflow.com/questions/39078466/uitableviewcell-gets-reused-and-shows-wrong-drawing-in-uiview

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!