Skip to content

Commit 6e2edfb

Browse files
committed
代码完善,全部改用snapkit,添加注释
1 parent 02e0faa commit 6e2edfb

12 files changed

Lines changed: 297 additions & 177 deletions

CustomTransition/CustomTransition-Swift/CustomTransition-Swift.xcodeproj/project.pbxproj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -131,9 +131,9 @@
131131
isa = PBXGroup;
132132
children = (
133133
9B5074F81C671E4A00C89416 /* CrossDissolveFirstViewController.swift */,
134+
9B5074FA1C68403000C89416 /* CrossDissolveSecondViewController.swift */,
134135
9B5075061C68CBE800C89416 /* HalfWaySpringAnimator.swift */,
135136
9B5075041C68982400C89416 /* CrossDissolveAnimator.swift */,
136-
9B5074FA1C68403000C89416 /* CrossDissolveSecondViewController.swift */,
137137
);
138138
path = "Cross Dissolve";
139139
sourceTree = "<group>";

CustomTransition/CustomTransition-Swift/CustomTransition-Swift/Cross Dissolve/CrossDissolveFirstViewController.swift

Lines changed: 39 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -13,35 +13,16 @@ class CrossDissolveFirstViewController: UIViewController, UIViewControllerTransi
1313

1414
override func viewDidLoad() {
1515
super.viewDidLoad()
16-
view.backgroundColor = [224, 222, 255].color // 设置背景颜色
17-
18-
/// 设置navigationItem
19-
navigationItem.title = "淡入淡出"
20-
navigationItem.leftBarButtonItem = UIBarButtonItem(title: "Menu", style: UIBarButtonItemStyle.Plain, target: self, action: Selector("leftBarButtonDidClicked"))
21-
22-
/// 创建label
23-
let label = UILabel(frame: CGRectMake(0,0,150,100))
24-
label.center = view.center
25-
label.text = "From"
26-
label.font = UIFont(name: "Helvetica", size: 60)
27-
view.addSubview(label)
28-
29-
/// 创建button
30-
let button = UIButton(frame: CGRectMake(0,0,250,60))
31-
button.center = view.center
32-
button.frame.origin.y = view.frame.maxY - 100
33-
button.setTitleColor(UIColor.blueColor(), forState: .Normal)
34-
button.setTitle("演示动画", forState: .Normal)
35-
button.addTarget(self, action: Selector("animationButtonDidClicked"), forControlEvents: .TouchUpInside)
36-
view.addSubview(button)
16+
setupView() // 主要是一些UI控件的布局,可以无视其实现细节
3717

3818
/// 为了使用自定义present动画进行的一些设置
3919
crossDissolveSecondViewController.modalPresentationStyle = .FullScreen
40-
crossDissolveSecondViewController.transitioningDelegate = self
20+
crossDissolveSecondViewController.transitioningDelegate = self // 设置动画代理,这里的代理就是这个类自己
4121
}
4222
}
4323

