强制自定义视图使用计时器重绘(或无效)

时间:2016-02-14 13:37:03

标签: ios swift2

我已经创建了一个动画的自定义小部件。现在我的问题是,当相应的数据更新时,我无法重绘视图。

在代码中不要反对我。这是我在swift中的第一段代码,我既没有使用swift,也没有使用Objective-C :-D

此外,我还阅读了以下问题,但他们并没有帮助我:

How to force a view to render itself?

what-is-the-most-robust-way-to-force-a-uiview-to-redraw

P.S。 :我可以在控制台中看到print(digit.phase)的输出。

p.s.s:我还使用performSelectorOnMainThread来调用setNeedsDisplay函数

代码:

import UIKit

struct Digit {
    var targetDigit: Int
    var currentDigit: Int
    var phase: Float
}

@IBDesignable class RollerCounter: UIView {
    var view: UIView!
    var viewRect: CGRect!
    var intNumber: Int
    var digits = [Digit]()
    let baseY = 20
    var timer: NSTimer?

    @IBInspectable var number: Int {
        get {
            return intNumber
        }
        set(number) {
            intNumber = number
            digits = []

            var tempNumber:Int = intNumber
            while tempNumber > 0 {
                digits.append(Digit(targetDigit: tempNumber % 10, currentDigit: Int(rand()) % 10, phase: 0.0))
                tempNumber /= 10
            }
        }
    }

    //init
    override init(frame: CGRect) {
        // set properties:
        intNumber = 1111
        super.init(frame: frame)

        // setup the thing!
        setup()
    }

    required init?(coder aDecoder: NSCoder) {

        intNumber = 1111

        super.init(coder: aDecoder)

        // setup the thing
        setup()
    }

    // Inital setup
    func setup() {
        let viewRect = CGRect(x: 0, y: 0, width: 280, height: 40)
        view = UIView(frame: viewRect)

        view.frame = bounds
        view.autoresizingMask = [.FlexibleWidth, .FlexibleHeight]

        addSubview(view)

        self.setNeedsDisplay()

        backgroundColor = UIColor(red: 1, green: 1, blue: 1, alpha: 0.0)
    }

    func animate() {
        timer = NSTimer.scheduledTimerWithTimeInterval(0.016, target: self, selector: Selector("tick"), userInfo: nil, repeats: true)
    }

    func tick() {
        for var digit in digits {
            digit.phase += Float(rand() % 100) / 100
            print(digit.phase)
        }

        setNeedsDisplay()

        //TEST: Also tested this
//      if let rect = viewRect {
//          drawRect(rect)
//      } else {
//          viewRect = CGRect(x: 0, y: 0, width: 280, height: 40)
//          drawRect(viewRect
//      }

    }


    // Only override drawRect: if you perform custom drawing.
    // An empty implementation adversely affects performance during animation.
    override func drawRect(rect: CGRect) {
        // Drawing code
        var tempNumber: Int = number
        let strTempNumber = String(tempNumber)

        var index: Int = 1
        let width = Float(rect.width)
        let charWidth: Float = Float(rect.width) / Float(strTempNumber.characters.count)
        let charHeight: CGFloat = 36

        let color = UIColor.blackColor()
        let font: UIFont = UIFont(name: "Helvetica Neue", size: charHeight)!
        let paraStyle = NSMutableParagraphStyle()
        paraStyle.lineSpacing = 6.0
        let skew = 0.1

        let textAttribs = [
            NSForegroundColorAttributeName: color,
            NSParagraphStyleAttributeName: paraStyle,
            NSObliquenessAttributeName: skew,
            NSFontAttributeName: font
        ]

        for digit in digits {

            let strCurrentDigit: NSString = String(digit.currentDigit) as NSString
            let strNextDigit: NSString = String(digit.currentDigit - 1) as NSString

            let xPos = width - Float(index) * charWidth
            let yPos = Float(baseY) + Float(charHeight) * digit.phase

            let point: CGPoint = CGPoint(x: Int(xPos), y: Int(yPos))
            strCurrentDigit.drawAtPoint(point, withAttributes: textAttribs)

            let nextDigitYPos = yPos - Float(charHeight) * 1.2
            let nextDigitPoint: CGPoint = CGPoint(x: Int(xPos), y: Int(nextDigitYPos))
            strNextDigit.drawAtPoint(nextDigitPoint, withAttributes: textAttribs)

            index++
            tempNumber /= 10
        }
    }
}

1 个答案:

答案 0 :(得分:0)

对不起伙计们。我的坏: - (

失效系统没有任何问题。这是错的:

RelativeLayout

事实证明,对for var digit in digits { digit.phase += Float(rand() % 100) / 100 print(digit.phase) } 的更改只会反映在for循环内的本地数字实例中

但为了清楚起见,phase方法中的setNeedsDisplay()调用对于要更新的​​视图至关重要。