【问题标题】:iOS: subclass UIView in a tableview rowiOS:tableview 行中的子类 UIView
【发布时间】:2018-01-14 22:17:15
【问题描述】:

我正在尝试在我的表格视图的每一行中设置此自定义视图。 在我的界面构建器中,我在 UITableViewCell 中添加了一个 UIView,并链接了 IBOutlet。所以我将其子类化为CircleView

这是它的类

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

【问题讨论】:

  • 您应该包含cellForRowAt 的代码,因为错误很可能存在于那里,而不是自定义CircleView 类本身。
  • 也许setColordraw 之前被调用。请尝试使用日志或断点进行检查。
  • 您确定没有调用该方法吗?你有没有在方法中设置断点来查看它是否被调用?
  • 我添加了断点...问题是setColordraw之前被调用
  • @CrazyDev 请包含cellForRowAt 的代码。我很确定问题在于没有正确初始化视图,而只是尝试将UIView 转换为CircleView,但没有相关代码,我无法确定。

标签: ios swift3 uiview tableview subclass


【解决方案1】:

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

【讨论】:

  • 你不需要在 Swift 中引用 self 除非它是为了消除歧义或在转义闭包中。只需使用myColor = color 就足够了。
  • 我同意,这只是一种习惯
  • 另外,由于CircleViewUIView 的直接子类,因此您不需要调用super.draw(rect),因为默认实现什么都不做。
【解决方案2】:

正如您在 cmets 中所述,通过设置断点,您意识到在调用 draw 之前调用了 setColor。由于UIView 的绘制周期,这是预期的行为。

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

视图绘图根据需要进行。首次显示视图时, 或者当它的全部或部分由于布局更改而变得可见时, 系统要求视图绘制其内容。对于包含 使用 UIKit 或 Core Graphics 自定义内容,系统调用 视图的 draw(_:) 方法。

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

【讨论】:

  • 很好的解决方案!谢谢,我没想到!
  • 不用担心,很高兴我能帮上忙。
猜你喜欢
  • 2011-09-04
  • 1970-01-01
  • 1970-01-01
  • 2017-04-08
  • 1970-01-01
  • 2013-06-28
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多