UITableViewCell 被重用并在 UIView 中显示错误的绘图 [英] UITableViewCell gets reused and shows wrong drawing in UIView

查看:21
本文介绍了UITableViewCell 被重用并在 UIView 中显示错误的绘图的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经遇到这个问题好几个星期了,我想我无法解决它.

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

我有一个 tableView,它有自定义的 tableViewCell 并且它们充满了数据.tableViewCell 有两个 UILabel 和一个 UIView.

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

当我滚动几次 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 在打开应用时完美显示

UIViews show perfectly when opening the app

UIViews 滚动后重叠

UIViews get overlapped after scrolling

我的 UITableViewcellForRowAtIndexPath 是:

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 = ""
    }
}

对于前面提到的 UIVIew 在我的自定义单元格中,我为它创建了一个单独的类来处理绘图,它看起来像这样:

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!)
}
}

视图需要绘制两个参数,我使用 func getWidth(freeBikes: Int, freeDocks: Int) 方法从`ViewController 调用它来传递它们.如果需要任何其他代码,您可以查看 repo.

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.

推荐答案

问题在于,在重用单元格时,您再次调用 drawRect 而不会清除已经绘制的 rect.在绘制另一个之前清除它.

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.

这篇关于UITableViewCell 被重用并在 UIView 中显示错误的绘图的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