iOS转场动画封装
寫在前面
iOS在modal 或push等操作時有默認的轉場動畫,但有時候我們又需要特定的轉場動畫效果,從iOS7開始,蘋果就提供了自定義轉場的API,模態推送present和dismiss、導航控制器push和pop、標簽控制器的控制器切換都可以自定義轉場。
自定義轉場動畫的實現步驟如下:
1、遵循<UIViewControllerAnimatedTransitioning>協議的動畫過渡管理對象,兩個必須實現的方法:
public func transitionDuration(transitionContext: UIViewControllerContextTransitioning?) -> NSTimeInterval// This method can only be a nop if the transition is interactive and not a percentDriven interactive transition.public func animateTransition(transitionContext: UIViewControllerContextTransitioning) // This is a convenience and if implemented will be invoked by the system when the transition context's completeTransition: method is invoked.optional public func animationEnded(transitionCompleted: Bool)2、繼承于UIPercentDrivenInteractiveTransition的手勢過渡管理對象,動畫的過程是通過百分比控制的。如果不需要手勢控制,這一步可不實現。
UIViewControllerInteractiveTransitioning {// This is the non-interactive duration that was returned when the// animators transitionDuration: method was called when the transition started.public var duration: CGFloat { get }// The last percentComplete value specified by updateInteractiveTransition:public var percentComplete: CGFloat { get }// completionSpeed defaults to 1.0 which corresponds to a completion duration of// (1 - percentComplete)*duration. It must be greater than 0.0. The actual// completion is inversely proportional to the completionSpeed. This can be set// before cancelInteractiveTransition or finishInteractiveTransition is called// in order to speed up or slow down the non interactive part of the// transition.public var completionSpeed: CGFloat// When the interactive part of the transition has completed, this property can// be set to indicate a different animation curve. It defaults to UIViewAnimationCurveEaseInOut.// Note that during the interactive portion of the animation the timing curve is linear. public var completionCurve: UIViewAnimationCurve// These methods should be called by the gesture recognizer or some other logic// to drive the interaction. This style of interaction controller should only be// used with an animator that implements a CA style transition in the animator's// animateTransition: method. If this type of interaction controller is// specified, the animateTransition: method must ensure to call the// UIViewControllerTransitionParameters completeTransition: method. The other// interactive methods on UIViewControllerContextTransitioning should NOT be// called.public func updateInteractiveTransition(percentComplete: CGFloat)public func cancelInteractiveTransition()public func finishInteractiveTransition()?
3、成為相應的代理,實現UIViewControllerAnimatedTransitioning的代理方法,返回我們前兩步自定義的對象。
模態推送實現的代理方法
@available(iOS 2.0, *)optional public func animationControllerForPresentedController(presented: UIViewController, presentingController presenting: UIViewController, sourceController source: UIViewController) -> UIViewControllerAnimatedTransitioning?@available(iOS 2.0, *)optional public func animationControllerForDismissedController(dismissed: UIViewController) -> UIViewControllerAnimatedTransitioning?optional public func interactionControllerForPresentation(animator: UIViewControllerAnimatedTransitioning) -> UIViewControllerInteractiveTransitioning?optional public func interactionControllerForDismissal(animator: UIViewControllerAnimatedTransitioning) -> UIViewControllerInteractiveTransitioning?@available(iOS 8.0, *)optional public func presentationControllerForPresentedViewController(presented: UIViewController, presentingViewController presenting: UIViewController, sourceViewController source: UIViewController) -> UIPresentationController??
轉場動畫Demo
下面直接看demo,封裝自定義的轉場動畫實現圖片在兩個控制器間放大過渡的動畫效果,面向協議進行開發,使用時將轉場動畫代理設置為SZAnimator。
import UIKit protocol SZAnimatorPresentDelegate: NSObjectProtocol {// 負責提供彈出動畫的視圖func presentView() -> UIView func presentFrameRect() -> CGRect func presentToRect() -> CGRect }protocol SZAnimatorDimissDelegate: NSObjectProtocol {// 負責提供dismiss動畫的視圖func dismissView() -> UIViewfunc dismissFrameRect() -> CGRect func dismissToRect() -> CGRect }class SZAnimator: NSObject {var isPresent: Bool = trueweak var presentDelegate: SZAnimatorPresentDelegate?weak var dismissDelegate: SZAnimatorDimissDelegate? }extension SZAnimator: UIViewControllerTransitioningDelegate {// 指定彈出時,處理動畫的對象func animationControllerForPresentedController(presented: UIViewController, presentingController presenting: UIViewController, sourceController source: UIViewController) -> UIViewControllerAnimatedTransitioning? {isPresent = truereturn self}// 指定彈下去時候, 處理動畫的對象func animationControllerForDismissedController(dismissed: UIViewController) -> UIViewControllerAnimatedTransitioning? {isPresent = falsereturn self} }// 消失動畫 // 彈出動畫 extension SZAnimator: UIViewControllerAnimatedTransitioning {// 返回動畫的時間func transitionDuration(transitionContext: UIViewControllerContextTransitioning?) -> NSTimeInterval {return 2.0}// 在這里, 實現真正的彈出, 或者消失的動畫// transitionContext func animateTransition(transitionContext: UIViewControllerContextTransitioning) { isPresent ? present(transitionContext) : dismiss(transitionContext) }func dismiss(transitionContext: UIViewControllerContextTransitioning) {// 自定義動畫// 面向協議進行開發// 1. 拿什么界面做動畫// 2. fromRect// 3. toRect let animationView = dismissDelegate!.dismissView()transitionContext.containerView()?.addSubview(animationView)// 初始的frameanimationView.frame = dismissDelegate!.dismissFrameRect() // 最終需要展示的視圖if #available(iOS 8.0, *) {let fromView = transitionContext.viewForKey(UITransitionContextFromViewKey)// 動畫 UIView.animateWithDuration(transitionDuration(transitionContext), animations: { // toView?.alpha = 1animationView.frame = self.dismissDelegate!.dismissToRect()fromView?.alpha = 0}) { (flag: Bool) in animationView.removeFromSuperview()transitionContext.completeTransition(true)}} }func present(transitionContext: UIViewControllerContextTransitioning) {// 自定義動畫// 面向協議進行開發// 1. 拿什么界面做動畫// 2. fromRect// 3. toRect let animationView = presentDelegate!.presentView()transitionContext.containerView()?.addSubview(animationView)// 初始的frameanimationView.frame = presentDelegate!.presentFrameRect() // 最終需要展示的視圖if #available(iOS 8.0, *) {let toView = transitionContext.viewForKey(UITransitionContextToViewKey)toView?.frame = UIScreen.mainScreen().boundstransitionContext.containerView()?.addSubview(toView!)toView?.alpha = 0// 動畫UIView.animateWithDuration(2.0, animations: {toView?.alpha = 1animationView.frame = self.presentDelegate!.presentToRect() }) { (flag: Bool) inanimationView.removeFromSuperview()transitionContext.completeTransition(true)}} } }?
轉載于:https://www.cnblogs.com/imsz/p/6977887.html
總結
- 上一篇: 第二阶段冲刺10天 第五天
- 下一篇: SQL-SQLServer(926)