4424
// MARK: - 实现UIViewControllerTransitioningDelegate协议
25+
// MARK: - 作为代理,需要提供present和dismiss时的animator,有时候一个animator可以同时在present和dismiss时用
4526
extension CrossDissolveFirstViewController {
4627
func animationControllerForPresentedController(presented: UIViewController, presentingController presenting: UIViewController, sourceController source: UIViewController) -> UIViewControllerAnimatedTransitioning? {
4728
// 也可以使用CrossDissolveAnimator,动画效果各有不同
@@ -54,6 +35,7 @@ extension CrossDissolveFirstViewController {
5435
}
5536
}
5637

38+
// MARK: - 处理UI控件的点击事件
5739
extension CrossDissolveFirstViewController {
5840
func animationButtonDidClicked() {
5941
self.presentViewController(crossDissolveSecondViewController, animated: true, completion: nil)
@@ -62,4 +44,39 @@ extension CrossDissolveFirstViewController {
6244
func leftBarButtonDidClicked() {
6345
self.dismissViewControllerAnimated(true, completion: nil)
6446
}
47+
}
48+
49+
// MARK: - 对视图上的基本UI控件进行初始化,读者可以忽略
50+
extension CrossDissolveFirstViewController {
51+
func setupView() {
52+
view.backgroundColor = [224, 222, 255].color // 设置背景颜色
53+
54+
/// 设置navigationItem
55+
navigationItem.title = "淡入淡出"
56+
navigationItem.leftBarButtonItem = UIBarButtonItem(title: "Menu", style: UIBarButtonItemStyle.Plain, target: self, action: Selector("leftBarButtonDidClicked"))
57+
58+
/// 创建label
59+
let label = UILabel()
60+
label.text = "From"
61+
label.font = UIFont(name: "Helvetica", size: 60)
62+
view.addSubview(label)
63+
label.snp_makeConstraints { (make) -> Void in
64+
make.center.equalTo(view)
65+
make.width.equalTo(150)
66+
make.height.equalTo(60)
67+
}
68+
69+
/// 创建button
70+
let button = UIButton()
71+
button.setTitleColor(UIColor.blueColor(), forState: .Normal)
72+
button.setTitle("演示动画", forState: .Normal)
73+
button.addTarget(self, action: Selector("animationButtonDidClicked"), forControlEvents: .TouchUpInside)
74+
view.addSubview(button)
75+
button.snp_makeConstraints { (make) -> Void in
76+
make.centerX.equalTo(view)
77+
make.width.equalTo(250)
78+
make.height.equalTo(60)
79+
make.bottom.equalTo(view).offset(-40)
80+
}
81+
}
6582
}

CustomTransition/CustomTransition-Swift/CustomTransition-Swift/Cross Dissolve/CrossDissolveSecondViewController.swift

Lines changed: 30 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -11,32 +11,48 @@ import UIKit
1111
class CrossDissolveSecondViewController: UIViewController {
1212
override func viewDidLoad() {
1313
super.viewDidLoad()
14+
setupView() // 主要是一些UI控件的布局,可以无视其实现细节
15+
}
16+
}
17+
18+
// MARK: - 处理UI控件的点击事件
19+
extension CrossDissolveSecondViewController {
20+
func buttonDidClicked() {
21+
/**
22+
* 应该由FirstVC执行下面这行代码,为了保持demo简单,突出重点,这里的写法其实是不严格的,请见谅
23+
*/
24+
self.dismissViewControllerAnimated(true, completion: nil)
25+
}
26+
}
27+
28+
// MARK: - 对视图上的基本UI控件进行初始化,读者可以忽略
29+
extension CrossDissolveSecondViewController {
30+
func setupView() {
1431
view.backgroundColor = [254, 223, 224].color // 设置背景颜色
1532

1633
/// 创建label
17-
let label = UILabel(frame: CGRectMake(0,0,150,100))
18-
label.center = view.center
34+
let label = UILabel()
1935
label.text = "To"
2036
label.textAlignment = .Center
2137
label.font = UIFont(name: "Helvetica", size: 60)
2238
view.addSubview(label)
39+
label.snp_makeConstraints { (make) -> Void in
40+
make.center.equalTo(view)
41+
make.width.equalTo(150)
42+
make.height.equalTo(60)
43+
}
2344

2445
/// 创建button
25-
let button = UIButton(frame: CGRectMake(0,0,250,60))
26-
button.center = view.center
27-
button.frame.origin.y = view.frame.maxY - 100
46+
let button = UIButton()
2847
button.setTitleColor(UIColor.blueColor(), forState: .Normal)
2948
button.setTitle("Dismiss", forState: .Normal)
3049
button.addTarget(self, action: Selector("buttonDidClicked"), forControlEvents: .TouchUpInside)
3150
view.addSubview(button)
32-
}
33-
}
34-
35-
extension CrossDissolveSecondViewController {
36-
func buttonDidClicked() {
37-
/**
38-
* 应该由FirstVC执行下面这行代码,为了保持demo简单,突出重点,这里的写法其实是不严格的,请见谅
39-
*/
40-
self.dismissViewControllerAnimated(true, completion: nil)
51+
button.snp_makeConstraints { (make) -> Void in
52+
make.centerX.equalTo(view)
53+
make.width.equalTo(250)
54+
make.height.equalTo(60)
55+
make.bottom.equalTo(view).offset(-40)
56+
}
4157
}
4258
}

CustomTransition/CustomTransition-Swift/CustomTransition-Swift/Cross Dissolve/HalfWaySpringAnimator.swift

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,35 +8,50 @@
88

99
import UIKit
1010

11+
/// 要实现UIViewControllerAnimatedTransitioning协议就必须实现下面两个方法
1112
class HalfWaySpringAnimator: NSObject, UIViewControllerAnimatedTransitioning {
13+
/// 设置动画的持续时间
1214
func transitionDuration(transitionContext: UIViewControllerContextTransitioning?) -> NSTimeInterval {
1315
return 1
1416
}
1517

18+
/// 设置动画的进行方式,附有详细注释,demo中其他地方的这个方法不再解释
1619
func animateTransition(transitionContext: UIViewControllerContextTransitioning) {
1720
let fromViewController = transitionContext.viewControllerForKey(UITransitionContextFromViewControllerKey)
1821
let toViewController = transitionContext.viewControllerForKey(UITransitionContextToViewControllerKey)
1922
let containerView = transitionContext.containerView()
2023

24+
// 需要关注一下from/to和presented/presenting的关系
25+
// For a Presentation:
26+
// fromView = The presenting view.
27+
// toView = The presented view.
28+
// For a Dismissal:
29+
// fromView = The presented view.
30+
// toView = The presenting view.
31+
2132
var fromView = fromViewController?.view
2233
var toView = toViewController?.view
2334

35+
// iOS8引入了viewForKey方法,尽可能使用这个方法而不是直接访问controller的view属性
36+
// 比如在form sheet样式中,我们为presentedViewController的view添加阴影或其他decoration,animator会对整个decoration view
37+
// 添加动画效果,而此时presentedViewController的view只是decoration view的一个子视图
2438
if transitionContext.respondsToSelector(Selector("viewForKey:")) {
2539
fromView = transitionContext.viewForKey(UITransitionContextFromViewKey)
2640
toView = transitionContext.viewForKey(UITransitionContextToViewKey)
2741
}
2842

29-
fromView?.frame = transitionContext.initialFrameForViewController(fromViewController!)
43+
// 我们让toview的origin.y在屏幕的一半处,这样它从屏幕的中间位置弹起而不是从屏幕底部弹起,弹起过程中逐渐变为不透明
3044
toView?.frame = CGRectMake(fromView!.frame.origin.x, fromView!.frame.maxY / 2, fromView!.frame.width, fromView!.frame.height)
31-
3245
toView?.alpha = 0.0
3346

47+
// 在present和,dismiss时,必须将toview添加到视图层次中
3448
containerView?.addSubview(toView!)
3549

3650
let transitionDuration = self.transitionDuration(transitionContext)
51+
// 使用spring动画,有弹簧效果,动画结束后一定要调用completeTransition方法
3752
UIView.animateWithDuration(transitionDuration, delay: 0, usingSpringWithDamping: 0.6, initialSpringVelocity: 0, options: .CurveLinear, animations: { () -> Void in
38-
toView!.alpha = 1.0
39-
toView?.frame = transitionContext.finalFrameForViewController(toViewController!)
53+
toView!.alpha = 1.0 // 逐渐变为不透明
54+
toView?.frame = transitionContext.finalFrameForViewController(toViewController!) // 移动到指定位置
4055
}) { (finished: Bool) -> Void in
4156
let wasCancelled = transitionContext.transitionWasCancelled()
4257
transitionContext.completeTransition(!wasCancelled)

CustomTransition/CustomTransition-Swift/CustomTransition-Swift/Custom Presentation/CustomPresentationController.swift

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ import UIKit
1111
class CustomPresentationController: UIPresentationController, UIViewControllerTransitioningDelegate {
1212

1313
let CORNER_RADIUS: CGFloat = 16
14-
var presentationWrappingView: UIView? = nil
14+
var presentationWrappingView: UIView? = nil // 被添加动画效果的view,在presentedViewController的基础上添加了其他效果
1515
var dimmingView: UIView? = nil
1616

1717
override init(presentedViewController: UIViewController, presentingViewController: UIViewController) {
@@ -28,27 +28,36 @@ class CustomPresentationController: UIPresentationController, UIViewControllerTr
2828
// MARK: - 两组对应的方法,实现自定义presentation
2929
extension CustomPresentationController {
3030
override func presentationTransitionWillBegin() {
31-
let presentedViewControllerView = super.presentedView()
32-
let presentationWrapperView = UIView(frame: self.frameOfPresentedViewInContainerView())
31+
let presentationWrapperView = UIView(frame: self.frameOfPresentedViewInContainerView()) // 添加阴影效果
3332
presentationWrapperView.layer.shadowOpacity = 0.44
3433
presentationWrapperView.layer.shadowRadius = 13
3534
presentationWrapperView.layer.shadowOffset = CGSizeMake(0, -6)
35+
/// 在重写父类的presentedView方法中,返回了self.presentationWrappingView,这个方法表示需要添加动画效果的视图
36+
/// 这里对self.presentationWrappingView赋值,从后面的代码可以看到这个视图处于视图层级的最上层
3637
self.presentationWrappingView = presentationWrapperView
3738

38-
let presentationRoundedCornerView = UIView(frame: UIEdgeInsetsInsetRect(presentationWrapperView.bounds, UIEdgeInsetsMake(0, 0, -CORNER_RADIUS, 0)))
39+
let presentationRoundedCornerView = UIView(frame: UIEdgeInsetsInsetRect(presentationWrapperView.bounds, UIEdgeInsetsMake(0, 0, -CORNER_RADIUS, 0))) // 添加圆角效果
3940
presentationRoundedCornerView.autoresizingMask = [UIViewAutoresizing.FlexibleHeight, UIViewAutoresizing.FlexibleWidth]
4041
presentationRoundedCornerView.layer.cornerRadius = CORNER_RADIUS
4142
presentationRoundedCornerView.layer.masksToBounds = true
4243

4344
let presentedViewControllerWrapperView = UIView(frame: UIEdgeInsetsInsetRect(presentationRoundedCornerView.bounds, UIEdgeInsetsMake(0, 0, CORNER_RADIUS, 0)))
4445
presentedViewControllerWrapperView.autoresizingMask = [UIViewAutoresizing.FlexibleWidth, UIViewAutoresizing.FlexibleHeight]
4546

47+
let presentedViewControllerView = super.presentedView()
4648
presentedViewControllerView?.autoresizingMask = [UIViewAutoresizing.FlexibleWidth, UIViewAutoresizing.FlexibleHeight]
4749
presentedViewControllerView?.frame = presentedViewControllerWrapperView.bounds
50+
51+
// 视图层级关系如下:
52+
// presentationWrapperView <- 添加阴影效果
53+
// |- presentationRoundedCornerView <- 添加圆角效果 (masksToBounds)
54+
// |- presentedViewControllerWrapperView
55+
// |- presentedViewControllerView (presentedViewController.view)
4856
presentedViewControllerWrapperView.addSubview(presentedViewControllerView!)
4957
presentationRoundedCornerView.addSubview(presentedViewControllerWrapperView)
5058
presentationWrapperView.addSubview(presentationRoundedCornerView)
5159

60+
/// 深色的一层覆盖视图,让背景看上去比较暗
5261
let dimmingView = UIView(frame: (self.containerView?.bounds)!)
5362
dimmingView.backgroundColor = UIColor.blackColor()
5463
dimmingView.opaque = false
@@ -64,20 +73,23 @@ extension CustomPresentationController {
6473
}, completion: nil)
6574
}
6675

76+
/// present结束时,把dimmingView和wrappingView都清空,这些临时视图用不到了
6777
override func presentationTransitionDidEnd(completed: Bool) {
6878
if !completed {
6979
self.presentationWrappingView = nil
7080
self.dimmingView = nil
7181
}
7282
}
7383

84+
/// dismiss开始时,让dimmingView完全透明,这个动画和animator中的动画同时发生
7485
override func dismissalTransitionWillBegin() {
7586
let transitionCoordinator = self.presentingViewController.transitionCoordinator()
7687
transitionCoordinator?.animateAlongsideTransition({ (context: UIViewControllerTransitionCoordinatorContext) -> Void in
7788
self.dimmingView?.alpha = 0
7889
}, completion: nil)
7990
}
8091

92+
/// dismiss结束时,把dimmingView和wrappingView都清空,这些临时视图用不到了
8193
override func dismissalTransitionDidEnd(completed: Bool) {
8294
if completed {
8395
self.presentationWrappingView = nil

CustomTransition/CustomTransition-Swift/CustomTransition-Swift/Custom Presentation/CustomPresentationFirstViewController.swift

Lines changed: 36 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -14,27 +14,7 @@ class CustomPresentationFirstViewController: UIViewController {
1414

1515
override func viewDidLoad() {
1616
super.viewDidLoad()
17-
view.backgroundColor = [224, 222, 255].color // 设置背景颜色
18-
19-
/// 设置navigationItem
20-
navigationItem.title = "自定义Presentation"
21-
navigationItem.leftBarButtonItem = UIBarButtonItem(title: "Menu", style: UIBarButtonItemStyle.Plain, target: self, action: Selector("leftBarButtonDidClicked"))
22-
23-
/// 创建label
24-
let label = UILabel(frame: CGRectMake(0,0,150,100))
25-
label.center = view.center
26-
label.text = "From"
27-
label.font = UIFont(name: "Helvetica", size: 60)
28-
view.addSubview(label)
29-
30-
/// 创建button
31-
let button = UIButton(frame: CGRectMake(0,0,250,60))
32-
button.center = view.center
33-
button.frame.origin.y = view.frame.maxY - 100
34-
button.setTitleColor(UIColor.blueColor(), forState: .Normal)
35-
button.setTitle("演示动画", forState: .Normal)
36-
button.addTarget(self, action: Selector("animationButtonDidClicked"), forControlEvents: .TouchUpInside)
37-
view.addSubview(button)
17+
setupView() // 主要是一些UI控件的布局,可以无视其实现细节
3818
}
3919

4020
override func didReceiveMemoryWarning() {
@@ -54,3 +34,38 @@ extension CustomPresentationFirstViewController {
5434
self.dismissViewControllerAnimated(true, completion: nil)
5535
}
5636
}
37+
38+
// MARK: - 对视图上的基本UI控件进行初始化,读者可以忽略
39+
extension CustomPresentationFirstViewController {
40+
func setupView() {
41+
view.backgroundColor = [224, 222, 255].color // 设置背景颜色
42+
43+
/// 设置navigationItem
44+
navigationItem.title = "自定义Presentation"
45+
navigationItem.leftBarButtonItem = UIBarButtonItem(title: "Menu", style: UIBarButtonItemStyle.Plain, target: self, action: Selector("leftBarButtonDidClicked"))
46+
47+
// 创建label
48+
let label = UILabel()
49+
label.text = "From"
50+
label.font = UIFont(name: "Helvetica", size: 60)
51+
view.addSubview(label)
52+
label.snp_makeConstraints { (make) -> Void in
53+
make.center.equalTo(view)
54+
make.width.equalTo(150)
55+
make.height.equalTo(60)
56+
}
57+
58+
/// 创建button
59+
let button = UIButton()
60+
button.setTitleColor(UIColor.blueColor(), forState: .Normal)
61+
button.setTitle("演示动画", forState: .Normal)
62+
button.addTarget(self, action: Selector("animationButtonDidClicked"), forControlEvents: .TouchUpInside)
63+
view.addSubview(button)
64+
button.snp_makeConstraints { (make) -> Void in
65+
make.centerX.equalTo(view)
66+
make.width.equalTo(250)
67+
make.height.equalTo(60)
68+
make.bottom.equalTo(view).offset(-40)
69+
}
70+
}
71+
}

0 commit comments

Comments
 (0)