Skip to content

Commit a84e2d8

Browse files
seedanteseedante
authored and
seedante
committed
Adjust file location and some code.
1 parent 011a657 commit a84e2d8

15 files changed

+158
-274
lines changed

CardAnimation.xcodeproj/project.pbxproj

+33-216
Large diffs are not rendered by default.

CardAnimation/Base.lproj/Main.storyboard

+10-3
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
2-
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="8191" systemVersion="14F27" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" initialViewController="BYZ-38-t0r">
2+
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="8191" systemVersion="15A284" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" initialViewController="BYZ-38-t0r">
33
<dependencies>
4+
<deployment identifier="iOS"/>
45
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="8154"/>
56
<capability name="Aspect ratio constraints" minToolsVersion="5.1"/>
67
<capability name="Constraints to layout margins" minToolsVersion="6.0"/>
@@ -39,7 +40,7 @@
3940
<view clipsSubviews="YES" tag="8" contentMode="scaleAspectFit" translatesAutoresizingMaskIntoConstraints="NO" id="fVC-76-ely" userLabel="View8">
4041
<rect key="frame" x="100" y="150" width="400" height="300"/>
4142
<subviews>
42-
<imageView clipsSubviews="YES" userInteractionEnabled="NO" tag="10" contentMode="scaleAspectFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="JLAFRICA.jpeg" translatesAutoresizingMaskIntoConstraints="NO" id="228-ej-cRm">
43+
<imageView clipsSubviews="YES" userInteractionEnabled="NO" tag="10" contentMode="scaleAspectFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="JLA.jpeg" translatesAutoresizingMaskIntoConstraints="NO" id="228-ej-cRm">
4344
<rect key="frame" x="0.0" y="0.0" width="400" height="300"/>
4445
<animations/>
4546
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="calibratedWhite"/>
@@ -222,6 +223,7 @@
222223
</view>
223224
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="duM-30-kXn">
224225
<rect key="frame" x="499" y="28" width="81" height="30"/>
226+
<animations/>
225227
<state key="normal" title="Component"/>
226228
<connections>
227229
<segue destination="fw9-rg-tLH" kind="presentation" id="u46-CM-cgV"/>
@@ -285,6 +287,7 @@
285287
<subviews>
286288
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="srb-xo-nyT">
287289
<rect key="frame" x="284" y="28" width="33" height="42"/>
290+
<animations/>
288291
<fontDescription key="fontDescription" type="system" pointSize="25"/>
289292
<state key="normal" title="UP"/>
290293
<connections>
@@ -293,6 +296,7 @@
293296
</button>
294297
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="31I-9l-4R6">
295298
<rect key="frame" x="262" y="531" width="77" height="42"/>
299+
<animations/>
296300
<fontDescription key="fontDescription" type="system" pointSize="25"/>
297301
<state key="normal" title="DOWN"/>
298302
<connections>
@@ -301,17 +305,20 @@
301305
</button>
302306
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="kKf-Oi-6h7" customClass="CardAnimationView" customModule="CardAnimation" customModuleProvider="target">
303307
<rect key="frame" x="20" y="78" width="560" height="445"/>
308+
<animations/>
304309
<color key="backgroundColor" white="0.66666666666666663" alpha="1" colorSpace="calibratedWhite"/>
305310
</view>
306311
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="xoa-u0-6h5">
307312
<rect key="frame" x="550" y="20" width="30" height="36"/>
313+
<animations/>
308314
<fontDescription key="fontDescription" type="system" pointSize="20"/>
309315
<state key="normal" title="X"/>
310316
<connections>
311317
<action selector="onClosePushed:" destination="fw9-rg-tLH" eventType="touchUpInside" id="QsT-Xz-Alv"/>
312318
</connections>
313319
</button>
314320
</subviews>
321+
<animations/>
315322
<color key="backgroundColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
316323
<constraints>
317324
<constraint firstAttribute="leadingMargin" secondItem="kKf-Oi-6h7" secondAttribute="leading" id="0s0-6z-zcR"/>
@@ -338,7 +345,7 @@
338345
</scene>
339346
</scenes>
340347
<resources>
341-
<image name="JLAFRICA.jpeg" width="840" height="328"/>
348+
<image name="JLA.jpeg" width="840" height="328"/>
342349
<image name="aquaman_young_justice_logo_by_kalangozilla.jpg" width="900" height="563"/>
343350
<image name="batman_begins_poster_style_logo_by_kalangozilla.jpg" width="900" height="563"/>
344351
<image name="classic_captain_marvel_jr_logo_by_kalangozilla.jpg" width="900" height="563"/>

CardAnimation/ComponentExampleViewController.swift

