Skip to content

Instantly share code, notes, and snippets.

@kemchenj
Last active October 4, 2018 03:38
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save kemchenj/f3f8a3cc0acfaada5844ad417710bbea to your computer and use it in GitHub Desktop.
Save kemchenj/f3f8a3cc0acfaada5844ad417710bbea to your computer and use it in GitHub Desktop.
//
// DimBackgroundVC+Animator.swift
// guru_iOS
//
// Created by kemchenj on 2018/10/4.
// Copyright © 2018 gelonghui. All rights reserved.
//
import UIKit
extension DimBackgroundVC {
class PresentAnimator: NSObject, UIViewControllerAnimatedTransitioning {
func transitionDuration(using transitionContext: UIViewControllerContextTransitioning?) -> TimeInterval {
return 0.33
}
func animateTransition(using transitionContext: UIViewControllerContextTransitioning) {
guard
let from = transitionContext.viewController(forKey: .from),
let to = transitionContext.viewController(forKey: .to)
else {
assertionFailure()
return
}
if let to = to as? DimBackgroundVC {
to.view.frame = UIScreen.main.bounds
to.view.backgroundColor = .clear
to.view.layoutIfNeeded()
transitionContext.containerView.addSubview(to.view)
UIView.animate(
withDuration: 0.33,
delay: 0,
options: [],
animations: {
to.show()
to.view.layoutIfNeeded()
to.view.backgroundColor = UIColor.black.withAlphaComponent(0.3)
},
completion: { _ in
transitionContext.completeTransition(true)
}
)
} else if let from = from as? DimBackgroundVC {
UIView.animate(
withDuration: 0.33,
delay: 0,
options: [],
animations: {
from.hide()
from.view.layoutIfNeeded()
from.view.backgroundColor = .clear
}, completion: { _ in
from.view.removeFromSuperview()
transitionContext.completeTransition(true)
}
)
} else {
assertionFailure()
}
}
}
}
//
// PopoverVC.swift
// guru_iOS
//
// Created by kemchenj on 2018/9/27.
// Copyright © 2018 gelonghui. All rights reserved.
//
import UIKit
class DimBackgroundVC: UIViewController {
private let animator = PresentAnimator()
override init(nibName nibNameOrNil: String?, bundle nibBundleOrNil: Bundle?) {
super.init(nibName: nibNameOrNil, bundle: nibBundleOrNil)
setupTransition()
}
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
setupTransition()
}
func show() {}
func hide() {}
private func setupTransition() {
modalPresentationStyle = .custom
transitioningDelegate = self
}
}
//
// MARK: - [ViewController] Life Cycle
//
extension DimBackgroundVC {
override func viewDidLoad() {
super.viewDidLoad()
let tapGesture = UITapGestureRecognizer(target: self, action: #selector(_dismiss))
tapGesture.delegate = self
view.addGestureRecognizer(tapGesture)
}
}
extension DimBackgroundVC {
@objc
private func _dismiss() {
dismiss(animated: true, completion: nil)
}
}
//
// MARK: - UIGestureRecognizerDelegate
//
extension DimBackgroundVC: UIGestureRecognizerDelegate {
func gestureRecognizerShouldBegin(_ gestureRecognizer: UIGestureRecognizer) -> Bool {
let location = gestureRecognizer.location(in: view)
return view.subviews.find(element: { $0.frame.contains(location) }) == nil
}
}
extension DimBackgroundVC: UIViewControllerTransitioningDelegate {
func animationController(forPresented presented: UIViewController, presenting: UIViewController, source: UIViewController) -> UIViewControllerAnimatedTransitioning? {
return animator
}
func animationController(forDismissed dismissed: UIViewController) -> UIViewControllerAnimatedTransitioning? {
return animator
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment