您的位置:首页 > 移动开发 > Swift

Swift自定义转场动画

2016-03-18 23:00 507 查看


1.通过storyBoard加载控制器

let sb = UIStoryboard(name: "WYPopViewController", bundle: nil)
// 1.需要勾选箭头
let vc = sb.instantiateInitialViewController()!
// 2.通过id加载
let vc = sb.instantiateViewControllerWithIdentifier("123")


2.设置代理

// 设置代理
vc.transitioningDelegate = popAnimation
//
vc.modalPresentationStyle = .Custom
// 3.弹出控制器
presentViewController(vc, animated: true, completion: nil)


3.准守协议,实现方法(UIViewControllerTransitioningDelegate,UIViewControllerAnimatedTransitioning)

负责转场动画的控制器
// iOS8之后推出的 告诉系统谁来负责转场动画
func presentationControllerForPresentedViewController(presented: UIViewController, presentingViewController presenting: UIViewController, sourceViewController source: UIViewController) -> UIPresentationController? {

let pop = WYPopPresentationController(presentedViewController: presented, presentingViewController: presenting)
pop.presentFrame = presentFrame
return pop
}


告诉系统谁来负责Modal的展现动画
// MARK: - 只要实现了以下方法, 那么系统自带的默认动画就没有了, "所有"东西都需要程序员自己来实现
/**
:param: presented  被展现视图
:param: presenting 发起的视图
:returns: 谁来负责
*/
func animationControllerForPresentedController(presented: UIViewController, presentingController presenting: UIViewController, sourceController source: UIViewController) -> UIViewControllerAnimatedTransitioning? {
isPresent = true

// 发出通知,箭头朝上
NSNotificationCenter.defaultCenter().postNotificationName(PopViewWillShow, object: nil)
return self
}


告诉系统谁来负责动画的消失
/**
- parameter dismissed: 被关闭的视图
- returns:
*/
func animationControllerForDismissedController(dismissed: UIViewController) -> UIViewControllerAnimatedTransitioning? {
isPresent = false
// 发出通知,箭头朝下
NSNotificationCenter.defaultCenter().postNotificationName(PopViewWillDismiss, object: nil)
return self
}


UIViewControllerAnimatedTransitioning的代理方法
/**
返回动画时长

:param: transitionContext 上下文, 里面保存了动画需要的所有参数
:returns: 动画时长
*/
func transitionDuration(transitionContext: UIViewControllerContextTransitioning?) -> NSTimeInterval {
return 0.5
}


告诉系统如何动画, 无论是展现还是消失都会调用这个方法

/**
:param: transitionContext 上下文, 里面保存了动画需要的所有参数
*/
func animateTransition(transitionContext: UIViewControllerContextTransitioning) {

if isPresent{
//print("展开")
let toView = transitionContext.viewForKey(UITransitionContextToViewKey)

toView?.transform = CGAffineTransformMakeScale(1.0, 0.0)

// 将试图添加到容器中
transitionContext.containerView()?.addSubview(toView!)

// 修改锚点
toView?.layer.anchorPoint = CGPointMake(0.5, 0)
// 执行动画
UIView.animateWithDuration(0.5, animations: { () -> Void in

toView?.transform = CGAffineTransformIdentity
}) { (_) -> Void in

transitionContext.completeTransition(true)
}

}else{
//print("关闭")
let formView = transitionContext.viewForKey(UITransitionContextFromViewKey)

UIView.animateWithDuration(0.5, animations: { () -> Void in

formView?.transform = CGAffineTransformMakeScale(1.0, 0.001)
}, completion: { (_) -> Void in

transitionContext.completeTransition(true)
})
}
}


4.自定义转场控制器

// 展示视图的尺寸
var presentFrame = CGRectZero
/**
- parameter presentedViewController:  被展示的控制器
- parameter presentingViewController: 执行转场的控制器

*/
override init(presentedViewController: UIViewController, presentingViewController: UIViewController) {
super.init(presentedViewController: presentedViewController, presentingViewController: presentingViewController)
}

/**
即将布局转场子视图时调用
*/
override func containerViewWillLayoutSubviews() {

// 设置展现视图的尺寸
if presentFrame == CGRectZero{
presentedView()?.frame = CGRectMake(100, 60, 200, 300)
}else{

presentedView()?.frame = presentFrame
}
// 在容器上添加一个蒙版,用来移除modal出来的控制器
containerView?.insertSubview(cover, atIndex: 0)
}

func close () {
presentedViewController.dismissViewControllerAnimated(true, completion: nil)
}

private lazy var cover : UIView = {

let cover = UIView()
// 设置尺寸
cover.frame = UIScreen.mainScreen().bounds
// 颜色
cover.backgroundColor = UIColor.clearColor()

// 添加手势
let tap = UITapGestureRecognizer(target: self, action: "close")
cover.addGestureRecognizer(tap)
return cover
}()


效果图:

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: