我想創建一個自定義的UIView子類,代表一羣星星在深藍色的天空。自定義UIView:延遲動畫subLayers
因此,我創造了這樣的觀點:
import UIKit
class ConstellationView: UIView {
// MARK: - Properties
@IBInspectable var numberOfStars: Int = 80
@IBInspectable var animated: Bool = false
// Private properties
private var starsToDraw = [CAShapeLayer]()
// Layers
private let starsLayer = CAShapeLayer()
// MARK: - Drawing
// override func drawRect(rect: CGRect) {
override func layoutSubviews() {
// Generate stars
drawStars(rect: self.bounds)
}
/// Generate stars
func drawStars(rect: CGRect) {
let width = rect.size.width
let height = rect.size.height
let screenBounds = UIScreen.main.bounds
// Create the stars and store them in starsToDraw array
for _ in 0 ..< numberOfStars {
let x = randomFloat() * width
let y = randomFloat() * height
// Calculate the thinness of the stars as a percentage of the screen resolution
let thin: CGFloat = max(screenBounds.width, screenBounds.height) * 0.003 * randomFloat()
let starLayer = CAShapeLayer()
starLayer.path = UIBezierPath(ovalIn: CGRect(x: x, y: y, width: thin, height: thin)).cgPath
starLayer.fillColor = UIColor.white.cgColor
starsToDraw.append(starLayer)
}
// Define a fade animation
let appearAnimation = CABasicAnimation(keyPath: "opacity")
appearAnimation.fromValue = 0.2
appearAnimation.toValue = 1
appearAnimation.duration = 1
appearAnimation.fillMode = kCAFillModeForwards
// Add the animation to each star (if animated)
for (index, star) in starsToDraw.enumerated() {
if animated {
// Add 1 s between each animation
appearAnimation.beginTime = CACurrentMediaTime() + TimeInterval(index)
star.add(appearAnimation, forKey: nil)
}
starsLayer.insertSublayer(star, at: 0)
}
// Add the stars layer to the view layer
layer.insertSublayer(starsLayer, at: 0)
}
private func randomFloat() -> CGFloat {
return CGFloat(arc4random())/CGFloat(UINT32_MAX)
}
}
不過,我想有它的動畫,也就是說,每一個的80顆星應該一個接一個地出現,延遲1秒。
我試圖增加我的動畫的beginTime
,但它似乎沒有辦法。 我檢查了drawRect
或layoutSubviews
,但沒有區別。
你能幫我嗎?
感謝
PS:重現我的應用程序,只需在Xcode中創建一個新的單一視圖的應用程序,創建此代碼的新文件,並設置視圖控制器的視圖作爲ConstellationView,具有深色背景。也可以在Interface Builder或代碼中將animated
屬性設置爲true。
PPS:這是斯威夫特3,但我認爲它仍然可以理解:-)
接得好 !技巧是'kCAFillModeBackwards'。動畫鍵在這裏不起任何作用,因爲它只是用來在動畫開始後識別動畫(如果你想在後面「捕捉」它)。 –
等待4小時才能獎賞賞金... –