iOS: 表视图行中的子类 UIView

iOS: subclass UIView in a tableview row

我试图在我的表格视图的每一行中设置这个自定义视图。 在我的界面生成器中,我在 UITableViewCell 中添加了一个 UIView,我 link IBOutlet。所以我把它class分给CircleView

这是它的class

class CircleView: UIView {

    var shapeLayer = CAShapeLayer()

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

        let circlePath = UIBezierPath(arcCenter: CGPoint(x: rect.width/2,y: rect.height/2), radius: CGFloat(20), startAngle: CGFloat(0), endAngle:CGFloat(Double.pi*2), clockwise: true)
        shapeLayer.path = circlePath.cgPath
        shapeLayer.fillColor = Constants.defaultCircleFillColor
        shapeLayer.strokeColor = UIColor.clear.cgColor
        shapeLayer.lineWidth = 1.5
        self.layer.addSublayer(shapeLayer)
    }

    func setColor(_ color: UIColor) {
        shapeLayer.strokeColor = color.cgColor
    }
}

但是当我尝试在 cellForRowAt 委托中调用 setColor 函数时,没有任何反应。 有没有办法管理它的笔触颜色?

这是 cellForRowAt:

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let remote_row: RemoteType = sections[indexPath.section].cellData[indexPath.row]

        if let cell = tableView.dequeueReusableCell(withIdentifier: remote_row.identifier) as? RemoteCell {
            switch remote_row {
            case .Item(circleColor: let color, text: let title):
                cell.configCell(circleColor: color, description: title)
            }
            return cell
        } else {
            fatalError("Unknown identifier")
        }
    }

和 RemoteCell:

class RemoteCell: UITableViewCell {

    @IBOutlet weak var title: UILabel!
    @IBOutlet weak var circleView: CircleView!
    @IBOutlet weak var settingButton: UIButton!

    func configCell(circleColor: UIColor, description: String) {
        title.text = description
        circleView.setColor(UIColor.blue)
    }
}

正如您在评论中所述,通过设置断点,您意识到 setColordraw 被调用之前被调用。由于 UIView.

的绘制周期,这是预期的行为

正如 UIView documentation 视图绘图周期 部分中所述,

View drawing occurs on an as-needed basis. When a view is first shown, or when all or part of it becomes visible due to layout changes, the system asks the view to draw its contents. For views that contain custom content using UIKit or Core Graphics, the system calls the view’s draw(_:) method.

这意味着在 cellForRowAt 中还没有调用 draw 方法,因为单元格本身甚至没有返回,也没有显示在屏幕上。您可以通过为 CircleView class 设置一个新的实例变量来解决此问题,该变量存储您要在 setColor 中使用的颜色,并直接在 [=11] 中使用该颜色=] 方法。在 cellForRowAt 中,只需将您之前用作 setColor 输入的颜色分配给这个新实例 属性,问题就应该得到解决。

draw 方法将在您的 tableView 绘制单元格时执行,因此颜色更改将被覆盖并设置为清除。

尝试这样的事情:

class CircleView: UIView {

    var shapeLayer = CAShapeLayer()
    var myColor:UIColor = UIColor.clear

    override func draw(_ rect: CGRect) {    
        let circlePath = UIBezierPath(arcCenter: CGPoint(x: rect.midX, y: rect.midY), radius: 20, startAngle: 0, endAngle:(.pi * 2), clockwise: true)
        shapeLayer.path = circlePath.cgPath
        shapeLayer.fillColor = Constants.defaultCircleFillColor
        shapeLayer.strokeColor = myColor.cgColor
        shapeLayer.lineWidth = 1.5
        self.layer.addSublayer(shapeLayer)
    }

    func setColor(_ color: UIColor) {
        myColor = color
        // shapeLayer.strokeColor = color.cgColor
    }
}