├── README.md
├── Swift-Animations.xcodeproj
├── project.pbxproj
├── project.xcworkspace
│ ├── contents.xcworkspacedata
│ ├── xcshareddata
│ │ └── IDEWorkspaceChecks.plist
│ └── xcuserdata
│ │ ├── YouXianMing.xcuserdatad
│ │ └── UserInterfaceState.xcuserstate
│ │ └── YouXianMing1987@iCloud.com.xcuserdatad
│ │ └── UserInterfaceState.xcuserstate
└── xcuserdata
│ ├── YouXianMing.xcuserdatad
│ ├── xcdebugger
│ │ └── Breakpoints_v2.xcbkptlist
│ └── xcschemes
│ │ ├── Swift-Animations.xcscheme
│ │ └── xcschememanagement.plist
│ └── YouXianMing1987@iCloud.com.xcuserdatad
│ ├── xcdebugger
│ └── Breakpoints_v2.xcbkptlist
│ └── xcschemes
│ ├── Swift-Animations.xcscheme
│ └── xcschememanagement.plist
└── Swift-Animations
├── AlertView.swift
├── AlertViewCollectionViewCell.swift
├── AlertViewController.swift
├── AnimationsListViewController.swift
├── AppDelegate.swift
├── AppleSystemService.swift
├── Assets.xcassets
├── AppIcon.appiconset
│ ├── App_Store_iOS_1024pt.png
│ ├── Contents.json
│ ├── iPhone_App_iOS_7-11_60pt@2x.png
│ ├── iPhone_App_iOS_7-11_60pt@3x.png
│ ├── iPhone_Notification_iOS_7-11_20pt@2x.png
│ ├── iPhone_Notification_iOS_7-11_20pt@3x.png
│ ├── iPhone_Settings_iOS_5-11_29pt@2x.png
│ ├── iPhone_Settings_iOS_5-11_29pt@3x.png
│ ├── iPhone_Spotlight_iOS_7-11_40pt@2x.png
│ └── iPhone_Spotlight_iOS_7-11_40pt@3x.png
├── Brand Assets.launchimage
│ ├── 1242x2208.png
│ ├── 640x1136.png
│ ├── 640x960.png
│ ├── 750x1334.png
│ ├── Contents.json
│ └── iPhoneX_bg@3x.png
├── Contents.json
├── 菜单图片
│ ├── Contents.json
│ ├── arrows_next.imageset
│ │ ├── Contents.json
│ │ └── arrows_next.png
│ ├── backIcon.imageset
│ │ ├── Contents.json
│ │ └── NodeModelViewControllerBack_black@3x.png
│ ├── backIconTypeTwo.imageset
│ │ ├── Contents.json
│ │ └── NodeModelViewControllerBack_black_typeTwo@3x.png
│ ├── backIconTypeTwo_pre.imageset
│ │ ├── Contents.json
│ │ └── NodeModelViewControllerBack_black_typeTwo_pre@3x.png
│ └── backIcon_pre.imageset
│ │ ├── Contents.json
│ │ └── NodeModelViewControllerBack_black_pre@3x.png
└── 项目图片
│ ├── 1.imageset
│ ├── 1.jpg
│ └── Contents.json
│ ├── 2.imageset
│ ├── 2.jpg
│ └── Contents.json
│ ├── 3.imageset
│ ├── 3.jpg
│ └── Contents.json
│ ├── 4.imageset
│ ├── 4.jpg
│ └── Contents.json
│ ├── 5.imageset
│ ├── 5.jpg
│ └── Contents.json
│ ├── Contents.json
│ ├── colors.imageset
│ ├── Contents.json
│ └── colors@2x.png
│ ├── pic_1.imageset
│ ├── Contents.json
│ └── pic_1@2x.png
│ ├── pic_2.imageset
│ ├── Contents.json
│ └── pic_2@2x.png
│ ├── pic_3.imageset
│ ├── Contents.json
│ └── pic_3@2x.png
│ ├── pic_4.imageset
│ ├── Contents.json
│ └── pic_4@2x.png
│ └── plane.imageset
│ ├── Contents.json
│ └── plane.png
├── BackgroundLineView.swift
├── BaseCustomNavigationController.swift
├── BaseCustomViewController.swift
├── BaseMessageView.swift
├── CATransform3DM34Controller.swift
├── CellDataAdapter.swift
├── CircleAnimationViewController.swift
├── CircleView.swift
├── ClassHeaderView.swift
├── ClassModel.swift
├── ComplexEasingValue.swift
├── ControllerBaseViewConfig.swift
├── ControllerItem.swift
├── CountDownTimeCell.swift
├── CountDownTimerController.swift
├── CustomCell.swift
├── CustomCollectionViewCell.swift
├── CustomHeaderFooterView.swift
├── DefaultNotificationCenter.swift
├── Easing.swift
├── EasingValue.swift
├── FontCell.swift
├── FontFamilyHeaderView.swift
├── FontFamilyModel.swift
├── FullTitleVisualEffectViewController.swift
├── GCDGroup.swift
├── GCDQueue.swift
├── GCDQueuePriority.swift
├── GCDSemaphore.swift
├── GCDTimer.swift
├── HeaderViewTapAnimationController.swift
├── Info.plist
├── ListItemCell.swift
├── LiveImageView.swift
├── LiveImageViewController.swift
├── Math.swift
├── MessageView.swift
├── MixedColorProgressViewController.swift
├── MoreInfoView.swift
├── NormalTitleViewController.swift
├── NotificationEvent.swift
├── PageFlipEffectController.swift
├── RootNavigationViewController.swift
├── RotateView.swift
├── ScrollImageViewController.swift
├── ShowLoadingView.swift
├── ShowTextCell.swift
├── ShowTextModel.swift
├── StoredValueTypeIs.swift
├── String+StringHeight.swift
├── StudentInfoCell.swift
├── StudentModel.swift
├── SystemFontInfoController.swift
├── TableViewTapAnimationCell.swift
├── TableViewTapAnimationController.swift
├── TapAnimationModel.swift
├── TapCellAnimationController.swift
├── TimeModel.swift
├── TranformFadeView.swift
├── TransformFadeViewController.swift
├── UIColor+Convenience.swift
├── UIColor+HexColor.swift
├── UIFont+extension.swift
├── UILabel+SizeToFit.swift
├── UIView+AnimationProperty.swift
├── UIView+CreateFrame.swift
├── UIView+Glow.swift
├── UIView+ScreensShot.swift
├── UIView+SetRect.swift
└── UIWindow+keyWindow.swift
/README.md:
--------------------------------------------------------------------------------
1 | # Swift-Animations
2 |
3 | Support Swift 3
4 |
5 | > Project [YoCelsius](https://github.com/YouXianMing/YoCelsius) in [AppStore](https://itunes.apple.com/us/app/yocelsius/id967721892?l=zh&ls=1&mt=8)
6 |
7 |  
8 |
9 | > Project [Animations](https://github.com/YouXianMing/Animations)
10 |
11 | 
12 |
13 | ## The Swift Animation Collection (Long-term Updates) .
14 |
15 | > TableViewTapAnimationController
16 |
17 | 
18 |
19 | > HeaderViewTapAnimationController
20 |
21 | 
22 |
23 | > CircleAnimationViewController
24 |
25 | 
26 |
27 | > LiveImageViewController
28 |
29 | 
30 |
31 | > ScrollImageViewController
32 |
33 | 
34 |
35 | > CATransform3DM34Controller
36 |
37 | 
38 |
39 | > TransformFadeViewController
40 |
41 | 
42 |
43 | > MixedColorProgressViewController
44 |
45 | 
46 |
47 | > PageFlipEffectController
48 |
49 | 
50 |
51 | > TapCellAnimationController
52 |
53 | 
54 |
55 | > CountDownTimerController
56 |
57 | 
58 |
--------------------------------------------------------------------------------
/Swift-Animations.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/Swift-Animations.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | IDEDidComputeMac32BitWarning
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/Swift-Animations.xcodeproj/project.xcworkspace/xcuserdata/YouXianMing.xcuserdatad/UserInterfaceState.xcuserstate:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/YouXianMing/Swift-Animations/b793f1224dd5d5a01ddfb3fe9cfa24a93212fa6d/Swift-Animations.xcodeproj/project.xcworkspace/xcuserdata/YouXianMing.xcuserdatad/UserInterfaceState.xcuserstate
--------------------------------------------------------------------------------
/Swift-Animations.xcodeproj/project.xcworkspace/xcuserdata/YouXianMing1987@iCloud.com.xcuserdatad/UserInterfaceState.xcuserstate:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/YouXianMing/Swift-Animations/b793f1224dd5d5a01ddfb3fe9cfa24a93212fa6d/Swift-Animations.xcodeproj/project.xcworkspace/xcuserdata/YouXianMing1987@iCloud.com.xcuserdatad/UserInterfaceState.xcuserstate
--------------------------------------------------------------------------------
/Swift-Animations.xcodeproj/xcuserdata/YouXianMing.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
--------------------------------------------------------------------------------
/Swift-Animations.xcodeproj/xcuserdata/YouXianMing.xcuserdatad/xcschemes/Swift-Animations.xcscheme:
--------------------------------------------------------------------------------
1 |
2 |
5 |
8 |
9 |
15 |
21 |
22 |
23 |
24 |
25 |
30 |
31 |
32 |
33 |
39 |
40 |
41 |
42 |
43 |
44 |
54 |
56 |
62 |
63 |
64 |
65 |
66 |
67 |
73 |
75 |
81 |
82 |
83 |
84 |
86 |
87 |
90 |
91 |
92 |
--------------------------------------------------------------------------------
/Swift-Animations.xcodeproj/xcuserdata/YouXianMing.xcuserdatad/xcschemes/xcschememanagement.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | SchemeUserState
6 |
7 | Swift-Animations.xcscheme
8 |
9 | orderHint
10 | 0
11 |
12 |
13 | SuppressBuildableAutocreation
14 |
15 | C57007EF1D5330B2003BFB5E
16 |
17 | primary
18 |
19 |
20 |
21 |
22 |
23 |
--------------------------------------------------------------------------------
/Swift-Animations.xcodeproj/xcuserdata/YouXianMing1987@iCloud.com.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
--------------------------------------------------------------------------------
/Swift-Animations.xcodeproj/xcuserdata/YouXianMing1987@iCloud.com.xcuserdatad/xcschemes/Swift-Animations.xcscheme:
--------------------------------------------------------------------------------
1 |
2 |
5 |
8 |
9 |
15 |
21 |
22 |
23 |
24 |
25 |
30 |
31 |
32 |
33 |
39 |
40 |
41 |
42 |
43 |
44 |
54 |
56 |
62 |
63 |
64 |
65 |
66 |
67 |
73 |
75 |
81 |
82 |
83 |
84 |
86 |
87 |
90 |
91 |
92 |
--------------------------------------------------------------------------------
/Swift-Animations.xcodeproj/xcuserdata/YouXianMing1987@iCloud.com.xcuserdatad/xcschemes/xcschememanagement.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | SchemeUserState
6 |
7 | Swift-Animations.xcscheme
8 |
9 | orderHint
10 | 0
11 |
12 |
13 | SuppressBuildableAutocreation
14 |
15 | C57007EF1D5330B2003BFB5E
16 |
17 | primary
18 |
19 |
20 |
21 |
22 |
23 |
--------------------------------------------------------------------------------
/Swift-Animations/AlertViewCollectionViewCell.swift:
--------------------------------------------------------------------------------
1 | //
2 | // AlertViewCollectionViewCell.swift
3 | // Swift-Animations
4 | //
5 | // Created by YouXianMing on 2017/9/13.
6 | // Copyright © 2017年 YouXianMing. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | class AlertViewCollectionViewCell: CustomCollectionViewCell {
12 |
13 | fileprivate var rightLineView : UIView!
14 | fileprivate var labelContentView : UIView!
15 | fileprivate var label : UILabel!
16 | fileprivate var highlightLabel : UILabel!
17 |
18 | override func buildSubview() {
19 |
20 | self.addSubview(UIView.CreateLine(CGRect.init(x: 0, y: height - 0.5, width: width, height: 0.5), lineColor: UIColor.gray.alpha(0.2)))
21 |
22 | rightLineView = UIView.CreateLine(CGRect.init(x: width - 0.5, y: 0, width: 0.5, height: height), lineColor: UIColor.gray.alpha(0.2))
23 | rightLineView.isHidden = true
24 | self.addSubview(rightLineView!)
25 |
26 | labelContentView = UIView.init(frame: self.bounds)
27 | self.addSubview(labelContentView)
28 |
29 | label = UILabel.init(frame : self.bounds)
30 | label.textAlignment = .center
31 | label.font = UIFont.HeitiSC(15)
32 | label.textColor = UIColor.black
33 | label.angle = CGFloat(Double.pi / 4)
34 | labelContentView.addSubview(label)
35 |
36 | highlightLabel = UILabel.init(frame : self.bounds)
37 | highlightLabel.textAlignment = .center
38 | highlightLabel.font = UIFont.HeitiSC(15)
39 | highlightLabel.textColor = UIColor.red
40 | highlightLabel.angle = CGFloat(Double.pi / 4)
41 | highlightLabel.alpha = 0
42 | labelContentView.addSubview(highlightLabel)
43 | }
44 |
45 | override func loadContent() {
46 |
47 | rightLineView.isHidden = ((indexPath?.row)! % 2 == 0 ? false : true)
48 |
49 | label.text = data as? String
50 | highlightLabel.text = data as? String
51 | }
52 |
53 | override func selectedEvent() {
54 |
55 | delegate?.customCollectionViewCell(self, event: data)
56 | }
57 |
58 | override var isHighlighted: Bool {
59 |
60 | get { return super.isHighlighted}
61 | set(newVal) {
62 |
63 | super.isHighlighted = newVal
64 |
65 | UIView.animate(withDuration: 0.25, delay: 0, options: .beginFromCurrentState, animations: {
66 |
67 | self.backgroundColor = (newVal ? UIColor.lightGray.alpha(0.1) : UIColor.white)
68 | self.label.alpha = (newVal ? 0 : 1)
69 | self.highlightLabel.alpha = (newVal ? 1 : 0)
70 | self.labelContentView.scale = (newVal ? 0.95 : 1)
71 |
72 | }, completion: nil)
73 | }
74 | }
75 | }
76 |
--------------------------------------------------------------------------------
/Swift-Animations/AlertViewController.swift:
--------------------------------------------------------------------------------
1 | //
2 | // AlertViewController.swift
3 | // Swift-Animations
4 | //
5 | // Created by YouXianMing on 2017/9/13.
6 | // Copyright © 2017年 YouXianMing. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | class AlertViewController: NormalTitleViewController, UICollectionViewDelegate, UICollectionViewDataSource, CustomCollectionViewCellDelegate, BaseMessageViewDelegate {
12 |
13 | fileprivate var collectionView : UICollectionView!
14 | fileprivate var layout : UICollectionViewFlowLayout!
15 | fileprivate var adapters : [CellDataAdapter] = []
16 |
17 | override func viewDidLoad() {
18 |
19 | super.viewDidLoad()
20 |
21 | // Layout.
22 | layout = UICollectionViewFlowLayout.init()
23 | layout.minimumLineSpacing = 0
24 | layout.minimumInteritemSpacing = 0
25 | layout.itemSize = CGSize.init(width: Screen.Width / 2, height: Screen.Width / 2)
26 |
27 | // CollectionView.
28 | collectionView = UICollectionView.init(frame: (contentView?.bounds)!, collectionViewLayout: layout!)
29 | collectionView.backgroundColor = UIColor.clear
30 | collectionView.delegate = self
31 | collectionView.dataSource = self
32 | contentView?.addSubview(collectionView!)
33 | AlertViewCollectionViewCell.RegisterTo(collectionView!)
34 |
35 | if #available(iOS 11.0, *) {
36 |
37 | collectionView?.contentInsetAdjustmentBehavior = .never
38 | }
39 |
40 | // Adapters.
41 | adapters.append(AlertViewCollectionViewCell.Adapter(data: "MessageView" as AnyObject))
42 | adapters.append(AlertViewCollectionViewCell.Adapter(data: "AlertView" as AnyObject))
43 | }
44 |
45 | // MARK: UICollectionViewDelegate, UICollectionViewDataSource
46 |
47 | func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
48 |
49 | return adapters.count
50 | }
51 |
52 | func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
53 |
54 | return collectionView.dequeueCellAndLoadContentFromAdapter(adapters[indexPath.row], indexPath: indexPath, delegate: self)
55 | }
56 |
57 | func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
58 |
59 | collectionView.selectedEventWithIndexPath(indexPath)
60 | }
61 |
62 | // MARK: CustomCollectionViewCellDelegate
63 |
64 | func customCollectionViewCell(_ cell: CustomCollectionViewCell?, event: Any?) {
65 |
66 | if event is String {
67 |
68 | let name = event as! String
69 |
70 | if name == "MessageView" {
71 |
72 | MessageView.Setup(messageObject : "If you find this post helpful, please recommend it for others to read." as AnyObject,
73 | contentView : UIWindow.getKeyWindow(),
74 | delegate : self).show()
75 |
76 | } else if name == "AlertView" {
77 |
78 | let messageObject = AlertViewMessageObject.init(title : "警告",
79 | content : "不要轻信陌生电话,短信;不要轻易点击信息中的链接;不要按陌生电话,短信要求转账汇款;不要安装不了解的软件.",
80 | buttonTitles : ["关闭", "更多信息"],
81 | buttonTitlesState : [AlertViewButtonType.Black, AlertViewButtonType.Red])
82 |
83 | AlertView.Setup(messageObject : messageObject as AnyObject,
84 | contentView : UIWindow.getKeyWindow(),
85 | delegate : self,
86 | autoHiden : false).show()
87 | }
88 | }
89 | }
90 |
91 | // MARK: BaseMessageViewDelegate
92 |
93 | func baseMessageView(_ messageView : BaseMessageView, event : AnyObject?) {
94 |
95 | if messageView.isKind(of: AlertView.classForCoder()) {
96 |
97 | print(event ?? "None")
98 | }
99 | }
100 |
101 | func baseMessageViewWillAppear(_ messageView : BaseMessageView) {
102 |
103 | print("baseMessageViewWillAppear")
104 | }
105 |
106 | func baseMessageViewDidAppear(_ messageView : BaseMessageView) {
107 |
108 | print("baseMessageViewDidAppear")
109 | }
110 |
111 | func baseMessageViewWillDisappear(_ messageView : BaseMessageView) {
112 |
113 | print("baseMessageViewWillDisappear")
114 | }
115 |
116 | func baseMessageViewDidDisappear(_ messageView : BaseMessageView) {
117 |
118 | print("baseMessageViewDidDisappear")
119 | }
120 | }
121 |
--------------------------------------------------------------------------------
/Swift-Animations/AppDelegate.swift:
--------------------------------------------------------------------------------
1 | //
2 | // AppDelegate.swift
3 | // Swift-Animations
4 | //
5 | // Created by YouXianMing on 16/8/4.
6 | // Copyright © 2016年 YouXianMing. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | @UIApplicationMain
12 |
13 | class AppDelegate: UIResponder, UIApplicationDelegate {
14 |
15 | var window : UIWindow?
16 |
17 | func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
18 |
19 | /*
20 | Lateast no warning version : Xcode 9.4.1 (9F2000)
21 | */
22 |
23 | window = UIWindow(frame: UIScreen.main.bounds)
24 |
25 | if let window = window {
26 |
27 | window.backgroundColor = UIColor.white
28 | let controller = AnimationsListViewController()
29 | let rootViewController = RootNavigationViewController(rootViewController: controller, hideNavBar: true)
30 | window.rootViewController = rootViewController
31 | window.makeKeyAndVisible()
32 | }
33 |
34 | return true
35 | }
36 | }
37 |
38 |
--------------------------------------------------------------------------------
/Swift-Animations/AppleSystemService.swift:
--------------------------------------------------------------------------------
1 | //
2 | // AppleSystemService.swift
3 | // Swift-Animations
4 | //
5 | // Created by YouXianMing on 16/8/11.
6 | // Copyright © 2016年 YouXianMing. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | class AppleSystemService : NSObject {
12 |
13 | /// Get the lauch image.
14 | class var LaunchImage : UIImage {
15 |
16 | get {
17 |
18 | var lauchImage : UIImage!
19 | var viewOrientation : String!
20 | let viewSize = UIScreen.main.bounds.size
21 | let orientation = UIApplication.shared.statusBarOrientation
22 |
23 | if orientation == .landscapeLeft || orientation == .landscapeRight {
24 |
25 | viewOrientation = "Landscape"
26 |
27 | } else {
28 |
29 | viewOrientation = "Portrait"
30 | }
31 |
32 | let imagesInfoArray = Bundle.main.infoDictionary!["UILaunchImages"]
33 | for dict : Dictionary in imagesInfoArray as! Array {
34 |
35 | let imageSize = NSCoder.cgSize(for: dict["UILaunchImageSize"]!)
36 | if imageSize.equalTo(viewSize) && viewOrientation == dict["UILaunchImageOrientation"]! as String {
37 |
38 | lauchImage = UIImage(named: dict["UILaunchImageName"]!)
39 | }
40 | }
41 |
42 | return lauchImage
43 | }
44 | }
45 | }
46 |
--------------------------------------------------------------------------------
/Swift-Animations/Assets.xcassets/AppIcon.appiconset/App_Store_iOS_1024pt.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/YouXianMing/Swift-Animations/b793f1224dd5d5a01ddfb3fe9cfa24a93212fa6d/Swift-Animations/Assets.xcassets/AppIcon.appiconset/App_Store_iOS_1024pt.png
--------------------------------------------------------------------------------
/Swift-Animations/Assets.xcassets/AppIcon.appiconset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "size" : "20x20",
5 | "idiom" : "iphone",
6 | "filename" : "iPhone_Notification_iOS_7-11_20pt@2x.png",
7 | "scale" : "2x"
8 | },
9 | {
10 | "size" : "20x20",
11 | "idiom" : "iphone",
12 | "filename" : "iPhone_Notification_iOS_7-11_20pt@3x.png",
13 | "scale" : "3x"
14 | },
15 | {
16 | "size" : "29x29",
17 | "idiom" : "iphone",
18 | "filename" : "iPhone_Settings_iOS_5-11_29pt@2x.png",
19 | "scale" : "2x"
20 | },
21 | {
22 | "size" : "29x29",
23 | "idiom" : "iphone",
24 | "filename" : "iPhone_Settings_iOS_5-11_29pt@3x.png",
25 | "scale" : "3x"
26 | },
27 | {
28 | "size" : "40x40",
29 | "idiom" : "iphone",
30 | "filename" : "iPhone_Spotlight_iOS_7-11_40pt@2x.png",
31 | "scale" : "2x"
32 | },
33 | {
34 | "size" : "40x40",
35 | "idiom" : "iphone",
36 | "filename" : "iPhone_Spotlight_iOS_7-11_40pt@3x.png",
37 | "scale" : "3x"
38 | },
39 | {
40 | "size" : "60x60",
41 | "idiom" : "iphone",
42 | "filename" : "iPhone_App_iOS_7-11_60pt@2x.png",
43 | "scale" : "2x"
44 | },
45 | {
46 | "size" : "60x60",
47 | "idiom" : "iphone",
48 | "filename" : "iPhone_App_iOS_7-11_60pt@3x.png",
49 | "scale" : "3x"
50 | },
51 | {
52 | "size" : "1024x1024",
53 | "idiom" : "ios-marketing",
54 | "filename" : "App_Store_iOS_1024pt.png",
55 | "scale" : "1x"
56 | }
57 | ],
58 | "info" : {
59 | "version" : 1,
60 | "author" : "xcode"
61 | }
62 | }
--------------------------------------------------------------------------------
/Swift-Animations/Assets.xcassets/AppIcon.appiconset/iPhone_App_iOS_7-11_60pt@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/YouXianMing/Swift-Animations/b793f1224dd5d5a01ddfb3fe9cfa24a93212fa6d/Swift-Animations/Assets.xcassets/AppIcon.appiconset/iPhone_App_iOS_7-11_60pt@2x.png
--------------------------------------------------------------------------------
/Swift-Animations/Assets.xcassets/AppIcon.appiconset/iPhone_App_iOS_7-11_60pt@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/YouXianMing/Swift-Animations/b793f1224dd5d5a01ddfb3fe9cfa24a93212fa6d/Swift-Animations/Assets.xcassets/AppIcon.appiconset/iPhone_App_iOS_7-11_60pt@3x.png
--------------------------------------------------------------------------------
/Swift-Animations/Assets.xcassets/AppIcon.appiconset/iPhone_Notification_iOS_7-11_20pt@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/YouXianMing/Swift-Animations/b793f1224dd5d5a01ddfb3fe9cfa24a93212fa6d/Swift-Animations/Assets.xcassets/AppIcon.appiconset/iPhone_Notification_iOS_7-11_20pt@2x.png
--------------------------------------------------------------------------------
/Swift-Animations/Assets.xcassets/AppIcon.appiconset/iPhone_Notification_iOS_7-11_20pt@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/YouXianMing/Swift-Animations/b793f1224dd5d5a01ddfb3fe9cfa24a93212fa6d/Swift-Animations/Assets.xcassets/AppIcon.appiconset/iPhone_Notification_iOS_7-11_20pt@3x.png
--------------------------------------------------------------------------------
/Swift-Animations/Assets.xcassets/AppIcon.appiconset/iPhone_Settings_iOS_5-11_29pt@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/YouXianMing/Swift-Animations/b793f1224dd5d5a01ddfb3fe9cfa24a93212fa6d/Swift-Animations/Assets.xcassets/AppIcon.appiconset/iPhone_Settings_iOS_5-11_29pt@2x.png
--------------------------------------------------------------------------------
/Swift-Animations/Assets.xcassets/AppIcon.appiconset/iPhone_Settings_iOS_5-11_29pt@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/YouXianMing/Swift-Animations/b793f1224dd5d5a01ddfb3fe9cfa24a93212fa6d/Swift-Animations/Assets.xcassets/AppIcon.appiconset/iPhone_Settings_iOS_5-11_29pt@3x.png
--------------------------------------------------------------------------------
/Swift-Animations/Assets.xcassets/AppIcon.appiconset/iPhone_Spotlight_iOS_7-11_40pt@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/YouXianMing/Swift-Animations/b793f1224dd5d5a01ddfb3fe9cfa24a93212fa6d/Swift-Animations/Assets.xcassets/AppIcon.appiconset/iPhone_Spotlight_iOS_7-11_40pt@2x.png
--------------------------------------------------------------------------------
/Swift-Animations/Assets.xcassets/AppIcon.appiconset/iPhone_Spotlight_iOS_7-11_40pt@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/YouXianMing/Swift-Animations/b793f1224dd5d5a01ddfb3fe9cfa24a93212fa6d/Swift-Animations/Assets.xcassets/AppIcon.appiconset/iPhone_Spotlight_iOS_7-11_40pt@3x.png
--------------------------------------------------------------------------------
/Swift-Animations/Assets.xcassets/Brand Assets.launchimage/1242x2208.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/YouXianMing/Swift-Animations/b793f1224dd5d5a01ddfb3fe9cfa24a93212fa6d/Swift-Animations/Assets.xcassets/Brand Assets.launchimage/1242x2208.png
--------------------------------------------------------------------------------
/Swift-Animations/Assets.xcassets/Brand Assets.launchimage/640x1136.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/YouXianMing/Swift-Animations/b793f1224dd5d5a01ddfb3fe9cfa24a93212fa6d/Swift-Animations/Assets.xcassets/Brand Assets.launchimage/640x1136.png
--------------------------------------------------------------------------------
/Swift-Animations/Assets.xcassets/Brand Assets.launchimage/640x960.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/YouXianMing/Swift-Animations/b793f1224dd5d5a01ddfb3fe9cfa24a93212fa6d/Swift-Animations/Assets.xcassets/Brand Assets.launchimage/640x960.png
--------------------------------------------------------------------------------
/Swift-Animations/Assets.xcassets/Brand Assets.launchimage/750x1334.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/YouXianMing/Swift-Animations/b793f1224dd5d5a01ddfb3fe9cfa24a93212fa6d/Swift-Animations/Assets.xcassets/Brand Assets.launchimage/750x1334.png
--------------------------------------------------------------------------------
/Swift-Animations/Assets.xcassets/Brand Assets.launchimage/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "extent" : "full-screen",
5 | "idiom" : "iphone",
6 | "subtype" : "2436h",
7 | "filename" : "iPhoneX_bg@3x.png",
8 | "minimum-system-version" : "11.0",
9 | "orientation" : "portrait",
10 | "scale" : "3x"
11 | },
12 | {
13 | "extent" : "full-screen",
14 | "idiom" : "iphone",
15 | "subtype" : "736h",
16 | "filename" : "1242x2208.png",
17 | "minimum-system-version" : "8.0",
18 | "orientation" : "portrait",
19 | "scale" : "3x"
20 | },
21 | {
22 | "extent" : "full-screen",
23 | "idiom" : "iphone",
24 | "subtype" : "667h",
25 | "filename" : "750x1334.png",
26 | "minimum-system-version" : "8.0",
27 | "orientation" : "portrait",
28 | "scale" : "2x"
29 | },
30 | {
31 | "orientation" : "portrait",
32 | "idiom" : "iphone",
33 | "filename" : "640x960.png",
34 | "extent" : "full-screen",
35 | "minimum-system-version" : "7.0",
36 | "scale" : "2x"
37 | },
38 | {
39 | "extent" : "full-screen",
40 | "idiom" : "iphone",
41 | "subtype" : "retina4",
42 | "filename" : "640x1136.png",
43 | "minimum-system-version" : "7.0",
44 | "orientation" : "portrait",
45 | "scale" : "2x"
46 | }
47 | ],
48 | "info" : {
49 | "version" : 1,
50 | "author" : "xcode"
51 | }
52 | }
--------------------------------------------------------------------------------
/Swift-Animations/Assets.xcassets/Brand Assets.launchimage/iPhoneX_bg@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/YouXianMing/Swift-Animations/b793f1224dd5d5a01ddfb3fe9cfa24a93212fa6d/Swift-Animations/Assets.xcassets/Brand Assets.launchimage/iPhoneX_bg@3x.png
--------------------------------------------------------------------------------
/Swift-Animations/Assets.xcassets/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "info" : {
3 | "version" : 1,
4 | "author" : "xcode"
5 | }
6 | }
--------------------------------------------------------------------------------
/Swift-Animations/Assets.xcassets/菜单图片/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "info" : {
3 | "version" : 1,
4 | "author" : "xcode"
5 | }
6 | }
--------------------------------------------------------------------------------
/Swift-Animations/Assets.xcassets/菜单图片/arrows_next.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "filename" : "arrows_next.png",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "scale" : "2x"
11 | },
12 | {
13 | "idiom" : "universal",
14 | "scale" : "3x"
15 | }
16 | ],
17 | "info" : {
18 | "version" : 1,
19 | "author" : "xcode"
20 | }
21 | }
--------------------------------------------------------------------------------
/Swift-Animations/Assets.xcassets/菜单图片/arrows_next.imageset/arrows_next.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/YouXianMing/Swift-Animations/b793f1224dd5d5a01ddfb3fe9cfa24a93212fa6d/Swift-Animations/Assets.xcassets/菜单图片/arrows_next.imageset/arrows_next.png
--------------------------------------------------------------------------------
/Swift-Animations/Assets.xcassets/菜单图片/backIcon.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "scale" : "1x"
6 | },
7 | {
8 | "idiom" : "universal",
9 | "scale" : "2x"
10 | },
11 | {
12 | "idiom" : "universal",
13 | "filename" : "NodeModelViewControllerBack_black@3x.png",
14 | "scale" : "3x"
15 | }
16 | ],
17 | "info" : {
18 | "version" : 1,
19 | "author" : "xcode"
20 | }
21 | }
--------------------------------------------------------------------------------
/Swift-Animations/Assets.xcassets/菜单图片/backIcon.imageset/NodeModelViewControllerBack_black@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/YouXianMing/Swift-Animations/b793f1224dd5d5a01ddfb3fe9cfa24a93212fa6d/Swift-Animations/Assets.xcassets/菜单图片/backIcon.imageset/NodeModelViewControllerBack_black@3x.png
--------------------------------------------------------------------------------
/Swift-Animations/Assets.xcassets/菜单图片/backIconTypeTwo.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "scale" : "1x"
6 | },
7 | {
8 | "idiom" : "universal",
9 | "scale" : "2x"
10 | },
11 | {
12 | "idiom" : "universal",
13 | "filename" : "NodeModelViewControllerBack_black_typeTwo@3x.png",
14 | "scale" : "3x"
15 | }
16 | ],
17 | "info" : {
18 | "version" : 1,
19 | "author" : "xcode"
20 | }
21 | }
--------------------------------------------------------------------------------
/Swift-Animations/Assets.xcassets/菜单图片/backIconTypeTwo.imageset/NodeModelViewControllerBack_black_typeTwo@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/YouXianMing/Swift-Animations/b793f1224dd5d5a01ddfb3fe9cfa24a93212fa6d/Swift-Animations/Assets.xcassets/菜单图片/backIconTypeTwo.imageset/NodeModelViewControllerBack_black_typeTwo@3x.png
--------------------------------------------------------------------------------
/Swift-Animations/Assets.xcassets/菜单图片/backIconTypeTwo_pre.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "scale" : "1x"
6 | },
7 | {
8 | "idiom" : "universal",
9 | "scale" : "2x"
10 | },
11 | {
12 | "idiom" : "universal",
13 | "filename" : "NodeModelViewControllerBack_black_typeTwo_pre@3x.png",
14 | "scale" : "3x"
15 | }
16 | ],
17 | "info" : {
18 | "version" : 1,
19 | "author" : "xcode"
20 | }
21 | }
--------------------------------------------------------------------------------
/Swift-Animations/Assets.xcassets/菜单图片/backIconTypeTwo_pre.imageset/NodeModelViewControllerBack_black_typeTwo_pre@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/YouXianMing/Swift-Animations/b793f1224dd5d5a01ddfb3fe9cfa24a93212fa6d/Swift-Animations/Assets.xcassets/菜单图片/backIconTypeTwo_pre.imageset/NodeModelViewControllerBack_black_typeTwo_pre@3x.png
--------------------------------------------------------------------------------
/Swift-Animations/Assets.xcassets/菜单图片/backIcon_pre.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "scale" : "1x"
6 | },
7 | {
8 | "idiom" : "universal",
9 | "scale" : "2x"
10 | },
11 | {
12 | "idiom" : "universal",
13 | "filename" : "NodeModelViewControllerBack_black_pre@3x.png",
14 | "scale" : "3x"
15 | }
16 | ],
17 | "info" : {
18 | "version" : 1,
19 | "author" : "xcode"
20 | }
21 | }
--------------------------------------------------------------------------------
/Swift-Animations/Assets.xcassets/菜单图片/backIcon_pre.imageset/NodeModelViewControllerBack_black_pre@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/YouXianMing/Swift-Animations/b793f1224dd5d5a01ddfb3fe9cfa24a93212fa6d/Swift-Animations/Assets.xcassets/菜单图片/backIcon_pre.imageset/NodeModelViewControllerBack_black_pre@3x.png
--------------------------------------------------------------------------------
/Swift-Animations/Assets.xcassets/项目图片/1.imageset/1.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/YouXianMing/Swift-Animations/b793f1224dd5d5a01ddfb3fe9cfa24a93212fa6d/Swift-Animations/Assets.xcassets/项目图片/1.imageset/1.jpg
--------------------------------------------------------------------------------
/Swift-Animations/Assets.xcassets/项目图片/1.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "filename" : "1.jpg",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "scale" : "2x"
11 | },
12 | {
13 | "idiom" : "universal",
14 | "scale" : "3x"
15 | }
16 | ],
17 | "info" : {
18 | "version" : 1,
19 | "author" : "xcode"
20 | }
21 | }
--------------------------------------------------------------------------------
/Swift-Animations/Assets.xcassets/项目图片/2.imageset/2.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/YouXianMing/Swift-Animations/b793f1224dd5d5a01ddfb3fe9cfa24a93212fa6d/Swift-Animations/Assets.xcassets/项目图片/2.imageset/2.jpg
--------------------------------------------------------------------------------
/Swift-Animations/Assets.xcassets/项目图片/2.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "filename" : "2.jpg",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "scale" : "2x"
11 | },
12 | {
13 | "idiom" : "universal",
14 | "scale" : "3x"
15 | }
16 | ],
17 | "info" : {
18 | "version" : 1,
19 | "author" : "xcode"
20 | }
21 | }
--------------------------------------------------------------------------------
/Swift-Animations/Assets.xcassets/项目图片/3.imageset/3.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/YouXianMing/Swift-Animations/b793f1224dd5d5a01ddfb3fe9cfa24a93212fa6d/Swift-Animations/Assets.xcassets/项目图片/3.imageset/3.jpg
--------------------------------------------------------------------------------
/Swift-Animations/Assets.xcassets/项目图片/3.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "filename" : "3.jpg",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "scale" : "2x"
11 | },
12 | {
13 | "idiom" : "universal",
14 | "scale" : "3x"
15 | }
16 | ],
17 | "info" : {
18 | "version" : 1,
19 | "author" : "xcode"
20 | }
21 | }
--------------------------------------------------------------------------------
/Swift-Animations/Assets.xcassets/项目图片/4.imageset/4.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/YouXianMing/Swift-Animations/b793f1224dd5d5a01ddfb3fe9cfa24a93212fa6d/Swift-Animations/Assets.xcassets/项目图片/4.imageset/4.jpg
--------------------------------------------------------------------------------
/Swift-Animations/Assets.xcassets/项目图片/4.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "filename" : "4.jpg",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "scale" : "2x"
11 | },
12 | {
13 | "idiom" : "universal",
14 | "scale" : "3x"
15 | }
16 | ],
17 | "info" : {
18 | "version" : 1,
19 | "author" : "xcode"
20 | }
21 | }
--------------------------------------------------------------------------------
/Swift-Animations/Assets.xcassets/项目图片/5.imageset/5.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/YouXianMing/Swift-Animations/b793f1224dd5d5a01ddfb3fe9cfa24a93212fa6d/Swift-Animations/Assets.xcassets/项目图片/5.imageset/5.jpg
--------------------------------------------------------------------------------
/Swift-Animations/Assets.xcassets/项目图片/5.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "filename" : "5.jpg",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "scale" : "2x"
11 | },
12 | {
13 | "idiom" : "universal",
14 | "scale" : "3x"
15 | }
16 | ],
17 | "info" : {
18 | "version" : 1,
19 | "author" : "xcode"
20 | }
21 | }
--------------------------------------------------------------------------------
/Swift-Animations/Assets.xcassets/项目图片/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "info" : {
3 | "version" : 1,
4 | "author" : "xcode"
5 | }
6 | }
--------------------------------------------------------------------------------
/Swift-Animations/Assets.xcassets/项目图片/colors.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "scale" : "1x"
6 | },
7 | {
8 | "idiom" : "universal",
9 | "filename" : "colors@2x.png",
10 | "scale" : "2x"
11 | },
12 | {
13 | "idiom" : "universal",
14 | "scale" : "3x"
15 | }
16 | ],
17 | "info" : {
18 | "version" : 1,
19 | "author" : "xcode"
20 | }
21 | }
--------------------------------------------------------------------------------
/Swift-Animations/Assets.xcassets/项目图片/colors.imageset/colors@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/YouXianMing/Swift-Animations/b793f1224dd5d5a01ddfb3fe9cfa24a93212fa6d/Swift-Animations/Assets.xcassets/项目图片/colors.imageset/colors@2x.png
--------------------------------------------------------------------------------
/Swift-Animations/Assets.xcassets/项目图片/pic_1.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "scale" : "1x"
6 | },
7 | {
8 | "idiom" : "universal",
9 | "filename" : "pic_1@2x.png",
10 | "scale" : "2x"
11 | },
12 | {
13 | "idiom" : "universal",
14 | "scale" : "3x"
15 | }
16 | ],
17 | "info" : {
18 | "version" : 1,
19 | "author" : "xcode"
20 | }
21 | }
--------------------------------------------------------------------------------
/Swift-Animations/Assets.xcassets/项目图片/pic_1.imageset/pic_1@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/YouXianMing/Swift-Animations/b793f1224dd5d5a01ddfb3fe9cfa24a93212fa6d/Swift-Animations/Assets.xcassets/项目图片/pic_1.imageset/pic_1@2x.png
--------------------------------------------------------------------------------
/Swift-Animations/Assets.xcassets/项目图片/pic_2.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "scale" : "1x"
6 | },
7 | {
8 | "idiom" : "universal",
9 | "filename" : "pic_2@2x.png",
10 | "scale" : "2x"
11 | },
12 | {
13 | "idiom" : "universal",
14 | "scale" : "3x"
15 | }
16 | ],
17 | "info" : {
18 | "version" : 1,
19 | "author" : "xcode"
20 | }
21 | }
--------------------------------------------------------------------------------
/Swift-Animations/Assets.xcassets/项目图片/pic_2.imageset/pic_2@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/YouXianMing/Swift-Animations/b793f1224dd5d5a01ddfb3fe9cfa24a93212fa6d/Swift-Animations/Assets.xcassets/项目图片/pic_2.imageset/pic_2@2x.png
--------------------------------------------------------------------------------
/Swift-Animations/Assets.xcassets/项目图片/pic_3.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "scale" : "1x"
6 | },
7 | {
8 | "idiom" : "universal",
9 | "filename" : "pic_3@2x.png",
10 | "scale" : "2x"
11 | },
12 | {
13 | "idiom" : "universal",
14 | "scale" : "3x"
15 | }
16 | ],
17 | "info" : {
18 | "version" : 1,
19 | "author" : "xcode"
20 | }
21 | }
--------------------------------------------------------------------------------
/Swift-Animations/Assets.xcassets/项目图片/pic_3.imageset/pic_3@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/YouXianMing/Swift-Animations/b793f1224dd5d5a01ddfb3fe9cfa24a93212fa6d/Swift-Animations/Assets.xcassets/项目图片/pic_3.imageset/pic_3@2x.png
--------------------------------------------------------------------------------
/Swift-Animations/Assets.xcassets/项目图片/pic_4.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "scale" : "1x"
6 | },
7 | {
8 | "idiom" : "universal",
9 | "filename" : "pic_4@2x.png",
10 | "scale" : "2x"
11 | },
12 | {
13 | "idiom" : "universal",
14 | "scale" : "3x"
15 | }
16 | ],
17 | "info" : {
18 | "version" : 1,
19 | "author" : "xcode"
20 | }
21 | }
--------------------------------------------------------------------------------
/Swift-Animations/Assets.xcassets/项目图片/pic_4.imageset/pic_4@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/YouXianMing/Swift-Animations/b793f1224dd5d5a01ddfb3fe9cfa24a93212fa6d/Swift-Animations/Assets.xcassets/项目图片/pic_4.imageset/pic_4@2x.png
--------------------------------------------------------------------------------
/Swift-Animations/Assets.xcassets/项目图片/plane.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "filename" : "plane.png",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "scale" : "2x"
11 | },
12 | {
13 | "idiom" : "universal",
14 | "scale" : "3x"
15 | }
16 | ],
17 | "info" : {
18 | "version" : 1,
19 | "author" : "xcode"
20 | }
21 | }
--------------------------------------------------------------------------------
/Swift-Animations/Assets.xcassets/项目图片/plane.imageset/plane.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/YouXianMing/Swift-Animations/b793f1224dd5d5a01ddfb3fe9cfa24a93212fa6d/Swift-Animations/Assets.xcassets/项目图片/plane.imageset/plane.png
--------------------------------------------------------------------------------
/Swift-Animations/BackgroundLineView.swift:
--------------------------------------------------------------------------------
1 | //
2 | // BackgroundLineView.swift
3 | // LineBackgroundView
4 | //
5 | // Created by YouXianMing on 16/8/14.
6 | // Copyright © 2016年 YouXianMing. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | // MARK: Public class : BackgroundLineView
12 |
13 | class BackgroundLineView: UIView {
14 |
15 | // MARK: Properties.
16 |
17 | /// Line width, default is 5.
18 | var lineWidth : CGFloat {
19 |
20 | get {return backgroundView.lineWidth}
21 |
22 | set(newVal) {
23 |
24 | backgroundView.lineWidth = newVal
25 | backgroundView.setNeedsDisplay()
26 | }
27 | }
28 |
29 | /// Line gap, default is 3.
30 | var lineGap : CGFloat {
31 |
32 | get {return backgroundView.lineGap}
33 |
34 | set(newVal) {
35 |
36 | backgroundView.lineGap = newVal
37 | backgroundView.setNeedsDisplay()
38 | }
39 | }
40 |
41 | /// Line color, default is grayColor.
42 | var lineColor : UIColor {
43 |
44 | get {return backgroundView.lineColor}
45 |
46 | set(newVal) {
47 |
48 | backgroundView.lineColor = newVal
49 | backgroundView.setNeedsDisplay()
50 | }
51 | }
52 |
53 | /// Rotate value, default is 0.
54 | var rotate : CGFloat {
55 |
56 | get {return backgroundView.rotate}
57 |
58 | set(newVal) {
59 |
60 | backgroundView.rotate = newVal
61 | backgroundView.setNeedsDisplay()
62 | }
63 | }
64 |
65 | convenience init(frame: CGRect, lineWidth : CGFloat, lineGap : CGFloat, lineColor : UIColor, rotate : CGFloat) {
66 |
67 | self.init(frame : frame)
68 | self.lineWidth = lineWidth
69 | self.lineGap = lineGap
70 | self.lineColor = lineColor
71 | self.rotate = rotate
72 | }
73 |
74 | // MARK: Override system method.
75 |
76 | override func layoutSubviews() {
77 |
78 | super.layoutSubviews()
79 | setupBackgroundView()
80 | }
81 |
82 | override init(frame: CGRect) {
83 |
84 | super.init(frame: frame)
85 |
86 | self.layer.masksToBounds = true
87 | self.addSubview(backgroundView)
88 | }
89 |
90 | required init?(coder aDecoder: NSCoder) {
91 |
92 | fatalError("init(coder:) has not been implemented")
93 | }
94 |
95 | // MARK: Private value & func.
96 |
97 | fileprivate let backgroundView = LineBackground(length: 0)
98 |
99 | fileprivate func setupBackgroundView() {
100 |
101 | let drawLength = sqrt(self.bounds.size.width * self.bounds.size.width + self.bounds.size.height * self.bounds.size.height)
102 | backgroundView.frame = CGRect(x: 0, y: 0, width: drawLength, height: drawLength)
103 | backgroundView.center = CGPoint(x: self.bounds.size.width / 2.0, y: self.bounds.size.height / 2.0)
104 | backgroundView.setNeedsDisplay()
105 | }
106 | }
107 |
108 | // MARK: Private class : LineBackground
109 |
110 | private class LineBackground : UIView {
111 |
112 | fileprivate var rotate : CGFloat = 0
113 | fileprivate var lineWidth : CGFloat = 5
114 | fileprivate var lineGap : CGFloat = 3
115 | fileprivate var lineColor : UIColor = UIColor.gray
116 |
117 | override init(frame: CGRect) {
118 |
119 | super.init(frame: frame)
120 | self.backgroundColor = UIColor.clear
121 | }
122 |
123 | required init?(coder aDecoder: NSCoder) {
124 |
125 | fatalError("init(coder:) has not been implemented")
126 | }
127 |
128 | convenience init(length : CGFloat) {
129 |
130 | self.init(frame : CGRect(x: 0, y: 0, width: length, height: length))
131 | }
132 |
133 | override func draw(_ rect: CGRect) {
134 |
135 | super.draw(rect)
136 |
137 | guard self.bounds.size.width > 0 && self.bounds.size.height > 0 else {
138 |
139 | return
140 | }
141 |
142 | let context = UIGraphicsGetCurrentContext()
143 | let width = self.bounds.size.width
144 | let height = self.bounds.size.height
145 | let drawLength = sqrt(width * width + height * height)
146 | let outerX = (drawLength - width) / 2.0
147 | let outerY = (drawLength - height) / 2.0
148 | let tmpLineWidth = lineWidth <= 0 ? 5 : lineWidth
149 | let tmpLineGap = lineGap <= 0 ? 3 : lineGap
150 |
151 | var red : CGFloat = 0
152 | var green : CGFloat = 0
153 | var blue : CGFloat = 0
154 | var alpha : CGFloat = 0
155 |
156 | context?.translateBy(x: 0.5 * drawLength, y: 0.5 * drawLength)
157 | context?.rotate(by: rotate)
158 | context?.translateBy(x: -0.5 * drawLength, y: -0.5 * drawLength)
159 |
160 | lineColor.getRed(&red, green: &green, blue: &blue, alpha: &alpha)
161 | context?.setFillColor(red: red, green: green, blue: blue, alpha: alpha)
162 |
163 | var currentX = -outerX
164 |
165 | while currentX < drawLength {
166 |
167 | context?.addRect(CGRect(x: currentX, y: -outerY, width: tmpLineWidth, height: drawLength))
168 | currentX += tmpLineWidth + tmpLineGap
169 | }
170 |
171 | context?.fillPath()
172 | }
173 | }
174 |
175 |
176 |
177 |
--------------------------------------------------------------------------------
/Swift-Animations/BaseCustomNavigationController.swift:
--------------------------------------------------------------------------------
1 | //
2 | // BaseCustomNavigationController.swift
3 | // Swift-Animations
4 | //
5 | // Created by YouXianMing on 2017/6/29.
6 | // Copyright © 2017年 YouXianMing. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | class BaseCustomNavigationController: UINavigationController {
12 |
13 | /// Init with rootViewController.
14 | ///
15 | /// - Parameters:
16 | /// - rootViewController: An UIViewController used as rootViewController.
17 | /// - hideTabBar: Navigation bar hide or not.
18 | convenience init(rootViewController: BaseCustomViewController, hideNavBar : Bool) {
19 |
20 | self.init(rootViewController : rootViewController)
21 | rootViewController.useInteractivePopGestureRecognizer()
22 | setNavigationBarHidden(hideNavBar, animated: false)
23 | }
24 |
25 | // MARK: -- System method && Debug message --
26 |
27 | deinit {
28 |
29 | print("[❌] '[NAV] " + String(describing: self.classForCoder) + "' is released.")
30 | }
31 |
32 | override func viewDidAppear(_ animated: Bool) {
33 |
34 | super.viewDidAppear(animated)
35 | print("[➡️] enter to --> '[NAV] " + String(describing: self.classForCoder) + "'.")
36 | }
37 |
38 | override func viewDidDisappear(_ animated: Bool) {
39 |
40 | super.viewDidDisappear(animated)
41 | print("[🕒] leave from <-- '[NAV] " + String(describing: self.classForCoder) + "'.")
42 | }
43 | }
44 |
--------------------------------------------------------------------------------
/Swift-Animations/BaseMessageView.swift:
--------------------------------------------------------------------------------
1 | //
2 | // BaseMessageView.swift
3 | // Swift-Animations
4 | //
5 | // Created by YouXianMing on 2017/9/13.
6 | // Copyright © 2017年 YouXianMing. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | // MARK: protocol CustomCellDelegate
12 |
13 | protocol BaseMessageViewDelegate : class {
14 |
15 | func baseMessageView(_ messageView : BaseMessageView, event : AnyObject?)
16 | func baseMessageViewWillAppear(_ messageView : BaseMessageView)
17 | func baseMessageViewDidAppear(_ messageView : BaseMessageView)
18 | func baseMessageViewWillDisappear(_ messageView : BaseMessageView)
19 | func baseMessageViewDidDisappear(_ messageView : BaseMessageView)
20 | }
21 |
22 | class BaseMessageView: UIView {
23 |
24 | // MARK: Properties
25 |
26 | /// The delegate.
27 | weak var delegate : BaseMessageViewDelegate?
28 |
29 | /// The message object.
30 | var messageObject : AnyObject?
31 |
32 | /// The contentView.
33 | var contentView : UIView? {
34 |
35 | get { return private_ContentView}
36 | set(newVal) {
37 |
38 | self.frame = (newVal != nil ? (newVal?.bounds)! : CGRect.zero)
39 | private_ContentView = newVal
40 | }
41 | }
42 | private weak var private_ContentView : UIView?
43 |
44 | /// Auto hiden or not, default is YES.
45 | var autoHiden : Bool = true
46 |
47 | /// If The autoHiden is YES, you should set the delay hiden duration, default is 2.0.
48 | var delayAutoHidenDuration : TimeInterval {
49 |
50 | get { return private_DelayAutoHidenDuration}
51 | set(newVal) {
52 |
53 | private_DelayAutoHidenDuration = (newVal <= 0 ? 0 : newVal)
54 | }
55 | }
56 | private var private_DelayAutoHidenDuration : TimeInterval = 2.0
57 |
58 | // MARK: Init related.
59 |
60 | required override init(frame : CGRect) {
61 |
62 | super.init(frame: CGRect.zero)
63 | }
64 |
65 | required convenience init() {
66 |
67 | self.init(frame: CGRect.zero)
68 | }
69 |
70 | required init?(coder aDecoder: NSCoder) {
71 |
72 | fatalError("init(coder:) has not been implemented")
73 | }
74 |
75 | deinit {
76 |
77 | print(String(describing: self.classForCoder) + " is released.")
78 | }
79 |
80 | class func Setup(messageObject : AnyObject? = nil,
81 | contentView : UIView? = nil,
82 | delegate : BaseMessageViewDelegate? = nil,
83 | autoHiden : Bool = true,
84 | delayAutoHidenDuration : TimeInterval = 2.0) -> Self {
85 |
86 | let messageView = self.init(frame: CGRect.zero)
87 |
88 | messageView.messageObject = messageObject
89 | messageView.contentView = contentView
90 | messageView.delegate = delegate
91 | messageView.autoHiden = autoHiden
92 | messageView.delayAutoHidenDuration = delayAutoHidenDuration
93 |
94 | return messageView
95 | }
96 |
97 | // MARK: Useful methods.
98 |
99 | /// Show the MessageView.
100 | final func show() {
101 |
102 | if (self.contentView != nil) {
103 |
104 | self.contentView?.addSubview(self)
105 | setupSubViews()
106 | beginShowAnimation()
107 |
108 | if autoHiden {
109 |
110 | let dispatchTime = DispatchTime.now() + delayAutoHidenDuration
111 | DispatchQueue.main.asyncAfter( deadline: dispatchTime ) {
112 |
113 | self.hide()
114 | }
115 | }
116 | }
117 | }
118 |
119 | /// Hide the MessageView.
120 | final func hide() {
121 |
122 | beginHideAnimation()
123 | }
124 |
125 | // MARK: Overwrite by subClass.
126 |
127 | /// Begin show animation.
128 | func beginShowAnimation() {
129 |
130 | beforeStartShowValueConfig()
131 | delegate?.baseMessageViewWillAppear(self)
132 | UIView.animate(withDuration: 0.3, delay: 0, options: .beginFromCurrentState, animations: {
133 |
134 | self.startShowAnimated()
135 |
136 | }) { (success) in
137 |
138 | self.delegate?.baseMessageViewDidAppear(self)
139 | }
140 | }
141 |
142 | /// Begin hide animation.
143 | func beginHideAnimation() {
144 |
145 | delegate?.baseMessageViewWillDisappear(self)
146 | UIView.animate(withDuration: 0.3, delay: 0, options: .beginFromCurrentState, animations: {
147 |
148 | self.startHideAnimated()
149 |
150 | }) { (success) in
151 |
152 | self.afterHideShowValueConfig()
153 | self.delegate?.baseMessageViewDidDisappear(self)
154 | self.removeFromSuperview()
155 | }
156 | }
157 |
158 | /// Add subviews to self.
159 | func setupSubViews() {
160 |
161 | }
162 |
163 | /// Before start show animated, you can do sth value config.
164 | func beforeStartShowValueConfig() {
165 |
166 | }
167 |
168 | /// Start show animated.
169 | func startShowAnimated() {
170 |
171 | }
172 |
173 | /// Start hide animated.
174 | func startHideAnimated() {
175 |
176 | }
177 |
178 | /// After hide animation is complete, you can do sth value config.
179 | func afterHideShowValueConfig() {
180 |
181 | }
182 | }
183 |
--------------------------------------------------------------------------------
/Swift-Animations/CATransform3DM34Controller.swift:
--------------------------------------------------------------------------------
1 | //
2 | // CATransform3DM34Controller.swift
3 | // Swift-Animations
4 | //
5 | // Created by YouXianMing on 16/8/19.
6 | // Copyright © 2016年 YouXianMing. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | class CATransform3DM34Controller: NormalTitleViewController {
12 |
13 | fileprivate var timer : Timer!
14 | fileprivate var layer : CALayer!
15 | fileprivate var transformState : Bool = false
16 |
17 | override func viewDidLoad() {
18 |
19 | super.viewDidLoad()
20 |
21 | initLayer()
22 |
23 | // Init timer.
24 | timer = Timer.scheduledTimer(timeInterval: 2.0, target: self, selector: #selector(CATransform3DM34Controller.timerEvent), userInfo: nil, repeats: true)
25 | }
26 |
27 | fileprivate func initLayer() {
28 |
29 | let image = UIImage(named: "1")
30 | layer = CALayer()
31 | layer.frame = CGRect(x: 0, y: 0, width: image!.size.width / 2, height: image!.size.height / 2)
32 | layer.position = (contentView?.middlePoint)!
33 | layer.borderWidth = 4
34 | layer.borderColor = UIColor.black.cgColor
35 | layer.contents = image?.cgImage
36 | contentView?.layer.addSublayer(layer)
37 | }
38 |
39 | @objc func timerEvent() {
40 |
41 | if transformState == false {
42 |
43 | transformState = true
44 | transformStateEvent()
45 |
46 | } else {
47 |
48 | transformState = false
49 | normalStateEvent()
50 | }
51 | }
52 |
53 | fileprivate func transformStateEvent() {
54 |
55 | var perspectiveTransform = CATransform3DIdentity
56 | perspectiveTransform.m34 = -1.0 / 500.0
57 | perspectiveTransform = CATransform3DTranslate(perspectiveTransform, 30, -35, 0)
58 | perspectiveTransform = CATransform3DRotate(perspectiveTransform, Math.RadianFromDegree(30), 0.75, 1, -0.5)
59 | perspectiveTransform = CATransform3DScale(perspectiveTransform, 0.75, 0.75, 0.75)
60 |
61 | layer.transform = perspectiveTransform
62 | layer.allowsEdgeAntialiasing = true
63 | layer.speed = 0.5
64 | }
65 |
66 | fileprivate func normalStateEvent() {
67 |
68 | let perspectiveTransform = CATransform3DIdentity
69 | layer.transform = perspectiveTransform
70 | layer.speed = 0.5
71 | }
72 |
73 | override func viewDidDisappear(_ animated: Bool) {
74 |
75 | super.viewDidDisappear(animated)
76 | timer.invalidate()
77 | }
78 | }
79 |
--------------------------------------------------------------------------------
/Swift-Animations/CellDataAdapter.swift:
--------------------------------------------------------------------------------
1 | //
2 | // CellDataAdapter.swift
3 | // Swift-Animations
4 | //
5 | // Created by YouXianMing on 16/8/5.
6 | // Copyright © 2016年 YouXianMing. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | class CellDataAdapter: NSObject {
12 |
13 | // MARK: property
14 |
15 | /// Cell's reused identifier.
16 | var cellReuseIdentifier : String?
17 |
18 | /// Data, can be nil.
19 | var data : AnyObject?
20 |
21 | /// Cell's height, only used for UITableView's cell.
22 | var cellHeight : CGFloat?
23 |
24 | /// Cell's type (The same cell, but maybe have different types).
25 | var cellType : Int?
26 |
27 | // MARK: convenience init
28 |
29 | convenience init(cellReuseIdentifier: String?, data: AnyObject?, cellHeight: CGFloat?, cellType: Int?) {
30 |
31 | self.init()
32 | self.cellReuseIdentifier = cellReuseIdentifier
33 | self.data = data
34 | self.cellHeight = cellHeight
35 | self.cellType = cellType
36 | }
37 | }
38 |
39 |
--------------------------------------------------------------------------------
/Swift-Animations/CircleAnimationViewController.swift:
--------------------------------------------------------------------------------
1 | //
2 | // CircleAnimationViewController.swift
3 | // Swift-Animations
4 | //
5 | // Created by YouXianMing on 16/8/16.
6 | // Copyright © 2016年 YouXianMing. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | class CircleAnimationViewController: NormalTitleViewController {
12 |
13 | fileprivate var circleView1 : CircleView!
14 | fileprivate var circleView2 : CircleView!
15 | fileprivate var circleView3 : CircleView!
16 | fileprivate var circleView4 : CircleView!
17 | fileprivate var timer : GCDTimer!
18 |
19 | override func viewDidLoad() {
20 |
21 | super.viewDidLoad()
22 |
23 | let gapFromTop : CGFloat = 64.0 + 20.0
24 | let width : CGFloat = Screen.Width
25 | let halfWidth : CGFloat = width / 2.0
26 | let radius : CGFloat = width / 3.0 + 20
27 | let bounds : CGRect = CGRect(x: 0, y: 0, width: radius, height: radius)
28 |
29 | let point1 = CGPoint(x: halfWidth / 2, y: gapFromTop + halfWidth / 2)
30 | let point2 = CGPoint(x: halfWidth / 2 + halfWidth, y: gapFromTop + halfWidth / 2)
31 | let point3 = CGPoint(x: halfWidth / 2, y: gapFromTop + halfWidth / 2 + halfWidth)
32 | let point4 = CGPoint(x: halfWidth / 2 + halfWidth, y: gapFromTop + halfWidth / 2 + halfWidth)
33 |
34 | circleView1 = CircleView(frame: bounds, lineWidth: 2, lineColor: UIColor.gray, clockWise: true, startDegree: 0)
35 | circleView1.center = point1
36 | contentView?.addSubview(circleView1)
37 |
38 | circleView2 = CircleView(frame: bounds, lineWidth: radius / 2, lineColor: UIColor.black, clockWise: true, startDegree: 0)
39 | circleView2.center = point2
40 | contentView?.addSubview(circleView2)
41 |
42 | circleView3 = CircleView(frame: bounds, lineWidth: 2, lineColor: UIColor.black, clockWise: true, startDegree: 0)
43 | circleView3.center = point3
44 | contentView?.addSubview(circleView3)
45 |
46 | circleView4 = CircleView(frame: bounds, lineWidth: radius / 2, lineColor: UIColor.black, clockWise: true, startDegree: 0)
47 | let imageView = UIImageView(frame: CGRect(x: 0, y: 0, width: radius, height: radius))
48 | imageView.image = UIImage(named: "colors")
49 | imageView.center = point4
50 | imageView.layer.mask = self.circleView4.layer
51 | contentView?.addSubview(imageView)
52 |
53 | weak var weakSelf = self
54 | timer = GCDTimer(in: GCDQueue.Main, delay: 0.6, interval: 1.5)
55 | timer.setTimerEventHandler { _ in
56 |
57 | let percent = Double(arc4random() % 100) / 100.0
58 | let anotherPercent = Double(arc4random() % 100) / 100.0
59 | let smallPercent = (percent < anotherPercent ? percent : anotherPercent)
60 | let largePercent = (percent < anotherPercent ? anotherPercent : percent)
61 |
62 | weakSelf?.circleView1.strokeEnd(largePercent, easingFunction: .elasticEaseInOut, animated: true, duration: 1.0)
63 | weakSelf?.circleView2.strokeEnd(largePercent, easingFunction: .exponentialEaseInOut, animated: true, duration: 1.0)
64 | weakSelf?.circleView3.strokeStart(smallPercent, easingFunction: .exponentialEaseInOut, animated: true, duration: 1.0)
65 | weakSelf?.circleView3.strokeEnd(largePercent, easingFunction: .exponentialEaseInOut, animated: true, duration: 1.0)
66 | weakSelf?.circleView4.strokeEnd(largePercent, easingFunction: .exponentialEaseOut, animated: true, duration: 1.0)
67 | }
68 |
69 | timer.start()
70 | }
71 |
72 | override func viewDidDisappear(_ animated: Bool) {
73 |
74 | super.viewDidDisappear(animated)
75 | timer.destroy()
76 | }
77 | }
78 |
--------------------------------------------------------------------------------
/Swift-Animations/ClassHeaderView.swift:
--------------------------------------------------------------------------------
1 | //
2 | // ClassHeaderView.swift
3 | // Swift-Animations
4 | //
5 | // Created by YouXianMing on 16/8/9.
6 | // Copyright © 2016年 YouXianMing. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | class ClassHeaderView: CustomHeaderFooterView {
12 |
13 | fileprivate var normalClassNameLabel : UILabel!
14 | fileprivate var highClassNameLabel : UILabel!
15 | fileprivate var rotateView : RotateView!
16 |
17 | override func setupHeaderFooterView() {
18 |
19 | setHeaderFooterViewBackgroundColor(UIColor.white)
20 | }
21 |
22 | override func buildSubview() {
23 |
24 | let contentView = UIView.CreateLine(CGRect(x: 0, y: 2, width: Screen.Width, height: 26), lineColor: UIColor.gray.alpha(0.05))
25 | self.addSubview(contentView)
26 | contentView.addSubview(UIView.CreateLine(CGRect(x: 0, y: 0, width: Screen.Width, height: 0.5), lineColor: UIColor.gray.alpha(0.25)))
27 | contentView.addSubview(UIView.CreateLine(CGRect(x: 0, y: 25.5, width: Screen.Width, height: 0.5), lineColor: UIColor.gray.alpha(0.25)))
28 |
29 | let button = UIButton(frame: CGRect(x: 0, y: 0, width: Screen.Width, height: 30))
30 | button.addTarget(self, action: #selector(ClassHeaderView.buttonEvent), for: .touchUpInside)
31 | self.addSubview(button)
32 |
33 | normalClassNameLabel = UILabel(frame: CGRect(x: 10, y: 0, width: 100, height: 26))
34 | normalClassNameLabel.font = UIFont.AppleSDGothicNeoThin(12)
35 | contentView.addSubview(normalClassNameLabel)
36 |
37 | highClassNameLabel = UILabel(frame: normalClassNameLabel.frame)
38 | highClassNameLabel.font = normalClassNameLabel.font
39 | highClassNameLabel.textColor = UIColor.red
40 | contentView.addSubview(highClassNameLabel)
41 |
42 | rotateView = RotateView(frame: CGRect(x: Screen.Width - 25, y: 5, width: 20, height: 20))
43 | self.addSubview(rotateView)
44 |
45 | let arrowImageView = UIImageView(frame: CGRect(x: 0, y: 0, width: 20 / 3.0, height: 36 / 3.0))
46 | arrowImageView.image = UIImage(named: "arrows_next")
47 | arrowImageView.center = rotateView.middlePoint
48 | rotateView.addSubview(arrowImageView)
49 | }
50 |
51 | override func loadContent() {
52 |
53 | let model = data as! ClassModel
54 |
55 | normalClassNameLabel.text = model.className
56 | highClassNameLabel.text = model.className
57 |
58 | if model.expend == true {
59 |
60 | extendStateAnimated(false)
61 |
62 | } else {
63 |
64 | normalStateAnimated(false)
65 | }
66 | }
67 |
68 | @objc func buttonEvent() {
69 |
70 | let model = data as! ClassModel
71 |
72 | if model.expend == true {
73 |
74 | model.expend = false
75 | normalStateAnimated(true)
76 |
77 | var indexPaths = [IndexPath]()
78 | let index = model.students.count
79 | for i in 0 ..< index {
80 |
81 | indexPaths.append(IndexPath(item: i, section: section!))
82 | }
83 | tableView?.deleteRows(at: indexPaths, with: .automatic)
84 |
85 | } else {
86 |
87 | model.expend = true
88 | extendStateAnimated(true)
89 |
90 | var indexPaths = [IndexPath]()
91 | let index = model.students.count
92 | for i in 0 ..< index {
93 |
94 | indexPaths.append(IndexPath(item: i, section: section!))
95 | }
96 | tableView?.insertRows(at: indexPaths, with: .automatic)
97 | }
98 | }
99 |
100 | func normalStateAnimated(_ animated : Bool) {
101 |
102 | UIView.animate(withDuration: animated == true ? 0.5 : 0, delay: 0, usingSpringWithDamping: 1, initialSpringVelocity: 0, options: .allowUserInteraction, animations: {
103 |
104 | self.normalClassNameLabel.alpha = 1;
105 | self.normalClassNameLabel.frame = CGRect(x: 10, y: 0, width: 100, height: 26);
106 | self.highClassNameLabel.alpha = 0;
107 | self.highClassNameLabel.frame = CGRect(x: 10, y: 0, width: 100, height: 26);
108 |
109 | }, completion: nil)
110 |
111 | rotateView.changeToUpAnimated(animated)
112 | }
113 |
114 | func extendStateAnimated(_ animated : Bool) {
115 |
116 | UIView.animate(withDuration: animated == true ? 0.5 : 0, delay: 0, usingSpringWithDamping: 1, initialSpringVelocity: 0, options: .allowUserInteraction, animations: {
117 |
118 | self.normalClassNameLabel.alpha = 0;
119 | self.normalClassNameLabel.frame = CGRect(x: 10 + 10, y: 0, width: 100, height: 26);
120 | self.highClassNameLabel.alpha = 1;
121 | self.highClassNameLabel.frame = CGRect(x: 10 + 10, y: 0, width: 100, height: 26);
122 |
123 | }, completion: nil)
124 |
125 | rotateView.changeToRightAnimated(animated)
126 | }
127 | }
128 |
--------------------------------------------------------------------------------
/Swift-Animations/ClassModel.swift:
--------------------------------------------------------------------------------
1 | //
2 | // ClassModel.swift
3 | // Swift-Animations
4 | //
5 | // Created by YouXianMing on 16/8/9.
6 | // Copyright © 2016年 YouXianMing. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | class ClassModel: NSObject {
12 |
13 | var className : String = ""
14 | var students : [StudentModel] = [StudentModel]()
15 | var expend : Bool = false
16 |
17 | convenience init(className : String) {
18 |
19 | self.init()
20 | self.className = className
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/Swift-Animations/ComplexEasingValue.swift:
--------------------------------------------------------------------------------
1 | //
2 | // ComplexEasingValue.swift
3 | // Swift-EasingAnimation
4 | //
5 | // Created by YouXianMing on 15/10/21.
6 | //
7 | // https://github.com/YouXianMing
8 | // http://home.cnblogs.com/u/YouXianMing/
9 | //
10 |
11 | import UIKit
12 |
13 | class ComplexEasingValue: EasingValue {
14 |
15 | /// 点A的动画函数(如果是 size,则点 A 表示 width;如果是 point,则点 A 表示 x)
16 | var easingA : EasingFunction!
17 |
18 | /// 点B的动画函数(如果是 size,则点 B 表示 height;如果是 point,则点 B 表示 y)
19 | var easingB : EasingFunction!
20 |
21 | // MARK: init
22 | override init() {
23 |
24 | super.init()
25 |
26 | easingA = EasingFunction.sineEaseIn
27 | easingB = EasingFunction.sineEaseIn
28 | frameCount = 60
29 | }
30 |
31 | init(withFunctionA : EasingFunction, FunctionB : EasingFunction, frameCount : size_t) {
32 |
33 | super.init()
34 |
35 | easingA = withFunctionA
36 | easingB = FunctionB
37 | self.frameCount = frameCount
38 | }
39 |
40 | /**
41 | 计算关键帧
42 |
43 | - parameter fromValue: 起始值
44 | - parameter toValue: 结束值
45 |
46 | - returns: 关键帧值数组
47 | */
48 | override func pointValueWith(fromPoint : CGPoint, toPoint : CGPoint) -> [AnyObject] {
49 |
50 | let values = NSMutableArray(capacity: frameCount)
51 |
52 | var t : Double = 0.0
53 | let dt : Double = 1.0 / (Double(frameCount) - 1)
54 |
55 | for _ in 0 ..< frameCount {
56 |
57 | let x : Double = Double(fromPoint.x) + easingA.function(t) * (Double(toPoint.x) - Double(fromPoint.x))
58 | let y : Double = Double(fromPoint.y) + easingB.function(t) * (Double(toPoint.y) - Double(fromPoint.y))
59 | let point : CGPoint = CGPoint(x : x, y : y)
60 | values.add(NSValue(cgPoint: point))
61 |
62 | t += dt
63 | }
64 |
65 | return values as [AnyObject]
66 | }
67 |
68 | /**
69 | 计算关键帧点
70 |
71 | - parameter fromPoint: 起始点
72 | - parameter toPoint: 结束点
73 |
74 | - returns: 关键帧点数组
75 | */
76 | override func sizeValueWith(fromSize : CGSize, toSize : CGSize) -> [AnyObject] {
77 |
78 | let values = NSMutableArray(capacity: frameCount)
79 |
80 | var t : Double = 0.0
81 | let dt : Double = 1.0 / (Double(frameCount) - 1)
82 |
83 | for _ in 0 ..< frameCount {
84 |
85 | let width : Double = Double(fromSize.width) + easingA.function(t) * (Double(toSize.width) - Double(fromSize.width))
86 | let height : Double = Double(fromSize.height) + easingB.function(t) * (Double(toSize.height) - Double(fromSize.height))
87 | let size : CGSize = CGSize(width: width, height: height)
88 | values.add(NSValue(cgSize : size))
89 |
90 | t += dt
91 | }
92 |
93 | return values as [AnyObject]
94 | }
95 | }
96 |
--------------------------------------------------------------------------------
/Swift-Animations/ControllerBaseViewConfig.swift:
--------------------------------------------------------------------------------
1 | //
2 | // ControllerBaseViewConfig.swift
3 | // Swift-Animations
4 | //
5 | // Created by YouXianMing on 2017/6/29.
6 | // Copyright © 2017年 YouXianMing. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | class ControllerBaseViewConfig: NSObject {
12 |
13 | var backgroundColor : UIColor?
14 | var frame : CGRect?
15 | var exist : Bool = true
16 | }
17 |
--------------------------------------------------------------------------------
/Swift-Animations/ControllerItem.swift:
--------------------------------------------------------------------------------
1 | //
2 | // ControllerItem.swift
3 | // Swift-Animations
4 | //
5 | // Created by YouXianMing on 16/8/7.
6 | // Copyright © 2016年 YouXianMing. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | class ControllerItem: NSObject {
12 |
13 | var controllerClass : AnyClass?
14 | var name : String?
15 |
16 | convenience init(controllerClass : AnyClass, name : String) {
17 |
18 | self.init()
19 | self.controllerClass = controllerClass
20 | self.name = name
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/Swift-Animations/CountDownTimeCell.swift:
--------------------------------------------------------------------------------
1 | //
2 | // CountDownTimeCell.swift
3 | // Swift-Animations
4 | //
5 | // Created by YouXianMing on 16/9/4.
6 | // Copyright © 2016年 YouXianMing. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | class CountDownTimeCell: CustomCell, DefaultNotificationCenterDelegate {
12 |
13 | fileprivate var titleLabel : UILabel!
14 | fileprivate var countdownLabel : UILabel!
15 | fileprivate var notificationCenter : DefaultNotificationCenter = DefaultNotificationCenter()
16 |
17 | override func setupCell() {
18 |
19 | super.setupCell()
20 | notificationCenter.addNotificationName(NotificationEvent.countDownTimeCellCountDown.notificationName)
21 | notificationCenter.delegate = self
22 | }
23 |
24 | override func buildSubview() {
25 |
26 | titleLabel = UILabel(frame: CGRect(x: 15, y: 10, width: Screen.Width - 20, height: 40))
27 | titleLabel.textColor = UIColor.gray
28 | titleLabel.font = UIFont.AvenirLight(20.0)
29 | addSubview(titleLabel)
30 |
31 | countdownLabel = UILabel(frame: CGRect(x: 10, y: 10, width: Screen.Width - 20, height: 40))
32 | countdownLabel.textColor = UIColor.gray
33 | countdownLabel.font = UIFont.AvenirLight(15.0)
34 | countdownLabel.textAlignment = .right
35 | addSubview(countdownLabel)
36 | }
37 |
38 | override func loadContent() {
39 |
40 | if let model = dataAdapter?.data as? TimeModel {
41 |
42 | titleLabel.text = model.title
43 | countdownLabel.text = model.currentTimeString
44 | }
45 | }
46 |
47 | func defaultNotificationCenter(_ notificationName: String, object: AnyObject?) {
48 |
49 | if display == true && notificationName == NotificationEvent.countDownTimeCellCountDown.notificationName {
50 |
51 | loadContent()
52 | }
53 | }
54 | }
55 |
--------------------------------------------------------------------------------
/Swift-Animations/CountDownTimerController.swift:
--------------------------------------------------------------------------------
1 | //
2 | // CountDownTimerController.swift
3 | // Swift-Animations
4 | //
5 | // Created by YouXianMing on 16/9/4.
6 | // Copyright © 2016年 YouXianMing. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | class CountDownTimerController: NormalTitleViewController, UITableViewDelegate, UITableViewDataSource {
12 |
13 | fileprivate var timesArray : [CellDataAdapter] = [CellDataAdapter]()
14 | fileprivate var tableView : UITableView!
15 | fileprivate var timer : Timer!
16 |
17 | override func viewDidLoad() {
18 |
19 | super.viewDidLoad()
20 |
21 | func add(title : String, countdownTime : Int) {
22 |
23 | timesArray.append(CountDownTimeCell.Adapter(data: TimeModel(title: title, countdownTime: countdownTime)))
24 | }
25 |
26 | add(title: "YouXianMing", countdownTime: 20034)
27 | add(title: "Aaron", countdownTime: 31)
28 | add(title: "Nicholas", countdownTime: 1003)
29 | add(title: "Quentin", countdownTime: 394)
30 | add(title: "Samirah", countdownTime: 345345)
31 | add(title: "Serafina", countdownTime: 233)
32 | add(title: "Shanon", countdownTime: 4649)
33 | add(title: "Sophie", countdownTime: 3454)
34 | add(title: "Steven", countdownTime: 54524)
35 | add(title: "Saadiya", countdownTime: 235)
36 |
37 | // Create TableView.
38 | tableView = UITableView(frame: (contentView?.bounds)!)
39 | tableView.delegate = self
40 | tableView.dataSource = self
41 | tableView.separatorStyle = .none
42 | tableView.rowHeight = 60
43 | contentView?.addSubview(tableView)
44 |
45 | if #available(iOS 11.0, *) {
46 |
47 | tableView.contentInsetAdjustmentBehavior = .never
48 | }
49 |
50 | // Register cell.
51 | CountDownTimeCell.RegisterTo(tableView)
52 |
53 | // Init timer.
54 | timer = Timer.scheduledTimer(timeInterval: 1.0, target: self, selector: #selector(CountDownTimerController.timerEvent), userInfo: nil, repeats: true)
55 | }
56 |
57 | @objc func timerEvent() {
58 |
59 | for (_, dataAdapter) in timesArray.enumerated() {
60 |
61 | if let model = dataAdapter.data as? TimeModel {
62 |
63 | model.countDown()
64 | }
65 | }
66 |
67 | DefaultNotificationCenter.PostMessageTo(NotificationEvent.countDownTimeCellCountDown.notificationName)
68 | }
69 |
70 | func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
71 |
72 | return timesArray.count
73 | }
74 |
75 | func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
76 |
77 | return tableView.dequeueCellAndLoadContentFromAdapter(timesArray[(indexPath as NSIndexPath).row], indexPath: indexPath)
78 | }
79 |
80 | func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) {
81 |
82 | (cell as! CustomCell).display = true
83 | }
84 |
85 | func tableView(_ tableView: UITableView, didEndDisplaying cell: UITableViewCell, forRowAt indexPath: IndexPath) {
86 |
87 | (cell as! CustomCell).display = false
88 | }
89 |
90 | override func viewDidDisappear(_ animated: Bool) {
91 |
92 | super.viewDidDisappear(animated)
93 | timer.invalidate()
94 | }
95 | }
96 |
97 |
98 |
--------------------------------------------------------------------------------
/Swift-Animations/CustomCell.swift:
--------------------------------------------------------------------------------
1 | //
2 | // CustomCell.swift
3 | // Swift-Animations
4 | //
5 | // Created by YouXianMing on 16/8/6.
6 | // Copyright © 2016年 YouXianMing. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | // MARK: extension UITableView
12 |
13 | extension UITableView {
14 |
15 | /**
16 | Dequeue and load content from adapter.
17 |
18 | - parameter adapter: The CellDataAdapter.
19 | - parameter indexPath: The indexPath.
20 | - parameter tableView: The TableView.
21 | - parameter delegate: The CustomCell's delegate.
22 | - parameter controller: The controller.
23 |
24 | - returns: The CustomCell instance.
25 | */
26 | func dequeueCellAndLoadContentFromAdapter(_ adapter : CellDataAdapter,
27 | indexPath : IndexPath,
28 | tableView : UITableView? = nil,
29 | delegate : CustomCellDelegate? = nil,
30 | controller : UIViewController? = nil) -> CustomCell {
31 |
32 | let cell = self.dequeueReusableCell(withIdentifier: adapter.cellReuseIdentifier!) as! CustomCell
33 | cell.indexPath = indexPath
34 | cell.dataAdapter = adapter
35 | cell.data = adapter.data
36 | cell.tableView = tableView
37 | cell.delegate = delegate
38 | cell.controller = controller
39 | cell.loadContent()
40 |
41 | return cell
42 | }
43 |
44 | func selectedEventWithIndexPath(_ indexPath : IndexPath) {
45 |
46 | let cell = self.cellForRow(at: indexPath) as! CustomCell
47 |
48 | // Make sure the cell is kind of CustomCell.
49 | guard cell.isKind(of: CustomCell.classForCoder()) == true else {
50 |
51 | return
52 | }
53 |
54 | cell.selectedEvent()
55 | }
56 | }
57 |
58 | // MARK: protocol CustomCellDelegate
59 |
60 | protocol CustomCellDelegate : class {
61 |
62 | /**
63 | CustomCell's event.
64 |
65 | - parameter cell: CustomCell type class.
66 | - parameter event: Event data.
67 | */
68 | func customCell(_ cell: CustomCell?, event: Any?)
69 | }
70 |
71 | // MARK: CustomCell
72 |
73 | class CustomCell: UITableViewCell {
74 |
75 | weak var delegate : CustomCellDelegate?
76 | weak var dataAdapter : CellDataAdapter?
77 | weak var data : AnyObject?
78 | var indexPath : IndexPath?
79 | weak var tableView : UITableView?
80 | weak var controller : UIViewController?
81 | var display : Bool?
82 |
83 | override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
84 |
85 | super.init(style: style, reuseIdentifier: reuseIdentifier)
86 | self.setupCell()
87 | self.buildSubview()
88 | }
89 |
90 | required init?(coder aDecoder: NSCoder) {
91 |
92 | fatalError("init(coder:) has not been implemented")
93 | }
94 |
95 | /**
96 | Setup cell, override by subclass.
97 | */
98 | func setupCell() {
99 |
100 | self.selectionStyle = .none
101 | }
102 |
103 | /**
104 | Build subview, override by subclass.
105 | */
106 | func buildSubview() {}
107 |
108 | /**
109 | Load content, override by subclass.
110 | */
111 | func loadContent() {}
112 |
113 | /**
114 | Selected event, you should use this method in 'tableView:didSelectRowAtIndexPath:' to make it effective.
115 | */
116 | func selectedEvent() {}
117 |
118 | /**
119 | Calculate the cell's height from data, override by subclass.
120 |
121 | - parameter data: Data.
122 |
123 | - returns: Cell's height.
124 | */
125 | class func HeightWithData(_ data : AnyObject? = nil) -> CGFloat { return 0}
126 |
127 | /**
128 | Create the CustomCell type data adapter.
129 |
130 | - parameter reuseIdentifier: The reuseIdentifier.
131 | - parameter data: The data.
132 | - parameter cellHeight: The cell's height.
133 | - parameter type: The cell's type.
134 |
135 | - returns: The cellDataAdapter.
136 | */
137 | class func Adapter(_ reuseIdentifier: String? = nil,
138 | data: AnyObject? = nil,
139 | cellHeight: CGFloat? = 0,
140 | type: Int? = nil) -> CellDataAdapter {
141 |
142 | return CellDataAdapter.init(cellReuseIdentifier: reuseIdentifier ?? "\(self.classForCoder())",
143 | data: data,
144 | cellHeight: cellHeight,
145 | cellType: type)
146 | }
147 |
148 | /**
149 | Register cell to tableView with cell reuse identifier.
150 |
151 | - parameter tableView: UITableView.
152 | - parameter cellReuseIdentifier: Cell reuse identifier.
153 | */
154 | class func RegisterTo(_ tableView : UITableView,
155 | cellReuseIdentifier : String? = nil) {
156 |
157 | tableView.register(self.classForCoder(), forCellReuseIdentifier: cellReuseIdentifier ?? "\(self.classForCoder())")
158 | }
159 |
160 | /**
161 | Update the cell's height with animated or not, before you use this method, you should have the weak reference 'tableView' and 'dataAdapter', and this method will update the weak reference dataAdapter's property cellHeight.
162 |
163 | - parameter height: The new cell height.
164 | - parameter animated: Animated or not, default is true.
165 | */
166 | func updateWithNewCellHeight(_ height : CGFloat, animated : Bool = true) {
167 |
168 | guard tableView != nil && dataAdapter != nil else {
169 |
170 | return
171 | }
172 |
173 | if animated {
174 |
175 | dataAdapter?.cellHeight = height
176 | if #available(iOS 11.0, *) {
177 |
178 | tableView?.performBatchUpdates(nil, completion: nil)
179 |
180 | } else {
181 |
182 | tableView?.beginUpdates()
183 | tableView?.endUpdates()
184 | }
185 |
186 | } else {
187 |
188 | dataAdapter?.cellHeight = height
189 | tableView?.reloadData()
190 | }
191 | }
192 | }
193 |
194 |
--------------------------------------------------------------------------------
/Swift-Animations/CustomCollectionViewCell.swift:
--------------------------------------------------------------------------------
1 | //
2 | // CustomCollectionViewCell.swift
3 | // Swift-Animations
4 | //
5 | // Created by YouXianMing on 2017/9/13.
6 | // Copyright © 2017年 YouXianMing. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | // MARK: extension UITableView
12 |
13 | extension UICollectionView {
14 |
15 | /**
16 | Dequeue and load content from adapter.
17 |
18 | - parameter adapter: The CellDataAdapter.
19 | - parameter indexPath: The indexPath.
20 | - parameter collectionView: The CollectionView.
21 | - parameter delegate: The CustomCollectionViewCell's delegate.
22 | - parameter controller: The controller.
23 |
24 | - returns: The CustomCell instance.
25 | */
26 | func dequeueCellAndLoadContentFromAdapter(_ adapter : CellDataAdapter,
27 | indexPath : IndexPath,
28 | collectionView : UICollectionView? = nil,
29 | delegate : CustomCollectionViewCellDelegate? = nil,
30 | controller : UIViewController? = nil) -> CustomCollectionViewCell {
31 |
32 | let cell = self.dequeueReusableCell(withReuseIdentifier: adapter.cellReuseIdentifier!, for: indexPath) as! CustomCollectionViewCell
33 | cell.indexPath = indexPath
34 | cell.dataAdapter = adapter
35 | cell.data = adapter.data
36 | cell.collectionView = collectionView
37 | cell.delegate = delegate
38 | cell.controller = controller
39 | cell.loadContent()
40 |
41 | return cell
42 | }
43 |
44 | func selectedEventWithIndexPath(_ indexPath : IndexPath) {
45 |
46 | let cell = self.cellForItem(at: indexPath) as! CustomCollectionViewCell
47 |
48 | // Make sure the cell is kind of CustomCell.
49 | guard cell.isKind(of: CustomCollectionViewCell.classForCoder()) == true else {
50 |
51 | return
52 | }
53 |
54 | cell.selectedEvent()
55 | }
56 | }
57 |
58 | // MARK: protocol CustomCellDelegate
59 |
60 | protocol CustomCollectionViewCellDelegate : class {
61 |
62 | /**
63 | CustomCell's event.
64 |
65 | - parameter cell: CustomCollectionViewCell type class.
66 | - parameter event: Event data.
67 | */
68 | func customCollectionViewCell(_ cell: CustomCollectionViewCell?, event: Any?)
69 | }
70 |
71 | class CustomCollectionViewCell: UICollectionViewCell {
72 |
73 | weak var delegate : CustomCollectionViewCellDelegate?
74 | weak var dataAdapter : CellDataAdapter?
75 | weak var data : AnyObject?
76 | var indexPath : IndexPath?
77 | weak var collectionView : UICollectionView?
78 | weak var controller : UIViewController?
79 | var display : Bool?
80 |
81 | override init(frame: CGRect) {
82 |
83 | super.init(frame: frame)
84 | setupCell()
85 | buildSubview()
86 | }
87 |
88 | required init?(coder aDecoder: NSCoder) {
89 |
90 | fatalError("init(coder:) has not been implemented")
91 | }
92 |
93 | /**
94 | Setup cell, override by subclass.
95 | */
96 | func setupCell() {}
97 |
98 | /**
99 | Build subview, override by subclass.
100 | */
101 | func buildSubview() {}
102 |
103 | /**
104 | Load content, override by subclass.
105 | */
106 | func loadContent() {}
107 |
108 | /**
109 | Selected event, you should use this method in 'tableView:didSelectRowAtIndexPath:' to make it effective.
110 | */
111 | func selectedEvent() {}
112 |
113 | /**
114 | Register cell to tableView with cell reuse identifier.
115 |
116 | - parameter collectionView: UICollectionView.
117 | - parameter cellReuseIdentifier: Cell reuse identifier.
118 | */
119 | class func RegisterTo(_ collectionView: UICollectionView, cellReuseIdentifier: String? = nil) {
120 |
121 | collectionView.register(self.classForCoder(),
122 | forCellWithReuseIdentifier: cellReuseIdentifier ?? "\(self.classForCoder())")
123 | }
124 |
125 | /**
126 | Create the CustomCell type data adapter.
127 |
128 | - parameter reuseIdentifier: The reuseIdentifier.
129 | - parameter data: The data.
130 | - parameter type: The cell's type.
131 |
132 | - returns: The cellDataAdapter.
133 | */
134 | class func Adapter(_ reuseIdentifier: String? = nil, data: AnyObject? = nil, type: Int? = nil) -> CellDataAdapter {
135 |
136 | return CellDataAdapter.init(cellReuseIdentifier: reuseIdentifier ?? "\(self.classForCoder())",
137 | data: data,
138 | cellHeight: 0, cellType: type)
139 | }
140 | }
141 |
--------------------------------------------------------------------------------
/Swift-Animations/CustomHeaderFooterView.swift:
--------------------------------------------------------------------------------
1 | //
2 | // CustomHeaderFooterView.swift
3 | // Swift-Animations
4 | //
5 | // Created by YouXianMing on 16/8/9.
6 | // Copyright © 2016年 YouXianMing. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | // MARK: protocol CustomCellDelegate
12 |
13 | protocol CustomHeaderFooterViewDelegate : class {
14 |
15 | /**
16 | CustomCell's event.
17 |
18 | - parameter cell: CustomCell type class.
19 | - parameter event: Event data.
20 | */
21 | func customHeaderFooterView(_ headerFooterView: CustomHeaderFooterView?, event: AnyObject?)
22 | }
23 |
24 | class CustomHeaderFooterView: UITableViewHeaderFooterView {
25 |
26 | weak var delegate : CustomHeaderFooterViewDelegate?
27 | weak var data : AnyObject?
28 | weak var tableView : UITableView?
29 | weak var controller : UIViewController?
30 | var section : Int?
31 |
32 | override init(reuseIdentifier: String?) {
33 |
34 | super.init(reuseIdentifier: reuseIdentifier)
35 | setupHeaderFooterView()
36 | buildSubview()
37 | }
38 |
39 | required init?(coder aDecoder: NSCoder) {
40 |
41 | fatalError("init(coder:) has not been implemented")
42 | }
43 |
44 | /**
45 | Setup headerFooterView, override by subclass.
46 | */
47 | func setupHeaderFooterView() {}
48 |
49 | /**
50 | Build subview, override by subclass.
51 | */
52 | func buildSubview() {}
53 |
54 | /**
55 | Load content, override by subclass.
56 | */
57 | func loadContent() {}
58 |
59 | /**
60 | Calculate the cell's height from data, override by subclass.
61 |
62 | - parameter data: Data.
63 |
64 | - returns: Cell's height.
65 | */
66 | class func HeightWithData(_ data : AnyObject? = nil) -> CGFloat { return 0}
67 |
68 | /**
69 | Set HeaderFooterView backgroundColor.
70 |
71 | - parameter color: Color.
72 | */
73 | func setHeaderFooterViewBackgroundColor(_ color : UIColor) {
74 |
75 | self.contentView.backgroundColor = color
76 | }
77 |
78 | /**
79 | Register headerFooterView to tableView with reuse identifier.
80 |
81 | - parameter tableView: UITableView.
82 | - parameter cellReuseIdentifier: HeaderFooterView reuse identifier.
83 | */
84 | class func RegisterTo(_ tableView: UITableView, reuseIdentifier: String? = nil) {
85 |
86 | tableView.register(self.classForCoder(), forHeaderFooterViewReuseIdentifier: (reuseIdentifier != nil) ? reuseIdentifier! : String(describing: self.classForCoder()))
87 | }
88 | }
89 |
--------------------------------------------------------------------------------
/Swift-Animations/DefaultNotificationCenter.swift:
--------------------------------------------------------------------------------
1 | //
2 | // DefaultNotificationCenter.swift
3 | // Swift-Animations
4 | //
5 | // Created by YouXianMing on 16/8/19.
6 | // Copyright © 2016年 YouXianMing. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | // MARK: protocol DefaultNotificationCenterDelegate
12 |
13 | protocol DefaultNotificationCenterDelegate : class {
14 |
15 | /**
16 | DefaultNotificationCenter's event.
17 |
18 | - parameter notificationName: Event name.
19 | - parameter object: Event object, maybe nil.
20 | */
21 | func defaultNotificationCenter(_ notificationName : String, object : AnyObject?)
22 | }
23 |
24 | // MARK: protocol DefaultNotificationCenter
25 |
26 | class DefaultNotificationCenter: NSObject {
27 |
28 | // MARK: Properties & funcs.
29 |
30 | /// DefaultNotificationCenter's delegate.
31 | weak var delegate : DefaultNotificationCenterDelegate?
32 |
33 | /**
34 | Post message to specified notification name.
35 |
36 | - parameter name: Notification name.
37 | - parameter object: Data.
38 | */
39 | class func PostMessageTo(_ name : String, object : AnyObject? = nil) {
40 |
41 | NotificationCenter.default.post(name: Notification.Name(rawValue: name), object: object)
42 | }
43 |
44 | convenience init(delegate: DefaultNotificationCenterDelegate, notificationNames : [String]? = nil) {
45 |
46 | self.init()
47 | self.delegate = delegate
48 |
49 | if notificationNames != nil {
50 |
51 | for name in notificationNames! {
52 |
53 | self.addNotificationName(name)
54 | }
55 | }
56 | }
57 |
58 | /**
59 | Add notification name.
60 |
61 | - parameter name: Notification name.
62 | */
63 | func addNotificationName(_ name : String) {
64 |
65 | var haveTheSameName = false
66 |
67 | // Check have the same name or not.
68 | for model in notificationModels {
69 |
70 | if model.name == name {
71 |
72 | haveTheSameName = true
73 | break
74 | }
75 | }
76 |
77 | // Add notification.
78 | if haveTheSameName == false {
79 |
80 | let model = DefaultNotificationCenterModel()
81 | model.name = name
82 | notificationModels.append(model)
83 |
84 | NotificationCenter.default.addObserver(self, selector: #selector(DefaultNotificationCenter.notificationEvent), name: NSNotification.Name(rawValue: model.name), object: nil)
85 | }
86 | }
87 |
88 | /**
89 | Delete notification name.
90 |
91 | - parameter name: Notification name.
92 | */
93 | func deleteNotificationName(_ name : String) {
94 |
95 | var haveTheSameName = false
96 | var index : Int = 0
97 | var model : DefaultNotificationCenterModel!
98 |
99 | // Check have the same name or not.
100 | for tmpModel in notificationModels {
101 |
102 | if tmpModel.name == name {
103 |
104 | haveTheSameName = true
105 | model = tmpModel
106 | break
107 | }
108 |
109 | index = index + 1
110 | }
111 |
112 | // Remove notification.
113 | if haveTheSameName == true {
114 |
115 | NotificationCenter.default.removeObserver(self, name: Notification.Name(rawValue: model.name), object: nil)
116 | notificationModels.remove(at: index)
117 | }
118 | }
119 |
120 | /**
121 | Remove all notifications.
122 | */
123 | func removeAllNotifications() {
124 |
125 | for model in notificationModels {
126 |
127 | NotificationCenter.default.removeObserver(self, name: Notification.Name(rawValue: model.name), object: nil)
128 | }
129 | }
130 |
131 | /**
132 | Get all the notification names.
133 |
134 | - returns: Notification names's array.
135 | */
136 | func notificationNames() -> [String] {
137 |
138 | var names = [String]()
139 |
140 | for model in notificationModels {
141 |
142 | names.append(model.name)
143 | }
144 |
145 | return names
146 | }
147 |
148 | /**
149 | Notification's event.
150 |
151 | - parameter obj: The NSNotification object.
152 | */
153 | @objc func notificationEvent(_ obj : AnyObject?) {
154 |
155 | let notification = obj as! Notification
156 | delegate?.defaultNotificationCenter(notification.name.rawValue, object: notification.object as AnyObject?)
157 | }
158 |
159 | // MARK: Private properties & func.
160 |
161 | /// Store the Notification's infomation.
162 | fileprivate var notificationModels : [DefaultNotificationCenterModel] = [DefaultNotificationCenterModel]()
163 |
164 | deinit {
165 |
166 | removeAllNotifications()
167 | }
168 | }
169 |
170 | // MARK: private DefaultNotificationCenterModel
171 |
172 | private class DefaultNotificationCenterModel : NSObject {
173 |
174 | var name : String!
175 | }
176 |
177 |
178 |
--------------------------------------------------------------------------------
/Swift-Animations/EasingValue.swift:
--------------------------------------------------------------------------------
1 | //
2 | // EasingValue.swift
3 | // Swift-EasingAnimation
4 | //
5 | // Created by YouXianMing on 15/10/21.
6 | //
7 | // https://github.com/YouXianMing
8 | // http://home.cnblogs.com/u/YouXianMing/
9 | //
10 |
11 | import UIKit
12 |
13 | class EasingValue: NSObject {
14 |
15 | // MARK: var
16 |
17 | /// 动画函数
18 | var easing : EasingFunction!
19 |
20 | /// 关键帧点数
21 | var frameCount : size_t!
22 |
23 | // MARK: init
24 | override init() {
25 |
26 | super.init()
27 |
28 | easing = EasingFunction.sineEaseIn
29 | frameCount = 60
30 | }
31 |
32 | init(withFunction : EasingFunction, frameCount : size_t) {
33 |
34 | super.init()
35 |
36 | self.easing = withFunction
37 | self.frameCount = frameCount
38 | }
39 |
40 | // MARK: func
41 |
42 | /**
43 | 计算关键帧
44 |
45 | - parameter fromValue: 起始值
46 | - parameter toValue: 结束值
47 |
48 | - returns: 关键帧值数组
49 | */
50 | func frameValueWith(fromValue : Double, toValue : Double) -> [AnyObject] {
51 |
52 | let values = NSMutableArray(capacity: frameCount)
53 |
54 | var t : Double = 0.0
55 | let dt : Double = 1.0 / (Double(frameCount) - 1)
56 |
57 | for _ in 0 ..< frameCount {
58 |
59 | let value = fromValue + easing.function(t) * (toValue - fromValue)
60 | values.add(value)
61 |
62 | t += dt
63 | }
64 |
65 | return values as [AnyObject]
66 | }
67 |
68 | /**
69 | 计算关键帧点
70 |
71 | - parameter fromPoint: 起始点
72 | - parameter toPoint: 结束点
73 |
74 | - returns: 关键帧点数组
75 | */
76 | func pointValueWith(fromPoint : CGPoint, toPoint : CGPoint) -> [AnyObject] {
77 |
78 | let values = NSMutableArray(capacity: frameCount)
79 |
80 | var t : Double = 0.0
81 | let dt : Double = 1.0 / (Double(frameCount) - 1)
82 |
83 | for _ in 0 ..< frameCount {
84 |
85 | let x : Double = Double(fromPoint.x) + easing.function(t) * (Double(toPoint.x) - Double(fromPoint.x))
86 | let y : Double = Double(fromPoint.y) + easing.function(t) * (Double(toPoint.y) - Double(fromPoint.y))
87 | let point : CGPoint = CGPoint(x : x, y : y)
88 | values.add(NSValue(cgPoint: point))
89 |
90 | t += dt
91 | }
92 |
93 | return values as [AnyObject]
94 | }
95 |
96 | /**
97 | 计算关键帧尺寸
98 |
99 | - parameter fromSize: 起始尺寸
100 | - parameter toSize: 结束尺寸
101 |
102 | - returns: 关键帧尺寸数组
103 | */
104 | func sizeValueWith(fromSize : CGSize, toSize : CGSize) -> [AnyObject] {
105 |
106 | let values = NSMutableArray(capacity: frameCount)
107 |
108 | var t : Double = 0.0
109 | let dt : Double = 1.0 / (Double(frameCount) - 1)
110 |
111 | for _ in 0 ..< frameCount {
112 |
113 | let width : Double = Double(fromSize.width) + easing.function(t) * (Double(toSize.width) - Double(fromSize.width))
114 | let height : Double = Double(fromSize.height) + easing.function(t) * (Double(toSize.height) - Double(fromSize.height))
115 | let size : CGSize = CGSize(width: width, height: height)
116 | values.add(NSValue(cgSize : size))
117 |
118 | t += dt
119 | }
120 |
121 | return values as [AnyObject]
122 | }
123 | }
124 |
--------------------------------------------------------------------------------
/Swift-Animations/FontCell.swift:
--------------------------------------------------------------------------------
1 | //
2 | // FontCell.swift
3 | // Swift-Animations
4 | //
5 | // Created by YouXianMing on 2017/9/15.
6 | // Copyright © 2017年 YouXianMing. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | class FontCell: CustomCell {
12 |
13 | fileprivate var label : UILabel!
14 |
15 | override func buildSubview() {
16 |
17 | label = UILabel.init(frame: CGRect.zero)
18 | self.addSubview(label)
19 | }
20 |
21 | override func loadContent() {
22 |
23 | let model = data as! FontModel
24 |
25 | label.text = model.fontName
26 | label.font = UIFont.init(name: model.fontName!, size: 16)
27 | label.sizeToFit()
28 |
29 | label.x = 15
30 | label.centerY = FontCell.HeightWithData() / 2
31 | }
32 |
33 | override class func HeightWithData(_ data : AnyObject? = nil) -> CGFloat {
34 |
35 | return 50
36 | }
37 |
38 | override func selectedEvent() {
39 |
40 | delegate?.customCell(self, event: data)
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/Swift-Animations/FontFamilyHeaderView.swift:
--------------------------------------------------------------------------------
1 | //
2 | // FontFamilyHeaderView.swift
3 | // Swift-Animations
4 | //
5 | // Created by YouXianMing on 2017/9/15.
6 | // Copyright © 2017年 YouXianMing. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | class FontFamilyHeaderView: CustomHeaderFooterView {
12 |
13 | fileprivate var label : UILabel!
14 |
15 | override func setupHeaderFooterView() {
16 |
17 | setHeaderFooterViewBackgroundColor(UIColor.white)
18 | }
19 |
20 | override func buildSubview() {
21 |
22 | self.addSubview(BackgroundLineView(frame : CGRect.init(x: 0, y: 0, width: Screen.Width, height: FontFamilyHeaderView.HeightWithData()),
23 | lineWidth : 4,
24 | lineGap : 4,
25 | lineColor : UIColor.black.alpha(0.015),
26 | rotate : CGFloat(Double.pi / 4)))
27 |
28 | self.addSubview(UIView.CreateLine(CGRect.init(x: 0, y: 0, width: Screen.Width, height: 0.5),
29 | lineColor: UIColor.black.alpha(0.05)))
30 | self.addSubview(UIView.CreateLine(CGRect.init(x: 0, y: FontFamilyHeaderView.HeightWithData() - 0.5, width: Screen.Width, height: 0.5),
31 | lineColor: UIColor.black.alpha(0.05)))
32 |
33 | label = UILabel.init(frame: CGRect.zero)
34 | self.addSubview(label)
35 |
36 | let button = UIButton.init(frame: CGRect.init(x: 0, y: 0, width: Screen.Width, height: FontFamilyHeaderView.HeightWithData()))
37 | button.addTarget(self, action: #selector(FontFamilyHeaderView.buttonEvent), for: .touchUpInside)
38 | self.addSubview(button)
39 |
40 | let redView = UIView.init(frame: CGRect.init(x: 0, y: 0, width: 2, height: 17))
41 | redView.backgroundColor = UIColor.red
42 | redView.centerY = FontFamilyHeaderView.HeightWithData() / 2
43 | self.addSubview(redView)
44 | }
45 |
46 | override func loadContent() {
47 |
48 | let model = data as! FontFamilyModel
49 |
50 | label.text = model.familyName
51 | label.font = UIFont.init(name: model.familyName!, size: 16)
52 | label.sizeToFit()
53 |
54 | label.x = 15
55 | label.centerY = FontFamilyHeaderView.HeightWithData() / 2
56 | }
57 |
58 | override class func HeightWithData(_ data : AnyObject? = nil) -> CGFloat {
59 |
60 | return 50
61 | }
62 |
63 | @objc private func buttonEvent() {
64 |
65 | delegate?.customHeaderFooterView(self, event: data)
66 | }
67 | }
68 |
--------------------------------------------------------------------------------
/Swift-Animations/FontFamilyModel.swift:
--------------------------------------------------------------------------------
1 | //
2 | // FontFamilyModel.swift
3 | // Swift-Animations
4 | //
5 | // Created by YouXianMing on 2017/9/15.
6 | // Copyright © 2017年 YouXianMing. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | class FontFamilyModel: NSObject {
12 |
13 | var familyName : String!
14 | var fonts : [FontModel]
15 |
16 | private override init() {
17 |
18 | self.fonts = []
19 | super.init()
20 | }
21 |
22 | convenience init(familyName : String) {
23 |
24 | self.init()
25 | self.familyName = familyName
26 | }
27 | }
28 |
29 | class FontModel: NSObject {
30 |
31 | var fontName : String?
32 |
33 | private override init() {
34 |
35 | super.init()
36 | }
37 |
38 | convenience init(fontName : String) {
39 |
40 | self.init()
41 | self.fontName = fontName
42 | }
43 | }
44 |
--------------------------------------------------------------------------------
/Swift-Animations/FullTitleVisualEffectViewController.swift:
--------------------------------------------------------------------------------
1 | //
2 | // FullTitleVisualEffectViewController.swift
3 | // Swift-Animations
4 | //
5 | // Created by YouXianMing on 16/8/18.
6 | // Copyright © 2016年 YouXianMing. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | class FullTitleVisualEffectViewController: BaseCustomViewController {
12 |
13 | fileprivate var effectView : UIVisualEffectView!
14 | fileprivate var vibrancyEffectView : UIVisualEffectView!
15 |
16 | override func setupSubViews() {
17 |
18 | effectView = UIVisualEffectView(effect: UIBlurEffect(style: .light))
19 | effectView.isUserInteractionEnabled = true
20 | effectView.frame = (titleView?.bounds)!
21 | titleView?.addSubview(effectView)
22 |
23 | vibrancyEffectView = UIVisualEffectView(effect: UIVibrancyEffect(blurEffect: effectView.effect as! UIBlurEffect))
24 | vibrancyEffectView.frame = effectView.bounds
25 | effectView.contentView.addSubview(vibrancyEffectView)
26 |
27 | let headlineLabel = UILabel.init(frame: CGRect.init(x: 0, y: 0, width: Screen.Width, height: 64))
28 | headlineLabel.font = UIFont.HeitiSC(20)
29 | headlineLabel.textAlignment = .center
30 | headlineLabel.textColor = UIColor(red: 0.329, green: 0.329, blue: 0.329, alpha: 1)
31 | headlineLabel.text = title
32 | headlineLabel.bottom = effectView.height
33 |
34 | let backButton = UIButton(frame: CGRect(x: 0, y: 0, width: 100, height: 64))
35 | backButton.center = CGPoint(x: 20, y: headlineLabel.centerY)
36 | backButton.setImage(UIImage(named: "backIconTypeTwo"), for: .normal)
37 | backButton.setImage(UIImage(named: "backIconTypeTwo_pre"), for: .highlighted)
38 | backButton.addTarget(self, action: #selector(FullTitleVisualEffectViewController.popSelf), for: .touchUpInside)
39 |
40 | vibrancyEffectView.contentView.addSubview(backButton)
41 | vibrancyEffectView.contentView.addSubview(headlineLabel)
42 | }
43 |
44 | override func makeViewsConfig(viewsConfig: [String : ControllerBaseViewConfig]) {
45 |
46 | let contentViewConfig = viewsConfig[contentViewId];
47 | contentViewConfig?.frame = CGRect(x: 0, y: 0, width: Screen.Width, height: Screen.Height);
48 |
49 | /// iPhoneX
50 | if Screen.CurrentScreen == Screen._375x812 {
51 |
52 | let titleViewConfig = viewsConfig[titleViewId]
53 | titleViewConfig?.frame = CGRect.init(x: 0, y: 0, width: Screen.Width, height: 64 + additionaliPhoneXTopSafeHeight)
54 | }
55 | }
56 |
57 | @objc func popSelf() {
58 |
59 | self.popViewControllerAnimated(true)
60 | }
61 | }
62 |
--------------------------------------------------------------------------------
/Swift-Animations/GCDGroup.swift:
--------------------------------------------------------------------------------
1 | //
2 | // GCDGroup.swift
3 | // Swift-GCD
4 | //
5 | // Created by YouXianMing on 2017/9/19.
6 | // Copyright © 2017年 TechCode. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | class GCDGroup {
12 |
13 | public let dispatchGroup : DispatchGroup
14 |
15 | init() {
16 |
17 | self.dispatchGroup = DispatchGroup()
18 | }
19 |
20 | /// 在指定的queue里面获取消息
21 | ///
22 | /// - Parameters:
23 | /// - queue: 指定的queue
24 | /// - execute: 执行的block
25 | func notifyIn(_ queue : GCDQueue, execute: @escaping () -> Void) {
26 |
27 | self.dispatchGroup.notify(queue: queue.dispatchQueue, execute: execute)
28 | }
29 |
30 | /// 进入group
31 | func enter() {
32 |
33 | self.dispatchGroup.enter()
34 | }
35 |
36 | /// 从group出来
37 | func leave() {
38 |
39 | self.dispatchGroup.leave()
40 | }
41 |
42 | /// [阻塞操作] 无限等待
43 | func wait() {
44 |
45 | self.dispatchGroup.wait()
46 | }
47 |
48 | /// [阻塞操作] 等待指定的时间
49 | ///
50 | /// - Parameter seconds: 等待的时间,最多精确到1ms
51 | /// - Returns: DispatchTimeoutResult对象
52 | func waitForSeconds(seconds : Float) -> DispatchTimeoutResult {
53 |
54 | return self.dispatchGroup.wait(timeout: .now() + .milliseconds(Int(seconds * 1000)))
55 | }
56 | }
57 |
--------------------------------------------------------------------------------
/Swift-Animations/GCDQueue.swift:
--------------------------------------------------------------------------------
1 | //
2 | // GCDQueue.swift
3 | // Swift-GCD
4 | //
5 | // Created by YouXianMing on 2017/9/19.
6 | // Copyright © 2017年 TechCode. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | class GCDQueue {
12 |
13 | public let dispatchQueue : DispatchQueue
14 |
15 | init(dispatchQueue : DispatchQueue) {
16 |
17 | self.dispatchQueue = dispatchQueue
18 | }
19 |
20 | // MARK: globalQueue & mainQueue
21 |
22 | /// 获取主线程
23 | public class var Main : GCDQueue {
24 |
25 | return GCDQueue.init(dispatchQueue: DispatchQueue.main)
26 | }
27 |
28 | /// 获取子线程
29 | ///
30 | /// - Parameter priority: 优先级
31 | /// - Returns: 子线程
32 | public class func Global(_ priority : GCDQueuePriority = .DefaultPriority) -> GCDQueue {
33 |
34 | return GCDQueue.init(dispatchQueue: DispatchQueue.global(qos: priority.getDispatchQoSClass()))
35 | }
36 |
37 | // MARK: concurrentQueue & serialQueue
38 |
39 | /// 获取并发线程
40 | ///
41 | /// - Parameters:
42 | /// - label: 线程标签
43 | /// - priority: 优先级
44 | /// - Returns: 并发线程
45 | public class func Concurrent(_ label : String = "", _ priority : GCDQueuePriority = .DefaultPriority) -> GCDQueue {
46 |
47 | return GCDQueue.init(dispatchQueue: DispatchQueue(label: label, qos: priority.getDispatchQoS(), attributes: .concurrent))
48 | }
49 |
50 | /// 获取串行线程
51 | ///
52 | /// - Parameters:
53 | /// - label: 线程标签
54 | /// - priority: 优先级
55 | /// - Returns: 串行线程
56 | public class func Serial(_ label : String = "", _ priority : GCDQueuePriority = .DefaultPriority) -> GCDQueue {
57 |
58 | return GCDQueue.init(dispatchQueue: DispatchQueue(label: label, qos: priority.getDispatchQoS()))
59 | }
60 |
61 | // MARK: Excute
62 |
63 | /// 异步执行
64 | ///
65 | /// - Parameter excute: 执行的block
66 | public func excute(_ excute : @escaping ()-> Void) {
67 |
68 | dispatchQueue.async(execute: excute)
69 | }
70 |
71 | /// 延时异步执行
72 | ///
73 | /// - Parameters:
74 | /// - seconds: 延时秒数,最多精确到1ms
75 | /// - excute: 执行的block
76 | public func excuteAfterDelay(_ seconds : Float, _ excute : @escaping ()-> Void) {
77 |
78 | dispatchQueue.asyncAfter(deadline: .now() + .milliseconds(Int(seconds * 1000)), execute: excute)
79 | }
80 |
81 | /// 同步执行
82 | ///
83 | /// - Parameter excute: 执行的block
84 | public func excuteAndWaitsUntilTheBlockCompletes(_ excute : @escaping ()-> Void) {
85 |
86 | dispatchQueue.sync(execute: excute)
87 | }
88 |
89 | /// 在group中执行
90 | ///
91 | /// - Parameters:
92 | /// - group: GCDGroup对象
93 | /// - excute: 执行的block
94 | public func excuteInGroup(_ group : GCDGroup, _ excute : @escaping ()-> Void) {
95 |
96 | dispatchQueue.async(group: group.dispatchGroup, execute: excute)
97 | }
98 |
99 | // MARK: Class method for excute
100 |
101 | /// 在主线程执行
102 | ///
103 | /// - Parameter excute: 执行的block
104 | class func ExcuteInMain(_ excute : @escaping ()-> Void) {
105 |
106 | GCDQueue.Main.excute(excute)
107 | }
108 |
109 | /// 在主线程延时执行
110 | ///
111 | /// - Parameters:
112 | /// - seconds: 延时秒数,最多精确到1ms
113 | /// - excute: 执行的block
114 | class func ExcuteInMainAfterDelay(_ seconds : Float, _ excute : @escaping ()-> Void) {
115 |
116 | GCDQueue.Main.excuteAfterDelay(seconds, excute)
117 | }
118 |
119 | /// 在子线程执行
120 | ///
121 | /// - Parameters:
122 | /// - priority: 优先级
123 | /// - excute: 执行的block
124 | class func ExcuteInGlobal(_ priority : GCDQueuePriority = .DefaultPriority, _ excute : @escaping ()-> Void) {
125 |
126 | GCDQueue.Global(priority).excute(excute)
127 | }
128 |
129 | /// 在子线程延时执行
130 | ///
131 | /// - Parameters:
132 | /// - seconds: 延时秒数,最多精确到1ms
133 | /// - excute: 执行的block
134 | class func ExcuteInGlobalAfterDelay(_ seconds : Float, _ excute : @escaping ()-> Void) {
135 |
136 | GCDQueue.Global().excuteAfterDelay(seconds, excute)
137 | }
138 | }
139 |
--------------------------------------------------------------------------------
/Swift-Animations/GCDQueuePriority.swift:
--------------------------------------------------------------------------------
1 | //
2 | // GCDQueuePriority.swift
3 | // Swift-GCD
4 | //
5 | // Created by YouXianMing on 2017/9/20.
6 | // Copyright © 2017年 TechCode. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | enum GCDQueuePriority {
12 |
13 | case BackgroundPriority // DISPATCH_QUEUE_PRIORITY_BACKGROUND
14 | case LowPriority // DISPATCH_QUEUE_PRIORITY_LOW
15 | case DefaultPriority // DISPATCH_QUEUE_PRIORITY_DEFAULT
16 | case HighPriority // DISPATCH_QUEUE_PRIORITY_HIGH
17 |
18 | case userInteractive
19 | case unspecified
20 |
21 | func getDispatchQoSClass() -> DispatchQoS.QoSClass {
22 |
23 | var qos: DispatchQoS.QoSClass
24 |
25 | switch self {
26 |
27 | case GCDQueuePriority.BackgroundPriority:
28 | qos = .background
29 | break
30 |
31 | case GCDQueuePriority.LowPriority:
32 | qos = .utility
33 | break
34 |
35 | case GCDQueuePriority.DefaultPriority:
36 | qos = .default
37 | break
38 |
39 | case GCDQueuePriority.HighPriority:
40 | qos = .userInitiated
41 | break
42 |
43 | case GCDQueuePriority.userInteractive:
44 | qos = .userInteractive
45 | break
46 |
47 | case GCDQueuePriority.unspecified:
48 | qos = .unspecified
49 | break
50 | }
51 |
52 | return qos
53 | }
54 |
55 | func getDispatchQoS() -> DispatchQoS {
56 |
57 | var qos: DispatchQoS
58 |
59 | switch self {
60 |
61 | case GCDQueuePriority.BackgroundPriority:
62 | qos = .background
63 | break
64 |
65 | case GCDQueuePriority.LowPriority:
66 | qos = .utility
67 | break
68 |
69 | case GCDQueuePriority.DefaultPriority:
70 | qos = .default
71 | break
72 |
73 | case GCDQueuePriority.HighPriority:
74 | qos = .userInitiated
75 | break
76 |
77 | case GCDQueuePriority.userInteractive:
78 | qos = .userInteractive
79 | break
80 |
81 | case GCDQueuePriority.unspecified:
82 | qos = .unspecified
83 | break
84 | }
85 |
86 | return qos
87 | }
88 | }
89 |
--------------------------------------------------------------------------------
/Swift-Animations/GCDSemaphore.swift:
--------------------------------------------------------------------------------
1 | //
2 | // GCDSemaphore.swift
3 | // Swift-GCD
4 | //
5 | // Created by YouXianMing on 2017/9/19.
6 | // Copyright © 2017年 TechCode. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | class GCDSemaphore {
12 |
13 | public let dispatchSemaphore : DispatchSemaphore
14 |
15 | init(initialSignal : Int = 0) {
16 |
17 | self.dispatchSemaphore = DispatchSemaphore(value: initialSignal)
18 | }
19 |
20 | // MARK: Singal
21 |
22 | /// 发信号
23 | func signal() {
24 |
25 | self.dispatchSemaphore.signal()
26 | }
27 |
28 | // MARK: Wait
29 |
30 | /// [阻塞操作] 无限等待
31 | func wait() {
32 |
33 | self.dispatchSemaphore.wait()
34 | }
35 |
36 | /// [阻塞操作] 等待指定的时间
37 | ///
38 | /// - Parameter seconds: 等待的时间,最多精确到1ms
39 | /// - Returns: DispatchTimeoutResult对象
40 | func waitForSeconds(_ seconds : Float) -> DispatchTimeoutResult {
41 |
42 | return self.dispatchSemaphore.wait(timeout: DispatchTime.now() + .milliseconds(Int(seconds * 1000)))
43 | }
44 | }
45 |
--------------------------------------------------------------------------------
/Swift-Animations/GCDTimer.swift:
--------------------------------------------------------------------------------
1 | //
2 | // GCDTimer.swift
3 | // Swift-GCD
4 | //
5 | // Created by YouXianMing on 2017/9/20.
6 | // Copyright © 2017年 TechCode. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | class GCDTimer {
12 |
13 | public let dispatchSourceTimer : DispatchSourceTimer
14 |
15 | init(in : GCDQueue, delay : Float = 0, interval : Float) {
16 |
17 | dispatchSourceTimer = DispatchSource.makeTimerSource(flags: [], queue: `in`.dispatchQueue)
18 | dispatchSourceTimer.schedule(deadline: .now() + .milliseconds(Int(delay * 1000)), repeating: .milliseconds(Int(interval * 1000)))
19 | }
20 |
21 | /// 设定定时器任务的回调函数
22 | ///
23 | /// - Parameter eventHandler: 回调函数
24 | func setTimerEventHandler(eventHandler: @escaping (GCDTimer)-> Void) {
25 |
26 | dispatchSourceTimer.setEventHandler {
27 |
28 | eventHandler(self)
29 | }
30 | }
31 |
32 | /// 设定定时器销毁时候的回调函数
33 | ///
34 | /// - Parameter eventHandler: 回调函数
35 | func setDestroyEventHandler(eventHandler: @escaping ()-> Void) {
36 |
37 | dispatchSourceTimer.setCancelHandler {
38 |
39 | eventHandler()
40 | }
41 | }
42 |
43 | /// 挂起
44 | func suspend() {
45 |
46 | dispatchSourceTimer.suspend()
47 | }
48 |
49 | /// 开始定时
50 | func start() {
51 |
52 | dispatchSourceTimer.resume()
53 | }
54 |
55 | /// 定时器销毁(执行了此方法后,start就会变得无效)
56 | func destroy() {
57 |
58 | dispatchSourceTimer.cancel()
59 | }
60 | }
61 |
--------------------------------------------------------------------------------
/Swift-Animations/HeaderViewTapAnimationController.swift:
--------------------------------------------------------------------------------
1 | //
2 | // HeaderViewTapAnimationController.swift
3 | // Swift-Animations
4 | //
5 | // Created by YouXianMing on 16/8/9.
6 | // Copyright © 2016年 YouXianMing. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | class HeaderViewTapAnimationController: NormalTitleViewController, UITableViewDelegate, UITableViewDataSource {
12 |
13 | fileprivate var classes : [ClassModel] = [ClassModel]()
14 | fileprivate var sectionFirstLoad : Bool = false
15 |
16 | fileprivate var tableView : UITableView!
17 | fileprivate weak var tmpHeadView : ClassHeaderView?
18 |
19 | override func viewDidLoad() {
20 |
21 | super.viewDidLoad()
22 |
23 | // TableView.
24 | tableView = UITableView(frame: (contentView?.bounds)!)
25 | tableView.dataSource = self
26 | tableView.delegate = self
27 | tableView.rowHeight = 60
28 | tableView.sectionHeaderHeight = 30
29 | tableView.separatorStyle = .none
30 | contentView?.addSubview(tableView!)
31 |
32 | if #available(iOS 11.0, *) {
33 |
34 | tableView.estimatedRowHeight = 0
35 | tableView.estimatedSectionHeaderHeight = 0
36 | tableView.estimatedSectionFooterHeight = 0
37 | }
38 |
39 | // Register.
40 | ClassHeaderView.RegisterTo(tableView)
41 | StudentInfoCell.RegisterTo(tableView)
42 |
43 | // Data source.
44 | let Aitna = ClassModel(className: "Aitna")
45 | Aitna.expend = false
46 | Aitna.students.append(StudentModel(name: "Y.X.M.", age: 27))
47 | Aitna.students.append(StudentModel(name: "Leif", age: 12))
48 | Aitna.students.append(StudentModel(name: "Lennon", age: 23))
49 | Aitna.students.append(StudentModel(name: "Jerome", age: 19))
50 | Aitna.students.append(StudentModel(name: "Isidore", age: 15))
51 |
52 | let Melete = ClassModel(className: "Melete")
53 | Melete.expend = false
54 | Melete.students.append(StudentModel(name: "Merle", age: 17))
55 | Melete.students.append(StudentModel(name: "Paddy", age: 31))
56 | Melete.students.append(StudentModel(name: "Perry", age: 59))
57 | Melete.students.append(StudentModel(name: "Philip", age: 23))
58 |
59 | let Aoede = ClassModel(className: "Aoede")
60 | Aoede.expend = false
61 | Aoede.students.append(StudentModel(name: "Verne", age: 12))
62 | Aoede.students.append(StudentModel(name: "Vincent", age: 89))
63 | Aoede.students.append(StudentModel(name: "Walter", age: 43))
64 | Aoede.students.append(StudentModel(name: "Zachary", age: 21))
65 |
66 | let Dione = ClassModel(className: "Dione")
67 | Dione.expend = false
68 | Dione.students.append(StudentModel(name: "Timothy", age: 72))
69 | Dione.students.append(StudentModel(name: "Roderick", age: 34))
70 | Dione.students.append(StudentModel(name: "Quentin", age: 12))
71 | Dione.students.append(StudentModel(name: "Paddy", age: 75))
72 |
73 | let Adanos = ClassModel(className: "Adanos")
74 | Adanos.expend = false
75 | Adanos.students.append(StudentModel(name: "Mortimer", age: 43))
76 | Adanos.students.append(StudentModel(name: "Michael", age: 64))
77 | Adanos.students.append(StudentModel(name: "Kevin", age: 23))
78 | Adanos.students.append(StudentModel(name: "Jeremy", age: 21))
79 |
80 | classes.append(Aitna)
81 | classes.append(Melete)
82 | classes.append(Aoede)
83 | classes.append(Dione)
84 | classes.append(Adanos)
85 |
86 | // GCDQueue delay.
87 | GCDQueue.Main.excuteAfterDelay(0.3) {
88 |
89 | self.sectionFirstLoad = true
90 | self.tableView.insertSections(IndexSet(integersIn: Range.init(NSMakeRange(0, self.classes.count))!), with: .fade)
91 |
92 | GCDQueue.Main.excuteAfterDelay(0.4, {
93 |
94 | if let headView = self.tmpHeadView {
95 |
96 | headView.buttonEvent()
97 | }
98 | })
99 | }
100 | }
101 |
102 | // MARK: UITableView's delegate & dataSource.
103 |
104 | func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
105 |
106 | let classModel = classes[section]
107 | if classModel.expend == true {
108 |
109 | return classModel.students.count
110 |
111 | } else {
112 |
113 | return 0
114 | }
115 | }
116 |
117 | func numberOfSections(in tableView: UITableView) -> Int {
118 |
119 | if sectionFirstLoad == false {
120 |
121 | return 0
122 |
123 | } else {
124 |
125 | return classes.count
126 | }
127 | }
128 |
129 | func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
130 |
131 | let classModel = classes[(indexPath as NSIndexPath).section]
132 | let customCell = tableView.dequeueReusableCell(withIdentifier: "StudentInfoCell") as! CustomCell
133 | customCell.data = classModel.students[(indexPath as NSIndexPath).row]
134 | customCell.indexPath = indexPath
135 | customCell.loadContent()
136 |
137 | return customCell
138 | }
139 |
140 | func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
141 |
142 | tableView.selectedEventWithIndexPath(indexPath)
143 | }
144 |
145 | func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
146 |
147 | let headerView = tableView.dequeueReusableHeaderFooterView(withIdentifier: "ClassHeaderView") as! ClassHeaderView
148 | headerView.section = section
149 | headerView.data = classes[section]
150 | headerView.tableView = tableView
151 | headerView.loadContent()
152 |
153 | if tmpHeadView == nil && section == 0 {
154 |
155 | tmpHeadView = headerView
156 | }
157 |
158 | return headerView
159 | }
160 | }
161 |
162 |
--------------------------------------------------------------------------------
/Swift-Animations/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | en
7 | CFBundleDisplayName
8 | Animations
9 | CFBundleExecutable
10 | $(EXECUTABLE_NAME)
11 | CFBundleIdentifier
12 | $(PRODUCT_BUNDLE_IDENTIFIER)
13 | CFBundleInfoDictionaryVersion
14 | 6.0
15 | CFBundleName
16 | $(PRODUCT_NAME)
17 | CFBundlePackageType
18 | APPL
19 | CFBundleShortVersionString
20 | 1.0
21 | CFBundleSignature
22 | ????
23 | CFBundleVersion
24 | 1
25 | LSRequiresIPhoneOS
26 |
27 | NSAppTransportSecurity
28 |
29 | NSAllowsArbitraryLoads
30 |
31 |
32 | UIRequiredDeviceCapabilities
33 |
34 | armv7
35 |
36 | UIStatusBarHidden
37 |
38 | UISupportedInterfaceOrientations
39 |
40 | UIInterfaceOrientationPortrait
41 |
42 | UIViewControllerBasedStatusBarAppearance
43 |
44 |
45 |
46 |
--------------------------------------------------------------------------------
/Swift-Animations/ListItemCell.swift:
--------------------------------------------------------------------------------
1 | //
2 | // ListItemCell.swift
3 | // Swift-Animations
4 | //
5 | // Created by YouXianMing on 16/8/6.
6 | // Copyright © 2016年 YouXianMing. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | class ListItemCell: CustomCell {
12 |
13 | // MARK: Private var.
14 |
15 | fileprivate var titlelabel : UILabel!
16 | fileprivate var subTitleLabel : UILabel!
17 |
18 | // MARK: Override CustomCell func.
19 |
20 | override func setupCell() {
21 |
22 | super.setupCell()
23 | self.accessoryType = .disclosureIndicator
24 | }
25 |
26 | override func buildSubview() {
27 |
28 | titlelabel = UILabel(frame: CGRect(x: 10, y: 8, width: 290, height: 25))
29 | titlelabel.font = UIFont.HeitiSC(16)
30 | self.addSubview(titlelabel)
31 |
32 | subTitleLabel = UILabel(frame: CGRect(x: 10, y: 35, width: 290, height: 10))
33 | subTitleLabel.font = UIFont.AvenirLight(8)
34 | subTitleLabel.textColor = UIColor.gray
35 | self.addSubview(subTitleLabel)
36 | }
37 |
38 | override func loadContent() {
39 |
40 | let item = data as! ControllerItem
41 | titlelabel.text = item.name
42 | subTitleLabel.text = NSStringFromClass(item.controllerClass!).components(separatedBy: ".").last
43 | }
44 |
45 | override func selectedEvent() {
46 |
47 | delegate?.customCell(self, event: data)
48 | }
49 |
50 | override func setHighlighted(_ highlighted: Bool, animated: Bool) {
51 |
52 | UIView.animate(withDuration: 0.35, delay: 0, options: .beginFromCurrentState, animations: {
53 |
54 | self.titlelabel.alpha = (highlighted == true ? 0.5 : 1.0)
55 | self.subTitleLabel.x = (highlighted == true ? 10 + 4 : 10)
56 |
57 | }, completion: nil)
58 | }
59 | }
60 |
--------------------------------------------------------------------------------
/Swift-Animations/LiveImageView.swift:
--------------------------------------------------------------------------------
1 | //
2 | // LiveImageView.swift
3 | // Swift-Animations
4 | //
5 | // Created by YouXianMing on 16/8/17.
6 | // Copyright © 2016年 YouXianMing. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | // MARK: Public class : LiveImageView
12 |
13 | class LiveImageView: UIImageView {
14 |
15 | // MARK: Properties.
16 |
17 | /// Animation's duration.
18 | var duration : CFTimeInterval = 0.3
19 |
20 | // MARK: Methods.
21 |
22 | /**
23 | Set image with animation or not.
24 |
25 | - parameter newVal: The new image.
26 | - parameter animated: Animated or not.
27 | */
28 | func setImage(_ newVal : UIImage, animated : Bool) {
29 |
30 | if animated == true {
31 |
32 | let animation = CABasicAnimation(keyPath: "contents")
33 | animation.fromValue = image?.cgImage
34 | animation.toValue = newVal.cgImage
35 | animation.duration = duration
36 |
37 | pLayer.contents = image?.cgImage
38 | pLayer.add(animation, forKey: nil)
39 |
40 | image = newVal
41 |
42 | } else {
43 |
44 | image = newVal
45 | }
46 | }
47 |
48 | // MARK: Private value & func.
49 |
50 | fileprivate var pLayer : CALayer!
51 |
52 | override init(frame: CGRect) {
53 |
54 | super.init(frame: frame)
55 | pLayer = layer
56 | }
57 |
58 | required init?(coder aDecoder: NSCoder) {
59 |
60 | fatalError("init(coder:) has not been implemented")
61 | }
62 | }
63 |
--------------------------------------------------------------------------------
/Swift-Animations/LiveImageViewController.swift:
--------------------------------------------------------------------------------
1 | //
2 | // LiveImageViewController.swift
3 | // Swift-Animations
4 | //
5 | // Created by YouXianMing on 16/8/17.
6 | // Copyright © 2016年 YouXianMing. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | class LiveImageViewController: NormalTitleViewController {
12 |
13 | fileprivate var timer : Timer!
14 | fileprivate var count : NSInteger = 0
15 | fileprivate var images : [UIImage] = [UIImage]()
16 | fileprivate var liveImageView : LiveImageView!
17 |
18 | override func viewDidLoad() {
19 |
20 | super.viewDidLoad()
21 |
22 | // Init images.
23 | images = [UIImage]()
24 | images.append(UIImage(named: "pic_1")!)
25 | images.append(UIImage(named: "pic_2")!)
26 | images.append(UIImage(named: "pic_3")!)
27 | images.append(UIImage(named: "pic_4")!)
28 |
29 | // Init LiveImageView.
30 | let image = images[0]
31 | liveImageView = LiveImageView(frame: CGRect(x: 0, y: 0, width: image.size.width, height: image.size.height))
32 | liveImageView.center = (contentView?.middlePoint)!
33 | liveImageView.layer.borderWidth = 3
34 | liveImageView.layer.borderColor = UIColor.black.cgColor
35 | liveImageView.duration = 0.5
36 | contentView?.addSubview(liveImageView)
37 |
38 | let currentIndex = count % images.count
39 | count = count + 1
40 | liveImageView.setImage(images[currentIndex], animated: true)
41 |
42 | // Init timer.
43 | timer = Timer.scheduledTimer(timeInterval: 1.5, target: self, selector: #selector(LiveImageViewController.timerEvent), userInfo: nil, repeats: true)
44 | }
45 |
46 | @objc func timerEvent() {
47 |
48 | let currentIndex = count % images.count
49 | count = count + 1
50 | liveImageView.setImage(images[currentIndex], animated: true)
51 |
52 | UIView.animate(withDuration: 0.5, animations: {
53 |
54 | var tmpRect = self.liveImageView.bounds
55 | tmpRect.size = (self.liveImageView.image?.size)!
56 | self.liveImageView.bounds = tmpRect
57 | self.liveImageView.center = (self.contentView?.middlePoint)!
58 | })
59 | }
60 |
61 | override func viewDidDisappear(_ animated: Bool) {
62 |
63 | super.viewDidDisappear(animated)
64 | timer.invalidate()
65 | }
66 | }
67 |
--------------------------------------------------------------------------------
/Swift-Animations/Math.swift:
--------------------------------------------------------------------------------
1 | //
2 | // Math.swift
3 | // Swift-Animations
4 | //
5 | // Created by YouXianMing on 16/8/18.
6 | // Copyright © 2016年 YouXianMing. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | class Math: NSObject {
12 |
13 | // MARK: Radian & degree.
14 |
15 | /**
16 | Convert radian to degree.
17 |
18 | - parameter radian: Radian.
19 |
20 | - returns: Degree.
21 | */
22 | class func DegreeFromRadian(_ radian : CGFloat) -> CGFloat {
23 |
24 | return ((radian) * (180.0 / CGFloat(Double.pi)));
25 | }
26 |
27 | /**
28 | Convert degree to radian.
29 |
30 | - parameter degree: Degree.
31 |
32 | - returns: Radian.
33 | */
34 | class func RadianFromDegree(_ degree : CGFloat) -> CGFloat {
35 |
36 | return ((degree) * CGFloat(Double.pi) / 180.0);
37 | }
38 |
39 | // MARK: Calculate radian.
40 |
41 | /**
42 | Radian value from math 'tan' function.
43 |
44 | - parameter sideA: Side A
45 | - parameter sideB: Side B
46 |
47 | - returns: Radian value.
48 | */
49 | class func RadianValueFromTanSideA(sideA : CGFloat, sideB : CGFloat) -> CGFloat {
50 |
51 | return atan2(sideA, sideB)
52 | }
53 |
54 | // MARK: Reset size.
55 |
56 | /**
57 | Get the new size with the fixed width.
58 |
59 | - parameter size: Old size.
60 | - parameter withFixedWidth: The fixed width.
61 |
62 | - returns: New size.
63 | */
64 | class func ResetFromSize(_ size : CGSize, withFixedWidth : CGFloat) -> CGSize {
65 |
66 | let newHeight = size.height * (withFixedWidth / size.width)
67 | return CGSize(width: withFixedWidth, height: newHeight)
68 | }
69 |
70 | /**
71 | Get the new size with the fixed height.
72 |
73 | - parameter size: Old size.
74 | - parameter withFixedHeight: The fixed width.
75 |
76 | - returns: New size.
77 | */
78 | class func ResetFromSize(_ size : CGSize, withFixedHeight : CGFloat) -> CGSize {
79 |
80 | let newWidth = size.width * (withFixedHeight / size.height)
81 | return CGSize(width: newWidth, height: withFixedHeight)
82 | }
83 |
84 | // MARK: Calculate once linear equation (Y = kX + b).
85 |
86 | var k : CGFloat!
87 | var b : CGFloat!
88 |
89 | convenience init(_ pointA : (CGFloat, CGFloat), _ pointB : (CGFloat, CGFloat)) {
90 |
91 | self.init()
92 | k = calculateSlope(x1: pointA.0, y1: pointA.1, x2: pointB.0, y2: pointB.1)
93 | b = calculateConstant(x1: pointA.0, y1: pointA.1, x2: pointB.0, y2: pointB.1)
94 | }
95 |
96 | /**
97 | Get X value when Y equal some number.
98 |
99 | - parameter yValue: Some number.
100 |
101 | - returns: X number.
102 | */
103 | func xValueWhenYEqual(_ yValue : CGFloat) -> CGFloat {
104 |
105 | if k == 0 {
106 |
107 | return 0
108 | }
109 |
110 | return (yValue - b) / k
111 | }
112 |
113 | /**
114 | Get the point value when Y equal some number.
115 |
116 | - parameter yValue: Some number.
117 |
118 | - returns: The point value.
119 | */
120 | func whenYEqual(_ yValue : CGFloat) -> (x : CGFloat, y : CGFloat) {
121 |
122 | if k == 0 {
123 |
124 | return (0, yValue)
125 | }
126 |
127 | return ((yValue - b) / k, yValue)
128 | }
129 |
130 | /**
131 | Get Y value when X equal some number.
132 |
133 | - parameter xValue: Some number.
134 |
135 | - returns: Y number.
136 | */
137 | func yValueWhenXEqual(_ xValue : CGFloat) -> CGFloat {
138 |
139 | return k * xValue + b
140 | }
141 |
142 | /**
143 | Get the point value when X equal some number.
144 |
145 | - parameter xValue: Some number.
146 |
147 | - returns: The point value.
148 | */
149 | func whenXEqual(_ xValue : CGFloat) -> (x : CGFloat, y : CGFloat) {
150 |
151 | return (xValue, k * xValue + b)
152 | }
153 |
154 | // MARK: Private func.
155 |
156 | fileprivate func calculateSlope(x1 : CGFloat, y1 : CGFloat, x2 : CGFloat, y2 : CGFloat) -> CGFloat {
157 |
158 | if x1 == x2 {
159 |
160 | return 0
161 |
162 | } else {
163 |
164 | return (y2 - y1) / (x2 - x1)
165 | }
166 | }
167 |
168 | fileprivate func calculateConstant(x1 : CGFloat, y1 : CGFloat, x2 : CGFloat, y2 : CGFloat) -> CGFloat {
169 |
170 | if x1 == x2 {
171 |
172 | return 0
173 |
174 | } else {
175 |
176 | return (y1*(x2 - x1) - x1*(y2 - y1)) / (x2 - x1)
177 | }
178 | }
179 | }
180 |
--------------------------------------------------------------------------------
/Swift-Animations/MessageView.swift:
--------------------------------------------------------------------------------
1 | //
2 | // MessageView.swift
3 | // Swift-Animations
4 | //
5 | // Created by YouXianMing on 2017/9/13.
6 | // Copyright © 2017年 YouXianMing. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | class MessageView: BaseMessageView {
12 |
13 | fileprivate var blackBackgroundView : UIView!
14 | fileprivate var blackView : UIView!
15 | fileprivate var label : UILabel!
16 |
17 | required init(frame : CGRect) {
18 |
19 | super.init(frame: CGRect.zero)
20 | }
21 |
22 | required convenience init() {
23 |
24 | self.init(frame: CGRect.zero)
25 | }
26 |
27 | required init?(coder aDecoder: NSCoder) {
28 |
29 | fatalError("init(coder:) has not been implemented")
30 | }
31 |
32 | override func setupSubViews() {
33 |
34 | blackBackgroundView = UIView.init(frame: (contentView?.bounds)!)
35 | blackBackgroundView.backgroundColor = UIColor.black
36 | blackBackgroundView.alpha = 0
37 | self.addSubview(blackBackgroundView)
38 |
39 | blackView = UIView.init()
40 | blackView.backgroundColor = UIColor.black.alpha(0.65)
41 | self.addSubview(blackView)
42 |
43 | label = UILabel.init()
44 | label.numberOfLines = 0
45 | label.font = UIFont.HeitiSC(15)
46 | label.textColor = UIColor.white
47 | label.text = self.messageObject as? String
48 | label.width = Screen.Width / 4 * 3
49 | label.sizeToFit()
50 | blackView.addSubview(label)
51 |
52 | blackView.bounds = CGRect.init(origin: CGPoint.zero, size: CGSize.init(width: label.width + 15, height: label.height + 15))
53 | label.center = blackView.middlePoint
54 | blackView.center = self.middlePoint
55 | blackView.alpha = 0
56 | blackView.scale = 1.5
57 | }
58 |
59 | override func beginShowAnimation() {
60 |
61 | beforeStartShowValueConfig()
62 | delegate?.baseMessageViewWillAppear(self)
63 | UIView.animate(withDuration: 0.6, delay: 0, usingSpringWithDamping: 0.35, initialSpringVelocity: 0.9, options: .beginFromCurrentState, animations: {
64 |
65 | self.blackView.scale = 1
66 |
67 | }) { (success) in
68 |
69 | self.delegate?.baseMessageViewDidAppear(self)
70 | }
71 |
72 | UIView.animate(withDuration: 0.3) {
73 |
74 | self.blackBackgroundView.alpha = 0.1
75 | self.blackView.alpha = 1
76 | }
77 | }
78 |
79 | override func startHideAnimated() {
80 |
81 | self.blackBackgroundView.alpha = 0
82 | blackView.alpha = 0
83 | }
84 | }
85 |
--------------------------------------------------------------------------------
/Swift-Animations/MixedColorProgressViewController.swift:
--------------------------------------------------------------------------------
1 | //
2 | // MixedColorProgressViewController.swift
3 | // Swift-Animations
4 | //
5 | // Created by YouXianMing on 16/8/21.
6 | // Copyright © 2016年 YouXianMing. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | class MixedColorProgressViewController: NormalTitleViewController {
12 |
13 | fileprivate var upView : UIView!
14 | fileprivate var upLabel : UILabel!
15 | fileprivate var downView : UIView!
16 | fileprivate var downLabel : UILabel!
17 | fileprivate var timer : Timer!
18 |
19 | override func viewDidLoad() {
20 |
21 | super.viewDidLoad()
22 |
23 | downView = UIView(frame: CGRect(x: 0, y: 0, width: 220, height: 17))
24 | downView.center = (contentView?.middlePoint)!
25 | downView.layer.cornerRadius = 2
26 | downView.backgroundColor = UIColor.white
27 | downView.layer.masksToBounds = true
28 | contentView?.addSubview(downView)
29 |
30 | downLabel = UILabel(frame: downView.bounds)
31 | downLabel.font = UIFont.HelveticaNeueThin(12.0)
32 | downLabel.text = "YouXianMing - iOS Programmer"
33 | downLabel.textColor = UIColor.red
34 | downLabel.textAlignment = .center
35 | downView.layer.borderWidth = 0.5
36 | downView.layer.borderColor = UIColor.red.cgColor
37 | downView.addSubview(downLabel)
38 |
39 | upView = UIView(frame: CGRect(x: 0, y: 0, width: 220, height: 17))
40 | upView.center = (contentView?.middlePoint)!
41 | upView.layer.cornerRadius = 2
42 | upView.backgroundColor = UIColor.red
43 | upView.layer.masksToBounds = true
44 | contentView?.addSubview(upView)
45 |
46 | upLabel = UILabel(frame: upView.bounds)
47 | upLabel.font = UIFont.HelveticaNeueThin(12.0)
48 | upLabel.text = "YouXianMing - iOS Programmer"
49 | upLabel.textColor = UIColor.white
50 | upLabel.textAlignment = .center
51 | upView.addSubview(upLabel)
52 |
53 | // Init timer.
54 | timer = Timer.scheduledTimer(timeInterval: 1.0, target: self, selector: #selector(MixedColorProgressViewController.timerEvent), userInfo: nil, repeats: true)
55 | }
56 |
57 | @objc func timerEvent() {
58 |
59 | UIView.animate(withDuration: 0.5, delay: 0, usingSpringWithDamping: 3, initialSpringVelocity: 0, options: UIView.AnimationOptions(), animations: {
60 |
61 | self.upView.width = CGFloat(arc4random() % 220)
62 |
63 | }, completion: nil)
64 | }
65 |
66 | override func viewDidDisappear(_ animated: Bool) {
67 |
68 | super.viewDidDisappear(animated)
69 | timer.invalidate()
70 | }
71 | }
72 |
--------------------------------------------------------------------------------
/Swift-Animations/MoreInfoView.swift:
--------------------------------------------------------------------------------
1 | //
2 | // MoreInfoView.swift
3 | // Swift-Animations
4 | //
5 | // Created by YouXianMing on 16/8/18.
6 | // Copyright © 2016年 YouXianMing. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | class MoreInfoView: UIView {
12 |
13 | var imageView : UIImageView!
14 |
15 | override init(frame: CGRect) {
16 |
17 | super.init(frame : frame)
18 |
19 | layer.borderWidth = 0.5
20 | layer.borderColor = UIColor.black.cgColor
21 | layer.masksToBounds = true
22 |
23 | /*
24 | * -------------- *
25 | *-50->|-view-width-|<-50-*
26 | * -------------- *
27 | */
28 | let rect = frame
29 | imageView = UIImageView(frame: CGRect(x: -50, y: 0, width: rect.size.width + 50 * 2, height: rect.size.height))
30 | imageView.contentMode = .scaleAspectFill
31 | self.addSubview(imageView)
32 | }
33 |
34 | required init?(coder aDecoder: NSCoder) {
35 |
36 | fatalError("init(coder:) has not been implemented")
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/Swift-Animations/NormalTitleViewController.swift:
--------------------------------------------------------------------------------
1 | //
2 | // NormalTitleViewController.swift
3 | // Swift-Animations
4 | //
5 | // Created by YouXianMing on 16/8/7.
6 | // Copyright © 2016年 YouXianMing. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | class NormalTitleViewController: BaseCustomViewController {
12 |
13 | override func makeViewsConfig(viewsConfig: [String : ControllerBaseViewConfig]) {
14 |
15 | /// iPhoneX
16 | if Screen.CurrentScreen == Screen._375x812 {
17 |
18 | let titleViewConfig = viewsConfig[titleViewId]
19 | titleViewConfig?.frame = CGRect.init(x: 0, y: 0, width: Screen.Width, height: 64 + additionaliPhoneXTopSafeHeight)
20 |
21 | let contentViewConfig = viewsConfig[contentViewId]
22 | contentViewConfig?.frame = CGRect.init(x: 0, y: 64 + additionaliPhoneXTopSafeHeight, width: Screen.Width, height: Screen.Height - (64 + additionaliPhoneXTopSafeHeight))
23 | }
24 | }
25 |
26 | override func setupSubViews() {
27 |
28 | // Title label.
29 | let headlinelabel = UILabel.init(frame: CGRect.init(x: 0, y: 0, width: Screen.Width, height: 64))
30 | headlinelabel.font = UIFont.HeitiSC(20)
31 | headlinelabel.textAlignment = .center
32 | headlinelabel.textColor = UIColor.gray
33 | headlinelabel.text = self.title
34 | headlinelabel.bottom = (self.titleView?.height)!
35 | self.titleView?.addSubview(headlinelabel)
36 |
37 | // Back button.
38 | let button = UIButton(frame : CGRect(x: 0, y: 0, width: 100, height: 64))
39 | button.center = CGPoint(x: 20, y: headlinelabel.centerY)
40 | button.imageView?.contentMode = .center
41 | button.setImage(UIImage(named: "backIcon"), for: UIControl.State())
42 | button.setImage(UIImage(named: "backIcon_pre"), for: .highlighted)
43 | self.titleView?.addSubview(button)
44 | button.addTarget(self, action: #selector(NormalTitleViewController.popSelf), for: .touchUpInside)
45 |
46 | // Line view.
47 | titleView?.addSubview(UIView.CreateLine(CGRect(x: 0, y: titleView!.height - 0.5, width: Screen.Width, height: 0.5), lineColor: UIColor.gray.alpha(0.2)))
48 | }
49 |
50 | @objc func popSelf() {
51 |
52 | self.popViewControllerAnimated(true)
53 | }
54 | }
55 |
--------------------------------------------------------------------------------
/Swift-Animations/NotificationEvent.swift:
--------------------------------------------------------------------------------
1 | //
2 | // NotificationEvent.swift
3 | // Swift-Animations
4 | //
5 | // Created by YouXianMing on 16/8/19.
6 | // Copyright © 2016年 YouXianMing. All rights reserved.
7 | //
8 |
9 | import Foundation
10 |
11 | enum NotificationEvent : String {
12 |
13 | case animationsListViewControllerFirstTimeLoadData = "animationsListViewControllerFirstTimeLoadData"
14 | case countDownTimeCellCountDown = "countDownTimeCellCountDown"
15 |
16 | var notificationName : String {
17 |
18 | get { return self.rawValue}
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/Swift-Animations/PageFlipEffectController.swift:
--------------------------------------------------------------------------------
1 | //
2 | // PageFlipEffectController.swift
3 | // Swift-Animations
4 | //
5 | // Created by YouXianMing on 16/8/22.
6 | // Copyright © 2016年 YouXianMing. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | class PageFlipEffectController: NormalTitleViewController {
12 |
13 | fileprivate var math : Math = Math((x : 0, degree : 0),
14 | (x : Screen.Width, degree : 180))
15 | fileprivate var layer : CALayer!
16 |
17 | override func viewDidLoad() {
18 |
19 | super.viewDidLoad()
20 |
21 | let image = UIImage(named: "pic_1")
22 | let size = Math.ResetFromSize((image?.size)!, withFixedWidth: Screen.Width / 2.0)
23 |
24 | layer = CALayer()
25 | layer.anchorPoint = CGPoint(x: 1.0, y: 0.5)
26 | layer.frame = CGRect(x: 0, y: 0, width: Screen.Width / 2, height: size.height)
27 | layer.allowsEdgeAntialiasing = true
28 | layer.position = CGPoint(x: Screen.Width / 2, y: contentView!.middleY)
29 | layer.contents = image?.cgImage
30 | layer.borderColor = UIColor.black.cgColor
31 | layer.borderWidth = 3.0
32 | layer.masksToBounds = true
33 | layer.transform = CATransform3DMakeRotation(Math.RadianFromDegree(0), 0, 1, 1)
34 | contentView?.layer.addSublayer(layer)
35 |
36 | let panGesture = UIPanGestureRecognizer(target: self, action: #selector(PageFlipEffectController.handlePan))
37 | view.addGestureRecognizer(panGesture)
38 | }
39 |
40 | @objc fileprivate func handlePan(_ sender : UIPanGestureRecognizer) {
41 |
42 | let curPoint = sender.location(in: view)
43 | let x = curPoint.x
44 |
45 | // 初始化3D变换,获取默认值
46 | var perspectiveTransform = CATransform3DIdentity
47 |
48 | // 透视
49 | perspectiveTransform.m34 = -1.0 / 2000.0
50 |
51 | // 空间旋转
52 | perspectiveTransform = CATransform3DRotate(perspectiveTransform, Math.RadianFromDegree(x * math.k), 0, 1, 0)
53 | CATransaction.setDisableActions(true)
54 | layer.transform = perspectiveTransform
55 |
56 | layer.contents = UIImage(named: x >= Screen.Width / 2.0 ? "pic_2" : "pic_1")?.cgImage
57 |
58 | if sender.state == .ended {
59 |
60 | // 初始化3D变换,获取默认值
61 | var perspectiveTransform = CATransform3DIdentity
62 |
63 | // 透视
64 | perspectiveTransform.m34 = -1.0 / 2000.0
65 |
66 | // 空间旋转
67 | perspectiveTransform = CATransform3DRotate(perspectiveTransform, Math.RadianFromDegree(x >= Screen.Width / 2.0 ? 180 : 0), 0, 1, 0)
68 |
69 | CATransaction.setDisableActions(false)
70 | layer.transform = perspectiveTransform
71 | }
72 | }
73 | }
74 |
--------------------------------------------------------------------------------
/Swift-Animations/RootNavigationViewController.swift:
--------------------------------------------------------------------------------
1 | //
2 | // RootNavigationViewController.swift
3 | // Swift-Animations
4 | //
5 | // Created by YouXianMing on 16/8/11.
6 | // Copyright © 2016年 YouXianMing. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | class RootNavigationViewController: BaseCustomNavigationController {
12 |
13 | override func viewDidLoad() {
14 |
15 | super.viewDidLoad()
16 |
17 | let lauchImageView = UIImageView(frame: self.view.bounds)
18 | lauchImageView.image = AppleSystemService.LaunchImage
19 | view.addSubview(lauchImageView)
20 |
21 | UIView.animate(withDuration: 1, delay: 1, options: UIView.AnimationOptions(), animations: {
22 |
23 | lauchImageView.scale = 1.3
24 | lauchImageView.alpha = 0
25 |
26 | }) { _ in
27 |
28 | lauchImageView.removeFromSuperview()
29 | DefaultNotificationCenter.PostMessageTo(NotificationEvent.animationsListViewControllerFirstTimeLoadData.notificationName)
30 | }
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/Swift-Animations/RotateView.swift:
--------------------------------------------------------------------------------
1 | //
2 | // RotateView.swift
3 | // Swift-Animations
4 | //
5 | // Created by YouXianMing on 16/8/14.
6 | // Copyright © 2016年 YouXianMing. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | // MARK: Public class : RotateView
12 |
13 | class RotateView: UIView {
14 |
15 | // MARK: Properties.
16 |
17 | var rotateDuration : TimeInterval = 0.25
18 |
19 | // MARK: Animation method.
20 |
21 | func changeToUpAnimated(_ animated : Bool) {
22 |
23 | UIView.animate(withDuration: (animated == true ? self.rotateDuration : 0.0), animations: {
24 |
25 | self.transform = self.defaultTransform
26 | })
27 | }
28 |
29 | func changeToLeftAnimated(_ animated : Bool) {
30 |
31 | UIView.animate(withDuration: (animated == true ? self.rotateDuration : 0.0), animations: {
32 |
33 | self.transform = self.defaultTransform.rotated(by: CGFloat(-Double.pi / 2))
34 | })
35 | }
36 |
37 | func changeToRightAnimated(_ animated : Bool) {
38 |
39 | UIView.animate(withDuration: (animated == true ? self.rotateDuration : 0.0), animations: {
40 |
41 | self.transform = self.defaultTransform.rotated(by: CGFloat(Double.pi / 2))
42 | })
43 | }
44 |
45 | func changeToDownAnimated(_ animated : Bool) {
46 |
47 | UIView.animate(withDuration: (animated == true ? self.rotateDuration : 0.0), animations: {
48 |
49 | self.transform = self.defaultTransform.rotated(by: CGFloat(Double.pi))
50 | })
51 | }
52 |
53 | // MARK: Private value & func & system method.
54 |
55 | fileprivate var defaultTransform : CGAffineTransform!
56 |
57 | override init(frame: CGRect) {
58 |
59 | super.init(frame : frame)
60 | defaultTransform = self.transform
61 | }
62 |
63 | required init?(coder aDecoder: NSCoder) {
64 |
65 | fatalError("init(coder:) has not been implemented")
66 | }
67 | }
68 |
--------------------------------------------------------------------------------
/Swift-Animations/ScrollImageViewController.swift:
--------------------------------------------------------------------------------
1 | //
2 | // ScrollImageViewController.swift
3 | // Swift-Animations
4 | //
5 | // Created by YouXianMing on 16/8/18.
6 | // Copyright © 2016年 YouXianMing. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | class ScrollImageViewController: FullTitleVisualEffectViewController, UIScrollViewDelegate {
12 |
13 | fileprivate let viewTag : Int = 1000
14 | fileprivate var pictures : [UIImage] = [UIImage]()
15 | fileprivate var scrollView : UIScrollView!
16 | fileprivate var onceLinearEquation : Math!
17 |
18 | override func viewDidLoad() {
19 |
20 | super.viewDidLoad()
21 |
22 | onceLinearEquation = Math((x : 0, imageViewX : -50),
23 | (x : contentView!.width, imageViewX : 270 - 80))
24 | pictures.append(UIImage(named: "1")!)
25 | pictures.append(UIImage(named: "2")!)
26 | pictures.append(UIImage(named: "3")!)
27 | pictures.append(UIImage(named: "4")!)
28 | pictures.append(UIImage(named: "5")!)
29 |
30 | scrollView = UIScrollView(frame: (contentView?.bounds)!)
31 | scrollView.delegate = self
32 | scrollView.isPagingEnabled = true
33 | scrollView.backgroundColor = UIColor.black
34 | scrollView.showsHorizontalScrollIndicator = false
35 | scrollView.bounces = false
36 | scrollView.contentSize = CGSize(width: CGFloat(pictures.count) * Screen.Width, height: Screen.Height)
37 | contentView?.addSubview(scrollView)
38 |
39 | for (i, image) in pictures.enumerated() {
40 |
41 | let showView = MoreInfoView(frame: CGRect(x: CGFloat(i) * Screen.Width, y: 0, width: Screen.Width, height: Screen.Height))
42 | showView.imageView.image = image
43 | showView.tag = viewTag + i
44 | scrollView.addSubview(showView)
45 | }
46 | }
47 |
48 | func scrollViewDidScroll(_ scrollView: UIScrollView) {
49 |
50 | let X = scrollView.contentOffset.x
51 |
52 | for i in 0 ..< pictures.count {
53 |
54 | let showView = scrollView.viewWithTag(viewTag + i) as! MoreInfoView
55 | showView.imageView.x = onceLinearEquation.k * (X - CGFloat(i) * Screen.Width) + onceLinearEquation.b
56 | }
57 | }
58 | }
59 |
60 |
61 |
--------------------------------------------------------------------------------
/Swift-Animations/ShowLoadingView.swift:
--------------------------------------------------------------------------------
1 | //
2 | // ShowLoadingView.swift
3 | // Swift-Animations
4 | //
5 | // Created by YouXianMing on 2017/6/29.
6 | // Copyright © 2017年 YouXianMing. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | class ShowLoadingView: UIView {
12 |
13 | public private(set) var count: Int = 0 {
14 |
15 | didSet {
16 |
17 | if count >= 1 {
18 |
19 | isUserInteractionEnabled = true
20 |
21 | } else {
22 |
23 | isUserInteractionEnabled = false
24 | }
25 | }
26 | }
27 |
28 | override init(frame: CGRect) {
29 |
30 | super.init(frame: frame)
31 | self.isUserInteractionEnabled = false
32 | }
33 |
34 | required init?(coder aDecoder: NSCoder) {
35 |
36 | fatalError("init(coder:) has not been implemented")
37 | }
38 |
39 | /// push 一次导致 count + 1
40 | public func push() {
41 |
42 | count += 1
43 | }
44 |
45 | /// pop 一次导致 count - 1
46 | public func pop() {
47 |
48 | count -= 1
49 | }
50 | }
51 |
--------------------------------------------------------------------------------
/Swift-Animations/ShowTextCell.swift:
--------------------------------------------------------------------------------
1 | //
2 | // ShowTextCell.swift
3 | // Swift-Animations
4 | //
5 | // Created by YouXianMing on 16/8/30.
6 | // Copyright © 2016年 YouXianMing. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | enum EShowTextCellType : Int {
12 |
13 | case normalType, expendType
14 | }
15 |
16 | private let heitiSC : UIFont = UIFont.HeitiSC(16)
17 | private let numberOfLines : Int = 4
18 |
19 | class ShowTextCell: CustomCell {
20 |
21 | fileprivate var expendLabel : UILabel!
22 | fileprivate var normalLabel : UILabel!
23 | fileprivate var lineView : UIView!
24 | fileprivate var redView : UIView!
25 |
26 | override func buildSubview() {
27 |
28 | normalLabel = UILabel(frame: CGRect.zero)
29 | normalLabel.font = heitiSC
30 | addSubview(normalLabel)
31 |
32 | expendLabel = UILabel(frame: CGRect.zero)
33 | expendLabel.font = heitiSC
34 | expendLabel.textColor = UIColor.gray.alpha(0.5)
35 | addSubview(expendLabel)
36 |
37 | redView = UIView(frame: CGRect(x: 0, y: 20, width: 2, height: 14))
38 | redView.backgroundColor = UIColor.red
39 | addSubview(redView)
40 |
41 | lineView = UIView.CreateLine(CGRect(x: 0, y: 0, width: Screen.Width, height: 0.5), lineColor: UIColor.black.alpha(0.1))
42 | addSubview(lineView)
43 | }
44 |
45 | override func loadContent() {
46 |
47 | (indexPath as NSIndexPath?)?.row == 0 ? (lineView.isHidden = true) : (lineView.isHidden = false)
48 | changeStateWithCellType((dataAdapter?.cellType!)!)
49 | }
50 |
51 | fileprivate func changeStateWithCellType(_ type : Int) {
52 |
53 | let model = data as! ShowTextModel
54 |
55 | normalLabel.sizeToFitWithString(model.inputString!, width: Screen.Width - 30, numberOfLines: numberOfLines)
56 | normalLabel.left = 15
57 | normalLabel.top = 15
58 |
59 | expendLabel.sizeToFitWithString(model.inputString!, width: Screen.Width - 30, numberOfLines: 0)
60 | expendLabel.left = 15
61 | expendLabel.top = 15
62 |
63 | if type == EShowTextCellType.normalType.rawValue {
64 |
65 | expendLabel.alpha = 0
66 | normalLabel.alpha = 1
67 | redView.backgroundColor = UIColor.gray
68 |
69 | } else if type == EShowTextCellType.expendType.rawValue {
70 |
71 | expendLabel.alpha = 1
72 | normalLabel.alpha = 0
73 | redView.backgroundColor = UIColor.red
74 | }
75 | }
76 |
77 | override func selectedEvent() {
78 |
79 | let model = data as! ShowTextModel
80 |
81 | if dataAdapter?.cellType == EShowTextCellType.normalType.rawValue {
82 |
83 | self.dataAdapter?.cellType = EShowTextCellType.expendType.rawValue
84 | self.updateWithNewCellHeight(model.expendStringHeight!)
85 |
86 | UIView.animate(withDuration: 0.25, animations: {
87 |
88 | self.normalLabel.alpha = 0
89 | self.expendLabel.alpha = 1
90 | self.redView.backgroundColor = UIColor.red
91 | })
92 |
93 | } else if dataAdapter?.cellType == EShowTextCellType.expendType.rawValue {
94 |
95 | self.dataAdapter?.cellType = EShowTextCellType.normalType.rawValue
96 | self.updateWithNewCellHeight(model.normalStringHeight!)
97 |
98 | UIView.animate(withDuration: 0.25, animations: {
99 |
100 | self.normalLabel.alpha = 1
101 | self.expendLabel.alpha = 0
102 | self.redView.backgroundColor = UIColor.gray.alpha(0.5)
103 | })
104 | }
105 | }
106 |
107 | override class func HeightWithData(_ data : AnyObject?) -> CGFloat {
108 |
109 | let model = data as! ShowTextModel
110 | model.expendStringHeight = 15 + (model.inputString?.heightWithFont(heitiSC, fixedWidth: Screen.Width - 30))! + 15
111 | model.normalStringHeight = 15 + String.HeightWithFont(heitiSC) * CGFloat(numberOfLines) + 15
112 | return model.normalStringHeight!
113 | }
114 | }
115 |
116 |
--------------------------------------------------------------------------------
/Swift-Animations/ShowTextModel.swift:
--------------------------------------------------------------------------------
1 | //
2 | // ShowTextModel.swift
3 | // Swift-Animations
4 | //
5 | // Created by YouXianMing on 16/8/30.
6 | // Copyright © 2016年 YouXianMing. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | class ShowTextModel: NSObject {
12 |
13 | var inputString : String?
14 | var expendStringHeight : CGFloat?
15 | var normalStringHeight : CGFloat?
16 |
17 | convenience init(_ inputString : String) {
18 |
19 | self.init()
20 | self.inputString = inputString
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/Swift-Animations/StoredValueTypeIs.swift:
--------------------------------------------------------------------------------
1 | //
2 | // StoredValueType.swift
3 | // SwiftDemo
4 | //
5 | // Created by YouXianMing on 2017/10/9.
6 | // Copyright © 2017年 TechCode. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | final class StoredValueTypeIs {
12 |
13 | private init() {}
14 |
15 | class var value : StoredValueTypeIs {
16 |
17 | get {
18 |
19 | return self.init()
20 | }
21 | }
22 |
23 | subscript(name : String) -> T? {
24 |
25 | get {
26 |
27 | return UserDefaults.standard.value(forKey: name) as? T
28 | }
29 |
30 | set (newValue) {
31 |
32 | UserDefaults.standard.set(newValue, forKey: name)
33 | }
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/Swift-Animations/String+StringHeight.swift:
--------------------------------------------------------------------------------
1 | //
2 | // String+StringHeight.swift
3 | // StringHeight
4 | //
5 | // Created by YouXianMing on 16/8/30.
6 | // Copyright © 2016年 YouXianMing. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | extension String {
12 |
13 | /**
14 | Get the height with the string.
15 |
16 | - parameter attributes: The string attributes.
17 | - parameter fixedWidth: The fixed width.
18 |
19 | - returns: The height.
20 | */
21 | func heightWithStringAttributes(_ attributes : [NSAttributedString.Key : Any], fixedWidth : CGFloat) -> CGFloat {
22 |
23 | guard self.count > 0 && fixedWidth > 0 else {
24 |
25 | return 0
26 | }
27 |
28 | let size = CGSize(width: fixedWidth, height: CGFloat.greatestFiniteMagnitude)
29 | let text = self as NSString
30 | let rect = text.boundingRect(with: size, options:.usesLineFragmentOrigin, attributes: attributes, context:nil)
31 |
32 | return rect.size.height
33 | }
34 |
35 | /**
36 | Get the height with font.
37 |
38 | - parameter font: The font.
39 | - parameter fixedWidth: The fixed width.
40 |
41 | - returns: The height.
42 | */
43 | func heightWithFont(_ font : UIFont = UIFont.systemFont(ofSize: 18), fixedWidth : CGFloat) -> CGFloat {
44 |
45 | guard self.count > 0 && fixedWidth > 0 else {
46 |
47 | return 0
48 | }
49 |
50 | let size = CGSize(width: fixedWidth, height: CGFloat.greatestFiniteMagnitude)
51 | let text = self as NSString
52 | let rect = text.boundingRect(with: size, options:.usesLineFragmentOrigin, attributes: [NSAttributedString.Key.font : font], context:nil)
53 |
54 | return rect.size.height
55 | }
56 |
57 | /**
58 | Get the height with font.
59 |
60 | - parameter font: The font.
61 | - parameter fixedWidth: The fixed width.
62 |
63 | - returns: The height.
64 | */
65 | static func HeightWithFont(_ font : UIFont = UIFont.systemFont(ofSize: 18)) -> CGFloat {
66 |
67 | let string = "One"
68 | let size = CGSize(width: 200, height: CGFloat.greatestFiniteMagnitude)
69 | let text = string as NSString
70 | let rect = text.boundingRect(with: size, options:.usesLineFragmentOrigin, attributes: [NSAttributedString.Key.font : font], context:nil)
71 |
72 | return rect.size.height
73 | }
74 |
75 | /**
76 | Get the width with the string.
77 |
78 | - parameter attributes: The string attributes.
79 |
80 | - returns: The width.
81 | */
82 | func widthWithStringAttributes(_ attributes : [NSAttributedString.Key : Any]) -> CGFloat {
83 |
84 | guard self.count > 0 else {
85 |
86 | return 0
87 | }
88 |
89 | let size = CGSize(width: CGFloat.greatestFiniteMagnitude, height: 0)
90 | let text = self as NSString
91 | let rect = text.boundingRect(with: size, options:.usesLineFragmentOrigin, attributes: attributes, context:nil)
92 |
93 | return rect.size.width
94 | }
95 |
96 | /**
97 | Get the width with the string.
98 |
99 | - parameter font: The font.
100 |
101 | - returns: The string's width.
102 | */
103 | func widthWithFont(_ font : UIFont = UIFont.systemFont(ofSize: 18)) -> CGFloat {
104 |
105 | guard self.count > 0 else {
106 |
107 | return 0
108 | }
109 |
110 | let size = CGSize(width: CGFloat.greatestFiniteMagnitude, height: 0)
111 | let text = self as NSString
112 | let rect = text.boundingRect(with: size, options:.usesLineFragmentOrigin, attributes: [NSAttributedString.Key.font : font], context:nil)
113 |
114 | return rect.size.width
115 | }
116 | }
117 |
118 |
119 |
120 |
--------------------------------------------------------------------------------
/Swift-Animations/StudentInfoCell.swift:
--------------------------------------------------------------------------------
1 | //
2 | // StudentInfoCell.swift
3 | // Swift-Animations
4 | //
5 | // Created by YouXianMing on 16/8/9.
6 | // Copyright © 2016年 YouXianMing. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | class StudentInfoCell: CustomCell {
12 |
13 | fileprivate var nameLabel : UILabel!
14 | fileprivate var ageLabel : UILabel!
15 |
16 | override func setupCell() {
17 |
18 | self.selectionStyle = .none
19 | }
20 |
21 | override func buildSubview() {
22 |
23 | nameLabel = UILabel(frame: CGRect(x: 20, y: 0, width: 200, height: 60))
24 | nameLabel.font = UIFont.AppleSDGothicNeoThin(20)
25 | self.addSubview(nameLabel)
26 |
27 | ageLabel = UILabel(frame: CGRect(x: Screen.Width - 220, y: 0, width: 200, height: 60))
28 | ageLabel.textAlignment = .right
29 | ageLabel.font = UIFont.AppleSDGothicNeoThin(20)
30 | self.addSubview(ageLabel)
31 |
32 | self.addSubview(UIView.CreateLine(CGRect(x: 0, y: 59.5, width: Screen.Width, height: 0.5), lineColor: UIColor.gray.alpha(0.1)))
33 | }
34 |
35 | override func loadContent() {
36 |
37 | let model = data as! StudentModel
38 |
39 | nameLabel.text = model.name
40 | ageLabel.text = model.age.stringValue
41 | }
42 |
43 | override func selectedEvent() {
44 |
45 | showSelectedAnimation()
46 | }
47 |
48 | fileprivate func showSelectedAnimation() {
49 |
50 | let tempView = UIView(frame: CGRect(x: 0, y: 0, width: Screen.Width, height: 60))
51 | tempView.backgroundColor = UIColor.cyan.alpha(0.2)
52 | tempView.alpha = 0
53 | self.addSubview(tempView)
54 |
55 | UIView.animate(withDuration: 0.2, delay: 0, options: .curveEaseIn, animations: {
56 |
57 | tempView.alpha = 0.8
58 |
59 | }) { (finished) in
60 |
61 | UIView.animate(withDuration: 0.2, delay: 0.1, options: .curveEaseOut, animations: {
62 |
63 | tempView.alpha = 0
64 |
65 | }, completion: { (finished) in
66 |
67 | tempView.removeFromSuperview()
68 | })
69 | }
70 | }
71 | }
72 |
--------------------------------------------------------------------------------
/Swift-Animations/StudentModel.swift:
--------------------------------------------------------------------------------
1 | //
2 | // StudentModel.swift
3 | // Swift-Animations
4 | //
5 | // Created by YouXianMing on 16/8/9.
6 | // Copyright © 2016年 YouXianMing. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | class StudentModel: NSObject {
12 |
13 | var name : String = ""
14 | var age : NSNumber = 0
15 |
16 | convenience init(name : String, age : NSNumber) {
17 |
18 | self.init()
19 | self.name = name
20 | self.age = age
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/Swift-Animations/SystemFontInfoController.swift:
--------------------------------------------------------------------------------
1 | //
2 | // SystemFontInfoController.swift
3 | // Swift-Animations
4 | //
5 | // Created by YouXianMing on 2017/9/15.
6 | // Copyright © 2017年 YouXianMing. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | class SystemFontInfoController: NormalTitleViewController, UITableViewDelegate, UITableViewDataSource, CustomCellDelegate, CustomHeaderFooterViewDelegate {
12 |
13 | fileprivate var fontFamilyArray : [FontFamilyModel] = []
14 | fileprivate var tableView : UITableView!
15 |
16 | override func viewDidLoad() {
17 |
18 | super.viewDidLoad()
19 |
20 | getFonts()
21 |
22 | tableView = UITableView.init(frame: (contentView?.bounds)!, style: .plain)
23 | tableView.delegate = self
24 | tableView.dataSource = self
25 | tableView.separatorStyle = .none
26 | tableView.rowHeight = FontCell.HeightWithData()
27 | tableView.sectionHeaderHeight = FontFamilyHeaderView.HeightWithData()
28 | contentView!.addSubview(tableView)
29 |
30 | // if #available(iOS 11.0, *) {
31 | //
32 | // tableView.contentInsetAdjustmentBehavior = .never
33 | // }
34 |
35 | FontCell.RegisterTo(tableView)
36 | FontFamilyHeaderView.RegisterTo(tableView)
37 | }
38 |
39 | // MARK: private
40 |
41 | private func getFonts() {
42 |
43 | for (familyName , fontNames) in FontInfomation.Shared.fontsDictionary() {
44 |
45 | let fontFamilyModel = FontFamilyModel.init(familyName: familyName)
46 |
47 | for fontName in fontNames {
48 |
49 | fontFamilyModel.fonts.append(FontModel.init(fontName: fontName))
50 | }
51 |
52 | fontFamilyArray.append(fontFamilyModel)
53 | }
54 | }
55 |
56 | // MARK: UITableViewDelegate, UITableViewDataSource
57 |
58 | func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
59 |
60 | let cell = tableView.dequeueReusableCell(withIdentifier: "FontCell") as! CustomCell
61 | cell.data = fontFamilyArray[indexPath.section].fonts[indexPath.row]
62 | cell.delegate = self
63 | cell.loadContent()
64 |
65 | return cell
66 | }
67 |
68 | func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
69 |
70 | return fontFamilyArray[section].fonts.count
71 | }
72 |
73 | func numberOfSections(in tableView: UITableView) -> Int {
74 |
75 | return fontFamilyArray.count
76 | }
77 |
78 | func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
79 |
80 | let headerView = tableView.dequeueReusableHeaderFooterView(withIdentifier: "FontFamilyHeaderView") as! CustomHeaderFooterView
81 | headerView.data = fontFamilyArray[section]
82 | headerView.delegate = self
83 | headerView.loadContent()
84 |
85 | return headerView
86 | }
87 |
88 | func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
89 |
90 | tableView.selectedEventWithIndexPath(indexPath)
91 | }
92 |
93 | // MARK: CustomCellDelegate
94 |
95 | func customCell(_ cell: CustomCell?, event: Any?) {
96 |
97 | if event is FontModel {
98 |
99 | print((event as! FontModel).fontName!)
100 | }
101 | }
102 |
103 | // MARK: CustomHeaderFooterViewDelegate
104 |
105 | func customHeaderFooterView(_ headerFooterView: CustomHeaderFooterView?, event: AnyObject?) {
106 |
107 | if event is FontFamilyModel {
108 |
109 | print((event as! FontFamilyModel).familyName!)
110 | }
111 | }
112 | }
113 |
114 | class FontInfomation : NSObject {
115 |
116 | // MARK: private
117 |
118 | private var infos : [String : Array]
119 |
120 | private override init() {
121 |
122 | infos = [String : Array]()
123 | for familyName in UIFont.familyNames {
124 |
125 | infos[familyName] = UIFont.fontNames(forFamilyName: familyName)
126 | }
127 | }
128 |
129 | // MARK: public
130 |
131 | static let Shared = FontInfomation()
132 |
133 | func fontsDictionary() -> [String : Array] {
134 |
135 | return FontInfomation.Shared.infos
136 | }
137 | }
138 |
--------------------------------------------------------------------------------
/Swift-Animations/TableViewTapAnimationCell.swift:
--------------------------------------------------------------------------------
1 | //
2 | // TableViewTapAnimationCell.swift
3 | // Swift-Animations
4 | //
5 | // Created by YouXianMing on 16/8/7.
6 | // Copyright © 2016年 YouXianMing. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | enum TableViewTapAnimationCellState : Int {
12 |
13 | case kNormalState, kSelectedState
14 | }
15 |
16 | class TableViewTapAnimationCell: CustomCell {
17 |
18 | // MARK: Private var.
19 |
20 | fileprivate var titleLabel : UILabel!
21 | fileprivate var iconView : UIImageView!
22 | fileprivate var lineView : UIView!
23 | fileprivate var rectView : UIView!
24 |
25 | // MARK: Override CustomCell func.
26 |
27 | override func buildSubview() {
28 |
29 | rectView = UIView(frame: CGRect(x: Screen.Width - 60, y: 23, width: 35, height: 35))
30 | rectView.layer.borderWidth = 1
31 | rectView.layer.borderColor = UIColor.gray.cgColor
32 | self.addSubview(rectView)
33 |
34 | iconView = UIImageView(frame: CGRect(x: Screen.Width - 62, y: 20, width: 40, height: 40))
35 | iconView.image = UIImage(named: "plane")
36 | iconView.alpha = 0
37 | self.addSubview(iconView)
38 |
39 | titleLabel = UILabel(frame: CGRect(x: 30, y: 10, width: 300, height: 60))
40 | titleLabel.font = UIFont.Avenir(20)
41 | titleLabel.textColor = UIColor.gray
42 | self.addSubview(titleLabel)
43 |
44 | lineView = UIView(frame: CGRect(x: 30, y: 70, width: 0, height: 2))
45 | lineView.alpha = 0
46 | lineView.backgroundColor = UIColor.red
47 | self.addSubview(lineView)
48 | }
49 |
50 | override func loadContent() {
51 |
52 | let model = self.data as! TapAnimationModel
53 | titleLabel.text = model.name
54 |
55 | if model.selected == true {
56 |
57 | changeToState(.kSelectedState, animated: false)
58 |
59 | } else {
60 |
61 | changeToState(.kNormalState, animated: false)
62 | }
63 | }
64 |
65 | override func selectedEvent() {
66 |
67 | showSelectedAnimation()
68 |
69 | let model = self.data as! TapAnimationModel
70 |
71 | if model.selected == true {
72 |
73 | model.selected = false
74 | changeToState(.kNormalState, animated: true)
75 |
76 | } else {
77 |
78 | model.selected = true
79 | changeToState(.kSelectedState, animated: true)
80 | }
81 |
82 | if let delegate = delegate {
83 |
84 | delegate.customCell(self, event: model.name as AnyObject?)
85 | }
86 | }
87 |
88 | // MARK: Private func.
89 |
90 | fileprivate func changeToState(_ state : TableViewTapAnimationCellState, animated : Bool) {
91 |
92 | switch state {
93 |
94 | case .kNormalState:
95 |
96 | UIView.animate(withDuration: animated == false ? 0 : 0.5, delay: 0, usingSpringWithDamping: 7, initialSpringVelocity: 4, options: UIView.AnimationOptions(), animations: {
97 |
98 | if animated == true {
99 |
100 | self.iconView.transform = CGAffineTransform(a: 0.5, b: 0, c: 0, d: 0.5, tx: 0, ty: 0)
101 | }
102 |
103 | self.iconView.alpha = 0
104 | self.lineView.alpha = 0
105 | self.lineView.frame = CGRect(x: 30, y: 70, width: 0, height: 2)
106 | self.titleLabel.frame = CGRect(x: 30, y: 10, width: 300, height: 60)
107 |
108 | self.rectView.layer.borderColor = UIColor.gray.cgColor
109 | self.rectView.transform = CGAffineTransform(a: 1, b: 0, c: 0, d: 1, tx: 0, ty: 0)
110 | self.rectView.layer.cornerRadius = 0
111 |
112 | }, completion: nil)
113 |
114 | case .kSelectedState:
115 |
116 | if animated == true {
117 |
118 | self.iconView.transform = CGAffineTransform(a: 2, b: 0, c: 0, d: 2, tx: 0, ty: 0)
119 | }
120 |
121 | UIView.animate(withDuration: animated == false ? 0 : 0.5, delay: 0, usingSpringWithDamping: 7, initialSpringVelocity: 4, options: UIView.AnimationOptions(), animations: {
122 |
123 | self.iconView.transform = CGAffineTransform(a: 1, b: 0, c: 0, d: 1, tx: 0, ty: 0)
124 | self.iconView.alpha = 1
125 | self.lineView.alpha = 1
126 | self.lineView.frame = CGRect(x: 30, y: 70, width: 200, height: 2)
127 | self.titleLabel.frame = CGRect(x: 30 + 50, y: 10, width: 300, height: 60)
128 |
129 | self.rectView.layer.borderColor = UIColor.red.cgColor
130 | self.rectView.transform = CGAffineTransform(a: 0.8, b: 0, c: 0, d: 0.8, tx: 0, ty: 0)
131 | self.rectView.layer.cornerRadius = 4
132 |
133 | }, completion: nil)
134 | }
135 | }
136 |
137 | fileprivate func showSelectedAnimation() {
138 |
139 | let tempView = UIView(frame: CGRect(x: 0, y: 0, width: Screen.Width, height: 80))
140 | tempView.backgroundColor = UIColor.cyan.alpha(0.2)
141 | tempView.alpha = 0
142 | self.addSubview(tempView)
143 |
144 | UIView.animate(withDuration: 0.2, delay: 0, options: .curveEaseIn, animations: {
145 |
146 | tempView.alpha = 0.8
147 |
148 | }) { (finished) in
149 |
150 | UIView.animate(withDuration: 0.2, delay: 0.1, options: .curveEaseOut, animations: {
151 |
152 | tempView.alpha = 0
153 |
154 | }, completion: { (finished) in
155 |
156 | tempView.removeFromSuperview()
157 | })
158 | }
159 | }
160 | }
161 |
--------------------------------------------------------------------------------
/Swift-Animations/TableViewTapAnimationController.swift:
--------------------------------------------------------------------------------
1 | //
2 | // TableViewTapAnimationController.swift
3 | // Swift-Animations
4 | //
5 | // Created by YouXianMing on 16/8/7.
6 | // Copyright © 2016年 YouXianMing. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | class TableViewTapAnimationController: NormalTitleViewController, UITableViewDelegate, UITableViewDataSource, CustomCellDelegate {
12 |
13 | fileprivate var adapters : [CellDataAdapter] = [CellDataAdapter]()
14 | fileprivate var tableView : UITableView!
15 |
16 | override func viewDidLoad() {
17 |
18 | super.viewDidLoad()
19 |
20 | func appendModel(_ model : TapAnimationModel, cellHeight : CGFloat = 80) {
21 |
22 | adapters.append(TableViewTapAnimationCell.Adapter(data: model, cellHeight: cellHeight))
23 | }
24 |
25 | // TableView.
26 | tableView = UITableView(frame: (contentView?.bounds)!)
27 | tableView.dataSource = self
28 | tableView.delegate = self
29 | tableView.separatorStyle = .none
30 | contentView?.addSubview(tableView!)
31 |
32 | // Register cell.
33 | TableViewTapAnimationCell.RegisterTo(tableView)
34 |
35 | // Data source.
36 | appendModel(TapAnimationModel(name: "YouXianMing", selected: false))
37 | appendModel(TapAnimationModel(name: "Animations", selected: false))
38 | appendModel(TapAnimationModel(name: "YoCelsius", selected: false))
39 | appendModel(TapAnimationModel(name: "iOS-Progrommer", selected: false))
40 | appendModel(TapAnimationModel(name: "Design-Patterns", selected: false))
41 | appendModel(TapAnimationModel(name: "Arabia-Terra", selected: false))
42 | appendModel(TapAnimationModel(name: "Swift", selected: false))
43 | }
44 |
45 | // MARK: UITableView's delegate & dataSource.
46 |
47 | func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
48 |
49 | return adapters.count
50 | }
51 |
52 | func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
53 |
54 | let cell = tableView.dequeueCellAndLoadContentFromAdapter(adapters[(indexPath as NSIndexPath).row], indexPath: indexPath)
55 | cell.delegate = self
56 |
57 | return cell
58 | }
59 |
60 | func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
61 |
62 | tableView.selectedEventWithIndexPath(indexPath)
63 | }
64 |
65 | func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
66 |
67 | return adapters[(indexPath as NSIndexPath).row].cellHeight!
68 | }
69 |
70 | // MARK: CustomCellDelegate.
71 |
72 | func customCell(_ cell: CustomCell?, event: Any?) {
73 |
74 | print("\(String(describing: cell)) + \(String(describing: event))")
75 | }
76 | }
77 |
78 |
79 |
--------------------------------------------------------------------------------
/Swift-Animations/TapAnimationModel.swift:
--------------------------------------------------------------------------------
1 | //
2 | // TapAnimationModel.swift
3 | // Swift-Animations
4 | //
5 | // Created by YouXianMing on 16/8/7.
6 | // Copyright © 2016年 YouXianMing. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | class TapAnimationModel: NSObject {
12 |
13 | var name : String = ""
14 | var selected : Bool = false
15 |
16 | convenience init(name : String, selected : Bool) {
17 |
18 | self.init()
19 | self.name = name
20 | self.selected = selected
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/Swift-Animations/TapCellAnimationController.swift:
--------------------------------------------------------------------------------
1 | //
2 | // TapCellAnimationController.swift
3 | // Swift-Animations
4 | //
5 | // Created by YouXianMing on 16/8/30.
6 | // Copyright © 2016年 YouXianMing. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | class TapCellAnimationController: NormalTitleViewController, UITableViewDelegate, UITableViewDataSource {
12 |
13 | fileprivate var tableView : UITableView!
14 | fileprivate var datas : [CellDataAdapter]!
15 |
16 | override func viewDidLoad() {
17 |
18 | super.viewDidLoad()
19 |
20 | datas = [CellDataAdapter]()
21 |
22 | tableView = UITableView(frame: (contentView?.bounds)!)
23 | tableView.delegate = self
24 | tableView.dataSource = self
25 | tableView.separatorStyle = .none
26 | ShowTextCell.RegisterTo(tableView)
27 | contentView?.addSubview(tableView)
28 |
29 | func addText(_ string : String) {
30 |
31 | let model = ShowTextModel(string)
32 |
33 | datas.append(ShowTextCell.Adapter(
34 | data : model,
35 | cellHeight : ShowTextCell.HeightWithData(model),
36 | type : EShowTextCellType.normalType.rawValue))
37 | }
38 |
39 | GCDQueue.Main.excuteAfterDelay(0.5) {
40 |
41 | addText("AFNetworking is a delightful networking library for iOS and Mac OS X. It's built on top of the Foundation URL Loading System, extending the powerful high-level networking abstractions built into Cocoa. It has a modular architecture with well-designed, feature-rich APIs that are a joy to use. Perhaps the most important feature of all, however, is the amazing community of developers who use and contribute to AFNetworking every day. AFNetworking powers some of the most popular and critically-acclaimed apps on the iPhone, iPad, and Mac. Choose AFNetworking for your next project, or migrate over your existing projects—you'll be happy you did!")
42 |
43 | addText("黄色的树林里分出两条路,可惜我不能同时去涉足,我在那路口久久伫立,我向着一条路极目望去,直到它消失在丛林深处。但我却选了另外一条路,它荒草萋萋,十分幽寂,显得更诱人、更美丽,虽然在这两条小路上,都很少留下旅人的足迹,虽然那天清晨落叶满地,两条路都未经脚印污染。呵,留下一条路等改日再见!但我知道路径延绵无尽头,恐怕我难以再回返。也许多少年后在某个地方,我将轻声叹息把往事回顾,一片树林里分出两条路,而我选了人迹更少的一条,从此决定了我一生的道路。")
44 |
45 | addText("★タクシー代がなかったので、家まで歩いて帰った。★もし事故が発生した场所、このレバーを引いて列车を止めてください。(丁)为了清楚地表示出一个短语或句节,其后须标逗号。如:★この薬を、夜寝る前に一度、朝起きてからもう一度、饮んでください。★私は、空を飞ぶ鸟のように、自由に生きて行きたいと思った。*****为了清楚地表示词语与词语间的关系,须标逗号。标注位置不同,有时会使句子的意思发生变化。如:★その人は大きな音にびっくりして、横から飞び出した子供にぶつかった。★その人は、大きな音にびっくりして横から飞び出した子供に、ぶつかった。")
46 |
47 | addText("Two roads diverged in a yellow wood, And sorry I could not travel both And be one traveler, long I stood And looked down one as far as I could To where it bent in the undergrowth; Then took the other, as just as fair, And having perhaps the better claim, Because it was grassy and wanted wear; Though as for that the passing there Had worn them really about the same, And both that morning equally lay In leaves no step had trodden black. Oh, I kept the first for another day! Yet knowing how way leads on to way, I doubted if I should ever come back. I shall be telling this with a sigh Somewhere ages and ages hence: Two roads diverged in a wood, and I- I took the one less traveled by, And that has made all the difference.")
48 |
49 | var indexPaths = [IndexPath]()
50 | for i in 0 ..< self.datas.count {
51 |
52 | indexPaths.append(IndexPath(item: i, section: 0))
53 | }
54 | self.tableView.insertRows(at: indexPaths, with: .fade)
55 |
56 | GCDQueue.Main.excuteAfterDelay(0.5, {
57 |
58 | let cell = self.tableView.cellForRow(at: IndexPath(item: 0, section: 0)) as! CustomCell
59 | cell.selectedEvent()
60 | })
61 | }
62 | }
63 |
64 | func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
65 |
66 | return tableView.dequeueCellAndLoadContentFromAdapter(datas[(indexPath as NSIndexPath).row], indexPath: indexPath, tableView: tableView)
67 | }
68 |
69 | func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
70 |
71 | return datas.count
72 | }
73 |
74 | func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
75 |
76 | return datas[(indexPath as NSIndexPath).row].cellHeight!
77 | }
78 |
79 | func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
80 |
81 | tableView.selectedEventWithIndexPath(indexPath)
82 | }
83 | }
84 |
--------------------------------------------------------------------------------
/Swift-Animations/TimeModel.swift:
--------------------------------------------------------------------------------
1 | //
2 | // TimeModel.swift
3 | // Swift-Animations
4 | //
5 | // Created by YouXianMing on 16/9/4.
6 | // Copyright © 2016年 YouXianMing. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | class TimeModel: NSObject {
12 |
13 | var title : String? = ""
14 | var countdownTime : Int? = 0
15 |
16 | var currentTimeString : String? {
17 |
18 | get {
19 |
20 | if let val = countdownTime {
21 |
22 | if val <= 0 {
23 |
24 | return "00:00:00"
25 |
26 | } else {
27 |
28 | return String(format:"%02.f:%02.f:%02.f",
29 | CGFloat(val) / 3600,
30 | CGFloat(val).truncatingRemainder(dividingBy: 3600) / 60,
31 | CGFloat(val).truncatingRemainder(dividingBy: 60))
32 | }
33 |
34 | } else {
35 |
36 | return Optional.none
37 | }
38 | }
39 | }
40 |
41 | convenience init(title : String, countdownTime : Int) {
42 |
43 | self.init()
44 | self.title = title
45 | self.countdownTime = countdownTime
46 | }
47 |
48 | func countDown() {
49 |
50 | countdownTime = countdownTime! - 1
51 | }
52 | }
53 |
--------------------------------------------------------------------------------
/Swift-Animations/TranformFadeView.swift:
--------------------------------------------------------------------------------
1 | //
2 | // TranformFadeView.swift
3 | // Swift-Animations
4 | //
5 | // Created by YouXianMing on 16/8/20.
6 | // Copyright © 2016年 YouXianMing. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | enum TranformFadeViewAnimatedType : Int {
12 |
13 | case fade, show
14 | }
15 |
16 | // MARK: TranformFadeView
17 |
18 | class TranformFadeView: UIView {
19 |
20 | // MARK: Convenience init.
21 |
22 | convenience init(frame: CGRect, verticalCount : Int, horizontalCount : Int, fadeDuradtion : TimeInterval, animationGapDuration : TimeInterval) {
23 |
24 | self.init(frame: frame)
25 | self.verticalCount = verticalCount
26 | self.horizontalCount = horizontalCount
27 | self.fadeDuradtion = fadeDuradtion
28 | self.animationGapDuration = animationGapDuration
29 | self.makeConfigEffective()
30 | }
31 |
32 | // MARK: Properies & funcs.
33 |
34 | /// The content imageView's image.
35 | var image : UIImage? {
36 |
37 | get { return imageView.image}
38 | set(newVal) { imageView.image = newVal}
39 | }
40 |
41 | /// The content imageView's contentMode.
42 | var imageContentMode: UIView.ContentMode {
43 |
44 | get { return imageView.contentMode}
45 | set(newVal) { imageView.contentMode = newVal}
46 | }
47 |
48 | /// Vertical direction view's count, default is 3.
49 | var verticalCount : Int = 3
50 |
51 | /// Horizontal direction view's count, default is 4.
52 | var horizontalCount : Int = 4
53 |
54 | /// One of the maskView's animation duration, default is 1.0
55 | var fadeDuradtion : TimeInterval = 1
56 |
57 | /// The animation duration two subViews from allMaskView, default is 0.2
58 | var animationGapDuration : TimeInterval = 0.2
59 |
60 | /**
61 | Make the config effective.
62 | */
63 | func makeConfigEffective() {
64 |
65 | guard verticalCount >= 1 && horizontalCount >= 1 else {
66 |
67 | return
68 | }
69 |
70 | if allMaskView != nil {
71 |
72 | allMaskView.removeFromSuperview()
73 | }
74 |
75 | countNumArray.removeAll()
76 |
77 | allMaskView = UIView(frame: bounds)
78 | mask = allMaskView
79 |
80 | let height = bounds.size.height
81 | let width = bounds.size.width
82 | let maskViewHeight = height / CGFloat(verticalCount)
83 | let maskViewWidth = width / CGFloat(horizontalCount)
84 |
85 | var count : Int = 0
86 | for horizontal in 0 ..< horizontalCount {
87 |
88 | for vertical in 0 ..< verticalCount {
89 |
90 | let frame = CGRect(x: maskViewWidth * CGFloat(horizontal), y: maskViewHeight * CGFloat(vertical), width: maskViewWidth, height: maskViewHeight)
91 | let maskView = UIView(frame: frame)
92 | maskView.tag = maskViewTag + count
93 | maskView.backgroundColor = UIColor.black
94 | allMaskView.addSubview(maskView)
95 |
96 | count = count + 1;
97 | }
98 | }
99 |
100 | maskViewCount = count
101 |
102 | for i in 0 ..< maskViewCount {
103 |
104 | countNumArray.append(i)
105 | }
106 | }
107 |
108 | /**
109 | Start transform to fade or show state.
110 |
111 | - parameter animated: Animated or not.
112 | - parameter transformTo: Show or fade.
113 | */
114 | func start(animated : Bool, transformTo : TranformFadeViewAnimatedType) {
115 |
116 | if animated == true {
117 |
118 | let tmpFadeDuradtion = fadeDuradtion < 0 ? 1.0 : fadeDuradtion
119 | let tmpGapDuration = animationGapDuration < 0 ? 0.2 : animationGapDuration
120 |
121 | for i in 0 ..< maskViewCount {
122 |
123 | let tmpView = allMaskView.viewWithTag(maskViewTag + i)
124 |
125 | UIView.animate(withDuration: tmpFadeDuradtion, delay: TimeInterval(i) * tmpGapDuration, options: .curveLinear, animations: {
126 |
127 | switch transformTo {
128 |
129 | case .fade :
130 | tmpView?.alpha = 0.0
131 |
132 | case .show :
133 | tmpView?.alpha = 1.0
134 | }
135 |
136 | }, completion: nil)
137 | }
138 |
139 | } else {
140 |
141 | for i in 0 ..< maskViewCount {
142 |
143 | let tmpView = allMaskView.viewWithTag(maskViewTag + i)
144 |
145 | switch transformTo {
146 |
147 | case .fade :
148 | tmpView?.alpha = 0.0
149 |
150 | case .show :
151 | tmpView?.alpha = 1.0
152 | }
153 | }
154 | }
155 | }
156 |
157 | // MARK: System methods & Private properties
158 |
159 | fileprivate var imageView : UIImageView!
160 | fileprivate var allMaskView : UIView!
161 | fileprivate var maskViewCount : Int!
162 | fileprivate var countNumArray : [Int]!
163 | fileprivate var maskViewTag : Int = 1000
164 |
165 | override init(frame: CGRect) {
166 |
167 | super.init(frame: frame)
168 |
169 | imageView = UIImageView(frame: bounds)
170 | imageView.layer.masksToBounds = true
171 | countNumArray = [Int]()
172 | self.addSubview(imageView)
173 | }
174 |
175 | required init?(coder aDecoder: NSCoder) {
176 |
177 | fatalError("init(coder:) has not been implemented")
178 | }
179 | }
180 |
--------------------------------------------------------------------------------
/Swift-Animations/TransformFadeViewController.swift:
--------------------------------------------------------------------------------
1 | //
2 | // TransformFadeViewController.swift
3 | // Swift-Animations
4 | //
5 | // Created by YouXianMing on 16/8/20.
6 | // Copyright © 2016年 YouXianMing. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | private enum EType : Int {
12 |
13 | case typeOne, typeTwo
14 | }
15 |
16 | class TransformFadeViewController: FullTitleVisualEffectViewController {
17 |
18 | fileprivate var images : [UIImage]!
19 | fileprivate var tranformFadeViewOne : TranformFadeView!
20 | fileprivate var tranformFadeViewTwo : TranformFadeView!
21 | fileprivate var type : EType = .typeOne
22 | fileprivate var count : Int = 0
23 | fileprivate var gcdTimer : GCDTimer!
24 |
25 | override func viewDidLoad() {
26 |
27 | super.viewDidLoad()
28 |
29 | images = [UIImage]()
30 | images.append(UIImage(named: "5")!)
31 | images.append(UIImage(named: "1")!)
32 | images.append(UIImage(named: "2")!)
33 | images.append(UIImage(named: "3")!)
34 | images.append(UIImage(named: "4")!)
35 |
36 | tranformFadeViewOne = TranformFadeView(frame: contentView!.bounds, verticalCount: 3, horizontalCount: 12,
37 | fadeDuradtion: 1, animationGapDuration: 0.075)
38 | tranformFadeViewOne.imageContentMode = .scaleAspectFill
39 | tranformFadeViewOne.image = currentImage()
40 | tranformFadeViewOne.start(animated: false, transformTo: .show)
41 | contentView!.addSubview(tranformFadeViewOne)
42 |
43 | tranformFadeViewTwo = TranformFadeView(frame: contentView!.bounds, verticalCount: 3, horizontalCount: 12,
44 | fadeDuradtion: 1, animationGapDuration: 0.075)
45 | tranformFadeViewTwo.imageContentMode = .scaleAspectFill
46 | tranformFadeViewTwo.image = currentImage()
47 | tranformFadeViewTwo.start(animated: false, transformTo: .fade)
48 | contentView!.addSubview(tranformFadeViewTwo)
49 |
50 | gcdTimer = GCDTimer(in: GCDQueue.Main, delay: 1.0, interval: 8.0)
51 | weak var weakSelf = self
52 | gcdTimer.setTimerEventHandler { _ in
53 |
54 | if weakSelf?.type == .typeOne {
55 |
56 | weakSelf?.type = .typeTwo
57 | weakSelf?.contentView?.sendSubviewToBack((weakSelf?.tranformFadeViewTwo)!)
58 | weakSelf?.tranformFadeViewTwo.image = weakSelf?.currentImage()
59 | weakSelf?.tranformFadeViewTwo.start(animated: false, transformTo: .show)
60 | weakSelf?.tranformFadeViewOne.start(animated: true, transformTo: .fade)
61 |
62 | } else {
63 |
64 | weakSelf?.type = .typeOne
65 | weakSelf?.contentView?.sendSubviewToBack((weakSelf?.tranformFadeViewOne)!)
66 | weakSelf?.tranformFadeViewOne.image = weakSelf?.currentImage()
67 | weakSelf?.tranformFadeViewOne.start(animated: false, transformTo: .show)
68 | weakSelf?.tranformFadeViewTwo.start(animated: true, transformTo: .fade)
69 | }
70 | }
71 |
72 | gcdTimer.start()
73 | }
74 |
75 | fileprivate func currentImage() -> UIImage {
76 |
77 | count = (count + 1) % images.count
78 | return images[count]
79 | }
80 |
81 | override func viewDidDisappear(_ animated: Bool) {
82 |
83 | super.viewDidDisappear(animated)
84 | gcdTimer.destroy()
85 | }
86 | }
87 |
--------------------------------------------------------------------------------
/Swift-Animations/UIColor+Convenience.swift:
--------------------------------------------------------------------------------
1 | //
2 | // UIColor+Convenience.swift
3 | // Swift-Animations
4 | //
5 | // Created by YouXianMing on 16/8/20.
6 | // Copyright © 2016年 YouXianMing. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | extension UIColor {
12 |
13 | /**
14 | Creates and returns a color object that has the same color space and component values as the receiver, but has the specified alpha component.
15 |
16 | - parameter alpha: The opacity value of the new UIColor object.
17 |
18 | - returns: The new UIColor object.
19 | */
20 | func alpha(_ alpha : CGFloat) -> UIColor {
21 |
22 | return self.withAlphaComponent(alpha)
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/Swift-Animations/UIColor+HexColor.swift:
--------------------------------------------------------------------------------
1 | //
2 | // UIColor+HexColor.swift
3 | // Swift-Animations
4 | //
5 | // Created by YouXianMing on 16/8/14.
6 | // Copyright © 2016年 YouXianMing. All rights reserved.
7 | //
8 |
9 | #if os(iOS) || os(tvOS)
10 |
11 | import UIKit
12 | typealias HexColor = UIColor
13 |
14 | #else
15 |
16 | import Cocoa
17 | typealias HexColor = NSColor
18 |
19 | #endif
20 |
21 | private extension Int {
22 |
23 | func duplicate4bits() -> Int {
24 |
25 | return (self << 4) + self
26 | }
27 | }
28 |
29 | extension HexColor {
30 |
31 | // MARK: class func.
32 |
33 | class func Hex(_ hex6 : Int) -> HexColor {
34 |
35 | if (0x000000 ... 0xFFFFFF) ~= hex6 {
36 |
37 | return HexColor(hex6: hex6, alpha: 1)!
38 |
39 | } else {
40 |
41 | return HexColor.white
42 | }
43 | }
44 |
45 | class func Hex6(_ hex6 : Int, alpha : Float) -> HexColor {
46 |
47 | if (0x000000 ... 0xFFFFFF) ~= hex6 {
48 |
49 | return HexColor(hex6: hex6, alpha: alpha)!
50 |
51 | } else {
52 |
53 | return HexColor.white
54 | }
55 | }
56 |
57 | class func Hex6(_ hex6 : Int) -> HexColor {
58 |
59 | if (0x000000 ... 0xFFFFFF) ~= hex6 {
60 |
61 | return HexColor(hex6: hex6, alpha: 1)!
62 |
63 | } else {
64 |
65 | return HexColor.white
66 | }
67 | }
68 |
69 | class func Hex3(_ hex3 : Int, alpha : Float) -> HexColor {
70 |
71 | if (0x000 ... 0xFFF) ~= hex3 {
72 |
73 | return HexColor(hex3: hex3, alpha: alpha)!
74 |
75 | } else {
76 |
77 | return HexColor.white
78 | }
79 | }
80 |
81 | class func Hex3(_ hex3 : Int) -> HexColor {
82 |
83 | if (0x000 ... 0xFFF) ~= hex3 {
84 |
85 | return HexColor(hex3: hex3, alpha: 1)!
86 |
87 | } else {
88 |
89 | return HexColor.white
90 | }
91 | }
92 |
93 | // MARK: Private func.
94 |
95 | fileprivate convenience init?(hex3: Int, alpha: Float) {
96 |
97 | self.init(red : CGFloat(((hex3 & 0xF00) >> 8).duplicate4bits()) / 255.0,
98 | green : CGFloat(((hex3 & 0x0F0) >> 4).duplicate4bits()) / 255.0,
99 | blue : CGFloat(((hex3 & 0x00F) >> 0).duplicate4bits()) / 255.0,
100 | alpha : CGFloat(alpha))
101 | }
102 |
103 | fileprivate convenience init?(hex6: Int, alpha: Float) {
104 |
105 | self.init(red : CGFloat((hex6 & 0xFF0000) >> 16) / 255.0,
106 | green : CGFloat((hex6 & 0x00FF00) >> 8) / 255.0,
107 | blue : CGFloat((hex6 & 0x0000FF) >> 0) / 255.0,
108 | alpha : CGFloat(alpha))
109 | }
110 | }
111 |
112 |
--------------------------------------------------------------------------------
/Swift-Animations/UIFont+extension.swift:
--------------------------------------------------------------------------------
1 | //
2 | // UIFont+extension.swift
3 | // Swift-Animations
4 | //
5 | // Created by YouXianMing on 16/8/7.
6 | // Copyright © 2016年 YouXianMing. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | extension UIFont {
12 |
13 | class func AppleSDGothicNeoThin(_ value : CGFloat) -> UIFont! {
14 |
15 | return self.init(name : "AppleSDGothicNeo-Thin", size: value)
16 | }
17 |
18 | class func Avenir(_ value : CGFloat) -> UIFont! {
19 |
20 | return self.init(name : "Avenir", size: value)
21 | }
22 |
23 | class func AvenirLight(_ value : CGFloat) -> UIFont! {
24 |
25 | return self.init(name : "Avenir-Light", size: value)
26 | }
27 |
28 | class func HeitiSC(_ value : CGFloat) -> UIFont! {
29 |
30 | return self.init(name : "Heiti SC", size: value)
31 | }
32 |
33 | class func HelveticaNeueThin(_ value : CGFloat) -> UIFont! {
34 |
35 | return self.init(name : "HelveticaNeue-Thin", size: value)
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/Swift-Animations/UILabel+SizeToFit.swift:
--------------------------------------------------------------------------------
1 | //
2 | // UILabel+SizeToFit.swift
3 | // Swift-Animations
4 | //
5 | // Created by YouXianMing on 16/8/30.
6 | // Copyright © 2016年 YouXianMing. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | extension UILabel {
12 |
13 | public func sizeToFitWithWidth(_ width : CGFloat, numberOfLines : Int = 0) {
14 |
15 | var frame = self.frame
16 | frame.size.width = width
17 | self.frame = frame
18 | self.numberOfLines = numberOfLines
19 | sizeToFit()
20 | }
21 |
22 | public func sizeToFitWithString(_ string : String, width : CGFloat, numberOfLines : Int = 0) {
23 |
24 | text = string
25 | var newFrame = self.frame
26 | newFrame.size.width = width
27 | frame = newFrame
28 | self.numberOfLines = numberOfLines
29 | sizeToFit()
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/Swift-Animations/UIView+AnimationProperty.swift:
--------------------------------------------------------------------------------
1 | //
2 | // UIView+AnimationProperty.swift
3 | // Swift-Animations
4 | //
5 | // Created by YouXianMing on 16/8/4.
6 | // Copyright © 2016年 YouXianMing. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | private var scaleKey: UInt8 = 0
12 | private var angleKey: UInt8 = 0
13 |
14 | extension UIView {
15 |
16 | /// CGAffineTransformMakeScale
17 | var scale : CGFloat? {
18 |
19 | get {
20 |
21 | if let tmpValue = objc_getAssociatedObject(self, &scaleKey) as? CGFloat {
22 |
23 | return tmpValue
24 |
25 | } else {
26 |
27 | return 0
28 | }
29 | }
30 |
31 | set(newVal) {
32 |
33 | objc_setAssociatedObject(self, &scaleKey, newVal, objc_AssociationPolicy.OBJC_ASSOCIATION_RETAIN_NONATOMIC)
34 | transform = CGAffineTransform(scaleX: newVal!, y: newVal!)
35 | }
36 | }
37 |
38 | /// CGAffineTransformMakeRotation
39 | var angle : CGFloat? {
40 |
41 | get {
42 |
43 | if let tmpValue = objc_getAssociatedObject(self, &angleKey) as? CGFloat {
44 |
45 | return tmpValue
46 |
47 | } else {
48 |
49 | return 0
50 | }
51 | }
52 |
53 | set(newVal) {
54 |
55 | objc_setAssociatedObject(self, &angleKey, newVal, objc_AssociationPolicy.OBJC_ASSOCIATION_RETAIN_NONATOMIC)
56 | transform = CGAffineTransform(rotationAngle: newVal!)
57 | }
58 | }
59 | }
60 |
61 |
--------------------------------------------------------------------------------
/Swift-Animations/UIView+CreateFrame.swift:
--------------------------------------------------------------------------------
1 | //
2 | // UIView+CreateFrame.swift
3 | // Swift-Animations
4 | //
5 | // Created by YouXianMing on 16/8/7.
6 | // Copyright © 2016年 YouXianMing. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | extension UIView {
12 |
13 | /**
14 | Create Line view.
15 |
16 | - parameter frame: The frame you give.
17 | - parameter lineColor: The line color.
18 |
19 | - returns: Line view.
20 | */
21 | class func CreateLine(_ frame : CGRect, lineColor : UIColor) -> UIView {
22 |
23 | let view = UIView(frame: frame)
24 | view.backgroundColor = lineColor
25 | view.isUserInteractionEnabled = false
26 |
27 | return view
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/Swift-Animations/UIView+ScreensShot.swift:
--------------------------------------------------------------------------------
1 | //
2 | // UIView+ScreensShot.swift
3 | // Swift-Animations
4 | //
5 | // Created by YouXianMing on 16/9/5.
6 | // Copyright © 2016年 YouXianMing. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | extension UIView {
12 |
13 | /**
14 | Get the view's screen shot, this function may be called from any thread of your app.
15 |
16 | - returns: The screen shot's image.
17 | */
18 | func screenShot() -> UIImage? {
19 |
20 | guard frame.size.height > 0 && frame.size.width > 0 else {
21 |
22 | return nil
23 | }
24 |
25 | UIGraphicsBeginImageContextWithOptions(frame.size, false, 0)
26 | layer.render(in: UIGraphicsGetCurrentContext()!)
27 | let image = UIGraphicsGetImageFromCurrentImageContext()
28 | UIGraphicsEndImageContext()
29 |
30 | return image
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/Swift-Animations/UIWindow+keyWindow.swift:
--------------------------------------------------------------------------------
1 | //
2 | // UIWindow+keyWindow.swift
3 | // Swift-Animations
4 | //
5 | // Created by YouXianMing on 2017/9/13.
6 | // Copyright © 2017年 YouXianMing. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | extension UIWindow {
12 |
13 | class func getKeyWindow() -> UIWindow {
14 |
15 | return UIApplication.shared.keyWindow!
16 | }
17 | }
18 |
--------------------------------------------------------------------------------