developer tip

Swift에서 간단한 페이드 인 애니메이션을 만드시겠습니까?

optionbox 2020. 11. 1. 17:37
반응형

Swift에서 간단한 페이드 인 애니메이션을 만드시겠습니까?


Swift로 간단한 애니메이션을 만들려고합니다. 페이드 인입니다.

나는 시도했다 :

self.myFirstLabel.alpha = 0
self.myFirstButton.alpha = 0
self.mySecondButton.alpha = 0

그러면 다음이 있습니다.

self.view.addSubview(myFirstLabel)
self.view.addSubview(myFirstButton)
self.view.addSubview(mySecondButton)

그리고:

UIView.animateWithDuration(1.5, animations: {
 self.myFirstLabel.alpha = 1.0
 self.myFirstButton.alpha = 1.0
 self.mySecondButton.alpha = 1.0
})

내 viewDidLoad 함수에이 모든 것이 있습니다.

이 작업을 어떻게 수행합니까?


문제는 뷰 컨트롤러의 수명주기에서 너무 일찍 애니메이션을 시작하려고한다는 것입니다. viewDidLoad에서 뷰가 방금 생성되었고 아직 뷰 계층 구조에 추가되지 않았으므로이 시점에서 하위 뷰 중 하나를 애니메이션하려고하면 잘못된 결과가 생성됩니다.

정말로해야 할 일은 viewDidLoad (또는 뷰를 생성 한 위치)에서 뷰의 알파를 계속 설정 한 다음 viewDidAppear : 메서드가 호출되기를 기다리는 것입니다. 이 시점에서 문제없이 애니메이션을 시작할 수 있습니다.

override func viewDidAppear(_ animated: Bool) {
    super.viewDidAppear(animated)


    UIView.animate(withDuration: 1.5, animations: {
        self.myFirstLabel.alpha = 1.0
        self.myFirstButton.alpha = 1.0
        self.mySecondButton.alpha = 1.0
    })
}

0x7ffffff 의 대답은 괜찮고 확실히 철저합니다.

플러스로 다음과 같이 UIView 확장을 만드는 것이 좋습니다.

public extension UIView {

  /**
  Fade in a view with a duration

  - parameter duration: custom animation duration
  */
  func fadeIn(duration duration: NSTimeInterval = 1.0) {
    UIView.animateWithDuration(duration, animations: {
        self.alpha = 1.0
    })
  }

  /**
  Fade out a view with a duration

  - parameter duration: custom animation duration
  */
  func fadeOut(duration duration: NSTimeInterval = 1.0) {
    UIView.animateWithDuration(duration, animations: {
        self.alpha = 0.0
    })
  }

}

스위프트 -3

/// Fade in a view with a duration
/// 
/// Parameter duration: custom animation duration
func fadeIn(withDuration duration: TimeInterval = 1.0) {
    UIView.animate(withDuration: duration, animations: {
        self.alpha = 1.0
    })
}

/// Fade out a view with a duration
///
/// - Parameter duration: custom animation duration
func fadeOut(withDuration duration: TimeInterval = 1.0) {
    UIView.animate(withDuration: duration, animations: {
        self.alpha = 0.0
    })
}

이러한 방식으로 코드에서 다음을 수행 할 수 있습니다.

let newImage = UIImage(named: "")
newImage.alpha = 0 // or newImage.fadeOut(duration: 0.0)
self.view.addSubview(newImage)
... 
newImage.fadeIn()

코드 재사용이 중요합니다!


Swift 전용 솔루션

Luca의 anwer 와 유사하게 UIView확장을 사용합니다 . 그의 솔루션과 비교하여 DispatchQueue.main.async애니메이션이 메인 스레드에서 수행되는지 확인 alpha하고 특정 값으로 페이드하기위한 duration매개 변수 및 더 깨끗한 코드를위한 선택적 매개 변수를 사용합니다.

extension UIView {
  func fadeTo(_ alpha: CGFloat, duration: TimeInterval = 0.3) {
    DispatchQueue.main.async {
      UIView.animate(withDuration: duration) {
        self.alpha = alpha
      }
    }
  }

  func fadeIn(_ duration: TimeInterval = 0.3) {
    fadeTo(1.0, duration: duration)
  }

  func fadeOut(_ duration: TimeInterval = 0.3) {
    fadeTo(0.0, duration: duration)
  }
}

이것을 어떻게 사용 하는가:

// fadeIn() - always animates to alpha = 1.0
yourView.fadeIn()     // uses default duration of 0.3
yourView.fadeIn(1.0)  // uses custom duration (1.0 in this example)

// fadeOut() - always animates to alpha = 0.0
yourView.fadeOut()    // uses default duration of 0.3
yourView.fadeOut(1.0) // uses custom duration (1.0 in this example)

// fadeTo() - used if you want a custom alpha value
yourView.fadeTo(0.5)  // uses default duration of 0.3
yourView.fadeTo(0.5, duration: 1.0)

반복 가능한 페이드 애니메이션을 원한다면 CABasicAnimation아래와 같이 사용할 수 있습니다.

먼저 편리한 UIView 확장을 만듭니다.

extension UIView {

    enum AnimationKeyPath: String {
        case opacity = "opacity"
    }

    func flash(animation: AnimationKeyPath ,withDuration duration: TimeInterval = 0.5, repeatCount: Float = 5){
        let flash = CABasicAnimation(keyPath: AnimationKeyPath.opacity.rawValue)
        flash.duration = duration
        flash.fromValue = 1 // alpha
        flash.toValue = 0 // alpha
        flash.timingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionEaseInEaseOut)
        flash.autoreverses = true
        flash.repeatCount = repeatCount

        layer.add(flash, forKey: nil)
    }
}

이것을 어떻게 사용 하는가:

    // You can use it with all kind of UIViews e.g. UIButton, UILabel, UIImage, UIImageView, ...
    imageView.flash(animation: .opacity, withDuration: 1, repeatCount: 5)
    titleLabel.flash(animation: .opacity, withDuration: 1, repeatCount: 5)

import UIKit

/*
 Here is simple subclass for CAAnimation which create a fadeIn animation
 */

class FadeInAdnimation: CABasicAnimation {
    override init() {
        super.init()
        keyPath = "opacity"
        duration = 2.0
        fromValue = 0
        toValue = 1
        fillMode = CAMediaTimingFillMode.forwards
        isRemovedOnCompletion = false
    }

    required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
    }
}

/*
 Example of usage
 */

class ViewController: UIViewController {

    weak var label: UILabel!

    override func loadView() {
        let view = UIView()
        view.backgroundColor = .white

        let label = UILabel()
        label.alpha = 0
        label.frame = CGRect(x: 150, y: 200, width: 200, height: 20)
        label.text = "Hello World!"
        label.textColor = .black
        view.addSubview(label)
        self.label = label

        let button = UIButton(type: .custom)
        button.frame = CGRect(x: 0, y: 250, width: 300, height: 100)
        button.setTitle("Press to Start FadeIn", for: UIControl.State())
        button.backgroundColor = .red
        button.addTarget(self, action: #selector(startFadeIn), for: .touchUpInside)
        view.addSubview(button)

        self.view = view
    }

    /*
     Animation in action
     */
    @objc private func startFadeIn() {
        label.layer.add(FadeInAdnimation(), forKey: "fadeIn")
    }

}

참고 URL : https://stackoverflow.com/questions/24111770/make-a-simple-fade-in-animation-in-swift

반응형