-
Notifications
You must be signed in to change notification settings - Fork 12
/
Copy pathBubbleTransition.swift
169 lines (141 loc) · 5.14 KB
/
BubbleTransition.swift
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
//
// BubbleTransition.swift
// desappstre framework
//
// Created by Adolfo Vera Blasco on 14/03/16.
// Copyright (c) 2016 Adolfo Vera Blasco. All rights reserved.
//
import UIKit
import Foundation
@objc public class BubbleTransition: NSObject
{
/// Point in which we situate the bubble.
/// By default Upper Left corner
public var startingPoint: CGPoint
/// The transition direction.
public var transitionMode: TransitionMode
/// The color of the bubble.
/// Non defined? We use the presented controller background color
public var bubbleColor: UIColor?
/// The bubble
private var bubble: UIView!
/// Transition duration
private var presentingDuration: Double
/// Dismiss duration
private var dismissDuration: Double
/**
Initializer
*/
public override init()
{
self.presentingDuration = 0.5
self.dismissDuration = 0.35
self.startingPoint = CGPointMake(0.0, 0.0)
self.transitionMode = TransitionMode.Present
}
//
// MARK: - Private Methods
//
/**
Calculate the circle needed to cover the screen completly
- Parameters:
- originalSize: Size that must be covered
- start: Where the bubble starts to growth
*/
private func frameForBubbleWithSize(originalSize: CGSize, start: CGPoint) -> CGRect
{
let lengthX = fmax(start.x, originalSize.width - start.x);
let lengthY = fmax(start.y, originalSize.height - start.y)
let offset = sqrt(lengthX * lengthX + lengthY * lengthY) * 2;
return CGRectMake(0, 0, offset, offset)
}
}
//
// MARK: - UIViewControllerAnimatedTransitioning Protocol
//
extension BubbleTransition: UIViewControllerAnimatedTransitioning
{
/**
Transition duration
*/
public func transitionDuration(transitionContext: UIViewControllerContextTransitioning?) -> NSTimeInterval
{
return self.transitionMode == .Present ? self.presentingDuration : self.dismissDuration
}
/**
Where the magic happends :)
*/
public func animateTransition(transitionContext: UIViewControllerContextTransitioning)
{
guard let
containerView = transitionContext.containerView(),
toView = transitionContext.viewForKey(UITransitionContextToViewKey),
fromView = transitionContext.viewForKey(UITransitionContextFromViewKey)
else
{
return
}
if transitionMode == TransitionMode.Present
{
let originalCenter = toView.center
let originalSize = toView.frame.size
let frame: CGRect = self.frameForBubbleWithSize(originalSize, start: self.startingPoint)
self.bubble = UIView(frame: frame)
self.bubble.layer.cornerRadius = CGRectGetHeight(self.bubble.frame) / 2
self.bubble.center = self.startingPoint
self.bubble.transform = CGAffineTransformMakeScale(0.001, 0.001)
if let bubbleColor = self.bubbleColor
{
self.bubble.backgroundColor = bubbleColor
}
else
{
self.bubble.backgroundColor = toView.backgroundColor
}
toView.center = startingPoint
toView.transform = CGAffineTransformMakeScale(0.001, 0.001)
toView.alpha = 0
containerView.addSubview(toView)
containerView.addSubview(self.bubble)
UIView.animateWithDuration(self.presentingDuration,
animations:
{
self.bubble.transform = CGAffineTransformIdentity
toView.transform = CGAffineTransformIdentity
toView.alpha = 1
toView.center = originalCenter
},
completion: { (finished: Bool) -> (Void) in
if finished
{
self.bubble.removeFromSuperview()
transitionContext.completeTransition(true)
}
}
)
}
else
{
let originalSize = fromView.frame.size
self.bubble.frame = self.frameForBubbleWithSize(originalSize, start: startingPoint)
self.bubble.layer.cornerRadius = CGRectGetHeight(self.bubble.frame) / 2
self.bubble.center = self.startingPoint
containerView.addSubview(toView)
containerView.addSubview(self.bubble)
UIView.animateWithDuration(self.dismissDuration,
animations:
{
self.bubble.transform = CGAffineTransformMakeScale(0.001, 0.001)
},
completion: { (finished: Bool) -> (Void) in
if finished
{
toView.removeFromSuperview()
self.bubble.removeFromSuperview()
transitionContext.completeTransition(true)
}
}
)
}
}
}