0

フェードイン アニメーションをアタッチした CATextLayer のサブクラスを作成し、ドロップスルー アニメーションをアタッチした CATextLayer に追加しました。マトリックス ムービー レイニング コード エフェクトを試して作成することが目標です。かなりうまく機能しますが、ゆっくりと、しかし確実に地面に押し込まれるという事実のために、私はますます多くのレイヤーを追加し続けているのではないかと思います. レイヤーが画面から離れたときを検出して削除できるようにするにはどうすればよいですか。

これがコードです...

class CATextSubLayer: CATextLayer, CAAnimationDelegate {

    private var starter:Float!
    private var ender:Float!

   required override init(layer: Any) {
    super.init(layer: layer)
    //UIFont.availableFonts()
    self.string = randomString(length: 1)
    self.backgroundColor = UIColor.black.cgColor
    self.foregroundColor = UIColor.white.cgColor
    self.alignmentMode = kCAAlignmentCenter
    self.font = CTFontCreateWithName("AvenirNextCondensed-BoldItalic" as CFString?, fontSize, nil)
    self.fontSize = 16
    self.opacity = 0.0
    makeFade()
}

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

}

func randomString(length: Int) -> String {

    let letters : NSString = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
    let len = UInt32(letters.length)

    var randomString = ""
    for _ in 0 ..< length {
        let rand = arc4random_uniform(len)
        var nextChar = letters.character(at: Int(rand))
        randomString += NSString(characters: &nextChar, length: 1) as String
    }

    return randomString
}

func makeFade() {
        let rands = Double(arc4random_uniform(UInt32(4)))
        let fadeInAndOut = CABasicAnimation(keyPath: "opacity")
        fadeInAndOut.duration = 16.0;
        fadeInAndOut.repeatCount = 1
        fadeInAndOut.fromValue = 0.0
        fadeInAndOut.toValue = 1
        fadeInAndOut.isRemovedOnCompletion = true
        fadeInAndOut.fillMode = kCAFillModeForwards;
        fadeInAndOut.delegate = self
        fadeInAndOut.beginTime = CACurrentMediaTime() + rands
        self.add(fadeInAndOut, forKey: "opacity")

}

func animationDidStop(_ anim: CAAnimation, finished flag: Bool) {
    self.removeAllAnimations()
}
}

外側のループ/View Controller で ..

class ViewController: UIViewController, CAAnimationDelegate {

var beeb: CATextSubLayer!
var meeb: CATextLayer!
var lines = [Int]()

override func viewDidLoad() {
    super.viewDidLoad()
    view.backgroundColor = UIColor.black
        // Do any additional setup after loading the view, typically from a nib.
    meeb = CATextLayer()
    for bing in stride(from:0, to: Int(view.bounds.width), by: 16) {
        lines.append(bing)
    }
    for _ in 0 ..< 9 {
        Timer.scheduledTimer(timeInterval: 0.5, target: self, selector: #selector(makeBeeb), userInfo: nil, repeats: true)
    }
}

func makeBeeb() {
    let rands = Double(arc4random_uniform(UInt32(4)))
    let beeb = CATextSubLayer(layer: meeb)
    let randx = Int(arc4random_uniform(UInt32(lines.count)))
    let monkey = lines[randx]
    beeb.frame = CGRect(x: monkey, y: 0, width: 16, height: 16)
    let dropThru = CABasicAnimation(keyPath: "position.y")
    dropThru.duration = 12.0;
    dropThru.repeatCount = 1
    dropThru.fromValue = 1
    dropThru.toValue = view.bounds.maxY
    dropThru.isRemovedOnCompletion = true
    dropThru.fillMode = kCAFillModeForwards;
    dropThru.beginTime = CACurrentMediaTime() + rands
    dropThru.delegate = self
    beeb.add(dropThru, forKey: "position.y")
    self.view.layer.addSublayer(beeb)
}

func animationDidStop(_ anim: CAAnimation, finished flag: Bool) {
    self.view.layer.removeAllAnimations()
}

override func didReceiveMemoryWarning() {
    super.didReceiveMemoryWarning()
    // Dispose of any resources that can be recreated.
}


}
4

2 に答える 2

1

レイヤーが画面から離れたことを検出して削除できるようにするにはどうすればよいですか

アニメーションの終了時に呼び出されるデリゲートを CABasicAnimation に既に指定しています。それがレイヤーを削除する合図です。(アニメーションを削除していますが、レイヤー自体は削除していません。)

于 2016-11-10T20:16:48.483 に答える
1

私があなたのコードを理解している限り、位置アニメーションが終了したら、レイヤーを削除できます。この時点で、親ビューの境界を離れているはずです。

ところで。レイヤーを削除および追加すると、パフォーマンスが低下します。削除する代わりに、次のアニメーションにレイヤーを再利用する必要があります。

于 2016-11-10T20:18:00.327 に答える