모달 전환의 애니메이션 사용자 정의
소개
앱에서 모달 전환할 때 몇 가지 기본 애니메이션이 제공되지만, 다른 애니메이션을 사용하고 싶을 때 직접 사용자 지정할 수 있는 것 같습니다.
이번에는
UIViewControllerAnimatedTransitioning
를 사용하여 옆으로 스 와이프했을 때와 같은 애니메이션을 구현해 보았습니다.구현 이미지
코드
모달을 호출하는 쪽 코드
BaseViewController.swift
import UIKit
class BaseViewController: UIViewController {
@IBOutlet weak var buttonShow: UIButton!
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
}
@IBAction func showModalView(_ sender: Any) {
guard let modalVC = UIStoryboard(name: String(describing: CustomModalViewController.self), bundle: nil)
.instantiateInitialViewController() as? CustomModalViewController else { return }
modalVC.modalPresentationStyle = .fullScreen
present(modalVC, animated: true)
}
}
모달로 호출되는 쪽 코드
CustomModalViewController.swift
import UIKit
class CustomModalViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
transitioningDelegate = self
}
@IBAction func touchCloseButton(_ sender: Any) {
dismiss(animated: true, completion: nil)
}
}
// モーダルとして呼び出す側に「UIViewControllerTransitioningDelegate」を継承させる。
// MARK: UIViewControllerTransitioningDelegate
extension CustomModalViewController: UIViewControllerTransitioningDelegate {
// presentのときに呼ばれる
func animationController(forPresented presented: UIViewController, presenting: UIViewController, source: UIViewController) -> UIViewControllerAnimatedTransitioning? {
return CustomAnimater(animationMode: .present)
}
// dismissのときに呼ばれる
func animationController(forDismissed dismissed: UIViewController) -> UIViewControllerAnimatedTransitioning? {
return CustomAnimater(animationMode: .dismiss)
}
}
애니메이션을 정의하는 클래스
CustomAnimeter.swift
class CustomAnimater: NSObject {
// 開くと閉じるしかないので、enumで定義しておくと楽
enum AnimationMode {
case present, dismiss
}
private let animationMode: AnimationMode
private let duration = 0.3
init(animationMode: AnimationMode) {
self.animationMode = animationMode
}
}
extension CustomAnimater: UIViewControllerAnimatedTransitioning {
func transitionDuration(using transitionContext: UIViewControllerContextTransitioning?) -> TimeInterval {
return duration
}
func animateTransition(using transitionContext: UIViewControllerContextTransitioning) {
if animationMode == .present {
guard let toView = transitionContext.view(forKey: .to) else { return }
guard let fromView = transitionContext.view(forKey: .from) else { return }
transitionContext.containerView.addSubview(toView)
toView.alpha = 0.0
toView.transform = CGAffineTransform(translationX:fromView.bounds.size.width * 0.8 , y: 0)
UIView.animate(withDuration: 0.5, delay: 0) { [weak self] in
guard let _ = self else { return }
toView.transform = CGAffineTransform(translationX: 0, y: 0)
toView.alpha = 1.0
} completion: { finish in
toView.transform = .identity
transitionContext.completeTransition(finish)
}
} else {
guard let toView = transitionContext.view(forKey: .to) else { return }
guard let fromView = transitionContext.view(forKey: .from) else { return }
transitionContext.containerView.addSubview(toView)
transitionContext.containerView.addSubview(fromView)
fromView.alpha = 1
UIView.animate(withDuration: 0.5, delay: 0) {
fromView.alpha = 0.0
fromView.transform = CGAffineTransform(translationX:-fromView.bounds.size.width * 0.8 , y: 0)
} completion: { finish in
// transformをもとに戻さないとバグの要因になることがあるみたい
fromView.transform = .identity
transitionContext.completeTransition(finish)
}
}
}
}
Reference
이 문제에 관하여(모달 전환의 애니메이션 사용자 정의), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://qiita.com/ctnc_67/items/6ce7835cdfc635ef2ede텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)