churabou / iOS-develop-blog

0 stars 0 forks source link

4月28日(土) 本気 #14

Open churabou opened 6 years ago

churabou commented 6 years ago

import UIKit

enum TransitionMode { case present, dismiss }

final class PopUpTransition: NSObject {

private var duration: TimeInterval {
    return  mode == .present ? 0.4 : 0.2
}

private var mode: TransitionMode

init(_ mode: TransitionMode) {
    self.mode = mode
}

func presentAnimation(_ transitionContext: UIViewControllerContextTransitioning) {

    let containerView = transitionContext.containerView

    guard let popUpVC = transitionContext.viewController(forKey: .to) as? PopUpController else {
        return
    }

    let toView = popUpVC.view!
    containerView.addSubview(toView)

    // アニメーションはここから

    toView.alpha = 0
    popUpVC.contentView.transform = CGAffineTransform.identity.scaledBy(x: 0.95, y: 0.95)

    let animator = UIViewPropertyAnimator(duration: duration, curve: .easeInOut) {
        toView.alpha = 1
        popUpVC.contentView.transform = .identity
    }

    animator.addCompletion { _ in
        transitionContext.completeTransition(true)
    }

    animator.startAnimation()

}

func dismissAnimation(_ transitionContext: UIViewControllerContextTransitioning) {
    guard let fromView = transitionContext.view(forKey: .from) else {
        fatalError("from view")
    }

    let animator = UIViewPropertyAnimator(duration: duration, curve: .easeInOut) {
        fromView.alpha = 0
    }

    animator.addCompletion { _ in
        transitionContext.completeTransition(true)
    }

    animator.startAnimation()
}

}

extension PopUpTransition: UIViewControllerAnimatedTransitioning {

func transitionDuration(using transitionContext: UIViewControllerContextTransitioning?) -> TimeInterval {
    return duration
}

func animateTransition(using transitionContext: UIViewControllerContextTransitioning) {

    switch mode {
    case .present:
        presentAnimation(transitionContext)
    case .dismiss:
        dismissAnimation(transitionContext)
    }
}

}

class BasePopUpView: BaseView { func setUpView(parent: UIView) { } }

final class ResultPopUpView: BasePopUpView {

override func setUpView(parent: UIView) {
    parent.backgroundColor = UIColor(white: 0, alpha: 0.3)
    parent.addSubview(self)

    self.backgroundColor = .blue
    self.bounds.size = CGSize(width: 300, height: 400)
    self.center = parent.center
}

}

final class PopUpController: BaseController {

convenience init(contentView: BasePopUpView) {
    self.init()
    self.contentView = contentView
}

override init(nibName nibNameOrNil: String?, bundle nibBundleOrNil: Bundle?) {
    super.init(nibName: nibNameOrNil, bundle: nibBundleOrNil)
    commonInit()
}

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

override func viewDidLoad() {
    super.viewDidLoad()
    initializeView()
}

override func commonInit() {
    providesPresentationContextTransitionStyle = true
    definesPresentationContext = true
    modalPresentationStyle = .custom
    transitioningDelegate = self
}

private (set) var contentView = BasePopUpView()
private var transiton: UIViewControllerAnimatedTransitioning?

override func initializeView() {
    contentView.setUpView(parent: view)
}

}

extension PopUpController: UIViewControllerTransitioningDelegate {

func animationController(forDismissed dismissed: UIViewController) -> UIViewControllerAnimatedTransitioning? {
    return PopUpTransition(.dismiss)
}

func animationController(forPresented presented: UIViewController, presenting: UIViewController, source: UIViewController) -> UIViewControllerAnimatedTransitioning? {
    return PopUpTransition(.present)
}

}