+1-1
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ enum JusticeLeagueLogos: String {
4949
case Aquaman = "aquaman_young_justice_logo_by_kalangozilla.jpg"
5050
case CaptainMarvel = "classic_captain_marvel_jr_logo_by_kalangozilla.jpg"
5151
//can't find Cybord's Logo.
52-
case AllMembers = "JLAFRICA.jpeg"
52+
case AllMembers = "JLA.jpeg"
5353

5454
static var logoArray : [JusticeLeagueLogos] {
5555
get {
File renamed without changes.

CardAnimation/ViewController.swift

+74-27
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ enum JusticeLeagueHeroLogo: String{
2626
case Aquaman = "aquaman_young_justice_logo_by_kalangozilla.jpg"
2727
case CaptainMarvel = "classic_captain_marvel_jr_logo_by_kalangozilla.jpg"
2828
//can't find Cybord's Logo.
29-
case AllMembers = "JLAFRICA.jpeg"
29+
case AllMembers = "JLA.jpeg"
3030
}
3131

3232

@@ -82,19 +82,36 @@ class ViewController: UIViewController {
8282

8383
var flipUpTransform3D = CATransform3DIdentity
8484
flipUpTransform3D.m34 = -1.0 / 1000.0
85-
flipUpTransform3D = CATransform3DRotate(flipUpTransform3D, 0, 1, 0, 0)
8685

8786
previousFrontView.hidden = false
88-
if let subView = previousFrontView.viewWithTag(10){
89-
subView.hidden = false
90-
}
9187

92-
UIView.animateWithDuration(0.2, animations: {
93-
previousFrontView.layer.transform = flipUpTransform3D
88+
let duration: NSTimeInterval = 0.5
89+
//adjust borderWidth. Because the animation of borderWidth change in keyFrame animation can't work, so place it in dispatch_after
90+
//本来 layer 的 borderWidth 是个可以动画的属性,但是在 UIView Animation 却不工作,没办法,只能用这种方式了
91+
let delayTime = dispatch_time(DISPATCH_TIME_NOW, Int64(duration * Double(NSEC_PER_SEC) / 2.0))
92+
dispatch_after(delayTime, dispatch_get_main_queue(), {
93+
previousFrontView.layer.borderWidth = previousFrontView.frame.width / 100.0
94+
})
95+
96+
//See annotation blew in flipDown: function.
97+
UIView.animateKeyframesWithDuration(duration, delay: 0, options: UIViewKeyframeAnimationOptions(), animations: {
98+
99+
UIView.addKeyframeWithRelativeStartTime(0, relativeDuration: 1, animations: {
100+
previousFrontView.layer.transform = CATransform3DIdentity
101+
})
102+
103+
UIView.addKeyframeWithRelativeStartTime(0.5, relativeDuration: 0.01, animations: {
104+
if let subView = previousFrontView.viewWithTag(10){
105+
subView.alpha = 1
106+
}
107+
})
108+
109+
94110
}, completion: {
95111
_ in
96112
self.adjustUpViewLayout()
97113
})
114+
98115
}
99116

100117
@IBAction func flipDown(sender: AnyObject) {
@@ -106,26 +123,53 @@ class ViewController: UIViewController {
106123
return
107124
}
108125

109-
if let subView = frontView.viewWithTag(10){
110-
subView.hidden = true
111-
}
126+
127+
let duration: NSTimeInterval = 0.5
128+
//adjust borderWidth. Because the animation of borderWidth change in keyFrame animation can't work, so place it in dispatch_after
129+
//本来 layer 的 borderWidth 是个可以动画的属性,但是在 UIView Animation 却不工作,没办法,只能用这种方式了
130+
let delayTime = dispatch_time(DISPATCH_TIME_NOW, Int64(duration * Double(NSEC_PER_SEC) / 2.0))
131+
dispatch_after(delayTime, dispatch_get_main_queue(), {
132+
frontView.layer.borderWidth = 0
133+
})
112134

113135
var flipDownTransform3D = CATransform3DIdentity
114136
flipDownTransform3D.m34 = -1.0 / 1000.0
115-
//此处有个很大的问题,折磨了我几个小时。原来官方的实现有个临界问题,旋转180度不会执行,其他的角度则没有问题
116-
flipDownTransform3D = CATransform3DRotate(flipDownTransform3D, CGFloat(-M_PI)*0.99, 1, 0, 0)
117-
UIView.animateWithDuration(0.3, animations: {
118-
frontView.layer.transform = flipDownTransform3D
137+
138+
//There is a bug when you want to rotate 180, if you use UIView blcok animation, it doesn't work as expected: 1.no animation, just jump to final value; 2.rotate wrong direction.
139+
//You could use a closed value or animate it in UIView key frame animation.
140+
//此处有个很大的问题,折磨了我几个小时。官方的实现有Bug,在 UIView block animation 里旋转180度时会出现两种情况,一是不会执行动画而是直接跳到终点值,二是反方向旋转。
141+
//其他的角度没有问题,这里使用近似值替代不会产生这个个问题。不过, 在 key frame animation 里执行这个动画是正常的。
142+
// flipDownTransform3D = CATransform3DRotate(flipDownTransform3D, CGFloat(-M_PI)*0.99, 1, 0, 0)
143+
// UIView.animateWithDuration(duration, animations: {
144+
// frontView.layer.transform = flipDownTransform3D
145+
// })
146+
147+
//And in key frame animtion, we can fix another bug: a view is transparent in transform rotate.
148+
//I put the view which show the content in a container view, when the container view is vertical to screen, hide the nested content view, then we can see only the content of background color, just like the back of a card.
149+
//用 key frame animation 可以方便地解决卡片在旋转过程中背面透明的问题,解决办法是将内容视图放入一个容器视图,当容器视图旋转90时,此时将内容视图隐藏,从这时候开始我们就只能看到容器视图的背景色了,这样一来就和现实接近了。
150+
//而在普通的 UIView animation 里,在旋转一半的时候将内容视图隐藏比较麻烦,比如先旋转90度,在 completion block 里将内容视图隐藏,然后再添加一个动画继续旋转。用 key frame 里就比较方便,而且没有UIView animation 里旋转180有问题的 bug。
151+
UIView.animateKeyframesWithDuration(duration, delay: 0, options: UIViewKeyframeAnimationOptions(), animations: {
152+
153+
UIView.addKeyframeWithRelativeStartTime(0, relativeDuration: 1, animations: {
154+
let flipDownHalfTransform3D = CATransform3DRotate(flipDownTransform3D, CGFloat(-M_PI), 1, 0, 0)
155+
frontView.layer.transform = flipDownHalfTransform3D
156+
})
157+
158+
UIView.addKeyframeWithRelativeStartTime(0.5, relativeDuration: 0.01, animations: {
159+
if let subView = frontView.viewWithTag(10){
160+
subView.alpha = 0
161+
}
162+
})
163+
119164
}, completion: {
120165
_ in
121-
122166
frontView.hidden = true
123167
self.adjustDownViewLayout()
124-
168+
125169
})
126-
127170
}
128171

172+
129173
func scrollOnView(gesture: UIPanGestureRecognizer){
130174
if frontCardTag > cardCount + 1{
131175
frontCardTag -= 1
@@ -161,6 +205,8 @@ class ViewController: UIViewController {
161205
case 0.0..<1.0:
162206
flipTransform3D = CATransform3DRotate(flipTransform3D, CGFloat(-M_PI) * percent, 1, 0, 0)
163207
frontView?.layer.transform = flipTransform3D
208+
//Here, like flipDown/Up function, is to fix transparent back bug in rotate. When rotate 90, hidden the content view, then we can see the back only.
209+
//And take care of borderWidth.
164210
if percent >= 0.5{
165211
if let subView = frontView?.viewWithTag(10){
166212
subView.hidden = true
@@ -370,6 +416,17 @@ class ViewController: UIViewController {
370416

371417
}
372418

419+
//MARK: Handle Screen Rotation
420+
override func viewWillTransitionToSize(size: CGSize, withTransitionCoordinator coordinator: UIViewControllerTransitionCoordinator) {
421+
super.viewWillTransitionToSize(size, withTransitionCoordinator: coordinator)
422+
coordinator.animateAlongsideTransition({
423+
_ in
424+
self.gradientBackgroundLayer.frame = self.view.bounds
425+
self.relayoutSubViews()
426+
}, completion: nil)
427+
}
428+
429+
373430
//MARK: Helper Method
374431
//f(x) = k * x + m
375432
func calculateFactorOfFunction(x1: CGFloat, x2: CGFloat, y1: CGFloat, y2: CGFloat) -> (CGFloat, CGFloat){
@@ -456,15 +513,5 @@ class ViewController: UIViewController {
456513
return scaleFactor * initialBorderWidth
457514
}
458515

459-
460-
//MARK: Handle Screen Rotation
461-
override func viewWillTransitionToSize(size: CGSize, withTransitionCoordinator coordinator: UIViewControllerTransitionCoordinator) {
462-
super.viewWillTransitionToSize(size, withTransitionCoordinator: coordinator)
463-
coordinator.animateAlongsideTransition({
464-
_ in
465-
self.gradientBackgroundLayer.frame = self.view.bounds
466-
self.relayoutSubViews()
467-
}, completion: nil)
468-
}
469516
}
470517

CardAnimation/CardAnimation/CardAnimationView.swift Classes/CardAnimationView.swift

+37-15
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,16 @@
88

99
import UIKit
1010

11+
protocol CardView {
12+
func contentVisible(visible:Bool)
13+
func prepareForReuse()
14+
}
15+
16+
public class BaseCardView: UIView, CardView {
17+
func contentVisible(visible:Bool) { }
18+
func prepareForReuse() { }
19+
}
20+
1121
public protocol CardAnimationViewDataSource : class {
1222
func numberOfVisibleCards() -> Int
1323
func numberOfCards() -> Int
@@ -82,8 +92,7 @@ public class CardAnimationView: UIView {
8292
private lazy var flipDownTransform3D : CATransform3D = {
8393
var transform = CATransform3DIdentity
8494
transform.m34 = -1.0 / 1000.0
85-
//此处有个很大的问题,折磨了我几个小时。原来官方的实现有个临界问题,旋转180度不会执行,其他的角度则没有问题
86-
transform = CATransform3DRotate(transform, CGFloat(-M_PI)*0.99, 1, 0, 0)
95+
transform = CATransform3DRotate(transform, CGFloat(-M_PI), 1, 0, 0)
8796
return transform
8897
}()
8998

@@ -136,21 +145,27 @@ public class CardAnimationView: UIView {
136145
guard currentIndex > 0 else {
137146
return false
138147
}
139-
148+
140149
currentIndex--
141-
150+
142151
let newView = addNewCardViewWithIndex(currentIndex)
143152
newView.layer.transform = flipDownTransform3D
144153

145154
let shouldRemoveLast = cardArray.count > maxVisibleCardCount
146-
147-
148-
UIView.animateWithDuration(animationsSpeed, animations: {
149-
newView.layer.transform = self.flipUpTransform3D
155+
156+
UIView.animateKeyframesWithDuration(animationsSpeed, delay: 0, options: UIViewKeyframeAnimationOptions(), animations: {
157+
158+
UIView.addKeyframeWithRelativeStartTime(0, relativeDuration: 1, animations: {
159+
newView.layer.transform = self.flipUpTransform3D
160+
})
161+
162+
UIView.addKeyframeWithRelativeStartTime(0.5, relativeDuration: 0.01, animations: {
163+
newView.contentVisible(true)
164+
})
165+
150166
}, completion: { _ in
151167
self.relayoutSubViewsAnimated(true, removeLast: shouldRemoveLast)
152168
})
153-
154169
return true
155170
}
156171

@@ -163,18 +178,25 @@ public class CardAnimationView: UIView {
163178
guard currentIndex < cardCount else {
164179
return false
165180
}
166-
181+
167182
currentIndex++
168-
183+
169184
let frontView = cardArray.removeFirst()
170185
let lastIndex = currentIndex + cardArray.count
171186
if lastIndex < cardCount {
172187
addNewCardViewWithIndex(lastIndex, insertOnRear: true)
173188
}
174-
frontView.contentVisible(false)
175-
176-
UIView.animateWithDuration(animationsSpeed*1.5, animations: {
177-
frontView.layer.transform = self.flipDownTransform3D
189+
190+
UIView.animateKeyframesWithDuration(animationsSpeed*1.5, delay: 0, options: UIViewKeyframeAnimationOptions(), animations: {
191+
192+
UIView.addKeyframeWithRelativeStartTime(0, relativeDuration: 1, animations: {
193+
frontView.layer.transform = self.flipDownTransform3D
194+
})
195+
196+
UIView.addKeyframeWithRelativeStartTime(0.5, relativeDuration: 0.01, animations: {
197+
frontView.contentVisible(false)
198+
})
199+
178200
}, completion: { _ in
179201
self.poolCardArray.append(frontView)
180202
frontView.removeFromSuperview()

CardAnimation/CardAnimation/CardViews.swift Classes/ImageCardView.swift

+3-12
Original file line numberDiff line numberDiff line change
@@ -8,16 +8,6 @@
88

99
import UIKit
1010

11-
protocol CardView {
12-
func contentVisible(visible:Bool)
13-
func prepareForReuse()
14-
}
15-
16-
public class BaseCardView: UIView, CardView {
17-
func contentVisible(visible:Bool) { }
18-
func prepareForReuse() { }
19-
}
20-
2111
public class ImageCardView: BaseCardView {
2212
var imageView:UIImageView!
2313
override init(frame: CGRect) {
@@ -39,9 +29,10 @@ public class ImageCardView: BaseCardView {
3929
imageView.contentMode = .ScaleAspectFill
4030
addSubview(imageView)
4131
}
42-
32+
33+
//hidden property can't be animationable, I recommand using alpha.
4334
override func contentVisible(visible:Bool) {
44-
imageView.hidden = !visible
35+
imageView.alpha = visible ? 1.0 : 0.0
4536
}
4637

4738
override func prepareForReuse() {

0 commit comments

Comments
 (0)