我已经创建了一个动画的自定义小部件。现在我的问题是,当相应的数据更新时,我无法重绘视图。
在代码中不要反对我。这是我在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
}
}
}
答案 0 :(得分:0)
对不起伙计们。我的坏: - (
失效系统没有任何问题。这是错的:
RelativeLayout
事实证明,对for var digit in digits {
digit.phase += Float(rand() % 100) / 100
print(digit.phase)
}
的更改只会反映在for循环内的本地数字实例中
但为了清楚起见,phase
方法中的setNeedsDisplay()
调用对于要更新的视图至关重要。