├── .gitignore
├── README.md
├── ZHFToolBox.xcodeproj
├── project.pbxproj
├── project.xcworkspace
│ ├── contents.xcworkspacedata
│ └── xcshareddata
│ │ └── IDEWorkspaceChecks.plist
└── xcuserdata
│ └── zhanghaifeng.xcuserdatad
│ ├── xcdebugger
│ └── Breakpoints_v2.xcbkptlist
│ └── xcschemes
│ └── xcschememanagement.plist
├── ZHFToolBox
├── 1.gif
├── AppDelegate.swift
├── Assets.xcassets
│ ├── AppIcon.appiconset
│ │ └── Contents.json
│ ├── Contents.json
│ ├── back_ground.imageset
│ │ ├── Contents.json
│ │ └── back_ground.png
│ ├── bmw_image.imageset
│ │ ├── 971c6e6b3c46c573e5914bec0d6cb645.jpg
│ │ └── Contents.json
│ ├── cancel_white.imageset
│ │ ├── Contents.json
│ │ ├── cancel_white@1x.png
│ │ ├── cancel_white@2x.png
│ │ └── cancel_white@3x.png
│ ├── icon_switch.imageset
│ │ ├── Contents.json
│ │ ├── icon_switch@2x.png
│ │ └── icon_switch@3x.png
│ ├── icon_switch_r.imageset
│ │ ├── Contents.json
│ │ ├── icon_switch_r@2x.png
│ │ └── icon_switch_r@3x.png
│ ├── inner_layerImage.imageset
│ │ ├── Contents.json
│ │ └── scanSucceed_back.png
│ ├── left.imageset
│ │ ├── Contents.json
│ │ └── left.png
│ ├── outer_layerImage.imageset
│ │ ├── Contents.json
│ │ └── scanSucceed_bottom.png
│ ├── progressHint.imageset
│ │ ├── Contents.json
│ │ ├── progressHint.png
│ │ ├── progressHint@2x.png
│ │ └── progressHint@3x.png
│ ├── right.imageset
│ │ ├── Contents.json
│ │ └── right.png
│ └── test1.imageset
│ │ ├── Contents.json
│ │ └── test1.jpg
├── Base.lproj
│ ├── LaunchScreen.storyboard
│ └── Main.storyboard
├── Info.plist
├── OneVC.swift
├── RedVC.swift
├── TBCalendar
│ ├── Const.swift
│ ├── Foundation+Extension.swift
│ ├── TBCalendar.swift
│ ├── TBCalendarAppearStyle.swift
│ ├── TBCalendarDateCell.swift
│ └── TBCalendarHeaderView.swift
├── TopTopTranslucentTableView
│ ├── MessgeShowVC.swift
│ ├── NormalCell.swift
│ ├── NormalCell.xib
│ └── TopTranslucentTableView.swift
├── TwoVC.swift
├── ViewController.swift
├── ZHFSubToolBox
│ ├── CalendarView.swift
│ ├── MyNSString.swift
│ ├── PopCheckboxButtonView.swift
│ ├── PopDiseaseView.swift
│ ├── PopGifOpenBox
│ │ ├── OpenBoxView.swift
│ │ ├── PopAwayOpenBackGroundView.swift
│ │ ├── PopBackGroundView.swift
│ │ └── open_boxA.gif
│ ├── PopImageView.swift
│ ├── PopProgressBar.swift
│ ├── PopRadioButtonView.swift
│ ├── PopSmallChangeBigFatherView.swift
│ ├── PopSomeColorView.swift
│ ├── PopTextView.swift
│ ├── PopTopOrBottomOutView.swift
│ ├── SlideView.swift
│ ├── SlideWhiteViewSubView.swift
│ ├── UpDownView.swift
│ ├── ZHFAlertControllerTool.swift
│ ├── ZHFCalendarView.swift
│ └── ZHFColor.swift
└── test.json
├── ZHFToolBoxTests
├── Info.plist
└── ZHFToolBoxTests.swift
└── ZHFToolBoxUITests
├── Info.plist
└── ZHFToolBoxUITests.swift
/.gitignore:
--------------------------------------------------------------------------------
1 | # Xcode
2 | #
3 | # gitignore contributors: remember to update Global/Xcode.gitignore, Objective-C.gitignore & Swift.gitignore
4 |
5 | ## Build generated
6 | build/
7 | DerivedData/
8 |
9 | ## Various settings
10 | *.pbxuser
11 | !default.pbxuser
12 | *.mode1v3
13 | !default.mode1v3
14 | *.mode2v3
15 | !default.mode2v3
16 | *.perspectivev3
17 | !default.perspectivev3
18 | xcuserdata/
19 |
20 | ## Other
21 | *.moved-aside
22 | *.xccheckout
23 | *.xcscmblueprint
24 |
25 | ## Obj-C/Swift specific
26 | *.hmap
27 | *.ipa
28 | *.dSYM.zip
29 | *.dSYM
30 |
31 | ## Playgrounds
32 | timeline.xctimeline
33 | playground.xcworkspace
34 |
35 | # Swift Package Manager
36 | #
37 | # Add this line if you want to avoid checking in source code from Swift Package Manager dependencies.
38 | # Packages/
39 | # Package.pins
40 | .build/
41 |
42 | # CocoaPods
43 | #
44 | # We recommend against adding the Pods directory to your .gitignore. However
45 | # you should judge for yourself, the pros and cons are mentioned at:
46 | # https://guides.cocoapods.org/using/using-cocoapods.html#should-i-check-the-pods-directory-into-source-control
47 | #
48 | # Pods/
49 |
50 | # Carthage
51 | #
52 | # Add this line if you want to avoid checking in source code from Carthage dependencies.
53 | # Carthage/Checkouts
54 |
55 | Carthage/Build
56 |
57 | # fastlane
58 | #
59 | # It is recommended to not store the screenshots in the git repo. Instead, use fastlane to re-generate the
60 | # screenshots whenever they are needed.
61 | # For more information about the recommended setup visit:
62 | # https://docs.fastlane.tools/best-practices/source-control/#source-control
63 |
64 | fastlane/report.xml
65 | fastlane/Preview.html
66 | fastlane/screenshots
67 | fastlane/test_output
68 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # ZHFToolBox
2 | ## 弹框,提示框,自定义弹框,自定义提示框。包含弹出输入框,弹出单选框,弹出多选框,弹出图片,弹出简单的打开奖品的动画效果等,和大家分享高效的自定义自己项目需要的弹框思路。--Swift版本
3 |
4 |
5 |
6 | 
7 | ### 最新更新 添加一个渐变的模拟进度条
8 | ### 效果图展现的内容包含下列弹框:
9 |
10 | 1.有序弹出一些View视图。(带回弹效果)
11 |
12 | 2.一个类似商品从盒子里弹出来的效果(带回弹效果)
13 |
14 | 3.一个类似商品从高空掉入盒子的效果(带回弹效果)
15 |
16 | 4.提示框由小变大弹出(弹出区域放的是一堆按钮,可多选)
17 |
18 | 5.提示框由小变大弹出(弹出区域放的是一堆按钮,可单选)
19 |
20 | 6.提示框由小变大弹出(弹出区域放一个带占位文字的输入框TextView)
21 |
22 | 7.提示框由小变大弹出(弹出区域放一张显示图片,尾部带两个自定义按钮)
23 |
24 | 8.弹出侧滑视图(侧滑视图带tableView点击跳转)
25 |
26 | 9.剩下的几个是对系统AlertView封装后弹出的效果
27 |
28 |
29 | ### 自定义这些弹框的思路:
30 |
31 | #### 一、弹框结构分析
32 |
33 | 我们知道弹框的结构基本上都是一个半透明的黑底View,然后上边放一个白色的View。白色View上放自己要在弹框里展示的内容(图片,按钮,文字,输入框等等)。
34 |
35 | #### 二、从思路分析中我们可以知道弹框的共性
36 |
37 | 半透明的黑底View,上边白色的View。这两个是必不可少的。甚至还有一个cancel按钮。
38 |
39 | 那么我们就自定义一下这个父视图(FatherView),因为我想让这个弹框弹出来时由小变大展示,我就给它起了PopSmallChangeBigFatherView这个名字。
40 |
41 | #### 然后我给这个父视图加上下面属性
42 |
43 | 1.背景区域的颜色和透明度
44 |
45 | var backgroundColor1:UIColor = UIColor.init(red: 0, green: 0, blue: 0, alpha: 0.4)
46 |
47 | 2.白色view用来装一些控件
48 |
49 | var WhiteView: UIView = UIView()
50 |
51 | 3.WhiteView从什么位置以什么样的大小弹出
52 |
53 | var whiteViewStartFrame: CGRect = CGRect.init(x: ScreenWidth/2 - 10, y: ScreenHeight/2 - 10, width: 20, height: 20)
54 |
55 | 4.WhiteView在什么位置以什么样的大小停下来
56 |
57 | var whiteViewEndFrame: CGRect = CGRect.init(x: 40, y: 100, width: ScreenWidth - 80, height: ScreenHeight - 230)
58 |
59 | 5.WhiteView变大变小的动画时间
60 |
61 | var defaultTime:CGFloat = 0.5
62 |
63 | 6.取消按钮
64 |
65 | var cancelBtn: UIButton = UIButton()
66 |
67 | #### 然后我让这个父视
68 |
69 | 1.有初始化方法
70 |
71 | func initPopBackGroundView() -> UIView
72 |
73 | 2.弹出效果(弹出按钮被点击)
74 |
75 | func addAnimate()
76 |
77 | 3. 收回的动画效果(取消按钮被点击)
78 |
79 | @objc func tapBtnAndcancelBtnClick()
80 |
81 | ### 三、就开始写一些需要自定义的弹框
82 | 就是所有弹框都继承: PopSmallChangeBigFatherView
83 |
84 | 1.class PopImageView: PopSmallChangeBigFatherView(弹个图、重写override func addAnimate())在父视图的WhiteView写要弹出的内容
85 |
86 | 2.class PopTextView: PopSmallChangeBigFatherView(弹个输入框、重写override func addAnimate())在父视图的WhiteView写要弹出的内容
87 |
88 | 3.class PopRadioButtonView: PopSmallChangeBigFatherView(弹个单选框、重写override func addAnimate())在父视图的WhiteView写要弹出的内容
89 |
90 | 4.class PopCheckboxButtonView: PopSmallChangeBigFatherView(弹个多选框、重写override func addAnimate())在父视图的WhiteView写要弹出的内容
91 |
92 | 5.class SlideWhiteViewSubView: SlideView(弹个左右滑视图、重写override func addAnimate())在父视图的WhiteView写要侧滑展示的内容
93 |
94 | ### 四、搞个特殊的(一个类似商品(从盒子里弹出来、从高空掉入盒子)的效果(带回弹效果)PopTopOrBottomOutView这个弹出效果和上面那几个不一样。那就继承UIView,以相同的思路写了。)
95 | # PS
96 | 如果感觉有用,感谢Star Fork!
97 |
--------------------------------------------------------------------------------
/ZHFToolBox.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/ZHFToolBox.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | IDEDidComputeMac32BitWarning
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/ZHFToolBox.xcodeproj/xcuserdata/zhanghaifeng.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
--------------------------------------------------------------------------------
/ZHFToolBox.xcodeproj/xcuserdata/zhanghaifeng.xcuserdatad/xcschemes/xcschememanagement.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | SchemeUserState
6 |
7 | ZHFToolBox.xcscheme
8 |
9 | orderHint
10 | 0
11 |
12 | ZHFToolBox.xcscheme_^#shared#^_
13 |
14 | orderHint
15 | 0
16 |
17 |
18 |
19 |
20 |
--------------------------------------------------------------------------------
/ZHFToolBox/1.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FighterLightning/ZHFAlertView/7d7d19d3872ba337270bb2df0841a78138ad9a9b/ZHFToolBox/1.gif
--------------------------------------------------------------------------------
/ZHFToolBox/AppDelegate.swift:
--------------------------------------------------------------------------------
1 | //
2 | // AppDelegate.swift
3 | // ZHFToolBox
4 | //
5 | // Created by 张海峰 on 2018/5/9.
6 | // Copyright © 2018年 张海峰. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | @UIApplicationMain
12 | class AppDelegate: UIResponder, UIApplicationDelegate {
13 |
14 | var window: UIWindow?
15 |
16 |
17 | func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
18 | // Override point for customization after application launch.
19 | return true
20 | }
21 | }
22 | //定义一个全局函数打印方法
23 | //自定义标记 ->项目 ->buildSettings -> swift flag ->Debug -> -D DEBUG
24 | func ZHFLog(message : T, file : String = #file, line : Int = #line) {
25 | //在DEBUG环境下打印,在RELEASE环境下不打印
26 | #if DEBUG
27 | let file1 = (file as NSString).lastPathComponent
28 | let line1 = (line as Int)
29 | print("\(file1):line\(line1)---\(message)")
30 | #endif
31 | }
32 |
--------------------------------------------------------------------------------
/ZHFToolBox/Assets.xcassets/AppIcon.appiconset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "iphone",
5 | "size" : "20x20",
6 | "scale" : "2x"
7 | },
8 | {
9 | "idiom" : "iphone",
10 | "size" : "20x20",
11 | "scale" : "3x"
12 | },
13 | {
14 | "idiom" : "iphone",
15 | "size" : "29x29",
16 | "scale" : "2x"
17 | },
18 | {
19 | "idiom" : "iphone",
20 | "size" : "29x29",
21 | "scale" : "3x"
22 | },
23 | {
24 | "idiom" : "iphone",
25 | "size" : "40x40",
26 | "scale" : "2x"
27 | },
28 | {
29 | "idiom" : "iphone",
30 | "size" : "40x40",
31 | "scale" : "3x"
32 | },
33 | {
34 | "idiom" : "iphone",
35 | "size" : "60x60",
36 | "scale" : "2x"
37 | },
38 | {
39 | "idiom" : "iphone",
40 | "size" : "60x60",
41 | "scale" : "3x"
42 | },
43 | {
44 | "idiom" : "ipad",
45 | "size" : "20x20",
46 | "scale" : "1x"
47 | },
48 | {
49 | "idiom" : "ipad",
50 | "size" : "20x20",
51 | "scale" : "2x"
52 | },
53 | {
54 | "idiom" : "ipad",
55 | "size" : "29x29",
56 | "scale" : "1x"
57 | },
58 | {
59 | "idiom" : "ipad",
60 | "size" : "29x29",
61 | "scale" : "2x"
62 | },
63 | {
64 | "idiom" : "ipad",
65 | "size" : "40x40",
66 | "scale" : "1x"
67 | },
68 | {
69 | "idiom" : "ipad",
70 | "size" : "40x40",
71 | "scale" : "2x"
72 | },
73 | {
74 | "idiom" : "ipad",
75 | "size" : "76x76",
76 | "scale" : "1x"
77 | },
78 | {
79 | "idiom" : "ipad",
80 | "size" : "76x76",
81 | "scale" : "2x"
82 | },
83 | {
84 | "idiom" : "ipad",
85 | "size" : "83.5x83.5",
86 | "scale" : "2x"
87 | },
88 | {
89 | "idiom" : "ios-marketing",
90 | "size" : "1024x1024",
91 | "scale" : "1x"
92 | }
93 | ],
94 | "info" : {
95 | "version" : 1,
96 | "author" : "xcode"
97 | }
98 | }
--------------------------------------------------------------------------------
/ZHFToolBox/Assets.xcassets/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "info" : {
3 | "author" : "xcode",
4 | "version" : 1
5 | }
6 | }
7 |
--------------------------------------------------------------------------------
/ZHFToolBox/Assets.xcassets/back_ground.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "scale" : "1x"
6 | },
7 | {
8 | "filename" : "back_ground.png",
9 | "idiom" : "universal",
10 | "scale" : "2x"
11 | },
12 | {
13 | "idiom" : "universal",
14 | "scale" : "3x"
15 | }
16 | ],
17 | "info" : {
18 | "author" : "xcode",
19 | "version" : 1
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/ZHFToolBox/Assets.xcassets/back_ground.imageset/back_ground.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FighterLightning/ZHFAlertView/7d7d19d3872ba337270bb2df0841a78138ad9a9b/ZHFToolBox/Assets.xcassets/back_ground.imageset/back_ground.png
--------------------------------------------------------------------------------
/ZHFToolBox/Assets.xcassets/bmw_image.imageset/971c6e6b3c46c573e5914bec0d6cb645.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FighterLightning/ZHFAlertView/7d7d19d3872ba337270bb2df0841a78138ad9a9b/ZHFToolBox/Assets.xcassets/bmw_image.imageset/971c6e6b3c46c573e5914bec0d6cb645.jpg
--------------------------------------------------------------------------------
/ZHFToolBox/Assets.xcassets/bmw_image.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "filename" : "971c6e6b3c46c573e5914bec0d6cb645.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 | }
--------------------------------------------------------------------------------
/ZHFToolBox/Assets.xcassets/cancel_white.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "filename" : "cancel_white@1x.png",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "filename" : "cancel_white@2x.png",
11 | "scale" : "2x"
12 | },
13 | {
14 | "idiom" : "universal",
15 | "filename" : "cancel_white@3x.png",
16 | "scale" : "3x"
17 | }
18 | ],
19 | "info" : {
20 | "version" : 1,
21 | "author" : "xcode"
22 | }
23 | }
--------------------------------------------------------------------------------
/ZHFToolBox/Assets.xcassets/cancel_white.imageset/cancel_white@1x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FighterLightning/ZHFAlertView/7d7d19d3872ba337270bb2df0841a78138ad9a9b/ZHFToolBox/Assets.xcassets/cancel_white.imageset/cancel_white@1x.png
--------------------------------------------------------------------------------
/ZHFToolBox/Assets.xcassets/cancel_white.imageset/cancel_white@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FighterLightning/ZHFAlertView/7d7d19d3872ba337270bb2df0841a78138ad9a9b/ZHFToolBox/Assets.xcassets/cancel_white.imageset/cancel_white@2x.png
--------------------------------------------------------------------------------
/ZHFToolBox/Assets.xcassets/cancel_white.imageset/cancel_white@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FighterLightning/ZHFAlertView/7d7d19d3872ba337270bb2df0841a78138ad9a9b/ZHFToolBox/Assets.xcassets/cancel_white.imageset/cancel_white@3x.png
--------------------------------------------------------------------------------
/ZHFToolBox/Assets.xcassets/icon_switch.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "scale" : "1x"
6 | },
7 | {
8 | "idiom" : "universal",
9 | "filename" : "icon_switch@2x.png",
10 | "scale" : "2x"
11 | },
12 | {
13 | "idiom" : "universal",
14 | "filename" : "icon_switch@3x.png",
15 | "scale" : "3x"
16 | }
17 | ],
18 | "info" : {
19 | "version" : 1,
20 | "author" : "xcode"
21 | }
22 | }
--------------------------------------------------------------------------------
/ZHFToolBox/Assets.xcassets/icon_switch.imageset/icon_switch@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FighterLightning/ZHFAlertView/7d7d19d3872ba337270bb2df0841a78138ad9a9b/ZHFToolBox/Assets.xcassets/icon_switch.imageset/icon_switch@2x.png
--------------------------------------------------------------------------------
/ZHFToolBox/Assets.xcassets/icon_switch.imageset/icon_switch@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FighterLightning/ZHFAlertView/7d7d19d3872ba337270bb2df0841a78138ad9a9b/ZHFToolBox/Assets.xcassets/icon_switch.imageset/icon_switch@3x.png
--------------------------------------------------------------------------------
/ZHFToolBox/Assets.xcassets/icon_switch_r.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "scale" : "1x"
6 | },
7 | {
8 | "idiom" : "universal",
9 | "filename" : "icon_switch_r@2x.png",
10 | "scale" : "2x"
11 | },
12 | {
13 | "idiom" : "universal",
14 | "filename" : "icon_switch_r@3x.png",
15 | "scale" : "3x"
16 | }
17 | ],
18 | "info" : {
19 | "version" : 1,
20 | "author" : "xcode"
21 | }
22 | }
--------------------------------------------------------------------------------
/ZHFToolBox/Assets.xcassets/icon_switch_r.imageset/icon_switch_r@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FighterLightning/ZHFAlertView/7d7d19d3872ba337270bb2df0841a78138ad9a9b/ZHFToolBox/Assets.xcassets/icon_switch_r.imageset/icon_switch_r@2x.png
--------------------------------------------------------------------------------
/ZHFToolBox/Assets.xcassets/icon_switch_r.imageset/icon_switch_r@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FighterLightning/ZHFAlertView/7d7d19d3872ba337270bb2df0841a78138ad9a9b/ZHFToolBox/Assets.xcassets/icon_switch_r.imageset/icon_switch_r@3x.png
--------------------------------------------------------------------------------
/ZHFToolBox/Assets.xcassets/inner_layerImage.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "filename" : "scanSucceed_back.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 | }
--------------------------------------------------------------------------------
/ZHFToolBox/Assets.xcassets/inner_layerImage.imageset/scanSucceed_back.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FighterLightning/ZHFAlertView/7d7d19d3872ba337270bb2df0841a78138ad9a9b/ZHFToolBox/Assets.xcassets/inner_layerImage.imageset/scanSucceed_back.png
--------------------------------------------------------------------------------
/ZHFToolBox/Assets.xcassets/left.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "filename" : "left.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 | }
--------------------------------------------------------------------------------
/ZHFToolBox/Assets.xcassets/left.imageset/left.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FighterLightning/ZHFAlertView/7d7d19d3872ba337270bb2df0841a78138ad9a9b/ZHFToolBox/Assets.xcassets/left.imageset/left.png
--------------------------------------------------------------------------------
/ZHFToolBox/Assets.xcassets/outer_layerImage.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "filename" : "scanSucceed_bottom.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 | }
--------------------------------------------------------------------------------
/ZHFToolBox/Assets.xcassets/outer_layerImage.imageset/scanSucceed_bottom.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FighterLightning/ZHFAlertView/7d7d19d3872ba337270bb2df0841a78138ad9a9b/ZHFToolBox/Assets.xcassets/outer_layerImage.imageset/scanSucceed_bottom.png
--------------------------------------------------------------------------------
/ZHFToolBox/Assets.xcassets/progressHint.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "filename" : "progressHint.png",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "filename" : "progressHint@2x.png",
11 | "scale" : "2x"
12 | },
13 | {
14 | "idiom" : "universal",
15 | "filename" : "progressHint@3x.png",
16 | "scale" : "3x"
17 | }
18 | ],
19 | "info" : {
20 | "version" : 1,
21 | "author" : "xcode"
22 | }
23 | }
--------------------------------------------------------------------------------
/ZHFToolBox/Assets.xcassets/progressHint.imageset/progressHint.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FighterLightning/ZHFAlertView/7d7d19d3872ba337270bb2df0841a78138ad9a9b/ZHFToolBox/Assets.xcassets/progressHint.imageset/progressHint.png
--------------------------------------------------------------------------------
/ZHFToolBox/Assets.xcassets/progressHint.imageset/progressHint@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FighterLightning/ZHFAlertView/7d7d19d3872ba337270bb2df0841a78138ad9a9b/ZHFToolBox/Assets.xcassets/progressHint.imageset/progressHint@2x.png
--------------------------------------------------------------------------------
/ZHFToolBox/Assets.xcassets/progressHint.imageset/progressHint@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FighterLightning/ZHFAlertView/7d7d19d3872ba337270bb2df0841a78138ad9a9b/ZHFToolBox/Assets.xcassets/progressHint.imageset/progressHint@3x.png
--------------------------------------------------------------------------------
/ZHFToolBox/Assets.xcassets/right.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "filename" : "right.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 | }
--------------------------------------------------------------------------------
/ZHFToolBox/Assets.xcassets/right.imageset/right.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FighterLightning/ZHFAlertView/7d7d19d3872ba337270bb2df0841a78138ad9a9b/ZHFToolBox/Assets.xcassets/right.imageset/right.png
--------------------------------------------------------------------------------
/ZHFToolBox/Assets.xcassets/test1.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "filename" : "test1.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 | }
--------------------------------------------------------------------------------
/ZHFToolBox/Assets.xcassets/test1.imageset/test1.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FighterLightning/ZHFAlertView/7d7d19d3872ba337270bb2df0841a78138ad9a9b/ZHFToolBox/Assets.xcassets/test1.imageset/test1.jpg
--------------------------------------------------------------------------------
/ZHFToolBox/Base.lproj/LaunchScreen.storyboard:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
--------------------------------------------------------------------------------
/ZHFToolBox/Base.lproj/Main.storyboard:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
--------------------------------------------------------------------------------
/ZHFToolBox/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | $(DEVELOPMENT_LANGUAGE)
7 | CFBundleExecutable
8 | $(EXECUTABLE_NAME)
9 | CFBundleIdentifier
10 | $(PRODUCT_BUNDLE_IDENTIFIER)
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | $(PRODUCT_NAME)
15 | CFBundlePackageType
16 | APPL
17 | CFBundleShortVersionString
18 | 1.0
19 | CFBundleVersion
20 | 1
21 | LSRequiresIPhoneOS
22 |
23 | UILaunchStoryboardName
24 | LaunchScreen
25 | UIMainStoryboardFile
26 | Main
27 | UIRequiredDeviceCapabilities
28 |
29 | armv7
30 |
31 | UISupportedInterfaceOrientations
32 |
33 | UIInterfaceOrientationPortrait
34 | UIInterfaceOrientationLandscapeLeft
35 | UIInterfaceOrientationLandscapeRight
36 |
37 | UISupportedInterfaceOrientations~ipad
38 |
39 | UIInterfaceOrientationPortrait
40 | UIInterfaceOrientationPortraitUpsideDown
41 | UIInterfaceOrientationLandscapeLeft
42 | UIInterfaceOrientationLandscapeRight
43 |
44 |
45 |
46 |
--------------------------------------------------------------------------------
/ZHFToolBox/OneVC.swift:
--------------------------------------------------------------------------------
1 | //
2 | // OneVC.swift
3 | // ZHFToolBox
4 | //
5 | // Created by 张海峰 on 2018/5/9.
6 | // Copyright © 2018年 张海峰. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | class OneVC: UIViewController {
12 | override func viewDidLoad() {
13 | super.viewDidLoad()
14 | self.view.backgroundColor = ZHFColor.orange
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/ZHFToolBox/RedVC.swift:
--------------------------------------------------------------------------------
1 | //
2 | // RedVC.swift
3 | // SlideViewTest
4 | //
5 | // Created by 张海峰 on 2018/11/14.
6 | // Copyright © 2018年 张海峰. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | class RedVC: UIViewController {
12 | var message:String = ""
13 | override func viewDidLoad() {
14 | super.viewDidLoad()
15 | self.view.backgroundColor = UIColor.red
16 | self.title = message
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/ZHFToolBox/TBCalendar/Const.swift:
--------------------------------------------------------------------------------
1 | //
2 | // Const.swift
3 | // SwiftTest
4 | //
5 | // Created by 1111 on 2017/11/7.
6 | // Copyright © 2017年 xuejianfeng. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | let kScreenHeight = UIScreen.main.bounds.size.height
12 | let kScreenWidth = UIScreen.main.bounds.size.width
13 |
14 | //=================系统参数相关===============
15 | // iPhone X
16 | let iPhoneX = (kScreenWidth == 375 && kScreenHeight == 812) ? true : false
17 | let CURRENT_SYS_VERSION = (UIDevice.current.systemVersion as NSString).floatValue
18 | let IOS8 = (UIDevice.current.systemVersion as NSString).doubleValue >= 8.0
19 | let NAV_HEIGHT = iPhoneX ? (44 + 44) : 64
20 | let TABBAR_HEIGHT = iPhoneX ? (49 + 34) : 49
21 | let kTabbarSafeBottomMargin = iPhoneX ? 34 : 0
22 | let BATTERY_BARHEIGHT = iPhoneX ? 44 : 20
23 | //===================================
24 | enum TBCalendarHeaderViewType: Int {
25 | case leftDate
26 | case centerDate
27 | }
28 |
29 | let CHANGE_SELECT_DATE: String = "change_select_date"
30 |
--------------------------------------------------------------------------------
/ZHFToolBox/TBCalendar/Foundation+Extension.swift:
--------------------------------------------------------------------------------
1 | //
2 | // Foundation+Extension.swift
3 | // SwiftTest
4 | //
5 | // Created by 1111 on 2018/3/19.
6 | // Copyright © 2018年 xuejianfeng. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | extension String {
12 | /// 计算文本的高度
13 | func textHeight(fontSize: CGFloat, width: CGFloat) -> CGFloat {
14 | return self.boundingRect(with: CGSize(width: width, height: CGFloat(MAXFLOAT)), options: .usesLineFragmentOrigin, attributes: [.font: UIFont.systemFont(ofSize: fontSize)], context: nil).size.height
15 | }
16 | }
17 |
18 | extension UIView{
19 | ///点击事件
20 | func addTargetForTouch(target: Any, action: Selector){
21 | let singleTap = UITapGestureRecognizer.init(target: target, action: action)
22 | self.addGestureRecognizer(singleTap)
23 | }
24 |
25 | // 长按事件
26 | func addTargetForLongTouch(target: Any, action: Selector){
27 | let singleTap = UILongPressGestureRecognizer.init(target: target, action: action)
28 | singleTap.cancelsTouchesInView = false
29 | singleTap.minimumPressDuration = 0
30 | self.addGestureRecognizer(singleTap)
31 | }
32 |
33 | func fadeIn() {
34 | self.transform = CGAffineTransform.init(scaleX: 1.3, y: 1.3)
35 | self.alpha = 0;
36 |
37 | UIView.animate(withDuration: 0.35) {
38 | self.alpha = 1;
39 | self.transform = CGAffineTransform.init(scaleX: 1.0, y: 1.0)
40 | }
41 | }
42 |
43 | func fadeOut() {
44 | UIView.animate(withDuration: 0.35, animations: {
45 | self.transform = CGAffineTransform.init(scaleX: 1.3, y: 1.3)
46 | self.alpha = 0.0;
47 | }) { (finished) in
48 | if (finished) {
49 | self.removeFromSuperview()
50 | }
51 | }
52 | }
53 |
54 | func show() {
55 | let keywindow = UIApplication.shared.keyWindow
56 | keywindow?.addSubview(self)
57 |
58 | self.center = CGPoint.init(x: (keywindow?.bounds.size.width)! / 2, y: (keywindow?.bounds.size.height)! / 2)
59 | self.fadeIn()
60 | }
61 |
62 | func dismiss(){
63 | self.fadeOut()
64 | }
65 | }
66 |
67 | extension UILabel {
68 | class func createWithLable(text: String, textColor: UIColor, textFont: UIFont, aliment: NSTextAlignment) -> UILabel {
69 |
70 | let label = UILabel.init()
71 | label.text = text
72 | label.textColor = textColor
73 | label.textAlignment = aliment
74 | label.font = textFont
75 |
76 | return label
77 | }
78 | }
79 |
80 | extension Date {
81 |
82 | func getDateWithDay() -> Int {
83 |
84 | return NSCalendar.current.component(.day, from: self)
85 | }
86 |
87 | func getDateWithMonth() -> Int {
88 | return NSCalendar.current.component(.month, from: self)
89 | }
90 |
91 | func getDateWithYear() -> Int {
92 | return NSCalendar.current.component(.year, from: self)
93 | }
94 |
95 | /// 判断当前日期是否为今年
96 | func isThisYear() -> Bool {
97 | // 获取当前日历
98 | let calender = Calendar.current
99 | // 获取日期的年份
100 | let yearComps = calender.component(.year, from: self)
101 | // 获取现在的年份
102 | let nowComps = calender.component(.year, from: Date())
103 |
104 | return yearComps == nowComps
105 | }
106 |
107 | /// 是否是昨天
108 | func isYesterday() -> Bool {
109 | // 获取当前日历
110 | let calender = Calendar.current
111 | // 获取日期的年份
112 | let comps = calender.dateComponents([.year, .month, .day], from: self, to: Date())
113 | // 根据头条显示时间 ,我觉得可能有问题 如果comps.day == 0 显示相同,如果是 comps.day == 1 显示时间不同
114 | // 但是 comps.day == 1 才是昨天 comps.day == 2 是前天
115 | // return comps.year == 0 && comps.month == 0 && comps.day == 1
116 | return comps.year == 0 && comps.month == 0 && comps.day == 0
117 | }
118 |
119 | /// 是否是前天
120 | func isBeforeYesterday() -> Bool {
121 | // 获取当前日历
122 | let calender = Calendar.current
123 | // 获取日期的年份
124 | let comps = calender.dateComponents([.year, .month, .day], from: self, to: Date())
125 | //
126 | // return comps.year == 0 && comps.month == 0 && comps.day == 2
127 | return comps.year == 0 && comps.month == 0 && comps.day == 1
128 | }
129 |
130 | /// 判断是否是今天
131 | func isToday() -> Bool {
132 | // 日期格式化
133 | let formatter = DateFormatter()
134 | // 设置日期格式
135 | formatter.dateFormat = "yyyy-MM-dd"
136 |
137 | let dateStr = formatter.string(from: self)
138 | let nowStr = formatter.string(from: Date())
139 | return dateStr == nowStr
140 | }
141 |
142 | }
143 |
144 | /**
145 | * 扩展部分
146 | */
147 | extension UIColor {
148 |
149 | /**
150 | * 16进制 转 RGBA
151 | */
152 | class func UIColorFromRGBA(rgb:Int, alpha:CGFloat) ->UIColor {
153 |
154 | return UIColor(red: ((CGFloat)((rgb & 0xFF0000) >> 16)) / 255.0,
155 | green: ((CGFloat)((rgb & 0xFF00) >> 8)) / 255.0,
156 | blue: ((CGFloat)(rgb & 0xFF)) / 255.0,
157 | alpha: alpha)
158 | }
159 |
160 | /**
161 | * 16进制 转 RGB
162 | */
163 | class func UIColorFromRGB(rgb:Int) ->UIColor {
164 |
165 | return UIColor(red: ((CGFloat)((rgb & 0xFF0000) >> 16)) / 255.0,
166 | green: ((CGFloat)((rgb & 0xFF00) >> 8)) / 255.0,
167 | blue: ((CGFloat)(rgb & 0xFF)) / 255.0,
168 | alpha: 1.0)
169 | }
170 | }
171 |
172 | /**
173 | * 设置控件的阴影参数
174 | */
175 |
176 | func setShadowForView(view: UIView, color: UIColor, shadowOffset: CGSize, shadowOpacity: CGFloat, shadowRadius: CGFloat){
177 | view.layer.shadowColor = color.cgColor//shadowColor阴影颜色
178 | view.layer.shadowOffset = shadowOffset//shadowOffset阴影偏移,x向右偏移4,y向下偏移4,默认(0, -3),这个跟shadowRadius配合使用
179 | view.layer.shadowOpacity = Float(shadowOpacity)//阴影透明度,默认0
180 | view.layer.shadowRadius = shadowRadius//阴影半径,默认3
181 | }
182 |
183 | func compareDate(oneDay: NSDate, anotherDay: NSDate) -> Int{
184 |
185 | let dateFormatter = DateFormatter.init()
186 | dateFormatter.dateFormat = "yyyy-MM"
187 |
188 | let dateA = dateFormatter.date(from: dateFormatter.string(from: oneDay as Date))
189 | let dateB = dateFormatter.date(from: dateFormatter.string(from: anotherDay as Date))
190 |
191 | let result = dateA?.compare(dateB!)
192 | if (result!.rawValue == ComparisonResult.orderedDescending.rawValue) {
193 | //NSLog(@"Date1 is in the future");
194 | return 1;
195 | }
196 | else if (result!.rawValue == ComparisonResult.orderedAscending.rawValue){
197 | //NSLog(@"Date1 is in the past");
198 | return -1;
199 | }
200 | //NSLog(@"Both dates are the same");
201 | return 0;
202 | }
203 |
204 | func getMonthEnd(date: NSDate) -> NSDate {
205 | let format = DateFormatter.init()
206 | format.dateFormat = "yyyy-MM"
207 | let newDate: Date = format.date(from: format.string(from: date as Date))!
208 | var interval: Double = 0
209 | var beginDate: Date = Date()
210 | var endDate: Date = Date()
211 | var calendar = NSCalendar.current
212 | calendar.firstWeekday = 2 //设定周一为周首日
213 | let ok: Bool = calendar.dateInterval(of: .month, start: &beginDate, interval: &interval, for: newDate)
214 | //分别修改为 NSDayCalendarUnit NSWeekCalendarUnit NSYearCalendarUnit
215 | if (ok) {
216 | endDate = beginDate.addingTimeInterval(interval - 1)
217 | }else {
218 | return Date.init() as NSDate;
219 | }
220 | let myDateFormatter = DateFormatter.init()
221 | myDateFormatter.dateFormat = "yyyy-MM-dd"
222 | endDate = myDateFormatter.date(from: myDateFormatter.string(from: endDate))!
223 | return endDate as NSDate;
224 | }
225 |
226 | func getMonthBegin(date: NSDate) -> NSDate {
227 | let format = DateFormatter.init()
228 | format.dateFormat = "yyyy-MM"
229 | let newDate: Date = format.date(from: format.string(from: date as Date))!
230 | var interval: Double = 0
231 | var beginDate: Date = Date()
232 | var endDate: Date = Date()
233 | var calendar = NSCalendar.current
234 | calendar.firstWeekday = 2 //设定周一为周首日
235 |
236 | let ok: Bool = calendar.dateInterval(of: .month, start: &beginDate, interval: &interval, for: newDate)
237 | //分别修改为 NSDayCalendarUnit NSWeekCalendarUnit NSYearCalendarUnit
238 | if (ok) {
239 | endDate = beginDate.addingTimeInterval(interval - 1)
240 | }else {
241 | return Date.init() as NSDate;
242 | }
243 |
244 | let myDateFormatter = DateFormatter.init()
245 | myDateFormatter.dateFormat = "yyyy-MM-dd"
246 | endDate = Date.init(timeInterval: -86400, since: beginDate)
247 |
248 | return endDate as NSDate;
249 | }
250 |
--------------------------------------------------------------------------------
/ZHFToolBox/TBCalendar/TBCalendar.swift:
--------------------------------------------------------------------------------
1 | //
2 | // TBCalendar.swift
3 | // SwiftTest
4 | //
5 | // Created by 1111 on 2018/4/9.
6 | // Copyright © 2018年 xuejianfeng. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | @objc protocol TBCalendarDataSource: NSObjectProtocol{
12 | /**
13 | * Tells the dataSource a call back is the calendar of height.
14 | */
15 | @objc func calender(calender: TBCalendar, layoutCallBackHeight: CGFloat) -> Void
16 |
17 | /**
18 | * Asks the dataSource for a title for the specific date as a replacement of the day text
19 | */
20 | @objc optional func calendar(calendar: TBCalendar, titleForDate: NSDate) -> String
21 |
22 | /**
23 | * Asks the dataSource for a subtitle for the specific date under the day text.
24 | */
25 | @objc optional func calender(calendar: TBCalendar, subTitleForDate: NSDate) -> String
26 | }
27 |
28 | @objc protocol TBCalendarDataDelegate: NSObjectProtocol{
29 | /**
30 | * Asks the delegate whether the specific date is allowed to be selected by tapping.
31 | */
32 | @objc optional func calender(calender: TBCalendar, shouldSelectDate: NSDate) -> Void
33 |
34 | /**
35 | * Tells the delegate a date in the calendar is selected by tapping.
36 | */
37 | @objc optional func calender(calender: TBCalendar, didSelectDate: NSDate) -> Void
38 | }
39 |
40 |
41 | class TBCalendar: UIView, UICollectionViewDelegate, UICollectionViewDataSource{
42 | static let TBCalendarDateCellID = "LZBCalendarDateCellID"
43 | static let limitation_Low = 28
44 | static let limitation_Medium = 35
45 | static let limitation_High = 42
46 |
47 | /**
48 | * The object that acts as the data source of the calendar.
49 | */
50 | var dataSource: TBCalendarDataSource?
51 |
52 | /**
53 | * The object that acts as the data source of the calendar.
54 | */
55 | var delegate: TBCalendarDataDelegate?
56 |
57 | private var itemHeight: CGFloat = 0
58 | private var style: TBCalendarAppearStyle?
59 | private var currentSelctCell: TBCalendarDateCell?
60 | private var dotArr = [UIView]()
61 | private var itemNum: Int?
62 |
63 | lazy var contentView: UIView = getContentView()
64 | lazy var collectionView: UICollectionView = getCollectionView()
65 | lazy var collectFlowLayout: UICollectionViewFlowLayout = getCollectFlowLayout()
66 | lazy var headerView: TBCalendarHeaderView = self.getHeaderView()
67 |
68 | init(style: TBCalendarAppearStyle, frame: CGRect) {
69 | super.init(frame: frame)
70 | self.style = style
71 | self.setupUI()
72 | }
73 |
74 | func setupUI() {
75 | self.addSubview(self.headerView)
76 | self.headerView.monthDate = (self.style?.today)!
77 | self.addSubview(self.contentView)
78 | self.contentView.addSubview(self.collectionView)
79 | self.collectionView.register(TBCalendarDateCell.self, forCellWithReuseIdentifier: TBCalendar.TBCalendarDateCellID)
80 |
81 |
82 | self.headerView.previousMonth = {(date) ->Void in
83 | self.style?.today = date;
84 | self.setNeedsLayout()
85 | self.collectionView.reloadData()
86 | }
87 |
88 | self.headerView.nextMonth = {(date) ->Void in
89 | self.style?.today = date;
90 | self.setNeedsLayout()
91 | self.collectionView.reloadData()
92 | }
93 | }
94 |
95 | override func layoutSubviews() {
96 | super.layoutSubviews()
97 |
98 | let width = self.bounds.size.width;
99 | self.headerView.frame = CGRect.init(x: 0, y: 0, width: width, height: (self.style?.headerViewHeihgt!)!);
100 | layoutCollectionView()
101 | self.itemNum = 1;
102 | }
103 |
104 | func layoutCollectionView() {
105 |
106 | let itemWidth = Int(self.bounds.size.width) / (self.style?.weekDateDays.count)!;
107 | var itemHeight = itemWidth;
108 | if((self.style?.isNeedCustomHeihgt)! && (self.style?.itemHeight)! > 0.0)
109 | {
110 | itemHeight = Int((self.style?.itemHeight)!)
111 | }
112 | else
113 | {
114 | itemHeight = itemWidth;
115 | }
116 | self.itemHeight = CGFloat(itemHeight);
117 | self.collectFlowLayout.itemSize = CGSize.init(width: CGFloat(itemWidth), height: CGFloat(itemHeight - 10))
118 |
119 | //collectinView高度
120 | let marginDays = self.firstDayInFirstWeekThisMonth(date: (self.style?.today)!)
121 | let itemCount = marginDays + self.totalDaysThisMonth(date: (self.style?.today)!)
122 | var collectionViewHeight = 0;
123 | if(itemCount <= TBCalendar.limitation_Low){
124 | collectionViewHeight = TBCalendar.limitation_Low / (self.style?.weekDateDays.count)! * Int(self.itemHeight)
125 | }
126 | else if(itemCount > TBCalendar.limitation_Low && itemCount <= TBCalendar.limitation_Medium){
127 | collectionViewHeight = TBCalendar.limitation_Medium/(self.style?.weekDateDays.count)! * Int(self.itemHeight)
128 | }
129 | else{
130 | collectionViewHeight = TBCalendar.limitation_High/(self.style?.weekDateDays.count)! * Int(self.itemHeight)
131 | }
132 |
133 |
134 | self.collectionView.frame = CGRect.init(x: 0, y: 0, width: Int(self.bounds.size.width), height: collectionViewHeight - 50);
135 |
136 |
137 | self.contentView.frame = CGRect.init(x: 0, y: self.headerView.frame.maxY, width: self.bounds.size.width, height: CGFloat(Int(collectionViewHeight) - 50))
138 | self.collectionView.collectionViewLayout = self.collectFlowLayout
139 |
140 | self.callBackHeight(height: CGFloat(collectionViewHeight) + (self.style?.headerViewHeihgt)! + 10)
141 | }
142 | // collectCell-dataSource
143 | func collectionView(_ collectionView: UICollectionView, shouldSelectItemAt indexPath: IndexPath) -> Bool {
144 |
145 | let marginDays = self.firstDayInFirstWeekThisMonth(date: (self.style?.today)!)
146 | let daysThisMonth = self.totalDaysThisMonth(date: (self.style?.today)!)
147 |
148 | if(indexPath.row >= marginDays && indexPath.row <= marginDays + daysThisMonth - 1)
149 | {
150 | var day = 0;
151 | day = indexPath.row - marginDays + 1
152 | let date = self.dateByday(day: day, date: (self.style?.today)!)
153 |
154 | return self.shouldSelectDate(date: date as NSDate)
155 | }
156 | else{
157 | return false
158 | }
159 |
160 | }
161 |
162 | @objc func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
163 |
164 | let marginDays: NSInteger = self.firstDayInFirstWeekThisMonth(date: (self.style?.today)!);
165 | let daysThisMonth: NSInteger = self.totalDaysThisMonth(date: (self.style?.today)!);
166 | if(indexPath.row >= marginDays && (indexPath.row <= (marginDays + daysThisMonth - 1))){
167 |
168 | let day: NSInteger = indexPath.row - marginDays + 1
169 | let date: Date = self.dateByday(day: day, date: (self.style?.today)!)
170 | let cell: TBCalendarDateCell = collectionView.cellForItem(at: indexPath) as! TBCalendarDateCell
171 | if(self.style!.isSupportMoreSelect!){
172 | self.didSelectDate(date: date as NSDate)
173 | cell.updateCellSelectCellColor()
174 | }
175 | else
176 | {
177 | if(self.currentSelctCell == cell)
178 | {
179 | return;
180 | }
181 |
182 | self.currentSelctCell?.isSelected = false
183 | self.currentSelctCell?.updateCellSelectCellColor()
184 | cell.isSelected = true
185 | self.currentSelctCell = cell
186 | self.didSelectDate(date: date as NSDate)
187 | cell.updateCellSelectCellColor(animation:true)
188 | }
189 | }
190 | else
191 | {
192 | // self.collectionView(collectionView, didDeselectItemAt: indexPath)
193 | }
194 | }
195 |
196 | // DataSource
197 | func titleForDate(date: NSDate) -> String {
198 |
199 | if (self.dataSource != nil) && (self.dataSource?.responds(to: #selector(TBCalendarDataSource.calendar(calendar:titleForDate:))))! {
200 | return (self.dataSource?.calendar!(calendar: self, titleForDate: date))!
201 | }
202 |
203 | return "";
204 | }
205 |
206 |
207 | func subtitleForDate(date: NSDate) -> String {
208 | if (self.dataSource != nil) && (self.dataSource?.responds(to: #selector(TBCalendarDataSource.calender(calendar:subTitleForDate:))))! {
209 | return (self.dataSource?.calender!(calendar: self, subTitleForDate: date))!
210 | }
211 |
212 | return ""
213 | }
214 |
215 | func callBackHeight(height: CGFloat) -> Void {
216 | if (self.dataSource != nil) && (self.dataSource?.responds(to: #selector(TBCalendarDataSource.calender(calender:layoutCallBackHeight:))))! {
217 | return (self.dataSource?.calender(calender: self, layoutCallBackHeight: height))!
218 | }
219 | }
220 |
221 | // delegate
222 | func shouldSelectDate(date: NSDate) -> Bool {
223 |
224 | if (self.delegate != nil) && (self.delegate?.responds(to: #selector(TBCalendarDataDelegate.calender(calender:shouldSelectDate:))))! {
225 | return ((self.delegate?.calender!(calender: self, shouldSelectDate: date)) != nil)
226 | }
227 |
228 | return true
229 | }
230 |
231 | func didSelectDate(date: NSDate) {
232 |
233 | if (self.delegate != nil) && (self.delegate?.responds(to: #selector(TBCalendarDataDelegate.calender(calender:didSelectDate:))))! {
234 | self.delegate?.calender!(calender: self, didSelectDate: date)
235 | }
236 | }
237 |
238 | func setDataArr(arr: [UIView]) {
239 | self.dotArr.removeAll()
240 | self.dotArr += arr
241 | self.collectionView.reloadData()
242 | }
243 |
244 | // private
245 | func totalDaysThisMonth(date: NSDate) -> Int {
246 | let range = NSCalendar.current.range(of: .day, in: .month, for: date as Date)
247 |
248 | return (range?.count)!
249 | }
250 |
251 | func firstDayInFirstWeekThisMonth(date: NSDate) -> Int {
252 | var calendar = NSCalendar.current
253 | calendar.firstWeekday = 1
254 |
255 | var comp = calendar.dateComponents([.year, .month, .day], from: date as Date)
256 | comp.day = 1;
257 |
258 | let firstDayOfMonthDate = calendar.date(from: comp)
259 | let firstWeekday = calendar.ordinality(of: .weekday, in: .weekOfMonth, for: firstDayOfMonthDate!)
260 | return firstWeekday! - 1
261 | }
262 |
263 | func dateByday(day: Int, date: NSDate) -> Date {
264 | let calendar = NSCalendar.current
265 | let comp = calendar.dateComponents([.year, .month, .day], from: date as Date)
266 | let newComp = NSDateComponents.init()
267 | newComp.day = day
268 | newComp.year = comp.year!
269 | newComp.month = comp.month!
270 |
271 | let formatter = DateFormatter.init()
272 | formatter.dateFormat = "YYYY-MM-dd"
273 | let string: String = "\(newComp.year)" + "-" + "\(newComp.month)" + "-" + "\(newComp.day)"
274 |
275 | return formatter.date(from: string)!
276 | }
277 |
278 | // UICollectionViewDataSource
279 | func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
280 |
281 | let marginDays = self.firstDayInFirstWeekThisMonth(date: (self.style?.today)!)
282 | let itemCount = marginDays + self.totalDaysThisMonth(date: (self.style?.today)!)
283 |
284 | if itemCount >= TBCalendar.limitation_High {
285 | return 0
286 | }
287 |
288 | if (itemCount > TBCalendar.limitation_Medium) && (itemCount <= TBCalendar.limitation_High) {
289 | return TBCalendar.limitation_High
290 | }
291 | else if (itemCount > TBCalendar.limitation_Low) && (itemCount <= TBCalendar.limitation_Medium){
292 | return TBCalendar.limitation_Medium
293 | }
294 | else{
295 | return TBCalendar.limitation_Low
296 | }
297 | }
298 |
299 | func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
300 |
301 | let cell: TBCalendarDateCell = collectionView.dequeueReusableCell(withReuseIdentifier: TBCalendar.TBCalendarDateCellID, for: indexPath) as! TBCalendarDateCell
302 | cell.isSelected = false
303 | cell.updateCellSelectCellColor()
304 | cell.style = (self.style)!
305 | let marginDays = self.firstDayInFirstWeekThisMonth(date: (self.style?.today)!)
306 | let daysThisMonth = self.totalDaysThisMonth(date: (self.style?.today)!)
307 |
308 | cell.updateCellDotView(status: "7")
309 | if indexPath.row < marginDays {
310 | cell.updateCellDotView(status: "7")
311 | cell.reloadCellData(title: "", subTitle: "")
312 | }
313 | else if indexPath.row > (marginDays + daysThisMonth - 1) {
314 | cell.updateCellDotView(status: "7")
315 | cell.reloadCellData(title: "", subTitle: "")
316 | }
317 | else{
318 | cell.updateCellDotView(status: "7")
319 |
320 | let day = indexPath.row - marginDays + 1
321 | let date = self.dateByday(day: day, date: (self.style?.today)!)
322 | cell.isSelected = self.isToday(date: date, cell: cell)
323 |
324 | let row = indexPath.row
325 | if (row % 7 == 0) || ((row + 1) % 7 == 0){
326 | cell.dateLabel.textColor = UIColor.UIColorFromRGB(rgb: 0x999999)
327 | }
328 | else{
329 | cell.dateLabel.textColor = UIColor.UIColorFromRGB(rgb: 0x000000)
330 | }
331 |
332 | let dateFormatter = DateFormatter.init()
333 | dateFormatter.dateFormat = "dd"
334 |
335 | if self.dotArr.count > 0 {
336 |
337 | let v = self.dotArr[indexPath.row - marginDays]
338 | if v.tag == -2 || v.tag == -1{
339 | cell.isSelected = true;
340 | self.currentSelctCell = cell
341 | }
342 | else
343 | {
344 | cell.isSelected = false
345 | }
346 | }
347 | else{
348 | cell.updateCellDotView(status: "7")
349 | }
350 |
351 | let dateStr: String = self.titleForDate(date: date as NSDate)
352 | if dateStr.count > 0{
353 | cell.reloadCellData(title: dateStr)
354 | }
355 | else {
356 | cell.reloadCellData(title: "\(day)")
357 | }
358 | }
359 |
360 | cell.updateCellSelectBackgroundColor()
361 | return cell
362 | }
363 |
364 | func isToday(date: Date, cell: TBCalendarDateCell) -> Bool {
365 |
366 | let nowDate = Date()
367 | if date.getDateWithMonth() == nowDate.getDateWithMonth() {
368 | let result = nowDate.getDateWithDay() - date.getDateWithDay()
369 | if result == 0 {
370 | self.currentSelctCell = cell
371 | return true
372 | }
373 | else {
374 | return false
375 | }
376 | }
377 |
378 | return true
379 | }
380 |
381 | // lazy
382 | func getHeaderView() -> TBCalendarHeaderView {
383 | let headerView = TBCalendarHeaderView.init(type: .centerDate, style: self.style!, frame: CGRect.init())
384 | return headerView
385 | }
386 |
387 | func getContentView() -> UIView {
388 | let view = UIView.init()
389 | view.backgroundColor = UIColor.UIColorFromRGB(rgb: 0xffffff)
390 | return view
391 | }
392 |
393 | func getCollectionView() -> UICollectionView {
394 | let collectionView = UICollectionView.init(frame: self.contentView.bounds, collectionViewLayout: self.collectFlowLayout)
395 | collectionView.dataSource = self
396 | collectionView.delegate = self
397 | collectionView.backgroundColor = UIColor.UIColorFromRGB(rgb: 0xffffff)
398 | return collectionView
399 | }
400 |
401 | func getCollectFlowLayout() -> UICollectionViewFlowLayout {
402 | let collectFlowLayout = UICollectionViewFlowLayout.init()
403 | collectFlowLayout.minimumLineSpacing = 0.0;
404 | collectFlowLayout.minimumInteritemSpacing = 0.0;
405 | collectFlowLayout.sectionInset = UIEdgeInsets(top: 0, left: 0, bottom: 0, right: 0);
406 | return collectFlowLayout
407 | }
408 |
409 | required init?(coder aDecoder: NSCoder) {
410 | fatalError("init(coder:) has not been implemented")
411 | }
412 | }
413 |
--------------------------------------------------------------------------------
/ZHFToolBox/TBCalendar/TBCalendarAppearStyle.swift:
--------------------------------------------------------------------------------
1 | //
2 | // TBCalendarAppearStyle.swift
3 | // SwiftTest
4 | //
5 | // Created by 1111 on 2018/4/2.
6 | // Copyright © 2018年 xuejianfeng. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | class TBCalendarAppearStyle: NSObject {
12 | // head-data
13 | /**
14 | * 设置item的高度,isNeedCustomHeihgt是YES,可以设置itemHeight
15 | */
16 | var isNeedCustomHeihgt: Bool?
17 | /**
18 | * 设置当前日期
19 | */
20 | var today: NSDate?
21 | /**
22 | * 设置是否支持同时选中多个日期,默认isSupportMoreSelect = NO
23 | */
24 | var isSupportMoreSelect: Bool?
25 | /**
26 | * 设置星期日期的样式,默认是中文 @"日",@"一",@"二",@"三",@"四",@"五",@"六"
27 | */
28 | var weekDateDays = [String]()
29 |
30 | //头部style设置
31 | /**
32 | * 设置头部View的选择月份View的高度
33 | */
34 | var headerViewDateHeight: CGFloat?
35 | /**
36 | * 设置头部View的星期几View的高度
37 | */
38 | var headerViewWeekHeight: CGFloat?
39 | /**
40 | * 设置头部View的星期几View与选择月份View中间分割线的高度
41 | */
42 | var headerViewLineHeight: CGFloat?
43 | /**
44 | * 获得整个头部View的高度
45 | */
46 | var headerViewHeihgt: CGFloat?
47 | /**
48 | * 设置头部View的选择月份View的字体
49 | */
50 | var headerViewDateFont: UIFont?
51 | /**
52 | * 设置头部View的选择月份View的字体颜色
53 | */
54 | var headerViewDateColor: UIColor?
55 | /**
56 | * 设置头部View的星期几View的字体
57 | */
58 | var headerViewWeekFont: UIFont?
59 | /**
60 | * 设置头部View的星期几View的字体颜色
61 | */
62 | var headerViewWeekColor: UIColor?
63 |
64 | // 日期sytle设置
65 | /**
66 | * 设置日期item的的高度,宽度根据屏幕宽度自动适应 isNeedCustomHeihgt = YES 有效
67 | */
68 | var itemHeight: CGFloat?
69 | /**
70 | * 设置日期item的标题字体大小
71 | */
72 | var dateTittleFont: UIFont?
73 | /**
74 | * 设置日期item的描述字体大小
75 | */
76 | var dateDescFont: UIFont?
77 | /**
78 | * 设置日期item的标题字体选中颜色
79 | */
80 | var dateTittleSelectColor: UIColor?
81 | /**
82 | * 设置日期item的标题字体未选中颜色
83 | */
84 | var dateTittleUnselectColor: UIColor?
85 | /**
86 | * 设置日期item的选中背景颜色
87 | */
88 | var dateBackSelectColor: UIColor?
89 | /**
90 | * 设置日期item的未选中背景颜色
91 | */
92 | var dateBackUnselectColor: UIColor?
93 | /**
94 | * 设置日期item的描述选中背景颜色
95 | */
96 | var dateDescSelectColor: UIColor?
97 | /**
98 | * 设置日期item的描述未选中背景颜色
99 | */
100 | var dateDescUnselectColor: UIColor?
101 | /**
102 | * 设置日期item的title与描述间距 UIOffset
103 | */
104 | var dateTitleDescOffset: UIOffset?
105 |
106 | override init() {
107 | self.isNeedCustomHeihgt = true;
108 | self.today = NSDate.init();
109 |
110 | self.headerViewDateHeight = 70;
111 | self.headerViewLineHeight = 1.0;
112 | self.headerViewWeekHeight = 20;
113 | self.weekDateDays = ["S","M","T","W","T","F","S"]
114 | self.headerViewDateFont = UIFont.systemFont(ofSize: 18)
115 | self.headerViewWeekFont = UIFont.systemFont(ofSize: 14)
116 | self.headerViewWeekColor = ZHFColor.zhf_color(withHex: 0x4F505F)
117 | self.headerViewDateColor = ZHFColor.zhf_color(withHex: 0x4F505F)
118 |
119 | self.itemHeight = 0;
120 | self.dateTittleFont = UIFont.systemFont(ofSize: 14)
121 | self.dateDescFont = UIFont.systemFont(ofSize: 14)
122 | self.dateTittleSelectColor = ZHFColor.zhf_color(withHex: 0x000000)
123 | self.dateTittleUnselectColor = ZHFColor.zhf_color(withHex: 0x000000)
124 | self.dateDescSelectColor = UIColor.blue
125 | self.dateDescUnselectColor = UIColor.purple
126 | self.dateBackUnselectColor = UIColor.white
127 | self.dateBackSelectColor = ZHFColor.zhf_color(withHex: 0xEEEEEE)
128 | self.isSupportMoreSelect = false;
129 | self.dateTitleDescOffset = UIOffset(horizontal: 0, vertical: 10);
130 | self.headerViewHeihgt = headerViewDateHeight! + headerViewLineHeight! + headerViewWeekHeight!
131 | }
132 | }
133 |
--------------------------------------------------------------------------------
/ZHFToolBox/TBCalendar/TBCalendarDateCell.swift:
--------------------------------------------------------------------------------
1 | //
2 | // TBCalendarDateCell.swift
3 | // SwiftTest
4 | //
5 | // Created by 1111 on 2018/4/9.
6 | // Copyright © 2018年 xuejianfeng. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | class TBCalendarDateCell: UICollectionViewCell {
12 | public var style: TBCalendarAppearStyle{
13 | get{
14 | return TBCalendarAppearStyle.init()
15 | }
16 |
17 | set{
18 | self.setStyle(style: newValue)
19 | }
20 | }
21 | lazy var dateLabel: UILabel = getDateLabel()
22 | lazy var dotView: UIView = getDotView()
23 | public var isToday: Bool?
24 |
25 | lazy var descLabel: UILabel = getDescLabel()
26 | private var dateLableHeight: CGFloat = 0
27 | private var descLabelHeiht: CGFloat = 0
28 |
29 | override init(frame: CGRect) {
30 | super.init(frame: frame)
31 |
32 | self.contentView.addSubview(dateLabel)
33 | self.contentView.addSubview(descLabel)
34 | self.dateLabel.addSubview(dotView)
35 | }
36 |
37 | override func layoutSubviews() {
38 | super.layoutSubviews()
39 |
40 | let width = self.bounds.size.width
41 | let height = self.bounds.size.height
42 | if(self.dateLableHeight > 0)
43 | {
44 | self.dateLabel.center = CGPoint.init(x: width * 0.5, y: height * 0.5)
45 | self.dateLabel.bounds = CGRect.init(x: 0, y: 0, width: 34, height: 34)
46 |
47 | self.dotView.center.x = self.dateLabel.frame.width * 0.5;
48 | self.dotView.center.y = self.dateLabel.frame.height * 0.5 + 10;
49 | self.dotView.bounds = CGRect.init(x: 0, y: 0, width: 4, height: 4)
50 | }
51 | if(self.descLabelHeiht > 0)
52 | {
53 | self.descLabel.center = CGPoint.init(x: width*0.5, y: height*0.5 + self.descLabelHeiht*0.5+(self.style.dateTitleDescOffset?.vertical)! * 0.5);
54 | self.descLabel.bounds = CGRect.init(x: 0, y: 0, width: Int(width), height: Int(self.descLabelHeiht) - 2)
55 | }
56 | }
57 |
58 | func setStyle(style: TBCalendarAppearStyle) {
59 |
60 | let str = "1"
61 | self.dateLableHeight = str.textHeight(fontSize: (style.dateTittleFont?.pointSize)!, width: 20)
62 | self.descLabelHeiht = str.textHeight(fontSize: (style.dateDescFont?.pointSize)!, width: 20)
63 | self.dateLabel.font = style.dateTittleFont;
64 | self.dateLabel.textColor = self.isSelected ? style.dateTittleSelectColor:style.dateTittleUnselectColor;
65 | self.descLabel.font = style.dateDescFont;
66 | self.descLabel.textColor = self.isSelected ? style.dateDescSelectColor:style.dateDescUnselectColor;
67 | }
68 | // 暴露出来的方法,供外界使用
69 | func reloadCellData(title: String) {
70 | self.dateLabel.text = title.count > 0 ? title : ""
71 | }
72 |
73 | func reloadCellData(subtitle: String) {
74 | self.descLabel.text = subtitle.count > 0 ? subtitle : ""
75 | }
76 |
77 | func reloadCellData(title: String, subTitle: String) {
78 | reloadCellData(title: title)
79 | reloadCellData(subtitle: subTitle)
80 | }
81 |
82 | func updateCellDotView(status: String) {
83 | // 旷工0 迟到1 早退2 异常3 人工处理过异常4 ERP处理过异常5 法定节假日6 休息7 正常8
84 | // 蓝色8 橙色0,1,2,3,9 剩下状态为没有颜色
85 |
86 | let statusToInt = Int(status)
87 | if (status.count > 0) {
88 | if (statusToInt == 8) { //正常签到或者ERP有补签卡都是正常
89 | self.dotView.backgroundColor = UIColor.UIColorFromRGB(rgb: 0x29B6F6)
90 | }
91 | else if (statusToInt == 0 || statusToInt == 1 || statusToInt == 2 || statusToInt == 3 || statusToInt == 9)
92 | {
93 | self.dotView.backgroundColor = UIColor.UIColorFromRGB(rgb: 0xF48900)
94 | }
95 | else
96 | {
97 | self.dotView.backgroundColor = UIColor.clear
98 | }
99 | }
100 | else
101 | {
102 | // 现在后台返回30条数据,然后status为null然后doubleValue后为0,所以会显示为旷工颜色,所以要做判空处理
103 | self.dotView.backgroundColor = UIColor.clear
104 | }
105 | }
106 |
107 | func updateCellSelectBackgroundColor() {
108 | self.dateLabel.backgroundColor = self.isSelected ? UIColor.UIColorFromRGB(rgb: 0xEEEEEE) : UIColor.UIColorFromRGB(rgb: 0xffffff);
109 | }
110 |
111 | func updateCellSelectTitleColor() {
112 | //self.dateLabel.textColor = self.isSelected ? self.style.dateTittleSelectColor:self.style.dateTittleUnselectColor;
113 | }
114 |
115 | func updateCellSelectSubtitleColor() {
116 | //self.descLabel.textColor = self.isSelected ? self.style.dateDescSelectColor:self.style.dateDescUnselectColor;
117 | }
118 |
119 | func updateCellSelectCellColor() {
120 | updateCellSelectCellColor(animation: false)
121 | }
122 |
123 | func updateCellSelectCellColor(animation: Bool) {
124 |
125 | updateCellSelectTitleColor()
126 | updateCellSelectSubtitleColor()
127 | updateCellSelectBackgroundColor()
128 | }
129 |
130 | // lazy 相关函数
131 | func getDateLabel() -> UILabel {
132 | let dateLabel = UILabel.init()
133 | dateLabel.layer.cornerRadius = 17
134 | dateLabel.layer.masksToBounds = true
135 | dateLabel.textAlignment = .center
136 | return dateLabel
137 | }
138 |
139 | func getDotView() -> UIView {
140 | let dotView = UIView.init()
141 | dotView.layer.cornerRadius = 2;
142 | dotView.layer.masksToBounds = true
143 | dotView.backgroundColor = UIColor.clear
144 | return dotView
145 | }
146 |
147 | func getDescLabel() -> UILabel {
148 | let descLabel = UILabel.init()
149 | descLabel.textAlignment = .center
150 | return descLabel
151 | }
152 |
153 | required init?(coder aDecoder: NSCoder) {
154 | fatalError("init(coder:) has not been implemented")
155 | }
156 | }
157 |
--------------------------------------------------------------------------------
/ZHFToolBox/TBCalendar/TBCalendarHeaderView.swift:
--------------------------------------------------------------------------------
1 | //
2 | // TBCalendarHeaderView.swift
3 | // SwiftTest
4 | //
5 | // Created by 1111 on 2018/4/2.
6 | // Copyright © 2018年 xuejianfeng. All rights reserved.
7 | //
8 |
9 | import UIKit
10 | class TBCalendarHeaderView: UIView {
11 |
12 | typealias click = (NSDate) -> Void
13 | public var previousMonth: ((_ date: NSDate) -> Void)?
14 | public var nextMonth: ((_ date: NSDate) -> Void)?
15 | public var monthDate: NSDate{
16 | get{
17 | return remberMonthDate
18 | }
19 |
20 | set{
21 | remberMonthDate = newValue
22 | self.setMonthDate(date: newValue)
23 | }
24 | }
25 | private var remberMonthDate = NSDate()
26 | private var headType: TBCalendarHeaderViewType
27 | private var style: TBCalendarAppearStyle
28 | lazy var topView: UIView = getTopView()
29 | lazy var dateLable: UILabel = getDateLable()
30 | lazy var previousButton: UIButton = getPreviousButton()
31 | lazy var nextButton: UIButton = getNextButton()
32 | lazy var bottomView: UIView = UIView.init()
33 | lazy var weekdayLabels: [UILabel] = [UILabel]()
34 | lazy var lineView: UIView = UIView.init()
35 |
36 | init(type: TBCalendarHeaderViewType, style: TBCalendarAppearStyle, frame: CGRect) {
37 | self.headType = type
38 | self.style = style
39 | super.init(frame: frame)
40 | self.setupUI()
41 | }
42 |
43 | func setupUI() {
44 | self.addSubview(self.topView)
45 | self.addSubview(self.bottomView)
46 | self.addSubview(self.lineView)
47 | self.topView.addSubview(self.dateLable)
48 |
49 | switch self.headType {
50 | case TBCalendarHeaderViewType.leftDate:
51 | break;
52 | case TBCalendarHeaderViewType.centerDate:
53 | self.topView.addSubview(self.previousButton)
54 | self.topView.addSubview(self.nextButton)
55 | self.previousButton.isHidden = false
56 | self.nextButton.isHidden = false
57 | break;
58 | }
59 |
60 | let weekDateDays: [String] = self.style.weekDateDays
61 |
62 | for _ in weekDateDays
63 | {
64 | let label = UILabel.init(frame: CGRect.zero)
65 | label.textAlignment = .center
66 | self.bottomView.addSubview(label)
67 | self.weekdayLabels.append(label)
68 | }
69 |
70 | self.initValidSettingData()
71 | }
72 |
73 | override func layoutSubviews() {
74 | super.layoutSubviews()
75 | let selfWidth: CGFloat = self.bounds.size.width
76 |
77 | if self.style.isNeedCustomHeihgt! {
78 | self.topView.frame = CGRect.init(x: 0, y:0, width: selfWidth, height: self.style.headerViewDateHeight!)
79 | self.lineView.frame = CGRect.init(x: 0, y: self.topView.frame.maxY, width: selfWidth, height: self.style.headerViewLineHeight!)
80 | self.bottomView.frame = CGRect.init(x: 0, y: self.lineView.frame.maxY, width: selfWidth, height: self.style.headerViewWeekHeight!)
81 |
82 | switch (self.headType)
83 | {
84 | case .leftDate:
85 |
86 | self.dateLable.frame = CGRect.init(x: 0, y: 0, width: selfWidth, height: self.topView.frame.size.height);
87 | self.dateLable.textAlignment = .center;
88 |
89 | break;
90 | case .centerDate:
91 |
92 | let image = UIImage.init(named: "icon_switch")
93 | self.dateLable.frame = CGRect.init(x: selfWidth * 0.5 - 60, y: 0, width: 120, height: self.topView.frame.size.height);
94 |
95 | self.previousButton.frame = CGRect.init(x: 30, y: 0, width: (image?.size.width)! + 20, height: self.topView.frame.size.height);
96 | self.nextButton.frame = CGRect.init(x: selfWidth - (image?.size.width)! - 50, y: 0, width: (image?.size.width)! + 20, height: self.topView.frame.size.height);
97 | break;
98 | }
99 |
100 | let weekdayWidth = self.bottomView.bounds.size.width / CGFloat(self.style.weekDateDays.count)
101 | let weekdayHeight = self.bottomView.bounds.size.height;
102 |
103 |
104 | for (index, value) in self.weekdayLabels.enumerated() {
105 |
106 | value.frame = CGRect.init(x: CGFloat(index) * weekdayWidth, y: 0, width: weekdayWidth, height: weekdayHeight)
107 | }
108 | }
109 | else
110 | {
111 | //计算高度
112 | }
113 | }
114 |
115 | func initValidSettingData(){
116 | self.dateLable.font = self.style.headerViewDateFont;
117 | self.dateLable.textColor = self.style.headerViewDateColor;
118 |
119 | for item: UILabel in self.weekdayLabels {
120 | item.font = self.style.headerViewWeekFont
121 | item.textColor = self.style.headerViewWeekColor
122 | }
123 |
124 | for (index, value) in self.weekdayLabels.enumerated() {
125 |
126 | if index < self.style.weekDateDays.count {
127 | value.text = self.style.weekDateDays[index];
128 | }
129 | }
130 | }
131 |
132 | func getTopView() -> UIView {
133 | let topView = UIView.init()
134 | topView.backgroundColor = UIColor.white
135 | return topView
136 | }
137 |
138 | func getDateLable() -> UILabel {
139 | let dateLabel = UILabel.init()
140 | dateLabel.numberOfLines = 2
141 | dateLabel.textAlignment = .center
142 | return dateLabel
143 | }
144 |
145 | func getPreviousButton() -> UIButton {
146 | let btn = UIButton.init(type: .custom)
147 | btn.setImage(UIImage.init(named: "icon_switch"), for: .normal)
148 | btn.addTarget(self, action: #selector(previousButtonClick), for: .touchUpInside)
149 | return btn
150 | }
151 |
152 | func getNextButton() -> UIButton {
153 | let btn = UIButton.init(type: .custom)
154 | btn.setImage(UIImage.init(named: "icon_switch_r"), for: .normal)
155 | btn.addTarget(self, action: #selector(nextButtonClick), for: .touchUpInside)
156 | return btn
157 | }
158 |
159 | @objc func previousButtonClick() {
160 | self.monthDate = self.lastMonth(date: self.monthDate)
161 | NotificationCenter.default.post(name: NSNotification.Name(rawValue: CHANGE_SELECT_DATE), object: monthDate)
162 | if self.previousMonth != nil {
163 | self.previousMonth!(self.monthDate)
164 | }
165 | }
166 |
167 | @objc func nextButtonClick() {
168 | self.monthDate = self.nextMonth(date: self.monthDate)
169 | NotificationCenter.default.post(name: NSNotification.Name(rawValue: CHANGE_SELECT_DATE), object: monthDate)
170 | if self.nextMonth != nil {
171 | self.nextMonth!(self.monthDate)
172 | }
173 | }
174 |
175 | func setMonthDate(date: NSDate){
176 | //如果点击的日期超过当前日期 不让其点击 || [TBUtils compareOneDay:monthDate withAnotherDay:[NSDate dateWithString:@"2017-03" format:@"yyyy-MM"]] == -1
177 | if compareDate(oneDay: monthDate, anotherDay: Date() as NSDate) == 1 {
178 | return;
179 | }
180 |
181 | self.nextButton.alpha = 1;
182 | self.previousButton.alpha = 1;
183 |
184 | let monthStr: String = self.month(date: date)
185 | let yearStr: String = "\(self.year(year: date))."
186 | self.dateLable.text = yearStr + monthStr
187 | //self.dateLable.attributedText = self.createAttrStr(monthStr: monthStr, yearStr: yearStr)
188 |
189 | var date = getMonthEnd(date: date)
190 |
191 | let myDateFormatter = DateFormatter.init()
192 | myDateFormatter.dateFormat = "yyyy-MM-dd"
193 | let endDate = Date.init(timeInterval: 86400, since: date as Date)
194 |
195 |
196 | if (compareDate(oneDay: endDate as NSDate, anotherDay: NSDate()) == 1) {
197 | self.nextButton.alpha = 0.5;
198 | self.nextButton.isEnabled = false;
199 | }
200 | else
201 | {
202 | self.nextButton.alpha = 1;
203 | self.nextButton.isEnabled = true;
204 | }
205 |
206 | date = getMonthBegin(date: date)
207 | let PreDate = Date.init(timeInterval: -86400, since: date as Date)
208 |
209 | let dateFormatter = DateFormatter.init()
210 | dateFormatter.dateFormat = "yyyy-MM"
211 |
212 | if compareDate(oneDay: PreDate as NSDate, anotherDay: dateFormatter.date(from: "2017-03")! as NSDate) == -1 {
213 | self.previousButton.alpha = 0.5;
214 | self.previousButton.isEnabled = false;
215 | }
216 | else
217 | {
218 | self.previousButton.alpha = 1;
219 | self.previousButton.isEnabled = true;
220 | }
221 | }
222 |
223 | func nextMonth(date: NSDate) -> NSDate{
224 |
225 | let dateComponents = NSDateComponents.init()
226 | let currentMonth = self.month(date: date)
227 |
228 | if(currentMonth == "12")
229 | {
230 | dateComponents.year = +1;
231 | dateComponents.month = -11;
232 | }
233 | else
234 | {
235 | dateComponents.month = +1;
236 | }
237 |
238 | return NSCalendar.current.date(byAdding: dateComponents as DateComponents, to: date as Date)! as NSDate
239 | }
240 |
241 | func lastMonth(date: NSDate) -> NSDate{
242 | let dateComponents = NSDateComponents.init()
243 | let currentMonth = self.month(date: date)
244 | if(currentMonth == "01")
245 | {
246 | dateComponents.year = -1;
247 | dateComponents.month = +11;
248 | }
249 | else
250 | {
251 | dateComponents.month = -1;
252 | }
253 |
254 | return NSCalendar.current.date(byAdding: dateComponents as DateComponents, to: date as Date)! as NSDate
255 | }
256 |
257 | func month(date: NSDate) -> String {
258 | var str = ""
259 | if (NSCalendar.current.component(.month, from: date as Date) < 10) {
260 | str = "0" + "\(NSCalendar.current.component(.month, from: date as Date))"
261 | }
262 | else
263 | {
264 | str = "\(NSCalendar.current.component(.month, from: date as Date))"
265 | }
266 |
267 | return str;
268 | }
269 |
270 | func year(year: NSDate) -> Int{
271 | return NSCalendar.current.component(.year, from: year as Date)
272 | }
273 |
274 | func createAttrStr(monthStr: String, yearStr: String) -> NSMutableAttributedString{
275 | let monthDict = [NSAttributedString.Key.font : UIFont.systemFont(ofSize: 24), NSAttributedString.Key.foregroundColor:ZHFColor.zhf_color(withHex: 0x4F505F)]
276 | let yearDict = [NSAttributedString.Key.font: UIFont.systemFont(ofSize: 14), NSAttributedString.Key.foregroundColor:ZHFColor.zhf_color(withHex: 0x999999)]
277 |
278 | let str: String = monthStr + yearStr
279 |
280 | let mutableAtt: NSMutableAttributedString = NSMutableAttributedString.init(string: str, attributes: monthDict)
281 | mutableAtt.addAttributes(yearDict, range: NSRange.init(location: monthStr.count, length: yearStr.count))
282 |
283 | return mutableAtt
284 | }
285 |
286 | required init?(coder aDecoder: NSCoder) {
287 | fatalError("init(coder:) has not been implemented")
288 | }
289 |
290 | }
291 |
--------------------------------------------------------------------------------
/ZHFToolBox/TopTopTranslucentTableView/MessgeShowVC.swift:
--------------------------------------------------------------------------------
1 | //
2 | // MessgeAlapaTableView.swift
3 | // Swift Test
4 | //
5 | // Created by IOSZHF on 2022/5/17.
6 | //
7 |
8 | import UIKit
9 |
10 | class MessgeShowVC: UIViewController {
11 | var number: NSInteger = 0
12 | var time: Timer = Timer()
13 | var topTranslucentTableView: TopTranslucentTableView = TopTranslucentTableView()
14 |
15 | override func viewWillDisappear(_ animated: Bool) {
16 | super.viewWillDisappear(animated)
17 | self.time.invalidate()
18 | }
19 | deinit {
20 | print("销毁MessgeAlapaTableView")
21 | }
22 | override func viewDidLoad() {
23 | super.viewDidLoad()
24 | self.view.backgroundColor = UIColor.white
25 | //背景图
26 | let imageView: UIView = UIImageView.init(image: UIImage.init(named: "back_ground"))
27 | imageView.frame = CGRect.init(x: 0, y: 0, width: UIScreen.main.bounds.size.width, height: UIScreen.main.bounds.size.height)
28 | imageView.contentMode = .scaleAspectFill
29 | self.view.addSubview(imageView)
30 | topTranslucentTableView.frame = CGRect.init(x: 0, y: UIScreen.main.bounds.size.height - 300, width: UIScreen.main.bounds.size.width, height: 300)
31 | self.view.addSubview(topTranslucentTableView.initTopTranslucentTableView())
32 |
33 | self.time = Timer.init(timeInterval: 1, target: self, selector: #selector(addMessage), userInfo: nil, repeats: true)
34 | RunLoop.current.add(self.time, forMode: .common)//,common 保证滚动时定时器也走
35 | }
36 | @objc func addMessage() {
37 | number = number + 1
38 | topTranslucentTableView.addMessageData(number: number)
39 | if number==20{//20秒关闭定时器退到上一页
40 | self.time.invalidate()
41 | self.navigationController?.popViewController(animated: true)
42 | }
43 | }
44 |
45 | }
46 |
--------------------------------------------------------------------------------
/ZHFToolBox/TopTopTranslucentTableView/NormalCell.swift:
--------------------------------------------------------------------------------
1 | //
2 | // NormalCell.swift
3 | // Swift Test
4 | //
5 | // Created by IOSZHF on 2022/5/17.
6 | //
7 |
8 | import UIKit
9 |
10 | class NormalCell: UITableViewCell {
11 |
12 | @IBOutlet weak var messageLabel: UILabel!
13 | override func awakeFromNib() {
14 | super.awakeFromNib()
15 | // Initialization code
16 | }
17 |
18 | override func setSelected(_ selected: Bool, animated: Bool) {
19 | super.setSelected(selected, animated: animated)
20 |
21 | // Configure the view for the selected state
22 | }
23 |
24 | }
25 |
--------------------------------------------------------------------------------
/ZHFToolBox/TopTopTranslucentTableView/NormalCell.xib:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
--------------------------------------------------------------------------------
/ZHFToolBox/TopTopTranslucentTableView/TopTranslucentTableView.swift:
--------------------------------------------------------------------------------
1 | //
2 | // TopTranslucentTableView.swift
3 | // ZHFToolBox
4 | //
5 | // Created by IOSZHF on 2022/5/19.
6 | // Copyright © 2022 张海峰. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | class TopTranslucentTableView: UIView {
12 | lazy var messageData :[String] = [String]()
13 | lazy var tableView : UITableView = {
14 | let tableView = UITableView.init(frame: CGRect.init(x: 0, y: 0, width: UIScreen.main.bounds.size.width, height: 300), style: .plain)
15 | // tableView.register(NormalCell.self, forCellReuseIdentifier: "normalcell")
16 | tableView.register(UINib.init(nibName: "NormalCell", bundle: Bundle.main), forCellReuseIdentifier: "NormalCellID")
17 | tableView.delegate = self
18 | tableView.dataSource = self
19 | tableView.backgroundColor = .clear
20 | tableView.separatorStyle = .none
21 | return tableView
22 | }()
23 | //初始化视图
24 | func initTopTranslucentTableView() -> UIView {
25 | self.backgroundColor = .clear
26 | // 渐变蒙层
27 | let layer :CAGradientLayer = CAGradientLayer.init()
28 | layer.colors = [
29 | UIColor.init(white: 0, alpha: 0.05).cgColor,
30 | UIColor.init(white: 0, alpha: 1.0).cgColor
31 | ];
32 | layer.locations = [0, 0.15]; // 设置颜色的范围
33 | layer.startPoint = CGPoint.init(x: 0, y: 0) // 设置颜色渐变的起点
34 | layer.endPoint = CGPoint.init(x: 0, y: 1) // 设置颜色渐变的终点,与 startPoint 形成一个颜色渐变方向
35 | layer.frame = CGRect.init(x: 0, y: 0, width: UIScreen.main.bounds.size.width, height: 300); // 设置 Frame
36 | self.layer.mask = layer; // 设置 mask 属性
37 | self.addSubview(self.tableView)
38 | return self
39 | }
40 | func addMessageData(number:NSInteger) {
41 | self.messageData.append("添加第\(number)条消息")
42 | self.tableView.insertRows(at: [IndexPath(row: self.messageData.count-1, section: 0)], with: .none)
43 | self.tableView.scrollToRow(at: IndexPath(row: self.messageData.count-1, section: 0), at: .bottom, animated: true)//滚到底部
44 | }
45 | }
46 | extension TopTranslucentTableView: UITableViewDelegate,UITableViewDataSource{
47 | func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
48 | return self.messageData.count
49 | }
50 |
51 | func numberOfSections(in tableView: UITableView) -> Int {
52 | return 1
53 | }
54 |
55 | func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
56 | return 0.1
57 | }
58 |
59 | func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
60 | let cell = tableView.dequeueReusableCell(withIdentifier: "NormalCellID", for: indexPath) as! NormalCell
61 | cell.backgroundColor = .clear
62 | cell.messageLabel.text = self.messageData[indexPath.row]
63 | cell.selectionStyle = UITableViewCell.SelectionStyle.none
64 | return cell
65 | }
66 |
67 | func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
68 | return 40
69 | }
70 | }
71 |
--------------------------------------------------------------------------------
/ZHFToolBox/TwoVC.swift:
--------------------------------------------------------------------------------
1 | //
2 | // TwoVC.swift
3 | // ZHFToolBox
4 | //
5 | // Created by 张海峰 on 2018/5/10.
6 | // Copyright © 2018年 张海峰. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | class TwoVC: UIViewController {
12 |
13 | override func viewDidLoad() {
14 | super.viewDidLoad()
15 | self.view.backgroundColor = ZHFColor.green
16 | }
17 |
18 | }
19 |
--------------------------------------------------------------------------------
/ZHFToolBox/ViewController.swift:
--------------------------------------------------------------------------------
1 | //
2 | // ViewController.swift
3 | // ZHFToolBox
4 | //
5 | // Created by 张海峰 on 2018/5/9.
6 | // Copyright © 2018年 张海峰. All rights reserved.
7 | //
8 | /*该demo是和大家分享一下,在项目中自定义各种弹框的思路,用来支撑自己项目的使用,无论什么样的弹框,只要有思路,
9 | 相信大家都能完美实现。感觉我这个demo对你有启发或者帮助,不妨给个星星吧
10 | https://github.com/FighterLightning/ZHFToolBox.git
11 | https://www.jianshu.com/p/88420bc4d32d
12 | */
13 | import UIKit
14 | //设备物理尺寸
15 | let ScreenHeight = UIScreen.main.bounds.size.height
16 | let ScreenWidth = UIScreen.main.bounds.size.width
17 | class ViewController: UIViewController {
18 | var tableView:UITableView!
19 | lazy var dataMarr:NSMutableArray = NSMutableArray()
20 | var popImageView: PopImageView = PopImageView()
21 | var popTextView: PopTextView = PopTextView()
22 | var popRadioButtonView: PopRadioButtonView = PopRadioButtonView()
23 | var popCheckboxButtonView: PopCheckboxButtonView = PopCheckboxButtonView()
24 | var popTopOrBottomOutView: PopTopOrBottomOutView = PopTopOrBottomOutView()
25 | var popSomeColorView: PopSomeColorView = PopSomeColorView()
26 | var slideWhiteViewSubView: SlideWhiteViewSubView = SlideWhiteViewSubView()
27 | //拆开一个盒子的动画效果
28 | var popAwayOpenView : PopAwayOpenBackGroundView = PopAwayOpenBackGroundView() //gif背景图
29 | var openBoxView : OpenBoxView! //盒子打开动画效果图
30 | var calendarView: CalendarView = CalendarView()
31 | var progressBar: PopProgressBar! //进度条
32 | var displayLink: CADisplayLink! //定时器
33 | var currentValue: CGFloat = 0;
34 |
35 | override func viewDidLoad() {
36 | super.viewDidLoad()
37 | self.title = "自定义几种提示框"
38 | self.addTableView()
39 | self.dataMarr = ["一个按钮,无点击事件",
40 | "一个按钮,有点击事件",
41 | "两个按钮,有点击事件",
42 | "提示框由小变大弹出(带图片)",
43 | "提示框由小变大弹出(带输入框)",
44 | "提示框由小变大弹出(单选按钮)",
45 | "提示框由小变大弹出(多选按钮)",
46 | "商品弹出盒子的效果",
47 | "商品落入盒子的效果",
48 | "有序弹出一堆框",
49 | "弹出一个带列表的左滑框",
50 | "弹出一个带列表的右滑框",
51 | "弹出一个带有gif背景图的拆产品",
52 | "模拟进度条",
53 | "单选病情",
54 | "弹出日历",
55 | "直播第一条消息半透明"]
56 | }
57 | func addTableView(){
58 | tableView = UITableView.init(frame: CGRect.init(x: 0, y: 44, width: ScreenWidth, height: ScreenHeight - 44), style: .plain)
59 | self.view.addSubview(tableView)
60 | tableView.backgroundColor = ZHFColor.zhff9_backGroundColor
61 | tableView.separatorColor = ZHFColor.initString(hex: "cccccc")
62 | tableView.separatorInset = UIEdgeInsets.init(top: 0, left: 25, bottom: 0, right: 0)
63 | tableView.delegate = self
64 | tableView.dataSource = self
65 | }
66 | }
67 | extension ViewController :UITableViewDataSource,UITableViewDelegate
68 | {
69 | func numberOfSections(in tableView: UITableView) -> Int {
70 | return 1
71 | }
72 | func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
73 | return self.dataMarr.count
74 | }
75 | func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
76 | let alertCellIdentifier = "alertCellIdentifier"
77 | var cell = tableView.dequeueReusableCell(withIdentifier: alertCellIdentifier)
78 | if cell == nil {
79 | cell = UITableViewCell(style:.default, reuseIdentifier: alertCellIdentifier)
80 | }
81 | cell?.textLabel?.text = self.dataMarr[indexPath.row] as? String
82 | cell?.textLabel?.font = UIFont.systemFont(ofSize: 13)
83 | cell?.textLabel?.textColor = ZHFColor.zhf_randomColor()
84 | cell?.selectionStyle = .none
85 | return cell!
86 | }
87 | func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
88 | let message = self.dataMarr[indexPath.row] as! String
89 | if indexPath.row == 0 {
90 | // 一个按钮,无点击事件
91 | ZHFAlertControllerTool.showAlert(currentVC: self, title: "", meg: message, cancelBtn: "确定")
92 | }
93 | else if indexPath.row == 1 {
94 | // 一个按钮,有点击事件
95 | ZHFAlertControllerTool.showAlert(currentVC: self, title: "提示", meg: message, okBtn: "点击跳页", handler: { (_) in
96 | let oneVC: OneVC = OneVC()
97 | self.navigationController?.pushViewController(oneVC, animated: true)
98 | })
99 | }
100 | else if indexPath.row == 2 {
101 | //两个按钮,有点击事件
102 | ZHFAlertControllerTool.showAlert(currentVC: self, title: "最美提示", meg: message, oneBtn: "跳页", otherBtn: "取消", oneHandler: { (_) in
103 | self.oneBtnClick(btn: UIButton())
104 | }, otherHandler: { (_) in
105 | //取消按钮要处理事件
106 | })
107 | }
108 | else if indexPath.row == 3 {
109 | //带图片的弹框
110 | self.popImageView.addAnimate()
111 | self.popImageView.oneBtn.addTarget(self, action: #selector(self.oneBtnClick), for: .touchUpInside)
112 | self.popImageView.otherBtn.addTarget(self, action: #selector(self.otherBtnClick), for: .touchUpInside)
113 | }
114 | else if indexPath.row == 4{
115 | //带输入框的弹框
116 | self.popTextView.whiteViewEndFrame = CGRect.init(x: 20, y: 100, width: ScreenWidth - 40, height: ScreenHeight - 300)
117 | self.popTextView.addAnimate()
118 | self.popTextView.textStr = message
119 | self.popTextView.oneBtn.addTarget(self, action: #selector(self.oneBtn4Click), for: .touchUpInside)
120 | self.popTextView.otherBtn.addTarget(self, action: #selector(self.otherBtn4Click), for: .touchUpInside)
121 | }
122 | else if indexPath.row == 5{
123 | //单选框的弹框
124 | self.popRadioButtonView.whiteViewEndFrame = CGRect.init(x: 20, y: 100, width: ScreenWidth - 40, height: ScreenHeight - 300)
125 | self.popRadioButtonView.contentArr = ["小炒肉","宫爆鸡丁","炒肉","油麦菜","大白菜","蚂蚁上树","西红柿炒鸡蛋","鱼香肉丝","糖醋排骨"]
126 | self.popRadioButtonView.addAnimate()
127 | self.popRadioButtonView.delegate = self
128 | }
129 | else if indexPath.row == 6{
130 | //多选框的弹框
131 | self.popCheckboxButtonView.whiteViewEndFrame = CGRect.init(x: 20, y: 100, width: ScreenWidth - 40, height: ScreenHeight - 300)
132 | self.popCheckboxButtonView.contentArr = ["小炒肉","宫爆鸡丁","炒肉","油麦菜","大白菜","蚂蚁上树","西红柿炒鸡蛋","鱼香肉丝","糖醋排骨"]
133 | self.popCheckboxButtonView.addAnimate()
134 | self.popCheckboxButtonView.delegate = self
135 | }
136 | else if indexPath.row == 7{
137 | //从下向上
138 | self.popTopOrBottomOutView.topOrBottomViewStartFrame = CGRect.init(x: 25, y: ScreenHeight, width: ScreenWidth - 50, height: 500)
139 | self.popTopOrBottomOutView.addAnimateFromBottom()
140 | }
141 | else if indexPath.row == 8{
142 | //从上向下
143 | self.popTopOrBottomOutView.topOrBottomViewStartFrame = CGRect.init(x: 25, y: -ScreenHeight, width: ScreenWidth - 50, height: 500)
144 | self.popTopOrBottomOutView.addAnimateFromTop()
145 | }
146 | else if indexPath.row == 9{
147 | //有序弹出一堆框
148 | self.popSomeColorView.addAnimate()
149 | self.popSomeColorView.delegate = self;
150 | //实现回调,获取回调回来的值 (闭包)
151 | self.popSomeColorView.backClosure = {
152 | (backStr: String) -> Void in
153 | let redVC: RedVC = RedVC()
154 | redVC.message = backStr
155 | self.navigationController?.pushViewController(redVC, animated: true)
156 | }
157 | }
158 | else if indexPath.row == 10{
159 | //弹出一个带列表的左滑框
160 | slideWhiteViewSubView.isfromLeft = true //从左边滑出
161 | let whiteViewWidth = ScreenWidth*3/4
162 | slideWhiteViewSubView.whiteViewStartFrame = CGRect.init(x: -whiteViewWidth, y: 0, width: whiteViewWidth, height: ScreenHeight)
163 | slideWhiteViewSubView.whiteViewEndFrame = CGRect.init(x: 0, y: 0, width: whiteViewWidth, height: ScreenHeight)
164 | slideWhiteViewSubView.addAnimate()
165 | slideWhiteViewSubView.delegate = self
166 | }
167 | else if indexPath.row == 11{
168 | //弹出一个带列表的右滑框
169 | slideWhiteViewSubView.isfromLeft = false //从右边滑出
170 | let whiteViewWidth = ScreenWidth*4/5
171 | let whiteViewHeight = ScreenHeight*8/9
172 | slideWhiteViewSubView.whiteViewStartFrame = CGRect.init(x: ScreenWidth, y:(ScreenHeight - whiteViewHeight)/2, width: whiteViewWidth, height: whiteViewHeight)
173 | slideWhiteViewSubView.whiteViewEndFrame = CGRect.init(x: ScreenWidth - whiteViewWidth, y: (ScreenHeight - whiteViewHeight)/2, width: whiteViewWidth, height: whiteViewHeight)
174 | slideWhiteViewSubView.addAnimate()
175 | slideWhiteViewSubView.delegate = self
176 | }
177 | else if indexPath.row == 12{
178 | //播放gif图
179 | self.popAwayOpenView.addAnimate()
180 | //当播放GIF图一半时,弹出加载的产品图 1.5 为GIF播放一半所用的时间
181 | if #available(iOS 10.0, *) {
182 | Timer.scheduledTimer(withTimeInterval: 1.5, repeats: false, block: { (_) in
183 | self.popGood()
184 | })
185 | } else {
186 | sleep(UInt32(1.5))
187 | self.popGood()
188 | }
189 | }
190 | else if indexPath.row == 13{
191 | //弹出一个模拟渐变进度条
192 | currentValue = 0
193 | progressBar = PopProgressBar()
194 | progressBar.addAnimate(view: progressBar.initPopBackGroundView())
195 | displayLink = CADisplayLink.init(target: self, selector: #selector(displayLinkRun))
196 | displayLink.add(to: RunLoop.current, forMode: .default)
197 | progressBar.displayLink = displayLink
198 | }
199 | else if indexPath.row == 14{
200 | let arr = ["心率失常","一度房室传导阻滞","心率失常","一度房室传导阻滞","心率失常","一度房室传导阻滞","心率失常","一度房室传导阻滞","心率失常","心率失常","一度房室传导阻滞","心率失常","心率失常","心率失常","一度房室传导阻滞","心率失常","一度房室传导阻滞","心率失常","一度房室传导阻滞","心率失常","一度房室传导阻滞","心率失常","心率失常","一度房室传导阻滞","心率失常","心率失常"]
201 | let popDiseaseView: PopDiseaseView = PopDiseaseView()
202 | popDiseaseView.addWhiteViewContent(arr: arr as NSArray)
203 | popDiseaseView.addAnimate(view: popDiseaseView.initPopDiseaseView())
204 | popDiseaseView.clickValueClosure { (text) in
205 | ZHFLog(message: text)
206 | }
207 | }
208 | else if indexPath.row == 15{
209 | let calendarView: ZHFCalendarView = ZHFCalendarView()
210 | calendarView.pointColor = ZHFColor.zhf_color(withHex: 0x42D2BE)//大小点颜色
211 | // calendarView.bigGreenPoints = [0] //大点数组
212 | // calendarView.smallGreenPoints = [0] //小点数组
213 | calendarView.addAnimate()
214 | //点击的是--年--月--日
215 | calendarView.clickValueClosure { (text) in
216 | let arr = text!.components(separatedBy:"-")
217 | ZHFLog(message: "\(arr[0]).\(arr[1]).\(arr[2])")
218 |
219 | }
220 | }
221 | else if indexPath.row == 16{
222 | self.navigationController?.pushViewController(MessgeShowVC.init(), animated: true)
223 | }
224 | }
225 | func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
226 | return 40
227 | }
228 | @objc func displayLinkRun(){
229 | if currentValue > 1 {
230 | //加载完成 关闭定时器,隐藏进度条
231 | displayLink.invalidate()
232 | displayLink = nil
233 | progressBar.removeFromSuperview()
234 | }
235 | else{
236 | currentValue = currentValue + 0.005;
237 | progressBar.passValue(currentValue: currentValue, allValue: 1.0)
238 | }
239 | }
240 | }
241 | extension ViewController{
242 | @objc func oneBtnClick(btn:UIButton){
243 | //先移除弹出来的图
244 | self.popImageView.removeFromSuperview()
245 | let oneVC: OneVC = OneVC()
246 | self.navigationController?.pushViewController(oneVC, animated: true)
247 | }
248 | @objc func otherBtnClick(btn:UIButton){
249 | //先移除弹出来的图
250 | self.popImageView.removeFromSuperview()
251 | let twoVC: TwoVC = TwoVC()
252 | self.navigationController?.pushViewController(twoVC, animated: true)
253 | }
254 | @objc func oneBtn4Click(btn:UIButton){
255 | self.dataMarr.replaceObject(at: 4, with: self.popTextView.textView.text as Any)
256 | self.popTextView.tapBtnAndcancelBtnClick()
257 | let indexPath: IndexPath = NSIndexPath.init(row: 4, section: 0) as IndexPath
258 | tableView.reloadRows(at: [indexPath], with: .none)
259 | }
260 | @objc func otherBtn4Click(btn:UIButton){
261 | self.popTextView.tapBtnAndcancelBtnClick()
262 | }
263 | //弹出加载的产品图
264 | @objc func popGood(){
265 | self.openBoxView = OpenBoxView()
266 | self.openBoxView.backgroundColor1 = UIColor.init(red: 0, green: 0, blue: 0, alpha: 0)
267 | self.popAwayOpenView.addSubview(self.openBoxView.initPopBackGroundView())
268 | self.openBoxView.addAnimate()
269 | }
270 | }
271 | extension ViewController:PopRadioButtonViewDelegate,PopCheckboxButtonViewDelegate,PopSomeColorViewDelegate,SlideWhiteViewSubViewDelegate{
272 | //PopRadioButtonViewDelegate
273 | func selectBtnMessage(content: String) {
274 | self.dataMarr.replaceObject(at: 5, with: content)
275 | self.popRadioButtonView.tapBtnAndcancelBtnClick()
276 | let indexPath: IndexPath = NSIndexPath.init(row: 5, section: 0) as IndexPath
277 | tableView.reloadRows(at: [indexPath], with: .none)
278 | }
279 | //PopCheckboxButtonViewDelegate
280 | func selectMessage(contentMarr: NSMutableArray) {
281 | var content :String = ""
282 | for i in 0 ..< contentMarr.count {
283 | content.append(" \(contentMarr[i] as! String)")
284 | }
285 | self.dataMarr.replaceObject(at: 6, with: content)
286 | self.popCheckboxButtonView.tapBtnAndcancelBtnClick()
287 | let indexPath: IndexPath = NSIndexPath.init(row: 6, section: 0) as IndexPath
288 | tableView.reloadRows(at: [indexPath], with: .none)
289 | }
290 | //PopSomeColorViewDelegate
291 | func selectBtnTag(btnTag:NSInteger) {
292 | self.dataMarr.replaceObject(at: 9, with: "选中按钮的tag为\(btnTag)")
293 | let indexPath: IndexPath = NSIndexPath.init(row: 9, section: 0) as IndexPath
294 | tableView.reloadRows(at: [indexPath], with: .none)
295 | }
296 | //SlideWhiteViewSubViewDelegate
297 | func selectMessage(message: String) {
298 | let redVC: RedVC = RedVC()
299 | redVC.message = message
300 | self.navigationController?.pushViewController(redVC, animated: true)
301 | }
302 | }
303 |
304 |
--------------------------------------------------------------------------------
/ZHFToolBox/ZHFSubToolBox/CalendarView.swift:
--------------------------------------------------------------------------------
1 | //
2 | // CalendarView.swift
3 | // ZHFToolBox
4 | //
5 | // Created by 张海峰 on 2019/2/21.
6 | // Copyright © 2019年 张海峰. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | class CalendarView: UpDownView, TBCalendarDataDelegate , TBCalendarDataSource {
12 |
13 | lazy var calender: TBCalendar = self.getCalendar()
14 | lazy var style: TBCalendarAppearStyle = self.getStyle()
15 | var titleLabel: UILabel!
16 | override func addAnimate() {
17 | UIApplication.shared.keyWindow?.addSubview(self.initPopBackGroundView())
18 | self.isHidden = false
19 | //按钮不要在动画完成后初始化(否则按钮没点击效果)
20 | UIView.animate(withDuration:TimeInterval(defaultTime), animations: {
21 | self.WhiteView.frame = self.whiteViewEndFrame
22 | }) { (_) in
23 | self.addWhiteVieSubView()
24 | }
25 | }
26 | //放一张展示图片
27 | func addWhiteVieSubView(){
28 | self.WhiteView.addSubview(calender)
29 | }
30 | func getCalendar() -> TBCalendar {
31 | NotificationCenter.default.addObserver(self, selector: #selector(changeDate(noty:)), name: NSNotification.Name(rawValue: CHANGE_SELECT_DATE), object: nil)
32 | let calendar = TBCalendar.init(style: self.style, frame: CGRect.init(x: 0, y: 0, width: ScreenWidth, height: 350))
33 | calendar.dataSource = self;
34 | calendar.delegate = self;
35 | return calendar
36 | }
37 | func getStyle() -> TBCalendarAppearStyle {
38 | let style = TBCalendarAppearStyle.init()
39 | style.isNeedCustomHeihgt = true;
40 | return style
41 | }
42 | }
43 | extension CalendarView{
44 | func calender(calender: TBCalendar, layoutCallBackHeight: CGFloat) {
45 | self.calender.frame = CGRect.init(x: 0, y: 64, width: self.frame.width, height: layoutCallBackHeight)
46 | }
47 | @objc func changeDate(noty: Notification){
48 | let date: NSDate = noty.object as! NSDate
49 | let endDate = getMonthEnd(date: date)
50 | ZHFLog(message: endDate)
51 | let formatter = DateFormatter.init()
52 | formatter.dateFormat = "dd"
53 | let formatter1 = DateFormatter.init()
54 | formatter1.dateFormat = "yyyy-MM"
55 | let nowDate = formatter1.string(from: Date())
56 | let changeDate = formatter1.string(from: date as Date)
57 | let str = formatter.string(from: endDate as Date)
58 | let count = Int(str)!
59 | let nowDay = Int(formatter.string(from: date as Date))!
60 | var dotViews = [UIView]()
61 | /*
62 | 原则上来说 这个地方是需要在viewDidLoad中直接设置self.calender.setDataArr(arr: dotViews)
63 | 这个dotView中可以放任何对象,在实际开发中可以根据后台返回的数据进行赋值,比如钉钉今日的签到情况,
64 | 可以放在一个模型中记录,然后放到该集合中,然后到TBCalender.swift中
65 | func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell
66 | 方法304行,集合>0的判断中进行自己逻辑的书写,此处的创建只是为了效果
67 | */
68 | for i in 0.. Bool {
15 | let count = mobile.count
16 | if count != 11
17 | {
18 | return false
19 | }else{
20 | return true
21 | // let CM_NUM :NSString = "^((13[4-9])|(147)|(15[0-2,7-9])|(178)|(18[2-4,7-8]))\\d{8}|(1705)\\d{7}$";
22 | // let CU_NUM :NSString = "^((13[0-2])|(145)|(15[5-6])|(176)|(18[5,6]))\\d{8}|(1709)\\d{7}$";
23 | // let CT_NUM :NSString = "^((133)|(153)|(177)|(173)|(18[0,1,9]))\\d{8}$";
24 | // let pred1: NSPredicate = NSPredicate(format: "SELF MATCHES %@", CM_NUM)
25 | // let isMatch1 :Bool = pred1.evaluate(with: mobile)
26 | // let pred2: NSPredicate = NSPredicate(format: "SELF MATCHES %@", CU_NUM)
27 | // let isMatch2 :Bool = pred2.evaluate(with: mobile)
28 | // let pred3: NSPredicate = NSPredicate(format: "SELF MATCHES %@", CT_NUM)
29 | // let isMatch3 :Bool = pred3.evaluate(with: mobile)
30 | // if (isMatch1 || isMatch2 || isMatch3) {
31 | // return true
32 | // }else{
33 | // return false
34 | // }
35 | }
36 | }
37 | // 获取当前时间字符串 当天传入0, 前一天传1, 后一天传-1,以此类推
38 | class func initNowDateStr(number:NSInteger) -> String{
39 | let date = Date.init(timeInterval: TimeInterval(-24*60*60*number), since: Date())
40 | //输出格式
41 | let dformatter = DateFormatter.init()
42 | dformatter.dateFormat = "MM月dd日"
43 | let time = dformatter.string(from: date)
44 | return time
45 | }
46 | // 获取当前时间字符串 当天传入0, 前一天传1, 后一天传-1,以此类推
47 | class func initNowMonthStr(number:NSInteger) -> String{
48 | let date = Date.init(timeInterval: TimeInterval(-24*60*60*number), since: Date())
49 | //输出格式
50 | let dformatter = DateFormatter.init()
51 | dformatter.dateFormat = "yyyy年MM月"
52 | let time = dformatter.string(from: date)
53 | return time
54 | }
55 | //把当前时间时间转换成10位时间戳
56 | class func initNowDate() -> String{
57 | let timeInterval = NSDate().timeIntervalSince1970 * 1000
58 | return (String(timeInterval) as NSString).substring(to: 10)
59 | }
60 | //时间戳转时间
61 | class func initTime(timeStamp:NSInteger) -> String{
62 | let timeInterval:TimeInterval = TimeInterval(timeStamp)
63 | let date = Date.init(timeIntervalSince1970: timeInterval)
64 | //输出格式
65 | let dformatter = DateFormatter.init()
66 | dformatter.dateFormat = "yyyy\\MM\\dd"
67 | let time = dformatter.string(from: date)
68 | return time
69 | }
70 | //判断是否是邮箱
71 | class func initmailBox(email: String) -> Bool {
72 | let emailRegex = "[A-Z0-9a-z._%+-]+@[A-Za-z0-9.-]+\\.[A-Za-z]{2,4}"
73 | let emailTest:NSPredicate = NSPredicate(format: "SELF MATCHES %@", emailRegex)
74 | return emailTest.evaluate(with: email)
75 | }
76 | }
77 | extension NSString{
78 | //2.Md5 字典加密
79 | class func initMd5(Arr: [String]) -> [String : AnyObject] {
80 | var string :String = "Surprisebox123"
81 | for str1 in Arr {
82 | let strArr = str1.components(separatedBy: "=")
83 | string.append("\(strArr[0])\(strArr[1])")
84 | }
85 | let str = string.cString(using: String.Encoding.utf8)
86 | let strLen = CUnsignedInt(string.lengthOfBytes(using: String.Encoding.utf8))
87 | let digestLen = Int(CC_MD5_DIGEST_LENGTH)
88 | let result = UnsafeMutablePointer.allocate(capacity: digestLen)
89 | CC_MD5(str!, strLen, result)
90 | let hash = NSMutableString()
91 | for i in 0 ..< digestLen {
92 | hash.appendFormat("%02x", result[i])
93 | }
94 | result.deallocate()
95 | let strMd5 = String(format: hash as String).uppercased()
96 | let parameters :NSMutableDictionary = ["sign":strMd5]
97 | for i in 0 ..< Arr.count {
98 | let str = Arr[i]
99 | let strArray = str.components(separatedBy: "=")
100 | parameters.setObject( strArray[1], forKey: strArray[0] as NSCopying)
101 | }
102 | return parameters as! [String : AnyObject]
103 | }
104 | //2.Md5 字符串加密
105 | class func initMd5Str(string: String) -> String {
106 | let string1 :String = "Surprisebox123\(string)"
107 | let str = string1.cString(using: String.Encoding.utf8)
108 | let strLen = CUnsignedInt(string1.lengthOfBytes(using: String.Encoding.utf8))
109 | let digestLen = Int(CC_MD5_DIGEST_LENGTH)
110 | let result = UnsafeMutablePointer.allocate(capacity: digestLen)
111 | CC_MD5(str!, strLen, result)
112 | let hash = NSMutableString()
113 | for i in 0 ..< digestLen {
114 | hash.appendFormat("%02x", result[i])
115 | }
116 | result.deallocate()
117 | let strMd5 = String(format: hash as String).uppercased()
118 | return strMd5
119 | }
120 | }
121 | extension NSString{
122 | //字典转字符串
123 | class func initGetJsonString(dic: NSDictionary) -> String{
124 | if (!JSONSerialization.isValidJSONObject(dic)) {
125 | // "无法解析"
126 | return ""
127 | }
128 | let data :NSData! = try? JSONSerialization.data(withJSONObject: dic, options: []) as NSData
129 | let jsonString = NSString(data: data as Data, encoding: String.Encoding.utf8.rawValue)
130 | return jsonString! as String
131 | }
132 | //字符串转字典
133 | class func getDictionaryFromJSONString(jsonString:String) ->NSDictionary{
134 |
135 | let jsonData:Data = jsonString.data(using: .utf8)!
136 |
137 | let dict = try? JSONSerialization.jsonObject(with: jsonData, options: .mutableContainers)
138 | if dict != nil {
139 | return dict as! NSDictionary
140 | }
141 | return NSDictionary()
142 | }
143 | }
144 | extension NSString{
145 | var removeAllSapce: String {
146 | if self.length != 11{
147 | //过滤手机号中的 " " 和 "-" 和不是数字的东西
148 | return self.replacingOccurrences(of: "[^0-9]", with: "", options: NSString.CompareOptions.regularExpression, range: NSRange.init(location: 0, length: self.length))
149 | }
150 | else{
151 | return self as String
152 | }
153 | }
154 | }
155 |
--------------------------------------------------------------------------------
/ZHFToolBox/ZHFSubToolBox/PopCheckboxButtonView.swift:
--------------------------------------------------------------------------------
1 | //
2 | // PopCheckboxButtonView.swift
3 | // ZHFToolBox
4 | //
5 | // Created by 张海峰 on 2018/5/10.
6 | // Copyright © 2018年 张海峰. All rights reserved.
7 | //
8 | /*该demo是和大家分享一下,在项目中自定义各种弹框的思路,用来支撑自己项目的使用,无论什么样的弹框,只要有思路,
9 | 相信大家都能完美实现。感觉我这个demo对你有启发或者帮助,不妨给个星星吧
10 | https://github.com/FighterLightning/ZHFToolBox.git
11 | https://www.jianshu.com/p/88420bc4d32d
12 | */
13 | /*弹出一个多选框*/
14 | import UIKit
15 | protocol PopCheckboxButtonViewDelegate {
16 | func selectMessage(contentMarr: NSMutableArray)
17 | }
18 | class PopCheckboxButtonView: PopSmallChangeBigFatherView {
19 | var delegate:PopCheckboxButtonViewDelegate?
20 | let titleHeight: CGFloat = 75
21 | var contentArr : [String] = [String]()
22 | lazy var contentMarr: NSMutableArray = NSMutableArray()
23 | var trueBtn:UIButton = UIButton()
24 | override func addAnimate() {
25 | UIApplication.shared.keyWindow?.addSubview(self.initPopBackGroundView())
26 | self.isHidden = false
27 |
28 | UIView.animate(withDuration:TimeInterval(defaultTime), animations: {
29 | self.WhiteView.frame = self.whiteViewEndFrame
30 | }) { (_) in
31 | self.cancelBtn.frame.origin.y = self.WhiteView.frame.maxY + 20
32 | self.cancelBtn.isHidden = false
33 | self.addWhiteVieSubView1()
34 | }
35 | }
36 | //放一张展示图片
37 | func addWhiteVieSubView1(){
38 | let titleLabel:UILabel = UILabel.init(frame: CGRect.init(x: 0, y: 0, width: self.WhiteView.frame.width, height: titleHeight))
39 | titleLabel.text = "请选择多个菜"
40 | titleLabel.textAlignment = NSTextAlignment.center
41 | titleLabel.font = UIFont.systemFont(ofSize: 25, weight: UIFont.Weight.bold)
42 | titleLabel.textColor = ZHFColor.zhf_randomColor()
43 | self.WhiteView.addSubview(titleLabel)
44 | //添加按钮
45 | var x: CGFloat = 25
46 | var y: CGFloat = titleHeight
47 | for i in 0 ..< contentArr.count{
48 | let name: String = contentArr[i]
49 | let nameLenth : CGFloat = CGFloat(name.count * 25)
50 | let btn : UIButton = UIButton.init(type: .custom)
51 | if x + nameLenth > ScreenWidth - 50{
52 | x = 25
53 | y = y + 40
54 | }
55 | btn.frame = CGRect.init(x: x, y: y - 10, width: nameLenth, height: 30)
56 | btn.layer.masksToBounds = true
57 | btn.layer.cornerRadius = 15
58 | btn.layer.borderColor = ZHFColor.zhf88_contentTextColor.cgColor
59 | btn.layer.borderWidth = 0.5
60 | btn.titleLabel?.font = UIFont.systemFont(ofSize: 13, weight: UIFont.Weight.ultraLight)
61 | btn.setTitle(name, for: .normal)
62 | btn.setTitleColor(ZHFColor.zhf88_contentTextColor, for: .normal)
63 | btn.setTitle(name, for: .selected)
64 | btn.setTitleColor(ZHFColor.zhf_selectColor, for: .selected)
65 | x = x + nameLenth + 15
66 | btn.tag = i
67 | btn.isSelected = false
68 | btn.addTarget(self, action: #selector(btnClick), for: .touchUpInside)
69 | self.WhiteView.addSubview(btn)
70 | }
71 | trueBtn = UIButton.init(type: .custom)
72 | trueBtn.frame = CGRect.init(x:25, y: self.WhiteView.frame.height - 55, width: self.WhiteView.frame.width - 50, height: 40)
73 | trueBtn.layer.masksToBounds = true
74 | trueBtn.layer.cornerRadius = 5
75 | trueBtn.backgroundColor = ZHFColor.orange
76 | trueBtn.setTitle("确定", for: .normal)
77 | trueBtn.titleLabel?.font = UIFont.systemFont(ofSize: 14)
78 | trueBtn.setTitleColor(UIColor.white, for: .normal)
79 | trueBtn.addTarget(self, action: #selector(trueBtnClick), for: .touchUpInside)
80 | self.WhiteView.addSubview(trueBtn)
81 | }
82 | @objc func btnClick(btn:UIButton){
83 | btn.isSelected = !btn.isSelected
84 | if btn.isSelected == true {
85 | btn.layer.borderColor = ZHFColor.zhf_selectColor.cgColor
86 | contentMarr.add((btn.titleLabel?.text)!)
87 | }
88 | else{
89 | btn.layer.borderColor = ZHFColor.zhf88_contentTextColor.cgColor
90 | contentMarr.remove((btn.titleLabel?.text)!)
91 | }
92 | }
93 | @objc func trueBtnClick(btn:UIButton){
94 | self.delegate?.selectMessage(contentMarr: (contentMarr))
95 | }
96 | }
97 |
--------------------------------------------------------------------------------
/ZHFToolBox/ZHFSubToolBox/PopDiseaseView.swift:
--------------------------------------------------------------------------------
1 | //
2 | // PopDiseaseView.swift
3 | // ZHFToolBox
4 | //
5 | // Created by 张海峰 on 2019/3/13.
6 | // Copyright © 2019年 张海峰. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | class PopDiseaseView: UIView {
12 | //声明闭包
13 | typealias clickBtnClosure = (String?) -> Void
14 | //把申明的闭包设置成属性
15 | var clickClosure: clickBtnClosure?
16 | //为闭包设置调用函数
17 | func clickValueClosure(closure:clickBtnClosure?){
18 | clickClosure = closure
19 | }
20 | //背景区域的颜色和透明度
21 | var backgroundColor1:UIColor = UIColor.init(red: 0, green: 0, blue: 0, alpha: 0.4)
22 | var radioBtn: UIButton!
23 | var okBtn: UIButton!
24 | //初始化视图
25 | func initPopDiseaseView() -> PopDiseaseView {
26 | self.frame = CGRect.init(x: 0, y: 0, width: ScreenWidth, height: ScreenHeight)
27 | self.backgroundColor = backgroundColor1
28 | return self
29 | }
30 | //弹出View
31 | func addAnimate(view:PopDiseaseView) {
32 | UIApplication.shared.keyWindow?.addSubview(view)
33 | }
34 | func addWhiteViewContent(arr: NSArray) {
35 | let whiteView:UIView = UIView()
36 | whiteView.backgroundColor = UIColor.white
37 |
38 | whiteView.frame = CGRect.init(x: 0, y: ScreenHeight - ScreenHeight*2/3, width: ScreenWidth, height: ScreenHeight*2/3)
39 | self.addSubview(whiteView)
40 | let scrollView: UIScrollView = UIScrollView.init(frame: CGRect.init(x: 0, y: 0, width: ScreenWidth, height: ScreenHeight*2/3 - 100))
41 | scrollView.contentSize = CGSize.init(width: 0, height: CGFloat(arr.count+2)/3 * 50)
42 | scrollView.showsVerticalScrollIndicator = false
43 | whiteView.addSubview(scrollView)
44 | for i in 0 ..< arr.count {
45 | let name: String = arr[i] as! String
46 | let btn: UIButton = UIButton.init(type: .custom)
47 | let btnW: CGFloat = (ScreenWidth - 40)/3
48 | btn.frame = CGRect.init(x: 10 + CGFloat(i%3) * (btnW + 10), y: 15 + CGFloat(i/3 * 50), width: btnW, height: 44)
49 | btn.setTitle(name, for: .normal)
50 | btn.setTitleColor(ZHFColor.zhf33_titleTextColor, for: .normal)
51 | btn.layer.masksToBounds = true
52 | btn.layer.cornerRadius = 10
53 | btn.layer.borderWidth = 1
54 | btn.layer.borderColor = ZHFColor.zhf_lineColor.cgColor
55 | btn.titleLabel?.font = UIFont.systemFont(ofSize: 12)
56 | btn.addTarget(self, action: #selector(btnClick), for: .touchUpInside)
57 | scrollView.addSubview(btn)
58 | }
59 |
60 | let lineView: UIView = UIView()
61 | lineView.frame = CGRect.init(x: 0, y: scrollView.frame.maxY + 20, width: ScreenWidth, height: 1)
62 | lineView.backgroundColor = ZHFColor.zhfcc_lineColor
63 | whiteView.addSubview(lineView)
64 | let cancelBtn: UIButton = UIButton.init(type: .custom)
65 | cancelBtn.frame = CGRect.init(x: 25, y: lineView.frame.maxY + 10, width: ScreenWidth/2 - 37.5, height: 40)
66 | cancelBtn.setTitle("取消", for: .normal)
67 | cancelBtn.backgroundColor = UIColor.red
68 | cancelBtn.setTitleColor(ZHFColor.white, for: .normal)
69 | cancelBtn.layer.masksToBounds = true
70 | cancelBtn.layer.cornerRadius = 20
71 | cancelBtn.addTarget(self, action: #selector(tapBtnAndcancelBtnClick), for: .touchUpInside)
72 | whiteView.addSubview(cancelBtn)
73 | okBtn = UIButton.init(type: .custom)
74 | okBtn.frame = CGRect.init(x:ScreenWidth/2 + 12.5, y: lineView.frame.maxY + 10, width: ScreenWidth/2 - 37.5, height: 40)
75 | okBtn.setTitle("确认修改", for: .normal)
76 | okBtn.backgroundColor = UIColor.red
77 | okBtn.setTitleColor(ZHFColor.white, for: .normal)
78 | okBtn.layer.masksToBounds = true
79 | okBtn.isUserInteractionEnabled = false
80 | okBtn.alpha = 0.5
81 | okBtn.layer.cornerRadius = 20
82 | okBtn.addTarget(self, action: #selector(okBtnClick), for: .touchUpInside)
83 | whiteView.addSubview(okBtn)
84 | }
85 | @objc func btnClick(btn:UIButton){
86 | if radioBtn != nil {
87 | radioBtn.backgroundColor = UIColor.white
88 | radioBtn.setTitleColor(ZHFColor.zhf33_titleTextColor, for: .normal)
89 | }
90 | okBtn.isUserInteractionEnabled = true
91 | okBtn.alpha = 1
92 | btn.backgroundColor = UIColor.red
93 | btn.setTitleColor(UIColor.white, for: .normal)
94 | radioBtn = btn
95 | }
96 | @objc func okBtnClick(btn:UIButton){
97 | if radioBtn != nil {
98 | if clickClosure != nil{
99 | clickClosure!(radioBtn.titleLabel!.text)
100 | }
101 | self.removeFromSuperview()
102 | }
103 | }
104 | //移除
105 | @objc func tapBtnAndcancelBtnClick() {
106 | self.removeFromSuperview()
107 | }
108 | }
109 |
--------------------------------------------------------------------------------
/ZHFToolBox/ZHFSubToolBox/PopGifOpenBox/OpenBoxView.swift:
--------------------------------------------------------------------------------
1 | //
2 | // OpenBoxView.swift
3 | // GifImageAndImageChange
4 | //
5 | // Created by 张海峰 on 2018/4/11.
6 | // Copyright © 2018年 张海峰. All rights reserved.
7 | //
8 | // 2.Gif播放一半,弹出自定义动画,循环播放Gif任意区间帧动画。
9 | /*该demo是和大家分享一下,在项目中自定义各种弹框的思路,用来支撑自己项目的使用,无论什么样的弹框,只要有思路,
10 | 相信大家都能完美实现。感觉我这个demo对你有启发或者帮助,不妨给个星星吧
11 | https://github.com/FighterLightning/ZHFToolBox.git
12 | https://www.jianshu.com/p/88420bc4d32d
13 | */
14 | import UIKit
15 |
16 | class OpenBoxView: PopBackGroundView {
17 | let titleHeight: CGFloat = 75
18 | override func addAnimate() {
19 | self.isHidden = false
20 | UIView.animate(withDuration:0.5, animations: {
21 | self.WhiteView.frame = CGRect.init(x: 40, y: 100, width: ScreenWidth - 80, height: ScreenHeight - 230)
22 | }) { (_) in
23 | self.cancelBtn.frame.origin.y = self.WhiteView.frame.maxY + 20
24 | self.cancelBtn.isHidden = false
25 | self.addWhiteViewSubView()
26 | }
27 | }
28 | func addWhiteViewSubView(){
29 | let shadowpath :UIBezierPath = UIBezierPath.init(rect: self.WhiteView.bounds)
30 | self.WhiteView.layer.shadowColor = UIColor.yellow.cgColor
31 | self.WhiteView.layer.shadowOffset = CGSize.init(width:0, height: 1)//设置阴影的偏移量
32 | self.WhiteView.layer.shadowOpacity = 1 //设置阴影的透明度
33 | self.WhiteView.layer.shadowPath = shadowpath.cgPath
34 | self.WhiteView.layer.shadowRadius = 22
35 | self.WhiteView.layer.masksToBounds = false
36 | let titleLabel: UILabel = UILabel.init(frame: CGRect.init(x: 0, y: 0, width: self.WhiteView.frame.width, height: titleHeight))
37 | titleLabel.text = "恭喜你拆出下列产品"
38 | titleLabel.textAlignment = NSTextAlignment.center
39 | titleLabel.textColor = UIColor.gray
40 | titleLabel.font = UIFont.systemFont(ofSize: 14)
41 | self.WhiteView.addSubview(titleLabel)
42 | let imageView: UIImageView = UIImageView.init(frame: CGRect.init(x: 0, y: titleHeight, width: self.WhiteView.frame.width, height: self.WhiteView.frame.height - titleHeight))
43 | imageView.image = UIImage.init(named: "test1")
44 | imageView.contentMode = .scaleAspectFill
45 | imageView.clipsToBounds = true
46 | self.WhiteView.addSubview(imageView)
47 | }
48 | override func tapBtnAndcancelBtnClick() {
49 | self.superview?.removeFromSuperview()
50 | }
51 |
52 | }
53 |
--------------------------------------------------------------------------------
/ZHFToolBox/ZHFSubToolBox/PopGifOpenBox/PopAwayOpenBackGroundView.swift:
--------------------------------------------------------------------------------
1 | //
2 | // PopAwayOpenBackGroundView.swift
3 | // AmazedBox
4 | //
5 | // Created by 张海峰 on 2018/4/10.
6 | // Copyright © 2018年 张海峰. All rights reserved.
7 | // 2.Gif播放一半,弹出自定义动画,循环播放Gif任意区间帧动画。
8 | /*该demo是和大家分享一下,在项目中自定义各种弹框的思路,用来支撑自己项目的使用,无论什么样的弹框,只要有思路,
9 | 相信大家都能完美实现。感觉我这个demo对你有启发或者帮助,不妨给个星星吧
10 | https://github.com/FighterLightning/ZHFToolBox.git
11 | https://www.jianshu.com/p/88420bc4d32d
12 | */
13 | import UIKit
14 | import ImageIO
15 | class PopAwayOpenBackGroundView: UIView {
16 |
17 | var topView1 :UIImageView = UIImageView()
18 | lazy var frames: NSMutableArray = NSMutableArray()
19 | lazy var framesLast: NSMutableArray = NSMutableArray()
20 | //初始化视图
21 | func initPopAwayOpenBackGroundView() -> UIView {
22 | self.backgroundColor = UIColor.init(red: 0, green: 0, blue: 0, alpha: 0)
23 | self.frame = CGRect.init(x: 0, y: 0, width: ScreenWidth, height: ScreenHeight)
24 | let fileUrl :NSURL = Bundle.main.url(forResource: "open_boxA", withExtension: "gif")! as NSURL //加载GIF图片
25 | let gifSource : CGImageSource = CGImageSourceCreateWithURL(fileUrl, nil)! //将GIF图片转换成对应的图片源
26 | let frameCout : NSInteger = CGImageSourceGetCount(gifSource)//获取其中图片源个数,即由多少帧图片组成
27 | self.frames = NSMutableArray.init()//定义数组存储拆分出来的图片
28 | self.framesLast = NSMutableArray.init()//定义数组存储拆分出来的图片
29 | for i in 0 ..< frameCout{
30 | let imageRef :CGImage = CGImageSourceCreateImageAtIndex(gifSource, i, nil)!//从GIF图片中取出源图片
31 | let image : UIImage = UIImage.init(cgImage: imageRef)
32 | self.frames.add(image)
33 | if i > frameCout*2/3{
34 | //截取整个gif图的后面1/3 寸进数组以达到循环播放后半部分
35 | self.framesLast.add(image)
36 | }
37 | }
38 | topView1 = UIImageView.init(frame: CGRect.init(x: ScreenWidth/2 - 10, y: ScreenHeight/2 - 10, width: 20, height: 20))
39 | topView1.image = self.frames.firstObject as? UIImage
40 | topView1.isUserInteractionEnabled = true
41 | topView1.contentMode = .scaleAspectFill
42 | self.addSubview(topView1)
43 | return self
44 | }
45 | func addAnimate() {
46 | UIApplication.shared.keyWindow?.addSubview(self.initPopAwayOpenBackGroundView())
47 | UIView.animate(withDuration:0.2, animations: {
48 | self.topView1.frame = CGRect.init(x: 0, y: 0, width: ScreenWidth, height: ScreenHeight)
49 | }) { (_) in
50 | let AnimationNtimer : NSInteger = 3
51 | self.topView1.animationImages = self.frames as? [UIImage]//将图片数组加入UIImageView动画数组中
52 | self.topView1.isUserInteractionEnabled = true
53 | self.topView1.contentMode = .scaleAspectFill
54 | self.topView1.animationDuration = TimeInterval(AnimationNtimer); //每次动画时长
55 | self.topView1.startAnimating()
56 | Timer.scheduledTimer(timeInterval: TimeInterval(AnimationNtimer), target: self, selector: #selector(self.ArrowAnimationPlay), userInfo: nil, repeats: false)
57 | }
58 | }
59 | //播放结束循环播放GIF图的后面1/3部分
60 | @objc func ArrowAnimationPlay(){
61 | self.topView1.animationImages = self.framesLast as? [UIImage]//将图片数组加入UIImageView动画数组中
62 | self.topView1.animationDuration = 1
63 | self.topView1.startAnimating()
64 | }
65 | }
66 |
--------------------------------------------------------------------------------
/ZHFToolBox/ZHFSubToolBox/PopGifOpenBox/PopBackGroundView.swift:
--------------------------------------------------------------------------------
1 | //
2 | // PopBackGroundVIew.swift
3 | // AmazedBox
4 | //
5 | // Created by 张海峰 on 2018/1/9.
6 | // Copyright © 2018年 张海峰. All rights reserved.
7 | //
8 | /*该demo是和大家分享一下,在项目中自定义各种弹框的思路,用来支撑自己项目的使用,无论什么样的弹框,只要有思路,
9 | 相信大家都能完美实现。感觉我这个demo对你有启发或者帮助,不妨给个星星吧
10 | https://github.com/FighterLightning/ZHFToolBox.git
11 | https://www.jianshu.com/p/88420bc4d32d
12 | */
13 |
14 | import UIKit
15 | class PopBackGroundView: UIView,UIGestureRecognizerDelegate {
16 | var WhiteView: UIView = UIView()
17 | var cancelBtn: UIButton = UIButton()
18 | var backgroundColor1:UIColor = UIColor.init(red: 0, green: 0, blue: 0, alpha: 0.4)
19 | //初始化视图
20 | func initPopBackGroundView() -> UIView {
21 | self.frame = CGRect.init(x: 0, y: 0, width: ScreenWidth, height: ScreenHeight)
22 | self.backgroundColor = backgroundColor1
23 | self.isHidden = true
24 | //设置添加地址的View
25 | self.WhiteView.frame = CGRect.init(x: ScreenWidth/2 - 10, y: ScreenHeight/2 - 10, width: 20, height: 20)
26 | WhiteView.backgroundColor = UIColor.white
27 | WhiteView.layer.masksToBounds = true
28 | WhiteView.layer.cornerRadius = 10
29 | self.addSubview(WhiteView)
30 | cancelBtn = UIButton.init(type: .custom)
31 | cancelBtn.frame = CGRect.init(x:ScreenWidth/2 - 20, y: WhiteView.frame.maxY + 20, width: 40, height: 40)
32 | cancelBtn.tag = 1
33 | cancelBtn.setImage(UIImage.init(named: "cancel_white"), for: .normal)
34 | cancelBtn.isHidden = true
35 | cancelBtn.addTarget(self, action: #selector(tapBtnAndcancelBtnClick), for: .touchUpInside)
36 | self.addSubview(cancelBtn)
37 | return self
38 | }
39 | //弹出的动画效果
40 | func addAnimate() {
41 |
42 | }
43 | //收回的动画效果
44 | @objc func tapBtnAndcancelBtnClick() {
45 | UIView.animate(withDuration: 0.2, animations: {
46 | self.cancelBtn.isHidden = true
47 | self.WhiteView.frame = CGRect.init(x: ScreenWidth/2 - 20, y: ScreenHeight/2 - 20, width: 40, height: 40)
48 | self.cancelBtn.frame.origin.y = self.WhiteView.frame.maxY + 20
49 | }) { (_) in
50 | self.isHidden = true
51 | for view in self.WhiteView.subviews{
52 | view.removeFromSuperview()
53 | }
54 | }
55 |
56 | }
57 | }
58 |
--------------------------------------------------------------------------------
/ZHFToolBox/ZHFSubToolBox/PopGifOpenBox/open_boxA.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FighterLightning/ZHFAlertView/7d7d19d3872ba337270bb2df0841a78138ad9a9b/ZHFToolBox/ZHFSubToolBox/PopGifOpenBox/open_boxA.gif
--------------------------------------------------------------------------------
/ZHFToolBox/ZHFSubToolBox/PopImageView.swift:
--------------------------------------------------------------------------------
1 | //
2 | // PopImageView.swift
3 | // ZHFToolBox
4 | //
5 | // Created by 张海峰 on 2018/5/9.
6 | // Copyright © 2018年 张海峰. All rights reserved.
7 | //
8 | /*该demo是和大家分享一下,在项目中自定义各种弹框的思路,用来支撑自己项目的使用,无论什么样的弹框,只要有思路,
9 | 相信大家都能完美实现。感觉我这个demo对你有启发或者帮助,不妨给个星星吧
10 | https://github.com/FighterLightning/ZHFToolBox.git
11 | https://www.jianshu.com/p/88420bc4d32d
12 | */
13 | /*弹出一个带图片的提示框*/
14 | import UIKit
15 |
16 | class PopImageView: PopSmallChangeBigFatherView {
17 | let titleHeight: CGFloat = 75
18 | var oneBtn:UIButton = UIButton()
19 | var otherBtn:UIButton = UIButton()
20 | override func addAnimate() {
21 | UIApplication.shared.keyWindow?.addSubview(self.initPopBackGroundView())
22 | self.isHidden = false
23 | //按钮不要在动画完成后初始化(否则按钮没点击效果)
24 | oneBtn = UIButton.init(type: .custom)
25 | otherBtn = UIButton.init(type: .custom)
26 | UIView.animate(withDuration:TimeInterval(defaultTime), animations: {
27 | self.WhiteView.frame = self.whiteViewEndFrame
28 | }) { (_) in
29 | self.cancelBtn.frame.origin.y = self.WhiteView.frame.maxY + 20
30 | self.cancelBtn.isHidden = false
31 | self.addWhiteVieSubView1()
32 | }
33 | }
34 | //放一张展示图片
35 | func addWhiteVieSubView1(){
36 | let titleLabel:UILabel = UILabel.init(frame: CGRect.init(x: 0, y: 0, width: self.WhiteView.frame.width, height: titleHeight))
37 | titleLabel.text = "带图片的弹框"
38 | titleLabel.textAlignment = NSTextAlignment.center
39 | titleLabel.font = UIFont.systemFont(ofSize: 25, weight: UIFont.Weight.bold)
40 | titleLabel.textColor = ZHFColor.zhf_randomColor()
41 | self.WhiteView.addSubview(titleLabel)
42 | let imageView :UIImageView = UIImageView.init(frame: CGRect.init(x: 20, y: titleHeight, width: self.WhiteView.frame.width - 40, height: self.WhiteView.frame.height - titleHeight - 80))
43 | imageView.layer.masksToBounds = true
44 | imageView.contentMode = .scaleAspectFill
45 | imageView.image = UIImage.init(named: "test1")
46 | self.WhiteView.addSubview(imageView)
47 |
48 | oneBtn.frame = CGRect.init(x:20, y: self.WhiteView.frame.height - 55, width: (self.WhiteView.frame.width - 50)/2, height: 40)
49 | oneBtn.layer.masksToBounds = true
50 | oneBtn.layer.cornerRadius = 5
51 | oneBtn.backgroundColor = ZHFColor.zhf_selectColor
52 | oneBtn.setTitle("按钮One", for: .normal)
53 | oneBtn.titleLabel?.font = UIFont.systemFont(ofSize: 14)
54 | oneBtn.setTitleColor(UIColor.white, for: .normal)
55 | self.WhiteView.addSubview(oneBtn)
56 |
57 | otherBtn.frame = CGRect.init(x:oneBtn.frame.maxX + 10, y: self.WhiteView.frame.height - 55, width: (self.WhiteView.frame.width - 50)/2, height: 40)
58 | otherBtn.layer.masksToBounds = true
59 | otherBtn.layer.cornerRadius = 5
60 | otherBtn.backgroundColor = ZHFColor.zhf_selectColor
61 | otherBtn.titleLabel?.font = UIFont.systemFont(ofSize: 14)
62 | otherBtn.setTitle("按钮Two", for: .normal)
63 | otherBtn.setTitleColor(UIColor.white, for: .normal)
64 | self.WhiteView.addSubview(otherBtn)
65 | }
66 | }
67 |
--------------------------------------------------------------------------------
/ZHFToolBox/ZHFSubToolBox/PopProgressBar.swift:
--------------------------------------------------------------------------------
1 | //
2 | // PopProgressBar.swift
3 | // test
4 | //
5 | // Created by 张海峰 on 2019/3/4.
6 | // Copyright © 2019年 张海峰. All rights reserved.
7 | //
8 | /*该demo是和大家分享一下,在项目中自定义各种弹框的思路,用来支撑自己项目的使用,无论什么样的弹框,只要有思路,
9 | 相信大家都能完美实现。感觉我这个demo对你有启发或者帮助,不妨给个星星吧
10 | https://github.com/FighterLightning/ZHFToolBox.git
11 | 渐变进度条:单独简书连接https://www.jianshu.com/p/d985207dac6b
12 | */
13 | import UIKit
14 |
15 | class PopProgressBar: UIView ,UIGestureRecognizerDelegate {
16 | //背景区域的颜色和透明度
17 | var backgroundColor1:UIColor = UIColor.init(red: 0, green: 0, blue: 0, alpha: 0.4)
18 | //进度条view
19 | var progressView: UIView = UIView()
20 | //提示按钮
21 | var hintBtn: UIButton!
22 | var beforeValue :CGFloat = 0 //前一个值
23 | var displayLink: CADisplayLink! //定时器 承接控制器里的定时器,删除view时保证定时器关闭
24 | var path: UIBezierPath!
25 | var progressLayer :CAShapeLayer!
26 | //初始化视图
27 | func initPopBackGroundView() -> PopProgressBar {
28 | self.frame = CGRect.init(x: 0, y: 0, width: ScreenWidth, height: ScreenHeight)
29 | self.backgroundColor = backgroundColor1
30 | let tap:UITapGestureRecognizer = UITapGestureRecognizer.init(target: self, action: #selector(tapBtnAndcancelBtnClick))
31 | tap.delegate = self
32 | self.addGestureRecognizer(tap)
33 | return self
34 | }
35 | //弹出View
36 | func addAnimate(view:PopProgressBar) {
37 | self.addProgressView()
38 | UIApplication.shared.keyWindow?.addSubview(view)
39 | }
40 | //添加进度条
41 | func addProgressView() {
42 | progressView = UIView.init(frame: CGRect.init(x: 25, y: 290, width: ScreenWidth - 50, height: 15))
43 | progressView.layer.masksToBounds = true
44 | progressView.layer.cornerRadius = 7.5
45 | progressView.backgroundColor = UIColor.white
46 | self.addSubview(progressView)
47 | hintBtn = UIButton.init(type: UIButton.ButtonType.custom)
48 | hintBtn.frame = CGRect.init(x: 8, y: progressView.frame.minY - 30, width: 34, height: 20)
49 | hintBtn.setBackgroundImage(UIImage.init(named: "progressHint"), for: UIControl.State.normal)
50 | hintBtn.setTitle("0.0%", for: UIControl.State.normal)
51 | hintBtn.titleLabel?.font = UIFont.systemFont(ofSize: 8)
52 | hintBtn.setTitleColor(UIColor.white, for: UIControl.State.normal)
53 | self.addSubview(hintBtn)
54 | self.gradentWith(frame: progressView.frame)
55 | }
56 | //为进度条添加遮罩,及layer
57 | @objc func gradentWith(frame:CGRect) {
58 | path = UIBezierPath.init()
59 | path.stroke()//添加遮罩
60 | progressLayer = CAShapeLayer.init()
61 | progressLayer.frame = progressView.bounds
62 | progressLayer.strokeColor = ZHFColor.initString(hex: "0x23D7DE").cgColor
63 | progressLayer.lineCap = CAShapeLayerLineCap.init(rawValue: "kCALineCapRound")
64 | progressLayer.lineWidth = progressView.frame.size.height //渐变图层
65 | let grain:CALayer = CALayer.init()
66 | let gradientLayer: CAGradientLayer = CAGradientLayer.init()
67 | let fixColor: UIColor = ZHFColor.initString(hex: "0x71FFB7")
68 | let preColor: UIColor = ZHFColor.initString(hex: "0x23D7DE")
69 | gradientLayer.frame = CGRect.init(x: 0, y: 0, width: progressView.frame.size.width, height: progressView.frame.size.height)
70 | gradientLayer.colors = [preColor.cgColor,fixColor.cgColor]
71 | // 开始点
72 | gradientLayer.startPoint = CGPoint.init(x: 0, y: 0)
73 | // 结束点
74 | gradientLayer.endPoint = CGPoint.init(x: 1, y: 1)
75 | grain.addSublayer(gradientLayer)
76 | grain.mask = progressLayer
77 | progressView.layer.addSublayer(grain)//增加动画
78 | let pathAnimation : CABasicAnimation = CABasicAnimation.init(keyPath: "strokeEnd")
79 | pathAnimation.duration = 0;
80 | pathAnimation.timingFunction = CAMediaTimingFunction.init(name: .linear)
81 | pathAnimation.fromValue = NSNumber.init(value: 0.0)
82 | pathAnimation.toValue = NSNumber.init(value: 1.0)
83 | pathAnimation.autoreverses = false
84 | pathAnimation.repeatCount = 1
85 | progressLayer.add(pathAnimation, forKey: "strokeEndAnimation")
86 | }
87 | //当前进度
88 | func passValue(currentValue: CGFloat,allValue: CGFloat) {
89 | if currentValue < allValue {
90 | //当前比例
91 | let currentProportion : CGFloat = currentValue/allValue
92 | hintBtn.frame = CGRect.init(x: 8 + currentProportion * progressView.frame.size.width, y: progressView.frame.minY - 30, width: 34, height: 20)
93 | hintBtn.setTitle("\(NSInteger(currentProportion*100))%", for: UIControl.State.normal)
94 | path.move(to: CGPoint.init(x: progressView.frame.size.width * (beforeValue/allValue), y: progressView.frame.size.height/2))
95 | path.addLine(to: CGPoint.init(x: progressView.frame.size.width * currentProportion, y: progressView.frame.size.height/2))
96 | progressLayer.path = path.cgPath
97 | }
98 | else{
99 | //上传/下载成功 隐藏当前状态
100 | self.tapBtnAndcancelBtnClick()
101 | }
102 | beforeValue = currentValue
103 | }
104 | //移除或者中断进度
105 | @objc func tapBtnAndcancelBtnClick() {
106 | self.removeFromSuperview()
107 | displayLink.invalidate()
108 | displayLink = nil
109 | }
110 |
111 | }
112 |
--------------------------------------------------------------------------------
/ZHFToolBox/ZHFSubToolBox/PopRadioButtonView.swift:
--------------------------------------------------------------------------------
1 | //
2 | // PopButtonView.swift
3 | // ZHFToolBox
4 | //
5 | // Created by 张海峰 on 2018/5/10.
6 | // Copyright © 2018年 张海峰. All rights reserved.
7 | //
8 | /*该demo是和大家分享一下,在项目中自定义各种弹框的思路,用来支撑自己项目的使用,无论什么样的弹框,只要有思路,
9 | 相信大家都能完美实现。感觉我这个demo对你有启发或者帮助,不妨给个星星吧
10 | https://github.com/FighterLightning/ZHFToolBox.git
11 | https://www.jianshu.com/p/88420bc4d32d
12 | */
13 | /*弹出一个单选框*/
14 | import UIKit
15 | protocol PopRadioButtonViewDelegate {
16 | func selectBtnMessage(content: String)
17 | }
18 | class PopRadioButtonView: PopSmallChangeBigFatherView {
19 | var delegate:PopRadioButtonViewDelegate?
20 | let titleHeight: CGFloat = 75
21 | var contentArr : [String] = [String]()
22 | var radioBtn:UIButton = UIButton()
23 | var trueBtn:UIButton = UIButton()
24 | override func addAnimate() {
25 | UIApplication.shared.keyWindow?.addSubview(self.initPopBackGroundView())
26 | self.isHidden = false
27 |
28 | UIView.animate(withDuration:TimeInterval(defaultTime), animations: {
29 | self.WhiteView.frame = self.whiteViewEndFrame
30 | }) { (_) in
31 | self.cancelBtn.frame.origin.y = self.WhiteView.frame.maxY + 20
32 | self.cancelBtn.isHidden = false
33 | self.addWhiteVieSubView1()
34 | }
35 | }
36 | //放一张展示图片
37 | func addWhiteVieSubView1(){
38 | let titleLabel:UILabel = UILabel.init(frame: CGRect.init(x: 0, y: 0, width: self.WhiteView.frame.width, height: titleHeight))
39 | titleLabel.text = "请选择一个菜"
40 | titleLabel.textAlignment = NSTextAlignment.center
41 | titleLabel.font = UIFont.systemFont(ofSize: 25, weight: UIFont.Weight.bold)
42 | titleLabel.textColor = ZHFColor.zhf_randomColor()
43 | self.WhiteView.addSubview(titleLabel)
44 | //添加按钮
45 | var x: CGFloat = 25
46 | var y: CGFloat = titleHeight
47 | for i in 0 ..< contentArr.count{
48 | let name: String = contentArr[i]
49 | let nameLenth : CGFloat = CGFloat(name.count * 25)
50 | let btn : UIButton = UIButton.init(type: .custom)
51 | if x + nameLenth > ScreenWidth - 50{
52 | x = 25
53 | y = y + 40
54 | }
55 | btn.frame = CGRect.init(x: x, y: y - 10, width: nameLenth, height: 30)
56 | btn.layer.masksToBounds = true
57 | btn.layer.cornerRadius = 15
58 | btn.layer.borderColor = ZHFColor.zhf88_contentTextColor.cgColor
59 | btn.layer.borderWidth = 0.5
60 | btn.titleLabel?.font = UIFont.systemFont(ofSize: 13, weight: UIFont.Weight.ultraLight)
61 | btn.setTitle(name, for: .normal)
62 | btn.setTitleColor(ZHFColor.zhf88_contentTextColor, for: .normal)
63 | btn.setTitle(name, for: .selected)
64 | btn.setTitleColor(ZHFColor.zhf_selectColor, for: .selected)
65 | x = x + nameLenth + 15
66 | btn.tag = i
67 | btn.isSelected = false
68 | btn.addTarget(self, action: #selector(btnClick), for: .touchUpInside)
69 | self.WhiteView.addSubview(btn)
70 | }
71 | trueBtn = UIButton.init(type: .custom)
72 | trueBtn.frame = CGRect.init(x:25, y: self.WhiteView.frame.height - 55, width: self.WhiteView.frame.width - 50, height: 40)
73 | trueBtn.layer.masksToBounds = true
74 | trueBtn.layer.cornerRadius = 5
75 | trueBtn.backgroundColor = ZHFColor.orange
76 | trueBtn.setTitle("确定", for: .normal)
77 | trueBtn.titleLabel?.font = UIFont.systemFont(ofSize: 14)
78 | trueBtn.setTitleColor(UIColor.white, for: .normal)
79 | trueBtn.addTarget(self, action: #selector(trueBtnClick), for: .touchUpInside)
80 | self.WhiteView.addSubview(trueBtn)
81 | }
82 | @objc func btnClick(btn:UIButton){
83 | radioBtn.isSelected = false
84 | radioBtn.layer.borderColor = ZHFColor.zhf88_contentTextColor.cgColor
85 | btn.layer.borderColor = ZHFColor.zhf_selectColor.cgColor
86 | btn.isSelected = true
87 | radioBtn = btn
88 | }
89 | @objc func trueBtnClick(btn:UIButton){
90 | self.delegate?.selectBtnMessage(content: (radioBtn.titleLabel?.text)!)
91 | }
92 | }
93 |
--------------------------------------------------------------------------------
/ZHFToolBox/ZHFSubToolBox/PopSmallChangeBigFatherView.swift:
--------------------------------------------------------------------------------
1 | //
2 | // FatherView.swift
3 | // ZHFToolBox
4 | //
5 | // Created by 张海峰 on 2018/5/9.
6 | // Copyright © 2018年 张海峰. All rights reserved.
7 | //
8 | /*该demo是和大家分享一下,在项目中自定义各种弹框的思路,用来支撑自己项目的使用,无论什么样的弹框,只要有思路,相信大家都能完美实现。感觉我这个demo对你有启发或者帮助,不妨给个星星吧
9 | https://github.com/FighterLightning/ZHFToolBox.git
10 | https://www.jianshu.com/p/88420bc4d32d
11 | */
12 | /*弹框的基础图*/
13 | import UIKit
14 | class PopSmallChangeBigFatherView: UIView ,UIGestureRecognizerDelegate{
15 | //白色view用来装一些控件
16 | var WhiteView: UIView = UIView()
17 | var whiteViewStartFrame: CGRect = CGRect.init(x: ScreenWidth/2 - 10, y: ScreenHeight/2 - 10, width: 20, height: 20)
18 | var whiteViewEndFrame: CGRect = CGRect.init(x: 40, y: 100, width: ScreenWidth - 80, height: ScreenHeight - 230)
19 | //取消按钮
20 | var cancelBtn: UIButton = UIButton()
21 | //背景区域的颜色和透明度
22 | var backgroundColor1:UIColor = UIColor.init(red: 0, green: 0, blue: 0, alpha: 0.4)
23 | var defaultTime:CGFloat = 0.5
24 |
25 | //初始化视图
26 | func initPopBackGroundView() -> UIView {
27 | self.frame = CGRect.init(x: 0, y: 0, width: ScreenWidth, height: ScreenHeight)
28 | self.backgroundColor = backgroundColor1
29 | self.isHidden = true
30 | //设置添加地址的View
31 | self.WhiteView.frame = whiteViewStartFrame
32 | WhiteView.backgroundColor = UIColor.white
33 | WhiteView.layer.masksToBounds = true
34 | WhiteView.layer.cornerRadius = 10
35 | self.addSubview(WhiteView)
36 | cancelBtn = UIButton.init(type: .custom)
37 | cancelBtn.frame = CGRect.init(x:ScreenWidth/2 - 20, y: WhiteView.frame.maxY + 20, width: 40, height: 40)
38 | cancelBtn.tag = 1
39 | cancelBtn.setImage(UIImage.init(named: "cancel_white"), for: .normal)
40 | cancelBtn.isHidden = true
41 | cancelBtn.addTarget(self, action: #selector(tapBtnAndcancelBtnClick), for: .touchUpInside)
42 | self.addSubview(cancelBtn)
43 | return self
44 | }
45 | //弹出的动画效果
46 | func addAnimate() {
47 |
48 | }
49 | //收回的动画效果
50 | @objc func tapBtnAndcancelBtnClick() {
51 | for view in WhiteView.subviews {
52 | view.removeFromSuperview()
53 | }
54 | UIView.animate(withDuration: TimeInterval(defaultTime), animations: {
55 | self.cancelBtn.isHidden = true
56 | self.WhiteView.frame = self.whiteViewStartFrame
57 | self.cancelBtn.frame.origin.y = self.WhiteView.frame.maxY + 20
58 | }) { (_) in
59 | self.isHidden = true
60 | }
61 |
62 | }
63 | }
64 |
--------------------------------------------------------------------------------
/ZHFToolBox/ZHFSubToolBox/PopSomeColorView.swift:
--------------------------------------------------------------------------------
1 | //
2 | // PopSelectColorView.swift
3 | // ZHFToolBox
4 | //
5 | // Created by 张海峰 on 2018/5/30.
6 | // Copyright © 2018年 张海峰. All rights reserved.
7 | //
8 | /*该demo是和大家分享一下,在项目中自定义各种弹框的思路,用来支撑自己项目的使用,无论什么样的弹框,只要有思路,
9 | 相信大家都能完美实现。感觉我这个demo对你有启发或者帮助,不妨给个星星吧
10 | https://github.com/FighterLightning/ZHFToolBox.git
11 | https://www.jianshu.com/p/88420bc4d32d
12 | */
13 | /*弹出一堆小视图,带回弹*/
14 | import UIKit
15 | protocol PopSomeColorViewDelegate {
16 | func selectBtnTag(btnTag: NSInteger)
17 | }
18 | //定义闭包类型(特定的函数类型函数类型)
19 | typealias InputClosureType = (String) -> Void
20 | class PopSomeColorView: UIView {
21 |
22 | var delegate:PopSomeColorViewDelegate?
23 | //接收上个页面传过来的闭包块
24 | var backClosure: InputClosureType?
25 | var animateTime:TimeInterval = 0.9 //动画总时长
26 | var delyTime:CGFloat = 0.1 //每两个动画间隔时长
27 | var cancelBtn :UIButton = UIButton()
28 | var Y :CGFloat = ScreenHeight/2 + 100 //每个按钮上移的距离
29 | let colors: NSArray = [UIColor.green,UIColor.yellow,UIColor.blue,UIColor.red,UIColor.purple,UIColor.orange];
30 | let btnWH: CGFloat = (ScreenWidth - 120)/3
31 | lazy var btnMarr: NSMutableArray = NSMutableArray()
32 | //背景区域的颜色和透明度
33 | var backgroundColor1:UIColor = UIColor.init(red: 0 , green: 0, blue: 0, alpha: 0.5) //初始化视图
34 | func initPopSelectColorView() -> UIView {
35 | self.frame = CGRect.init(x: 0, y: 0, width: ScreenWidth, height: ScreenHeight)
36 | self.backgroundColor = backgroundColor1
37 | self.isHidden = true
38 | for j in 0 ..< colors.count {
39 | let btn :UIButton = UIButton.init(type: .custom)
40 | btn.frame = CGRect.init(x: 50 + (10 + btnWH) * CGFloat(j%3), y: ScreenHeight + CGFloat(j/3) * (btnWH + 40), width: btnWH, height:btnWH)
41 | btn.layer.borderColor = ZHFColor.zhff9_backGroundColor.cgColor
42 | btn.layer.borderWidth = 4
43 | btn.backgroundColor = colors[j] as? UIColor;
44 | btn.tag = j
45 | btn.addTarget(self, action: #selector(cancelBtnClick), for: .touchUpInside)
46 | self.btnMarr.add(btn)
47 | self.addSubview(btn)
48 | if j == colors.count - 1{
49 | self.cancelBtn = UIButton.init(type: .custom)
50 | self.cancelBtn.frame = CGRect.init(x:ScreenWidth/2 - 20, y: btn.frame.maxY + 40, width: 40, height: 40)
51 | self.cancelBtn.setImage(UIImage.init(named: "cancel_white"), for: .normal)
52 | self.cancelBtn.addTarget(self, action: #selector(cancelBtnClick), for: .touchUpInside)
53 | self.addSubview(cancelBtn)
54 | }
55 | }
56 | return self
57 | }
58 | func addAnimate(){
59 | UIApplication.shared.keyWindow?.addSubview(self.initPopSelectColorView())
60 | self.isHidden = false
61 | for i in 0 ..< self.btnMarr.count {
62 | let btn: UIButton = self.btnMarr[i] as! UIButton
63 | let btnY : CGFloat = btn.frame.origin.y
64 | let cancelBtnY :CGFloat = self.cancelBtn.frame.origin.y
65 | UIView.animate(withDuration: self.animateTime, delay: TimeInterval(self.delyTime * CGFloat(i)) , usingSpringWithDamping: 0.7, initialSpringVelocity: 0.2, options: .curveEaseInOut, animations: {
66 | btn.frame.origin.y = btnY - self.Y
67 | }, completion: { (_) in
68 | self.cancelBtn.transform = CGAffineTransform.init(rotationAngle:0)
69 | UIView.animate(withDuration: self.animateTime, animations: {
70 | self.cancelBtn.frame.origin.y = cancelBtnY - self.Y
71 | self.cancelBtn.transform = CGAffineTransform.init(rotationAngle:.pi/2)
72 | })
73 | })
74 | }
75 | }
76 | @objc func cancelBtnClick(btn: UIButton){
77 | if btn != cancelBtn {
78 | self.delegate?.selectBtnTag(btnTag: btn.tag)
79 | }
80 | self.isHidden = false
81 | UIView.animate(withDuration: self.animateTime, animations: {
82 | self.cancelBtn.frame.origin.y += self.Y
83 | self.cancelBtn.transform = CGAffineTransform.init(rotationAngle:0)
84 | }) { (_) in
85 | for i in 0 ..< self.btnMarr.count {
86 | let btn: UIButton = self.btnMarr[self.btnMarr.count - i - 1] as! UIButton;
87 | let btnY : CGFloat = btn.frame.origin.y;
88 | UIView.animate(withDuration: self.animateTime, delay: TimeInterval(self.delyTime * CGFloat(i)) , usingSpringWithDamping: 0.7, initialSpringVelocity: 0.2, options: .curveEaseInOut, animations: {
89 | btn.frame.origin.y = btnY + self.Y
90 | }, completion: { (_) in
91 | self.btnMarr = NSMutableArray.init()
92 | self.removeFromSuperview()
93 | })
94 | }
95 | }
96 | }
97 | }
98 |
--------------------------------------------------------------------------------
/ZHFToolBox/ZHFSubToolBox/PopTextView.swift:
--------------------------------------------------------------------------------
1 | //
2 | // PopTextView.swift
3 | // ZHFToolBox
4 | //
5 | // Created by 张海峰 on 2018/5/10.
6 | // Copyright © 2018年 张海峰. All rights reserved.
7 | //
8 | /*该demo是和大家分享一下,在项目中自定义各种弹框的思路,用来支撑自己项目的使用,无论什么样的弹框,只要有思路,
9 | 相信大家都能完美实现。感觉我这个demo对你有启发或者帮助,不妨给个星星吧
10 | https://github.com/FighterLightning/ZHFToolBox.git
11 | https://www.jianshu.com/p/88420bc4d32d
12 | */
13 | /*弹出一个输入框*/
14 | import UIKit
15 |
16 | class PopTextView: PopSmallChangeBigFatherView {
17 | let titleHeight: CGFloat = 75
18 | var placeHoldLable: UILabel = UILabel()
19 | var textView:UITextView = UITextView()
20 | var textStr : String = "请输入内容"
21 | var oneBtn:UIButton = UIButton()
22 | var otherBtn:UIButton = UIButton()
23 | override func addAnimate() {
24 | UIApplication.shared.keyWindow?.addSubview(self.initPopBackGroundView())
25 | self.isHidden = false
26 | //按钮不要在动画完成后初始化(否则按钮没点击效果)
27 | oneBtn = UIButton.init(type: .custom)
28 | otherBtn = UIButton.init(type: .custom)
29 | UIView.animate(withDuration:TimeInterval(defaultTime), animations: {
30 | self.WhiteView.frame = self.whiteViewEndFrame
31 | }) { (_) in
32 | self.addWhiteVieSubView1()
33 | }
34 | }
35 | //放一个输入框
36 | func addWhiteVieSubView1(){
37 | let titleLabel:UILabel = UILabel.init(frame: CGRect.init(x: 0, y: 0, width: self.WhiteView.frame.width, height: titleHeight))
38 | titleLabel.text = "修改cell内容"
39 | titleLabel.textAlignment = NSTextAlignment.center
40 | titleLabel.font = UIFont.systemFont(ofSize: 25, weight: UIFont.Weight.bold)
41 | titleLabel.textColor = ZHFColor.zhf_randomColor()
42 | self.WhiteView.addSubview(titleLabel)
43 |
44 | //占位Label的位置自行调整
45 | placeHoldLable = UILabel.init(frame: CGRect.init(x: 25, y: titleHeight + 8, width: self.WhiteView.frame.width - 50, height: 20))
46 | placeHoldLable.text = textStr
47 | placeHoldLable.textColor = ZHFColor.black
48 | placeHoldLable.font = UIFont.systemFont(ofSize: 15)//大小和textView字体大小一致
49 | self.WhiteView.addSubview(placeHoldLable)
50 |
51 | textView = UITextView.init(frame: CGRect.init(x: 20, y: titleHeight, width: self.WhiteView.frame.width - 40, height: self.WhiteView.frame.height - titleHeight - 80))
52 | textView.layer.masksToBounds = true
53 | textView.layer.borderColor = ZHFColor.zhfcc_lineColor.cgColor
54 | textView.layer.borderWidth = 1
55 | textView.layer.cornerRadius = 5
56 | textView.backgroundColor = UIColor.white
57 | textView.alpha = 0.5
58 | textView.delegate = self
59 | textView.returnKeyType = UIReturnKeyType.done
60 | textView.font = UIFont.systemFont(ofSize: 15)
61 | self.WhiteView.addSubview(textView)
62 |
63 | oneBtn.frame = CGRect.init(x:20, y: self.WhiteView.frame.height - 55, width: (self.WhiteView.frame.width - 50)/2, height: 40)
64 | oneBtn.layer.masksToBounds = true
65 | oneBtn.layer.cornerRadius = 5
66 | oneBtn.backgroundColor = ZHFColor.orange
67 | oneBtn.setTitle("确定", for: .normal)
68 | oneBtn.titleLabel?.font = UIFont.systemFont(ofSize: 14)
69 | oneBtn.setTitleColor(UIColor.white, for: .normal)
70 | self.WhiteView.addSubview(oneBtn)
71 |
72 | otherBtn.frame = CGRect.init(x:oneBtn.frame.maxX + 10, y: self.WhiteView.frame.height - 55, width: (self.WhiteView.frame.width - 50)/2, height: 40)
73 | otherBtn.layer.masksToBounds = true
74 | otherBtn.layer.cornerRadius = 5
75 | otherBtn.backgroundColor = ZHFColor.orange
76 | otherBtn.titleLabel?.font = UIFont.systemFont(ofSize: 14)
77 | otherBtn.setTitle("取消", for: .normal)
78 | otherBtn.setTitleColor(UIColor.white, for: .normal)
79 | self.WhiteView.addSubview(otherBtn)
80 | }
81 | }
82 | extension PopTextView:UITextViewDelegate{
83 | override func touchesBegan(_ touches: Set, with event: UIEvent?) {
84 | self.endEditing(true);
85 | textView.resignFirstResponder()
86 | }
87 | func textViewDidChange(_ textView: UITextView) {
88 | if textView.text == ""{
89 | placeHoldLable.isHidden = false
90 | textView.alpha = 0.5
91 | }
92 | else{
93 | placeHoldLable.isHidden = true
94 | textView.alpha = 1
95 | }
96 | }
97 | //监听return 按钮被点击
98 | func textView(_ textView: UITextView, shouldChangeTextIn range: NSRange, replacementText text: String) -> Bool {
99 | if text == "\n" {
100 | self.endEditing(true);
101 | textView.resignFirstResponder()
102 | return false;
103 | }
104 | return true;
105 | }
106 | }
107 |
--------------------------------------------------------------------------------
/ZHFToolBox/ZHFSubToolBox/PopTopOrBottomOutView.swift:
--------------------------------------------------------------------------------
1 | //
2 | // PopTopOrBottomOutFatherView.swift
3 | // ZHFToolBox
4 | //
5 | // Created by 张海峰 on 2018/5/10.
6 | // Copyright © 2018年 张海峰. All rights reserved.
7 | //
8 | /*该demo是和大家分享一下,在项目中自定义各种弹框的思路,用来支撑自己项目的使用,无论什么样的弹框,只要有思路,
9 | 相信大家都能完美实现。感觉我这个demo对你有启发或者帮助,不妨给个星星吧
10 | https://github.com/FighterLightning/ZHFToolBox.git
11 | https://www.jianshu.com/p/88420bc4d32d
12 | */
13 | /*从底部或顶部弹出卡片,带回弹*/
14 | import UIKit
15 |
16 | class PopTopOrBottomOutView: UIView {
17 | var cancelBtn :UIButton = UIButton()
18 | var outerImage:UIImageView = UIImageView()
19 | var whiteView :UIView = UIView()
20 | //背景区域的颜色和透明度
21 | var backgroundColor1:UIColor = UIColor.init(red: 0, green: 0, blue: 0, alpha: 0.4)
22 | var topOrBottomViewStartFrame = CGRect.init(x: 25, y: ScreenHeight, width: ScreenWidth - 50, height: 500)
23 | //初始化视图
24 | func initPopBackGroundView() -> UIView {
25 | self.frame = CGRect.init(x: 0, y: 0, width: ScreenWidth, height: ScreenHeight)
26 | self.backgroundColor = backgroundColor1
27 | self.isHidden = true
28 | //为落下的视图添加背景图
29 | let innerImage:UIImageView = UIImageView.init(frame: CGRect.init(x: 0, y: ScreenHeight - 210, width: ScreenWidth, height: 210))
30 | innerImage.image = UIImage.init(named: "inner_layerImage")
31 | self.addSubview(innerImage)
32 |
33 | outerImage = UIImageView.init(frame: CGRect.init(x: 0, y: 0, width: ScreenWidth, height: ScreenHeight))
34 | outerImage.image = UIImage.init(named: "outer_layerImage")
35 | self.addSubview(outerImage)
36 | return self
37 | }
38 | //为白色视图添加子视图
39 | func addWhiteViewSubView() {
40 | let imageView: UIImageView = UIImageView.init(frame: CGRect.init(x: 0, y: 0, width: whiteView.frame.size.width, height: whiteView.frame.size.height))
41 | imageView.layer.masksToBounds = true
42 | imageView.contentMode = .scaleAspectFill
43 | imageView.image = UIImage.init(named: "bmw_image")
44 | whiteView.addSubview(imageView)
45 | let titleLabel: UILabel = UILabel.init(frame: CGRect.init(x: 5, y: 0, width: whiteView.frame.size.width - 10, height: 50))
46 | titleLabel.textColor = UIColor.white
47 | titleLabel.font = UIFont.systemFont(ofSize: 20)
48 | titleLabel.text = "恭喜你获得一台 “别摸我”!!!!"
49 | imageView.addSubview(titleLabel)
50 | let contentLabel: UILabel = UILabel.init(frame: CGRect.init(x: 20, y: titleLabel.frame.maxY, width: whiteView.frame.size.width - 40, height: 70))
51 | contentLabel.textColor = UIColor.orange
52 | contentLabel.font = UIFont.systemFont(ofSize: 15)
53 | contentLabel.numberOfLines = 0
54 | contentLabel.textAlignment = NSTextAlignment.right
55 | contentLabel.text = "别摸我是一款超级牛逼的车,据说上天都不用梯子,全靠空气动力支撑,能上天,能下海,我只不过是瞎说的。"
56 | imageView.addSubview(contentLabel)
57 | }
58 | //从下面弹出来
59 | func addAnimateFromBottom() {
60 | UIApplication.shared.keyWindow?.addSubview(self.initPopBackGroundView())
61 | self.isHidden = false
62 | self.cancelBtn.isHidden = true
63 | self.whiteView.frame = topOrBottomViewStartFrame
64 | self.whiteView.backgroundColor = ZHFColor.zhf_colorAlpha(withHex: 0xffffff, alpha: 0)
65 | self.addSubview(self.whiteView)
66 | addWhiteViewSubView()
67 |
68 | self.cancelBtn = UIButton.init(type: .custom)
69 | UIView.animate(withDuration:0.5, animations: {
70 | self.whiteView.frame.origin.y = ScreenHeight - 670
71 | self.bringSubviewToFront(self.outerImage)
72 | }) { (_) in
73 | UIView.animate(withDuration: 0.2, animations: {
74 | self.whiteView.frame.origin.y = ScreenHeight - 530
75 | }, completion: { (_) in
76 | UIView.animate(withDuration: 0.2, animations: {
77 | self.whiteView.frame.origin.y = ScreenHeight - 570
78 | }, completion: { (_) in
79 | self.cancelBtn.isHidden = false
80 | self.cancelBtn.frame = CGRect.init(x:self.frame.maxX - 60, y:ScreenHeight - 610, width: 40, height: 40)
81 | self.cancelBtn.tag = 1
82 | self.cancelBtn.setImage(UIImage.init(named: "cancel_white"), for: .normal)
83 | self.cancelBtn.addTarget(self, action: #selector(self.cancelBtnClickBottom), for: .touchUpInside)
84 | self.addSubview(self.cancelBtn)
85 | })
86 | })
87 | }
88 | }
89 | //从上面弹出来
90 | func addAnimateFromTop() {
91 | UIApplication.shared.keyWindow?.addSubview(self.initPopBackGroundView())
92 | self.isHidden = false
93 | self.cancelBtn.isHidden = true
94 | self.whiteView.frame = topOrBottomViewStartFrame
95 | self.whiteView.backgroundColor = ZHFColor.zhf_colorAlpha(withHex: 0xffffff, alpha: 0.5)
96 | self.addSubview(self.whiteView)
97 | addWhiteViewSubView()
98 |
99 | self.cancelBtn = UIButton.init(type: .custom)
100 | UIView.animate(withDuration:0.5, animations: {
101 | self.whiteView.frame.origin.y = ScreenHeight - 470
102 | self.bringSubviewToFront(self.outerImage)
103 | }) { (_) in
104 | UIView.animate(withDuration: 0.2, animations: {
105 | self.whiteView.frame.origin.y = ScreenHeight - 610
106 | }, completion: { (_) in
107 | UIView.animate(withDuration: 0.2, animations: {
108 | self.whiteView.frame.origin.y = ScreenHeight - 570
109 | }, completion: { (_) in
110 | self.cancelBtn.isHidden = false
111 | self.cancelBtn.frame = CGRect.init(x:self.frame.maxX - 60, y:ScreenHeight - 610, width: 40, height: 40)
112 | self.cancelBtn.setImage(UIImage.init(named: "cancel_white"), for: .normal)
113 | self.cancelBtn.addTarget(self, action: #selector(self.cancelBtnClickTop), for: .touchUpInside)
114 | self.addSubview(self.cancelBtn)
115 | })
116 | })
117 | }
118 | }
119 | @objc func cancelBtnClickTop(btn:UIButton){
120 | self.cancelBtn.isHidden = true
121 | UIView.animate(withDuration: 0.5, animations: {
122 | self.whiteView.frame.origin.y = -ScreenHeight
123 | }) { (_) in
124 | self.removeFromSuperview()
125 | }
126 | }
127 | @objc func cancelBtnClickBottom(btn:UIButton){
128 | self.cancelBtn.isHidden = true
129 | UIView.animate(withDuration: 0.5, animations: {
130 | self.whiteView.frame.origin.y = ScreenHeight
131 | }) { (_) in
132 | self.removeFromSuperview()
133 | }
134 | }
135 | }
136 |
--------------------------------------------------------------------------------
/ZHFToolBox/ZHFSubToolBox/SlideView.swift:
--------------------------------------------------------------------------------
1 | //
2 | // SlideView.swift
3 | // SlideViewTest
4 | //
5 | // Created by 张海峰 on 2018/11/8.
6 | // Copyright © 2018年 张海峰. All rights reserved.
7 | //
8 | /*该demo是和大家分享一下,在项目中自定义各种弹框的思路,用来支撑自己项目的使用,无论什么样的弹框,只要有思路,
9 | 相信大家都能完美实现。感觉我这个demo对你有启发或者帮助,不妨给个星星吧
10 | https://github.com/FighterLightning/ZHFToolBox.git
11 | https://www.jianshu.com/p/88420bc4d32d
12 | */
13 | /*侧滑视图主框架*/
14 | import UIKit
15 | enum SlideDirection: NSInteger {
16 | case left
17 | case right
18 | }
19 | class SlideView: UIView,UIGestureRecognizerDelegate {
20 | var isfromLeft: Bool = true
21 | var currentPanDirection: SlideDirection?
22 | //白色view用来装一些控件
23 | var WhiteView: UIView = UIView()
24 | var whiteViewStartFrame: CGRect = CGRect.init(x: -ScreenWidth*4/5, y: 0, width: ScreenWidth*4/5, height: ScreenHeight)
25 | var whiteViewEndFrame: CGRect = CGRect.init(x: 0, y: 0, width: ScreenWidth*4/5, height: ScreenHeight)
26 | //背景区域的颜色和透明度
27 | var backgroundColor1:UIColor = UIColor.init(red: 0, green: 0, blue: 0, alpha: 0.4)
28 | var defaultTime:CGFloat = 0.5
29 | //初始化视图
30 | func initPopBackGroundView() -> UIView {
31 | self.frame = CGRect.init(x: 0, y: 0, width: ScreenWidth, height: ScreenHeight)
32 | self.backgroundColor = backgroundColor1
33 | self.isHidden = true
34 | //设置添加地址的View
35 | self.WhiteView.frame = whiteViewStartFrame
36 | WhiteView.backgroundColor = UIColor.white
37 | self.addSubview(WhiteView)
38 | //添加点击手势
39 | let tap: UITapGestureRecognizer = UITapGestureRecognizer.init(target: self, action: #selector(tapBtnAndbackBtnClick))
40 | tap.delegate = self
41 | self.addGestureRecognizer(tap)
42 | //添加侧滑手势
43 | let pan: UIPanGestureRecognizer = UIPanGestureRecognizer.init(target: self, action: #selector(self.didPanEvent))
44 | pan.delegate = self
45 | self.addGestureRecognizer(pan)
46 | return self
47 | }
48 | //弹出的动画效果
49 | func addAnimate() {
50 |
51 | }
52 | //收回的动画效果
53 | @objc func tapBtnAndbackBtnClick() {
54 | UIView.animate(withDuration: TimeInterval(defaultTime), animations: {
55 | self.WhiteView.frame = self.whiteViewStartFrame
56 | }) { (_) in
57 | for view in self.WhiteView.subviews {
58 | view.removeFromSuperview()
59 | }
60 | self.isHidden = true
61 | }
62 | }
63 | //通过手势收回的动画效果
64 | @objc func didPanEvent(recognizer: UIPanGestureRecognizer){
65 | //拿到手势在移动过程中当前位置(相对于其实位置为(0,0))
66 | let translation: CGPoint = recognizer.translation(in: self)
67 | if (translation.x != 0){
68 | //确定移动(并判断手势方向)
69 | currentPanDirection = translation.x > 0 ? SlideDirection.right : SlideDirection.left
70 | }
71 | //位置归0
72 | recognizer.setTranslation(CGPoint.zero, in: self)
73 | //根据手势操作
74 | switch recognizer.state {
75 | case .began: break
76 | case .changed:
77 | let tempX :CGFloat = self.WhiteView.frame.minX + translation.x
78 | //从左边出来
79 | if isfromLeft == true{
80 | //可移动的条件 左滑||右滑 小于打开时的minX
81 | if translation.x < 0 || (translation.x > 0 && tempX < 0){
82 | self.WhiteView.frame = CGRect.init(x: tempX, y: (ScreenHeight - WhiteView.frame.height)/2, width: WhiteView.frame.width, height: WhiteView.frame.height)
83 | }
84 | }
85 | //从右边出来
86 | if isfromLeft == false{
87 | //可移动的条件 右滑||左滑 大于打开时的minX
88 | if translation.x > 0 || (translation.x < 0 && tempX > (ScreenWidth - WhiteView.frame.width)){
89 | self.WhiteView.frame = CGRect.init(x: tempX, y: (ScreenHeight - WhiteView.frame.height)/2, width: WhiteView.frame.width, height: WhiteView.frame.height)
90 | }
91 | }
92 | case .cancelled: break
93 | case .ended:
94 | if isfromLeft == true{
95 | if self.currentPanDirection == SlideDirection.left{
96 | self.tapBtnAndbackBtnClick()
97 | }
98 | if self.currentPanDirection == SlideDirection.right{
99 | self.WhiteView.frame = CGRect.init(x: 0, y: (ScreenHeight - WhiteView.frame.height)/2, width: WhiteView.frame.width, height: WhiteView.frame.height)
100 | }
101 | }
102 | if isfromLeft == false{
103 | if self.currentPanDirection == SlideDirection.right{
104 | self.tapBtnAndbackBtnClick()
105 | }
106 | if self.currentPanDirection == SlideDirection.left{
107 | self.WhiteView.frame = CGRect.init(x: ScreenWidth - WhiteView.frame.width, y: (ScreenHeight - WhiteView.frame.height)/2, width: WhiteView.frame.width, height: WhiteView.frame.height)
108 | }
109 | }
110 | default:
111 | break
112 | }
113 | }
114 | //防止侧滑视图手势与列表点击起冲突
115 | func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldReceive touch: UITouch) -> Bool {
116 | /**
117 | *判断如果点击的是tableView的cell,就把手势给关闭了 不是点击cell手势开启
118 | **/
119 | if NSStringFromClass((touch.view?.classForCoder)!) == "UITableViewCellContentView" {
120 | return false
121 | }
122 | return true
123 | }
124 | }
125 |
--------------------------------------------------------------------------------
/ZHFToolBox/ZHFSubToolBox/SlideWhiteViewSubView.swift:
--------------------------------------------------------------------------------
1 | //
2 | // SlideWhiteViewSubView.swift
3 | // SlideViewTest
4 | //
5 | // Created by 张海峰 on 2018/11/14.
6 | // Copyright © 2018年 张海峰. All rights reserved.
7 | //
8 | /*该demo是和大家分享一下,在项目中自定义各种弹框的思路,用来支撑自己项目的使用,无论什么样的弹框,只要有思路,
9 | 相信大家都能完美实现。感觉我这个demo对你有启发或者帮助,不妨给个星星吧
10 | https://github.com/FighterLightning/ZHFToolBox.git
11 | https://www.jianshu.com/p/88420bc4d32d
12 | */
13 | /*侧滑视图为白色视图添加内容*/
14 | import UIKit
15 | //添加一个列表点击代理
16 | protocol SlideWhiteViewSubViewDelegate {
17 | func selectMessage(message: String)
18 | }
19 | class SlideWhiteViewSubView: SlideView {
20 | var delegate:SlideWhiteViewSubViewDelegate?
21 | lazy var dataMarr:NSMutableArray = NSMutableArray()
22 | override func addAnimate() {
23 | UIApplication.shared.keyWindow?.addSubview(self.initPopBackGroundView())
24 | self.isHidden = false
25 | UIView.animate(withDuration:TimeInterval(defaultTime), animations: {
26 | self.WhiteView.frame = self.whiteViewEndFrame
27 | }) { (_) in
28 | //添加白色视图内容
29 | self.addWhiteViewSubViews()
30 | }
31 | }
32 | func addWhiteViewSubViews(){
33 | //添加头部内容
34 | let imageView: UIImageView = UIImageView.init(frame: CGRect.init(x: (WhiteView.frame.width - 100)/2, y: 50, width: 100, height: 100))
35 | imageView.image = UIImage.init(named: "test1")
36 | imageView.layer.masksToBounds = true
37 | imageView.layer.cornerRadius = 50
38 | WhiteView.addSubview(imageView)
39 | //添加一个列表
40 | self.dataMarr = ["视图标题一","视图标题二","视图标题三","视图标题四","视图标题五"]
41 | addTableView()
42 | //添加底部按钮(底部按钮点击响应可以1.通过代理方法(类似列表的代理实现)2.也可以把按钮定义成全局的,在VC中直接 WhiteView.setBtn1.addTarget(self, action: #selector(setBtn1Click), for: UIControlEvents.touchUpInside))
43 | let setBtn1: UIButton = UIButton.init(type: UIButton.ButtonType.custom)
44 | setBtn1.frame = CGRect.init(x: 40, y: WhiteView.frame.height - 100, width: 50, height: 30)
45 | setBtn1.setTitle("设置1", for: UIControl.State.normal)
46 | setBtn1.backgroundColor = UIColor.orange
47 |
48 | WhiteView.addSubview(setBtn1)
49 | let setBtn2: UIButton = UIButton.init(type: UIButton.ButtonType.custom)
50 | setBtn2.frame = CGRect.init(x: setBtn1.frame.maxX + 30, y: WhiteView.frame.height - 100, width: 50, height: 30)
51 | setBtn2.setTitle("设置2", for: UIControl.State.normal)
52 | setBtn2.backgroundColor = UIColor.red
53 | WhiteView.addSubview(setBtn2)
54 | }
55 | func addTableView(){
56 | let tableView = UITableView.init(frame: CGRect.init(x: 0, y: 200, width: WhiteView.frame.width, height: WhiteView.frame.height - 300), style: UITableView.Style.plain)
57 | WhiteView.addSubview(tableView)
58 | tableView.backgroundColor = UIColor.white
59 | tableView.separatorColor = UIColor.black
60 | tableView.separatorStyle = UITableViewCell.SeparatorStyle.none
61 | tableView.separatorInset = UIEdgeInsets.init(top: 0, left: 0, bottom: 0, right: 0)
62 | tableView.delegate = self
63 | tableView.dataSource = self
64 | }
65 |
66 | }
67 | extension SlideWhiteViewSubView :UITableViewDataSource,UITableViewDelegate
68 | {
69 | func numberOfSections(in tableView: UITableView) -> Int {
70 | return 1
71 | }
72 | func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
73 | return self.dataMarr.count
74 | }
75 | func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
76 | let alertCellIdentifier = "alertCellIdentifier"
77 | var cell = tableView.dequeueReusableCell(withIdentifier: alertCellIdentifier)
78 | if cell == nil {
79 | cell = UITableViewCell(style:.default, reuseIdentifier: alertCellIdentifier)
80 | }
81 | cell?.textLabel?.text = self.dataMarr[indexPath.row] as? String
82 | cell?.textLabel?.font = UIFont.systemFont(ofSize: 13)
83 | cell?.textLabel?.textColor = UIColor.lightGray
84 | cell?.selectionStyle = UITableViewCell.SelectionStyle.none
85 | return cell!
86 | }
87 | func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
88 | let message = self.dataMarr[indexPath.row] as! String
89 | //先回收再传值
90 | UIView.animate(withDuration: 0.5, animations: {
91 | self.tapBtnAndbackBtnClick()
92 | }) { (_) in
93 | self.delegate?.selectMessage(message:message)
94 | }
95 | }
96 | func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
97 | return 40
98 | }
99 | }
100 |
101 |
--------------------------------------------------------------------------------
/ZHFToolBox/ZHFSubToolBox/UpDownView.swift:
--------------------------------------------------------------------------------
1 | //
2 | // UpDownView.swift
3 | // ZHFToolBox
4 | //
5 | // Created by 张海峰 on 2019/2/21.
6 | // Copyright © 2019年 张海峰. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | class UpDownView: UIView ,UIGestureRecognizerDelegate{
12 | //白色view用来装一些控件
13 | var WhiteView: UIView = UIView()
14 | var whiteViewStartFrame: CGRect = CGRect.init(x: 0, y: ScreenHeight, width: ScreenWidth, height: 420)
15 | var whiteViewEndFrame: CGRect = CGRect.init(x: 0, y: ScreenHeight - 420, width: ScreenWidth, height: 420)
16 | //确定按钮
17 | var okBtn: UIButton = UIButton()
18 | //背景区域的颜色和透明度
19 | var backgroundColor1:UIColor = UIColor.init(red: 0, green: 0, blue: 0, alpha: 0.4)
20 | var defaultTime:CGFloat = 0.5
21 |
22 | //初始化视图
23 | func initPopBackGroundView() -> UIView {
24 | self.frame = CGRect.init(x: 0, y: 0, width: ScreenWidth, height: ScreenHeight)
25 | self.backgroundColor = backgroundColor1
26 | self.isHidden = true
27 | //设置添加地址的View
28 | self.WhiteView.frame = whiteViewStartFrame
29 | WhiteView.backgroundColor = UIColor.white
30 | self.addSubview(WhiteView)
31 | //添加点击手势
32 | let tap: UITapGestureRecognizer = UITapGestureRecognizer.init(target: self, action: #selector(tapBtnAndcancelBtnClick))
33 | tap.delegate = self
34 | self.addGestureRecognizer(tap)
35 | okBtn = UIButton.init(type: .custom)
36 | okBtn.frame = CGRect.init(x:ScreenWidth - 80, y: 10, width: 60, height: 40)
37 | okBtn.tag = 1
38 | okBtn.setTitle("确定", for: .normal)
39 | okBtn.setTitleColor(ZHFColor.green, for: .normal)
40 | okBtn.addTarget(self, action: #selector(tapBtnAndcancelBtnClick), for: .touchUpInside)
41 | WhiteView.addSubview(okBtn)
42 | return self
43 | }
44 | //弹出的动画效果
45 | func addAnimate() {
46 |
47 | }
48 | //收回的动画效果
49 | @objc func tapBtnAndcancelBtnClick() {
50 | for view in WhiteView.subviews {
51 | view.removeFromSuperview()
52 | }
53 | UIView.animate(withDuration: TimeInterval(defaultTime), animations: {
54 | self.WhiteView.frame = self.whiteViewStartFrame
55 | }) { (_) in
56 | self.isHidden = true
57 | }
58 | }
59 | func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldReceive touch: UITouch) -> Bool {
60 | //点击WhiteView不回收
61 | if (touch.view?.isDescendant(of: self.WhiteView))!{
62 | return false
63 | }
64 | return true
65 | }
66 | }
67 |
--------------------------------------------------------------------------------
/ZHFToolBox/ZHFSubToolBox/ZHFAlertControllerTool.swift:
--------------------------------------------------------------------------------
1 | //
2 | // ZHFAlertControllerTool.swift
3 | // ZHFToolBox
4 | //
5 | // Created by 张海峰 on 2018/5/9.
6 | // Copyright © 2018年 张海峰. All rights reserved.
7 | //
8 | /*该demo是和大家分享一下,在项目中自定义各种弹框的思路,用来支撑自己项目的使用,无论什么样的弹框,只要有思路,
9 | 相信大家都能完美实现。感觉我这个demo对你有启发或者帮助,不妨给个星星吧
10 | https://github.com/FighterLightning/ZHFToolBox.git
11 | https://www.jianshu.com/p/88420bc4d32d
12 | */
13 | import Foundation
14 | import UIKit
15 | /*
16 | - parameter currentVC: 当前控制器
17 | - parameter title: 标题
18 | - parameter meg: 提示消息
19 | - parameter cancelBtn: 取消按钮
20 | - parameter otherBtn: 其他按钮
21 | - parameter handler: 其他按钮处理事件
22 | */
23 | class ZHFAlertControllerTool {
24 | /**
25 | alterController 一个按钮 不处理事件,简单实用
26 | */
27 | static func showAlert(currentVC:UIViewController, title:String,meg:String, cancelBtn:String){
28 | var title1 = ""
29 | if title == "" || title == nil {
30 | title1 = "温馨提示"}
31 | else{
32 | title1 = title
33 | }
34 | let alertController = UIAlertController(title:title1,message:meg , preferredStyle: .alert)
35 | let cancelAction = UIAlertAction(title:cancelBtn, style: .cancel, handler:nil)
36 | alertController.addAction(cancelAction)
37 | currentVC.present(alertController, animated: true, completion: nil)
38 | }
39 | /**
40 | alterController 一个按钮 处理事件
41 | */
42 | static func showAlert(currentVC:UIViewController, title:String, meg:String, okBtn:String, handler:((UIAlertAction) -> Void)?){
43 | var title1 = ""
44 | if title == "" || title == nil {
45 | title1 = "温馨提示"}
46 | else{
47 | title1 = title
48 | }
49 | let alertController = UIAlertController(title:title1,message:meg , preferredStyle: .alert)
50 | if okBtn != nil{
51 | let settingsAction = UIAlertAction(title: okBtn, style: .default, handler: { (action) -> Void in
52 | handler?(action)
53 | })
54 | alertController.addAction(settingsAction)
55 | }
56 | currentVC.present(alertController, animated: true, completion: nil)
57 | }
58 | /**
59 | 两个按钮 都处理事件
60 | **/
61 | static func showAlert(currentVC:UIViewController, title:String, meg:String, oneBtn:String, otherBtn:String?,oneHandler:((UIAlertAction) -> Void)?, otherHandler:((UIAlertAction) -> Void)?){
62 | var title1 = ""
63 | if title == "" || title == nil {
64 | title1 = "温馨提示"}
65 | else{
66 | title1 = title
67 | }
68 | let alertController = UIAlertController(title:title1,
69 | message:meg ,
70 | preferredStyle: .alert)
71 | let cancelAction = UIAlertAction(title:oneBtn, style: .cancel, handler:{ (action) -> Void in
72 | oneHandler?(action)
73 | })
74 | alertController.addAction(cancelAction)
75 | if otherBtn != nil{
76 | let settingsAction = UIAlertAction(title: otherBtn, style: .default, handler: { (action) -> Void in
77 | otherHandler?(action)
78 | })
79 | alertController.addAction(settingsAction)
80 | }
81 | currentVC.present(alertController, animated: true, completion: nil)
82 | }
83 | }
84 |
--------------------------------------------------------------------------------
/ZHFToolBox/ZHFSubToolBox/ZHFCalendarView.swift:
--------------------------------------------------------------------------------
1 | //
2 | // ZHFCalendarView.swift
3 | // 日历弹窗
4 | //
5 | // Created by 张海峰 on 2019/4/5.
6 | // Copyright © 2019年 张海峰. All rights reserved.
7 | //
8 | /*该demo是和大家分享一下,在项目中集成一个日历弹窗,用自己可想到的最少代码实现日历弹窗
9 | 当然这个弹窗也是我自定义弹窗的极小部分,对Swift弹窗感兴趣的帅哥美女,可戳下面链接
10 | https://github.com/FighterLightning/ZHFToolBox.git
11 | */
12 | import UIKit
13 |
14 | class ZHFCalendarView: UpDownView {
15 | var pointColor: UIColor = ZHFColor.zhf_color(withHex: 0x42D2BE)
16 | //声明闭包
17 | typealias clickBtnClosure = (String?) -> Void
18 | //把申明的闭包设置成属性
19 | var clickClosure: clickBtnClosure?
20 | //为闭包设置调用函数
21 | func clickValueClosure(closure:clickBtnClosure?){
22 | clickClosure = closure
23 | }
24 | var bigGreenPoints:[NSInteger] = [5,7,10]
25 | var smallGreenPoints:[NSInteger] = [3,7,8,10,25]
26 | var nowMonth: NSInteger = 1 //现在时间
27 | var nowYear: NSInteger = 2019 //现在时间
28 | var monthNumber: NSInteger = 1 // 可变化的时间
29 | var yearNumber: NSInteger = 2019 // 可变化的时间
30 | let topMargin :CGFloat = 10;
31 | let leftMargin :CGFloat = 25;//靠边数字距离左边和右边距离
32 | let bothMargin :CGFloat = 10;//两个数字间距离
33 | let viewWH :CGFloat = (ScreenWidth - 25*2 - 10*6)/7; //每个数字的宽高
34 | var titleLabel1: UILabel = UILabel()
35 | var rightBtn:UIButton = UIButton()
36 | var calendarView: UIView = UIView()
37 | override func addAnimate() {
38 | UIApplication.shared.keyWindow?.addSubview(self.initPopBackGroundView())
39 | self.isHidden = false
40 | //按钮不要在动画完成后初始化(否则按钮没点击效果)
41 | UIView.animate(withDuration:TimeInterval(defaultTime), animations: {
42 | self.WhiteView.frame = self.whiteViewEndFrame
43 | }) { (_) in
44 | self.addWhiteVieSubView()
45 | }
46 | }
47 | //放一张展示图片
48 | func addWhiteVieSubView(){
49 | monthNumber = convertDateToMonth(date: NSDate.init())
50 | yearNumber = convertDateToYear(date: NSDate.init())
51 | nowMonth = convertDateToMonth(date: NSDate.init())
52 | nowYear = convertDateToYear(date: NSDate.init())
53 | calendarViewHeader()
54 | test(month: monthNumber)
55 | }
56 | //日历头
57 | func calendarViewHeader(){
58 | let headerView: UIView = UIView.init(frame: CGRect.init(x: 0, y: 50, width: ScreenWidth, height: 80))
59 | WhiteView.addSubview(headerView)
60 | let leftBtn:UIButton = UIButton.init(type: UIButton.ButtonType.custom)
61 | leftBtn.frame = CGRect.init(x: 25, y: 0, width: 60, height: 40)
62 | leftBtn.setImage(UIImage.init(named: "left"), for: UIControl.State.normal)
63 | leftBtn.titleLabel?.font = UIFont.systemFont(ofSize: 14)
64 | leftBtn.setTitleColor(UIColor.gray, for: UIControl.State.normal)
65 | leftBtn.addTarget(self, action: #selector(leftBtnClick), for: UIControl.Event.touchUpInside)
66 | headerView.addSubview(leftBtn)
67 | titleLabel1 = UILabel.init(frame: CGRect.init(x: ScreenWidth/2 - 80, y: 0, width: 160, height: 40))
68 | titleLabel1.textAlignment = NSTextAlignment.center
69 | titleLabel1.textColor = ZHFColor.zhf_color(withHex: 0x333333)
70 | titleLabel1.font = UIFont.systemFont(ofSize: 17)
71 | headerView.addSubview(titleLabel1)
72 | rightBtn = UIButton.init(type: UIButton.ButtonType.custom)
73 | rightBtn.frame = CGRect.init(x: ScreenWidth - 85, y: 0, width: 60, height: 40)
74 | rightBtn.setImage(UIImage.init(named: "right"), for: UIControl.State.normal)
75 | rightBtn.titleLabel?.font = UIFont.systemFont(ofSize: 14)
76 | rightBtn.setTitleColor(UIColor.gray, for: UIControl.State.normal)
77 | rightBtn.addTarget(self, action: #selector(rightBtnClick), for: UIControl.Event.touchUpInside)
78 | headerView.addSubview(rightBtn)
79 | let arr = ["S","M","T","W","T","F","S"]
80 | for i in 0 ..< 7 {
81 | let textLabel: UILabel = UILabel.init(frame: CGRect.init(x: leftMargin + (viewWH+bothMargin)*CGFloat(i), y: 40, width: viewWH, height: 40))
82 | textLabel.text = arr[i]
83 | textLabel.font = UIFont.systemFont(ofSize: 13)
84 | textLabel.textAlignment = NSTextAlignment.center
85 | textLabel.textColor = ZHFColor.zhf_color(withHex: 0x999999);
86 | headerView.addSubview(textLabel)
87 | }
88 | calendarView = UIView.init(frame: CGRect.init(x: 0, y: headerView.frame.maxY, width: ScreenWidth, height: WhiteView.frame.size.height - headerView.frame.maxY))
89 | WhiteView.addSubview(calendarView)
90 | }
91 | //上个月
92 | @objc func leftBtnClick(){
93 | monthNumber = monthNumber - 1
94 | test(month: monthNumber)
95 | }
96 | //下个月
97 | @objc func rightBtnClick(){
98 | monthNumber = monthNumber + 1
99 | test(month: monthNumber)
100 | }
101 | //是否隐藏右按钮
102 | func isHiddenRightBtn() {
103 | if nowYear > yearNumber {
104 | rightBtn.isHidden = false
105 | }
106 | else{
107 | if nowMonth > monthNumber{
108 | rightBtn.isHidden = false
109 | }
110 | else{
111 | rightBtn.isHidden = true
112 | }
113 | }
114 | }
115 | func test(month:NSInteger){
116 | for view1 in calendarView.subviews {
117 | view1.removeFromSuperview()
118 | }
119 | if (monthNumber > 12) {
120 | monthNumber = 1;
121 | yearNumber = yearNumber + 1;
122 | }
123 | if (monthNumber <= 0) {
124 | monthNumber = 12;
125 | yearNumber = yearNumber - 1;
126 | }
127 | let dateFormatter: DateFormatter = DateFormatter.init()
128 | dateFormatter.dateFormat = "yyyy-MM"
129 | var string:String = "\(yearNumber)-\(monthNumber)"
130 | if monthNumber < 10 {
131 | string = "\(yearNumber)-0\(monthNumber)"
132 | }
133 | isHiddenRightBtn()
134 | titleLabel1.text = string
135 | let date: NSDate = dateFormatter.date(from: string)! as NSDate
136 | logCalendarWith(date: date, day: 5, isHiden: false)
137 | }
138 | func logCalendarWith(date:NSDate,day:NSInteger,isHiden:Bool) {
139 | let firstWeekDay :NSInteger = convertDateToFirstWeekDay(date: date) //本月第一天是周几
140 | let totalDays: NSInteger = convertDateToTotalDays(date: date)//本月总天数
141 | var available: NSInteger = 1//本月第一天
142 | var nextMonthDay: NSInteger = 1//下月第一天
143 | let lastMonthDate: NSDate = getDateFrom(date: date, offsetMonths: -1)//上月月数
144 | let lastMonthTotalDays :NSInteger = convertDateToTotalDays(date: lastMonthDate) //上月总天数
145 | let line :NSInteger = (totalDays + firstWeekDay + 6)/7; //计算行数
146 | let column: NSInteger = 7 //一共从周日到周一7列
147 | for i in 0 ..< line {
148 | for j in 0 ..< column {
149 | //尾
150 | if (available > totalDays) {
151 | if (isHiden == true) {
152 | // print("\t");
153 | }
154 | else{
155 | //print("\t%ld",nextMonthDay);
156 | let view: UIView = UIView.init(frame: CGRect.init(x: leftMargin + (bothMargin+viewWH)*CGFloat(j) , y: topMargin+(bothMargin+viewWH)*CGFloat(i), width: viewWH, height: viewWH))
157 | calendarView.addSubview(view)
158 | view.tag = nextMonthDay;
159 | // self.isSelect(isSelect: false, isHavePoint: false, fatherView: view)
160 | }
161 | nextMonthDay = nextMonthDay + 1;
162 | continue;
163 | }
164 | //头
165 | if (i == 0 && j < firstWeekDay) {
166 | //根据当月第一天是周几,回推出上个月最后几天对应的位置。
167 | let lastMonthDay :NSInteger = lastMonthTotalDays - firstWeekDay + j + 1; //j从0开始,所以这里+1
168 | if (isHiden == true) {
169 | // print("\t");
170 | }
171 | else{
172 | // print("\t%ld",lastMonthDay);
173 | let view: UIView = UIView.init(frame: CGRect.init(x: leftMargin + (bothMargin+viewWH)*CGFloat(j), y: topMargin, width: viewWH, height: viewWH))
174 | calendarView.addSubview(view)
175 | view.tag = lastMonthDay;
176 | // self.isSelect(isSelect: false, isHavePoint: false, fatherView: view)
177 | }
178 | }else {
179 | //打印当月数据
180 | let view: UIView = UIView.init(frame: CGRect.init(x: leftMargin + (bothMargin+viewWH)*CGFloat(j), y: topMargin+(bothMargin+viewWH)*CGFloat(i), width: viewWH, height: viewWH))
181 | calendarView.addSubview(view)
182 | view.tag = available
183 | if (bigGreenPoints.contains(available)&&smallGreenPoints.contains(available)){
184 | self.isSelect(isSelect: true, isHavePoint: true, fatherView: view)
185 | }
186 | else if (bigGreenPoints.contains(available)&&(smallGreenPoints.contains(available)==false)){
187 | self.isSelect(isSelect: true, isHavePoint: false, fatherView: view)
188 | }
189 | else if (smallGreenPoints.contains(available)&&(bigGreenPoints.contains(available)==false)){
190 | self.isSelect(isSelect: false, isHavePoint: true, fatherView: view)
191 | }
192 | else{
193 | self.isSelect(isSelect: false, isHavePoint: false, fatherView: view)
194 | }
195 | available = available + 1;
196 | }
197 | }
198 | }
199 | }
200 | func isSelect(isSelect:Bool,isHavePoint:Bool,fatherView:UIView){
201 | let tap:UITapGestureRecognizer = UITapGestureRecognizer.init(target: self, action: #selector(tapClick))
202 | fatherView.addGestureRecognizer(tap)
203 | let textLabel:UILabel = UILabel.init(frame: CGRect.init(x: 5, y: 0, width: viewWH-10, height: viewWH-10))
204 | textLabel.layer.masksToBounds = true
205 | textLabel.layer.cornerRadius = (viewWH-10)/2
206 | textLabel.text = "\(fatherView.tag)"
207 | textLabel.font = UIFont.systemFont(ofSize: 12)
208 | textLabel.textAlignment = NSTextAlignment.center
209 | textLabel.backgroundColor = UIColor.white
210 | textLabel.textColor = UIColor.black
211 | fatherView.addSubview(textLabel)
212 | if (isSelect == true) {
213 | textLabel.backgroundColor = pointColor
214 | }
215 | else{
216 | textLabel.backgroundColor = UIColor.white
217 | }
218 | if (isHavePoint == true) {
219 | let pointView:UIView = UIView.init(frame: CGRect.init(x: viewWH/2-4, y: viewWH-8, width: 6, height: 6))
220 | pointView.backgroundColor = pointColor
221 | pointView.layer.masksToBounds = true
222 | pointView.layer.cornerRadius = 3
223 | fatherView.addSubview(pointView)
224 | }
225 | }
226 | @objc func tapClick(tap:UITapGestureRecognizer) {
227 | if clickClosure != nil{
228 | tapBtnAndcancelBtnClick()
229 | clickClosure!("\(yearNumber)-\(monthNumber)-\(tap.view!.tag)")
230 | }
231 | }
232 | //根据date获取日
233 | func convertDateToDay(date: NSDate) -> NSInteger {
234 | let calendar:NSCalendar = NSCalendar.current as NSCalendar
235 | let components:NSDateComponents = calendar.components(NSCalendar.Unit(rawValue: NSCalendar.Unit.day.rawValue), from: date as Date) as NSDateComponents
236 | return components.day;
237 | }
238 |
239 | //根据date获取月
240 | func convertDateToMonth(date: NSDate) -> NSInteger {
241 | let calendar:NSCalendar = NSCalendar.current as NSCalendar
242 | let components:NSDateComponents = calendar.components(NSCalendar.Unit(rawValue: NSCalendar.Unit.month.rawValue), from: date as Date) as NSDateComponents
243 | return components.month;
244 | }
245 | //根据date获取年
246 | func convertDateToYear(date: NSDate) -> NSInteger {
247 | let calendar:NSCalendar = NSCalendar.current as NSCalendar
248 | let components:NSDateComponents = calendar.components(NSCalendar.Unit(rawValue: NSCalendar.Unit.year.rawValue), from: date as Date) as NSDateComponents
249 | return components.year;
250 | }
251 | //根据date获取当月周几
252 | func convertDateToFirstWeekDay(date:NSDate) -> NSInteger {
253 | let calendar:NSCalendar = NSCalendar.current as NSCalendar
254 | calendar.firstWeekday = 1//1.Sun. 2.Mon. 3.Thes. 4.Wed. 5.Thur. 6.Fri. 7.Sat.
255 | let comp :NSDateComponents = calendar.components(NSCalendar.Unit(rawValue: NSCalendar.Unit.year.rawValue | NSCalendar.Unit.month.rawValue | NSCalendar.Unit.day.rawValue), from: date as Date) as NSDateComponents
256 | comp.day = 1
257 | let firstDayOfMonthDate:NSDate = calendar.date(from: comp as DateComponents)! as NSDate
258 | let firstWeekday :UInt = UInt(calendar.ordinality(of: NSCalendar.Unit.weekday, in:NSCalendar.Unit.weekOfMonth, for: firstDayOfMonthDate as Date))
259 | let firstWeekday1 = firstWeekday - 1
260 | return NSInteger(firstWeekday1); //美国时间周日为星期的第一天,所以周日-周六为1-7,改为0-6方便计算
261 | }
262 | //根据date获取当月总天数
263 | func convertDateToTotalDays(date: NSDate) -> NSInteger {
264 | let calendar = Calendar(identifier:Calendar.Identifier.gregorian)
265 | let daysInOfMonth:NSRange = ((calendar as NSCalendar?)?.range(of: NSCalendar.Unit.day, in: NSCalendar.Unit.month, for: date as Date))!
266 | return daysInOfMonth.length
267 | }
268 | //根据date获取偏移指定月数的date
269 | func getDateFrom(date: NSDate,offsetMonths: NSInteger) -> NSDate {
270 | let formatter: DateFormatter = DateFormatter.init()
271 | formatter.dateFormat = "yyyy-MM"
272 | let calendar:NSCalendar = NSCalendar.current as NSCalendar
273 | let lastMonthComps:NSDateComponents = NSDateComponents.init()
274 | lastMonthComps.month = offsetMonths //year = 1表示1年后的时间 year = -1为1年前的日期,month day 类推
275 | let newdate:NSDate = calendar.date(byAdding: lastMonthComps as DateComponents, to: date as Date, options: NSCalendar.Options.init(rawValue: 0))! as NSDate
276 | return newdate;
277 | }
278 | }
279 |
--------------------------------------------------------------------------------
/ZHFToolBox/ZHFSubToolBox/ZHFColor.swift:
--------------------------------------------------------------------------------
1 | //
2 | // ZHFColor.swift
3 | // AmazedBox
4 | //
5 | // Created by lantian on 2017/12/4.
6 | // Copyright © 2017年 张海峰. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | class ZHFColor: UIColor {
12 | /// 主题色(及选中颜色)
13 | open class var zhf_selectColor: UIColor {
14 | //橙色
15 | get {
16 | return self.zhf_color(withHex: 0xF98507)
17 | }
18 | }
19 | /// 标题字体颜色
20 | open class var zhf33_titleTextColor: UIColor {
21 |
22 | get {
23 | return self.zhf_color(withHex: 0x333333)
24 | }
25 | }
26 | /// 内容字体颜色
27 | open class var zhf88_contentTextColor: UIColor {
28 |
29 | get {
30 | return self.zhf_color(withHex: 0x888888)
31 | }
32 | }
33 | open class var zhf66_contentTextColor: UIColor {
34 |
35 | get {
36 | return self.zhf_color(withHex: 0x666666)
37 | }
38 | }
39 | open class var zhfe8_backGroundColor: UIColor {
40 | get {
41 | return self.zhf_color(withHex: 0xe8e8e8)
42 | }
43 | }
44 | open class var zhff9_backGroundColor: UIColor {
45 | get {
46 | return self.zhf_color(withHex: 0xf9f9f9)
47 | }
48 | }
49 | open class var zhfcc_lineColor: UIColor {
50 | get {
51 | return self.zhf_color(withHex: 0xcccccc)
52 | }
53 | }
54 | //分割线的颜色
55 | open class var zhf_lineColor: UIColor {
56 | get {
57 | return self.zhf_color(withHex: 0xebf0f5)
58 | }
59 | }
60 |
61 | /// 随机色
62 | ///
63 | /// - Returns: 随机的颜色
64 | class func zhf_randomColor() -> UIColor {
65 |
66 | let r = CGFloat(arc4random() % 256) / 255.0
67 | let g = CGFloat(arc4random() % 256) / 255.0
68 | let b = CGFloat(arc4random() % 256) / 255.0
69 |
70 | return UIColor(red: r, green: g, blue: b, alpha: 1.0)
71 | }
72 |
73 | /// 十六进制颜色
74 | ///
75 | /// - Parameter withHex: 0xFFFFFF
76 | /// - Returns: color
77 | class func zhf_color(withHex: UInt32) -> UIColor {
78 |
79 | let r = ((CGFloat)((withHex & 0xFF0000) >> 16)) / 255.0
80 | let g = ((CGFloat)((withHex & 0xFF00) >> 8)) / 255.0
81 | let b = ((CGFloat)(withHex & 0xFF)) / 255.0
82 |
83 | return UIColor(red: r, green: g, blue: b, alpha: 1.0)
84 | }
85 |
86 | class func zhf_colorAlpha(withHex: UInt32,alpha: CGFloat) -> UIColor {
87 |
88 | let r = ((CGFloat)((withHex & 0xFF0000) >> 16)) / 255.0
89 | let g = ((CGFloat)((withHex & 0xFF00) >> 8)) / 255.0
90 | let b = ((CGFloat)(withHex & 0xFF)) / 255.0
91 |
92 | return UIColor(red: r, green: g, blue: b, alpha: alpha)
93 | }
94 |
95 | /// 0~255 颜色
96 | ///
97 | /// - Parameters:
98 | /// - withRed: red(0~255)
99 | /// - green: green(0~255)
100 | /// - blue: blue(0~255)
101 | /// - Returns: color
102 | class func zhf_color(withRed: UInt8, green: UInt8, blue: UInt8) -> UIColor {
103 |
104 | let r = CGFloat(withRed) / 255.0
105 | let g = CGFloat(green) / 255.0
106 | let b = CGFloat(blue) / 255.0
107 |
108 | return UIColor(red: r, green: g, blue: b, alpha: 1.0)
109 | }
110 | class func initString(hex: String) -> UIColor {
111 | let scanner = Scanner(string: hex)
112 | scanner.scanLocation = 0
113 | var rgbValue: UInt64 = 0
114 | scanner.scanHexInt64(&rgbValue)
115 | let r = ((CGFloat)((rgbValue & 0xFF0000) >> 16)) / 255.0
116 | let g = ((CGFloat)((rgbValue & 0xFF00) >> 8)) / 255.0
117 | let b = ((CGFloat)(rgbValue & 0xFF)) / 255.0
118 | return UIColor(red: r, green: g, blue: b, alpha: 1.0)
119 | }
120 | }
121 |
122 |
--------------------------------------------------------------------------------
/ZHFToolBoxTests/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | $(DEVELOPMENT_LANGUAGE)
7 | CFBundleExecutable
8 | $(EXECUTABLE_NAME)
9 | CFBundleIdentifier
10 | $(PRODUCT_BUNDLE_IDENTIFIER)
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | $(PRODUCT_NAME)
15 | CFBundlePackageType
16 | BNDL
17 | CFBundleShortVersionString
18 | 1.0
19 | CFBundleVersion
20 | 1
21 |
22 |
23 |
--------------------------------------------------------------------------------
/ZHFToolBoxTests/ZHFToolBoxTests.swift:
--------------------------------------------------------------------------------
1 | //
2 | // ZHFToolBoxTests.swift
3 | // ZHFToolBoxTests
4 | //
5 | // Created by 张海峰 on 2018/5/9.
6 | // Copyright © 2018年 张海峰. All rights reserved.
7 | //
8 |
9 | import XCTest
10 | @testable import ZHFToolBox
11 |
12 | class ZHFToolBoxTests: XCTestCase {
13 |
14 | override func setUp() {
15 | super.setUp()
16 | // Put setup code here. This method is called before the invocation of each test method in the class.
17 | }
18 |
19 | override func tearDown() {
20 | // Put teardown code here. This method is called after the invocation of each test method in the class.
21 | super.tearDown()
22 | }
23 |
24 | func testExample() {
25 | // This is an example of a functional test case.
26 | // Use XCTAssert and related functions to verify your tests produce the correct results.
27 | }
28 |
29 | func testPerformanceExample() {
30 | // This is an example of a performance test case.
31 | self.measure {
32 | // Put the code you want to measure the time of here.
33 | }
34 | }
35 |
36 | }
37 |
--------------------------------------------------------------------------------
/ZHFToolBoxUITests/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | $(DEVELOPMENT_LANGUAGE)
7 | CFBundleExecutable
8 | $(EXECUTABLE_NAME)
9 | CFBundleIdentifier
10 | $(PRODUCT_BUNDLE_IDENTIFIER)
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | $(PRODUCT_NAME)
15 | CFBundlePackageType
16 | BNDL
17 | CFBundleShortVersionString
18 | 1.0
19 | CFBundleVersion
20 | 1
21 |
22 |
23 |
--------------------------------------------------------------------------------
/ZHFToolBoxUITests/ZHFToolBoxUITests.swift:
--------------------------------------------------------------------------------
1 | //
2 | // ZHFToolBoxUITests.swift
3 | // ZHFToolBoxUITests
4 | //
5 | // Created by 张海峰 on 2018/5/9.
6 | // Copyright © 2018年 张海峰. All rights reserved.
7 | //
8 |
9 | import XCTest
10 |
11 | class ZHFToolBoxUITests: XCTestCase {
12 |
13 | override func setUp() {
14 | super.setUp()
15 |
16 | // Put setup code here. This method is called before the invocation of each test method in the class.
17 |
18 | // In UI tests it is usually best to stop immediately when a failure occurs.
19 | continueAfterFailure = false
20 | // UI tests must launch the application that they test. Doing this in setup will make sure it happens for each test method.
21 | XCUIApplication().launch()
22 |
23 | // In UI tests it’s important to set the initial state - such as interface orientation - required for your tests before they run. The setUp method is a good place to do this.
24 | }
25 |
26 | override func tearDown() {
27 | // Put teardown code here. This method is called after the invocation of each test method in the class.
28 | super.tearDown()
29 | }
30 |
31 | func testExample() {
32 | // Use recording to get started writing UI tests.
33 | // Use XCTAssert and related functions to verify your tests produce the correct results.
34 | }
35 |
36 | }
37 |
--------------------------------------------------------------------------------