2016-11-10 20 views
0

내가 dropThru 애니메이션을 첨부 한 CATextLayer에 추가하는 fadeIn 애니메이션을 첨부 한 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 = "ABCDEFGHIJKLMNOPQRSTUVWXYZ" 
    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() 
} 
} 

..

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. 
} 


} 

답변

1

코드를 이해하면 위치 애니메이션이 종료 될 때 레이어를 제거 할 수 있습니다. 이 순간에 부모보기의 범위를 벗어나야합니다.

btw. 레이어를 제거하고 추가하면 성능이 떨어집니다. 대신 제거하면 다음 애니메이션을 위해 레이어를 다시 사용해야합니다.

+0

좋아,이 소리도 좋습니다. xCord를 리셋 할 때 레이어를 다시 사용하십시오. 나는 그것을 줄 것이다! 그러나 애니메이션이 방금 완료된 레이어에서 어떻게 기다려야하는지 알 수 있습니까? – user3069232

+0

완료 블록을 설정할 수있는 CATransaction에서 애니메이션을 만들 수 있습니다. – clemens

+0

이 작품! 이 줄을 VC에 추가했습니다. CATransaction.begin() CATransaction.setCompletionBlock ({ beeb.removeFromSuperlayer() }) 및이 줄을 그 안에있는 animationDidStop에 연결합니다. CATransaction.commit(). 내가 만든 메모리 돼지를 고치는 것 같다! – user3069232

1

가 어떻게이 층 그래서 화면을 떠난 때 월 검색 할 수 있습니다 ... 코드입니다 그것을 삭제하십시오

당신은 이미 CABasicAnimation에게 애니메이션 완료. 그것은 레이어를 제거하라는 신호입니다. (애니메이션은 제거하지만 레이어 자체는 삭제하지 않습니다.)

+0

네,하지만 애니메이션이있는 레이어의 핸들을 얻는 방법은 무엇입니까? 누락 된 코드 줄을 파악할 수 없습니다. 그것은 anim에 있습니까? – user3069232

+0

너무 빨리 다시와 주셔서 감사합니다. – user3069232

+0

내가하는 일은 키 - 값 코딩을 사용하여 애니메이션에 레이어를 추가하는 것입니다. 애니메이션을 구성하고 레이어에 추가 한 다음 추가하고 위임 메서드에서 레이어를 추출하면 제거 할 레이어를 알 수 있습니다. – matt