// 这个类相当于A
class CrossDissolveFirstViewController: UIViewController, UIViewControllerTransitioningDelegate {
// 这个对象相当于B
crossDissolveSecondViewController.transitioningDelegate = self
// 点击按钮触发的函数
func animationButtonDidClicked() {
self.presentViewController(crossDissolveSecondViewController,
animated: true, completion: nil)
}
// 下面这两个函数定义在UIViewControllerTransitioningDelegate协议中
// 用于为present和dismiss提供animator
func animationControllerForPresentedController(presented: UIViewController, presentingController presenting: UIViewController, sourceController source: UIViewController) -> UIViewControllerAnimatedTransitioning? {
// 也可以使用CrossDissolveAnimator,动画效果各有不同
// return CrossDissolveAnimator()
return HalfWaySpringAnimator()
}
func animationControllerForDismissedController(dismissed: UIViewController) -> UIViewControllerAnimatedTransitioning? {
return CrossDissolveAnimator()
}
}
class HalfWaySpringAnimator: NSObject, UIViewControllerAnimatedTransitioning {
/// 设置动画的持续时间
func transitionDuration(transitionContext: UIViewControllerContextTransitioning?) -> NSTimeInterval {
return 2
}
/// 设置动画的进行方式,附有详细注释,demo中其他地方的这个方法不再解释
func animateTransition(transitionContext: UIViewControllerContextTransitioning) {
let fromViewController = transitionContext.viewControllerForKey(UITransitionContextFromViewControllerKey)
let toViewController = transitionContext.viewControllerForKey(UITransitionContextToViewControllerKey)
let containerView = transitionContext.containerView()
// 需要关注一下from/to和presented/presenting的关系
// For a Presentation:
// fromView = The presenting view.
// toView = The presented view.
// For a Dismissal:
// fromView = The presented view.
// toView = The presenting view.
var fromView = fromViewController?.view
var toView = toViewController?.view
// iOS8引入了viewForKey方法,尽可能使用这个方法而不是直接访问controller的view属性
// 比如在form sheet样式中,我们为presentedViewController的view添加阴影或其他decoration,animator会对整个decoration view
// 添加动画效果,而此时presentedViewController的view只是decoration view的一个子视图
if transitionContext.respondsToSelector(Selector("viewForKey:")) {
fromView = transitionContext.viewForKey(UITransitionContextFromViewKey)
toView = transitionContext.viewForKey(UITransitionContextToViewKey)
}
// 我们让toview的origin.y在屏幕的一半处,这样它从屏幕的中间位置弹起而不是从屏幕底部弹起,弹起过程中逐渐变为不透明
toView?.frame = CGRectMake(fromView!.frame.origin.x, fromView!.frame.maxY / 2, fromView!.frame.width, fromView!.frame.height)
toView?.alpha = 0.0
// 在present和,dismiss时,必须将toview添加到视图层次中
containerView?.addSubview(toView!)
let transitionDuration = self.transitionDuration(transitionContext)
// 使用spring动画,有弹簧效果,动画结束后一定要调用completeTransition方法
UIView.animateWithDuration(transitionDuration, delay: 0, usingSpringWithDamping: 0.6, initialSpringVelocity: 0, options: .CurveLinear, animations: { () -> Void in
toView!.alpha = 1.0 // 逐渐变为不透明
toView?.frame = transitionContext.finalFrameForViewController(toViewController!) // 移动到指定位置
}) { (finished: Bool) -> Void in
let wasCancelled = transitionContext.transitionWasCancelled()
transitionContext.completeTransition(!wasCancelled)
}
}
}
// 这个相当于fromViewController
class InteractivityFirstViewController: UIViewController {
// 这个相当于toViewController
lazy var interactivitySecondViewController: InteractivitySecondViewController = InteractivitySecondViewController()
// 定义了一个InteractivityTransitionDelegate类作为代理
lazy var customTransitionDelegate: InteractivityTransitionDelegate = InteractivityTransitionDelegate()
override func viewDidLoad() {
super.viewDidLoad()
setupView() // 主要是一些UI控件的布局,可以无视其实现细节
/// 设置动画代理,这个代理比较复杂,所以我们新建了一个代理对象而不是让self作为代理
interactivitySecondViewController.transitioningDelegate = customTransitionDelegate
}
// 触发手势时,也会调用animationButtonDidClicked方法
func interactiveTransitionRecognizerAction(sender: UIScreenEdgePanGestureRecognizer) {
if sender.state == .Began {
self.animationButtonDidClicked(sender)
}
}
func animationButtonDidClicked(sender: AnyObject) {
self.presentViewController(interactivitySecondViewController, animated: true, completion: nil)
}
}
class InteractivityTransitionDelegate: NSObject, UIViewControllerTransitioningDelegate {
func animationControllerForPresentedController(presented: UIViewController, presentingController presenting: UIViewController, sourceController source: UIViewController) -> UIViewControllerAnimatedTransitioning? {
return InteractivityTransitionAnimator(targetEdge: targetEdge)
}
func animationControllerForDismissedController(dismissed: UIViewController) -> UIViewControllerAnimatedTransitioning? {
return InteractivityTransitionAnimator(targetEdge: targetEdge)
}
/// 前两个函数和淡入淡出demo中的实现一致
/// 后两个函数用于实现交互式动画
func interactionControllerForPresentation(animator: UIViewControllerAnimatedTransitioning) -> UIViewControllerInteractiveTransitioning? {
return TransitionInteractionController(gestureRecognizer: gestureRecognizer, edgeForDragging: targetEdge)
}
func interactionControllerForDismissal(animator: UIViewControllerAnimatedTransitioning) -> UIViewControllerInteractiveTransitioning? {
return TransitionInteractionController(gestureRecognizer: gestureRecognizer, edgeForDragging: targetEdge)
}
}
class TransitionInteractionController: UIPercentDrivenInteractiveTransition {
/// 当手势有滑动时触发这个函数
func gestureRecognizeDidUpdate(gestureRecognizer: UIScreenEdgePanGestureRecognizer) {
switch gestureRecognizer.state {
case .Began: break
case .Changed: self.updateInteractiveTransition(self.percentForGesture(gestureRecognizer)) //手势滑动,更新百分比
case .Ended: // 滑动结束,判断是否超过一半,如果是则完成剩下的动画,否则取消动画
if self.percentForGesture(gestureRecognizer) >= 0.5 {
self.finishInteractiveTransition()
}
else {
self.cancelInteractiveTransition()
}
default: self.cancelInteractiveTransition()
}
}
private func percentForGesture(gesture: UIScreenEdgePanGestureRecognizer) -> CGFloat {
let percent = 根据gesture计算得出
return percent
}
}
// 这个相当于fromViewController
class CustomPresentationFirstViewController: UIViewController {
// 这个相当于toViewController
lazy var customPresentationSecondViewController: CustomPresentationSecondViewController = CustomPresentationSecondViewController()
// 创建PresentationController
lazy var customPresentationController: CustomPresentationController = CustomPresentationController(presentedViewController: self.customPresentationSecondViewController, presentingViewController: self)
override func viewDidLoad() {
super.viewDidLoad()
setupView() // 主要是一些UI控件的布局,可以无视其实现细节
// 设置转场动画代理
customPresentationSecondViewController.transitioningDelegate = customPresentationController
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
func animationButtonDidClicked() {
self.presentViewController(customPresentationSecondViewController, animated: true, completion: nil)
}
}
class CustomPresentationController: UIPresentationController, UIViewControllerTransitioningDelegate {
var presentationWrappingView: UIView? // 这个视图封装了原视图,添加了阴影和圆角效果
var dimmingView: UIView? = nil // alpha为0.5的黑色蒙版
// 告诉UIKit为哪个视图添加动画效果
override func presentedView() -> UIView? {
return self.presentationWrappingView
}
}
// 四个方法自定义转场动画发生前后的操作
extension CustomPresentationController {
override func presentationTransitionWillBegin() {
// 设置presentationWrappingView和dimmingView的UI效果
let transitionCoordinator = self.presentingViewController.transitionCoordinator()
self.dimmingView?.alpha = 0
// 通过转场协调器执行同步的动画效果
transitionCoordinator?.animateAlongsideTransition({ (context: UIViewControllerTransitionCoordinatorContext) -> Void in
self.dimmingView?.alpha = 0.5
}, completion: nil)
}
/// present结束时,把dimmingView和wrappingView都清空,这些临时视图用不到了
override func presentationTransitionDidEnd(completed: Bool) {
if !completed {
self.presentationWrappingView = nil
self.dimmingView = nil
}
}
/// dismiss开始时,让dimmingView完全透明,这个动画和animator中的动画同时发生
override func dismissalTransitionWillBegin() {
let transitionCoordinator = self.presentingViewController.transitionCoordinator()
transitionCoordinator?.animateAlongsideTransition({ (context: UIViewControllerTransitionCoordinatorContext) -> Void in
self.dimmingView?.alpha = 0
}, completion: nil)
}
/// dismiss结束时,把dimmingView和wrappingView都清空,这些临时视图用不到了
override func dismissalTransitionDidEnd(completed: Bool) {
if completed {
self.presentationWrappingView = nil
self.dimmingView = nil
}
}
}
extension CustomPresentationController {
}
class FromViewController: UIViewController, UINavigationControllerDelegate {
let toViewController: ToViewController = ToViewController()
override func viewDidLoad() {
super.viewDidLoad()
setupView() // 主要是一些UI控件的布局,可以无视其实现细节
self.navigationController.delegate = self
}
}
func navigationController(navigationController: UINavigationController,
animationControllerForOperation operation: UINavigationControllerOperation,
fromViewController fromVC: UIViewController,
toViewController toVC: UIViewController)
-> UIViewControllerAnimatedTransitioning? {
if operation == .Push {
return PushAnimator()
}
if operation == .Pop {
return PopAnimator()
}
return nil;
}
机械节能产品生产企业官网模板...
大气智能家居家具装修装饰类企业通用网站模板...
礼品公司网站模板
宽屏简约大气婚纱摄影影楼模板...
蓝白WAP手机综合医院类整站源码(独立后台)...苏ICP备2024110244号-2 苏公网安备32050702011978号 增值电信业务经营许可证编号:苏B2-20251499 | Copyright 2018 - 2025 源码网商城 (www.ymwmall.com) 版权所有