我的CoreGraphics代码工作得非常慢。如何让这个自定义UIScrollView表现更好?

时间:2016-07-07 18:16:12

标签: ios swift performance uiscrollview core-graphics

我创建了一个自定义类,它创建了一种水平滚动的时间轴。以下是我的自定义UIScrollView的代码:

import UIKit

struct DataPoint {
    var fillColor: UIColor = UIColor.grayColor()

    init(color: UIColor) {
        fillColor = color
    }
}

@IBDesignable
class MyView: UIScrollView {

    @IBInspectable var lineColor: UIColor = UIColor.grayColor()
    @IBInspectable var lineHeight: CGFloat = 65
    @IBInspectable var lineWidth: CGFloat = 15
    @IBInspectable var lineGap: CGFloat = 25
    @IBInspectable var lineCount: Int = 0

    var dataPoints = [DataPoint(color: UIColor.greenColor()), DataPoint(color: UIColor.blueColor())]

    override init(frame: CGRect) {
        super.init(frame: frame)
        setupValues()

    }

    required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
        setupValues()
        //fatalError("init(coder:) has not been implemented")
    }

    func setupValues() {

        self.contentSize = CGSize(width: self.frame.width * 2, height: self.frame.height)

        self.backgroundColor = UIColor.whiteColor()
        self.lineCount = Int(self.frame.width / lineGap)
    }

    override internal func layoutSubviews() {
        super.layoutSubviews()
        self.setNeedsDisplay()
        self.layoutIfNeeded()
    }

    override func drawRect(rect: CGRect) {

        let ctx = UIGraphicsGetCurrentContext()
        CGContextSaveGState(ctx)

        for i in 0...lineCount {

            let start = CGPoint(x: CGFloat(i) * lineGap, y: self.frame.height)
            let end = CGPoint(x: CGFloat(i) * lineGap, y: self.frame.height - lineHeight)

            drawLine(from: start, to: end, color: UIColor.grayColor())

            if i % (lineCount / (dataPoints.count + 2)) == 0 && i != 0 && i != lineCount {
                drawPoint(at: end, radius: 5, color: UIColor.orangeColor())
            }
        }

        CGContextRestoreGState(ctx)
    }

    func drawLine(from start: CGPoint, to end: CGPoint, color: UIColor) {

        let path = UIBezierPath()
        path.moveToPoint(start)
        path.addLineToPoint(end)

        let shapeLayer = CAShapeLayer()
        shapeLayer.path = path.CGPath
        shapeLayer.strokeColor = color.CGColor
        shapeLayer.lineWidth = 1

        self.layer.addSublayer(shapeLayer)
    }

    func drawPoint(at center: CGPoint, radius: CGFloat, color: UIColor) {

        let path = UIBezierPath(arcCenter: center, radius: radius, startAngle: CGFloat(0), endAngle: CGFloat(M_PI * 2), clockwise: true)

        let shapeLayer = CAShapeLayer()
        shapeLayer.path = path.CGPath
        shapeLayer.fillColor = color.CGColor
        shapeLayer.strokeColor = UIColor.blackColor().CGColor
        shapeLayer.lineWidth = 0.5

        self.layer.addSublayer(shapeLayer)
    }
}

在我的设备和模拟器上,这是非常缓慢和滞后的。我到底错在了什么?在滚动时我可以采取哪些步骤来实现稳定的60fps?

2 个答案:

答案 0 :(得分:1)

您好我发现了您的问题,您的问题是

override internal func layoutSubviews() {
    super.layoutSubviews()
    self.setNeedsDisplay()
    self.layoutIfNeeded()
}

你无意中处于永无止境的油漆循环中

用此替换

override internal func layoutSubviews() {
    super.layoutSubviews()
}

或完全删除

我希望这会帮助你,因为我工作得很好

答案 1 :(得分:0)

在我看来,你每次都在画同样的东西。一切都是静态的...那么为什么不把它全部绘制成一个图形上下文并从中创建一个UIImage来添加到scrollview的背景(或者前景,取决于你正在做的其他事情)?