├── .DS_Store
├── Example
├── .DS_Store
├── SPAlertController.xcodeproj
│ ├── project.pbxproj
│ ├── project.xcworkspace
│ │ ├── contents.xcworkspacedata
│ │ ├── xcshareddata
│ │ │ └── IDEWorkspaceChecks.plist
│ │ └── xcuserdata
│ │ │ ├── leshengping.xcuserdatad
│ │ │ └── UserInterfaceState.xcuserstate
│ │ │ ├── libo.xcuserdatad
│ │ │ └── UserInterfaceState.xcuserstate
│ │ │ └── shengping_le.xcuserdatad
│ │ │ └── UserInterfaceState.xcuserstate
│ └── xcuserdata
│ │ ├── leshengping.xcuserdatad
│ │ ├── xcdebugger
│ │ │ └── Breakpoints_v2.xcbkptlist
│ │ └── xcschemes
│ │ │ └── xcschememanagement.plist
│ │ ├── libo.xcuserdatad
│ │ ├── xcdebugger
│ │ │ └── Breakpoints_v2.xcbkptlist
│ │ └── xcschemes
│ │ │ └── xcschememanagement.plist
│ │ └── shengping_le.xcuserdatad
│ │ ├── xcdebugger
│ │ └── Breakpoints_v2.xcbkptlist
│ │ └── xcschemes
│ │ └── xcschememanagement.plist
├── SPAlertController
│ ├── .DS_Store
│ ├── AppDelegate.h
│ ├── AppDelegate.m
│ ├── Assets.xcassets
│ │ ├── AppIcon.appiconset
│ │ │ └── Contents.json
│ │ ├── Contents.json
│ │ ├── publish_0.imageset
│ │ │ ├── Contents.json
│ │ │ ├── publish_0@2x.png
│ │ │ └── publish_0@3x.png
│ │ ├── publish_1.imageset
│ │ │ ├── Contents.json
│ │ │ ├── publish_1@2x.png
│ │ │ └── publish_1@3x.png
│ │ ├── publish_10.imageset
│ │ │ ├── Contents.json
│ │ │ ├── publish_10@2x.png
│ │ │ └── publish_10@3x.png
│ │ ├── publish_11.imageset
│ │ │ ├── Contents.json
│ │ │ ├── publish_11@2x.png
│ │ │ └── publish_11@3x.png
│ │ ├── publish_2.imageset
│ │ │ ├── Contents.json
│ │ │ ├── publish_2@2x.png
│ │ │ └── publish_2@3x.png
│ │ ├── publish_3.imageset
│ │ │ ├── Contents.json
│ │ │ ├── publish_3@2x.png
│ │ │ └── publish_3@3x.png
│ │ ├── publish_4.imageset
│ │ │ ├── Contents.json
│ │ │ ├── publish_4@2x.png
│ │ │ └── publish_4@3x.png
│ │ ├── publish_5.imageset
│ │ │ ├── Contents.json
│ │ │ ├── publish_5@2x.png
│ │ │ └── publish_5@3x.png
│ │ ├── publish_6.imageset
│ │ │ ├── Contents.json
│ │ │ ├── publish_6@2x.png
│ │ │ └── publish_6@3x.png
│ │ ├── publish_7.imageset
│ │ │ ├── Contents.json
│ │ │ ├── publish_7@2x.png
│ │ │ └── publish_7@3x.png
│ │ ├── publish_8.imageset
│ │ │ ├── Contents.json
│ │ │ ├── publish_8@2x.png
│ │ │ └── publish_8@3x.png
│ │ ├── publish_9.imageset
│ │ │ ├── Contents.json
│ │ │ ├── publish_9@2x.png
│ │ │ └── publish_9@3x.png
│ │ ├── success.imageset
│ │ │ ├── Contents.json
│ │ │ └── 勾.png
│ │ ├── telephone.imageset
│ │ │ ├── Contents.json
│ │ │ ├── telephone@2x.png
│ │ │ └── telephone@3x.png
│ │ ├── video.imageset
│ │ │ ├── Contents.json
│ │ │ ├── video@2x.png
│ │ │ └── video@3x.png
│ │ ├── wechatLogo.imageset
│ │ │ ├── Contents.json
│ │ │ ├── wechatLogo@2x.png
│ │ │ └── wechatLogo@3x.png
│ │ ├── zhiwen.imageset
│ │ │ ├── Contents.json
│ │ │ ├── zhiwen@2x.png
│ │ │ └── zhiwen@3x.png
│ │ ├── 减号.imageset
│ │ │ ├── Contents.json
│ │ │ ├── 减号-1.png
│ │ │ ├── 减号-2.png
│ │ │ └── 减号.png
│ │ ├── 加号.imageset
│ │ │ ├── Contents.json
│ │ │ ├── 加号-1.png
│ │ │ ├── 加号-3.png
│ │ │ └── 加号-4.png
│ │ ├── 取消.imageset
│ │ │ ├── Contents.json
│ │ │ ├── 叉-1.png
│ │ │ ├── 叉-2.png
│ │ │ └── 叉-3.png
│ │ └── 苹果logo.imageset
│ │ │ ├── Contents.json
│ │ │ └── 苹果logo.png
│ ├── Base.lproj
│ │ ├── LaunchScreen.storyboard
│ │ └── Main.storyboard
│ ├── CustomViews
│ │ ├── CustomView1
│ │ │ ├── SPTextView.h
│ │ │ ├── SPTextView.m
│ │ │ ├── SendAlertView.h
│ │ │ ├── SendAlertView.m
│ │ │ └── SendAlertView.xib
│ │ ├── CustomView17
│ │ │ ├── HCSStarRatingView.h
│ │ │ ├── HCSStarRatingView.m
│ │ │ ├── ScoreView.h
│ │ │ └── ScoreView.m
│ │ ├── CustomView2
│ │ │ ├── MyView.h
│ │ │ ├── MyView.m
│ │ │ ├── MyView.xib
│ │ │ ├── PassWordView.h
│ │ │ └── PassWordView.m
│ │ ├── CustomView3
│ │ │ ├── ShoppingCartCell.h
│ │ │ ├── ShoppingCartCell.m
│ │ │ ├── ShoppingCartCell.xib
│ │ │ ├── ShoppingCartItem.h
│ │ │ ├── ShoppingCartItem.m
│ │ │ ├── ShoppingCartView.h
│ │ │ └── ShoppingCartView.m
│ │ ├── CustomView4
│ │ │ ├── CommodityListView.h
│ │ │ └── CommodityListView.m
│ │ ├── CustomView5
│ │ │ ├── PickerView.h
│ │ │ └── PickerView.m
│ │ ├── CustomView6
│ │ │ ├── MyCenterView.h
│ │ │ └── MyCenterView.m
│ │ └── CustomView7
│ │ │ ├── PopView.h
│ │ │ ├── PopView.m
│ │ │ ├── SPButton.h
│ │ │ └── SPButton.m
│ ├── Images
│ │ ├── image0.jpg
│ │ ├── image1.jpg
│ │ ├── image2.jpg
│ │ ├── image3.jpg
│ │ ├── image4.jpg
│ │ ├── image5.jpg
│ │ ├── image6.jpg
│ │ ├── image7.jpg
│ │ ├── image8.jpg
│ │ ├── image9.jpg
│ │ ├── send0.jpeg
│ │ ├── send1.jpeg
│ │ ├── 背景1.jpg
│ │ └── 背景2.jpg
│ ├── Info.plist
│ ├── SPAlertController
│ │ ├── SPAlertController.h
│ │ └── SPAlertController.m
│ ├── UIColor+DarkMode.h
│ ├── UIColor+DarkMode.m
│ ├── ViewController.h
│ └── ViewController.m
├── SPAlertControllerTests
│ ├── Info.plist
│ ├── SPAlertControllerTests.m
│ └── main.m
└── SPAlertControllerUITests
│ ├── Info.plist
│ └── SPAlertControllerUITests.m
├── Images
├── .DS_Store
├── 3006981-0b23494c3ba2a6fc.jpg
├── 3006981-3cd4a2b6ff4da206.jpg
├── 3006981-41170beb443f32f0.jpg
├── 3006981-6f3752d49e579460.jpg
├── 3006981-9544748007937417.jpg
├── 3006981-9ed0416190e155dc.jpg
├── 3006981-a12eae25bc1061d6.jpg
├── 3006981-b35b79b657815756.jpg
├── 3CB7E93FDA241F253BFE156D0B4AA7E2.jpg
├── 6AAAA07F90853F52CA6166D815F619A9.jpg
└── F4FB539593B4CC499E65735E4F1E8227.jpg
├── LICENSE
├── README.md
├── SPAlertController.podspec
└── SPAlertController
├── SPAlertController.h
└── SPAlertController.m
/.DS_Store:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SPStore/SPAlertController/b472fd0338825b485c3b3d46cb68e5a2f0022414/.DS_Store
--------------------------------------------------------------------------------
/Example/.DS_Store:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SPStore/SPAlertController/b472fd0338825b485c3b3d46cb68e5a2f0022414/Example/.DS_Store
--------------------------------------------------------------------------------
/Example/SPAlertController.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/Example/SPAlertController.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | IDEDidComputeMac32BitWarning
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/Example/SPAlertController.xcodeproj/project.xcworkspace/xcuserdata/leshengping.xcuserdatad/UserInterfaceState.xcuserstate:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SPStore/SPAlertController/b472fd0338825b485c3b3d46cb68e5a2f0022414/Example/SPAlertController.xcodeproj/project.xcworkspace/xcuserdata/leshengping.xcuserdatad/UserInterfaceState.xcuserstate
--------------------------------------------------------------------------------
/Example/SPAlertController.xcodeproj/project.xcworkspace/xcuserdata/libo.xcuserdatad/UserInterfaceState.xcuserstate:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SPStore/SPAlertController/b472fd0338825b485c3b3d46cb68e5a2f0022414/Example/SPAlertController.xcodeproj/project.xcworkspace/xcuserdata/libo.xcuserdatad/UserInterfaceState.xcuserstate
--------------------------------------------------------------------------------
/Example/SPAlertController.xcodeproj/project.xcworkspace/xcuserdata/shengping_le.xcuserdatad/UserInterfaceState.xcuserstate:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SPStore/SPAlertController/b472fd0338825b485c3b3d46cb68e5a2f0022414/Example/SPAlertController.xcodeproj/project.xcworkspace/xcuserdata/shengping_le.xcuserdatad/UserInterfaceState.xcuserstate
--------------------------------------------------------------------------------
/Example/SPAlertController.xcodeproj/xcuserdata/leshengping.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
8 |
14 |
15 |
16 |
17 |
18 |
--------------------------------------------------------------------------------
/Example/SPAlertController.xcodeproj/xcuserdata/leshengping.xcuserdatad/xcschemes/xcschememanagement.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | SchemeUserState
6 |
7 | SPAlertController.xcscheme
8 |
9 | orderHint
10 | 0
11 |
12 | SPAlertController.xcscheme_^#shared#^_
13 |
14 | orderHint
15 | 0
16 |
17 |
18 |
19 |
20 |
--------------------------------------------------------------------------------
/Example/SPAlertController.xcodeproj/xcuserdata/libo.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
8 |
14 |
15 |
16 |
17 |
18 |
--------------------------------------------------------------------------------
/Example/SPAlertController.xcodeproj/xcuserdata/libo.xcuserdatad/xcschemes/xcschememanagement.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | SchemeUserState
6 |
7 | SPAlertController.xcscheme_^#shared#^_
8 |
9 | orderHint
10 | 0
11 |
12 |
13 |
14 |
15 |
--------------------------------------------------------------------------------
/Example/SPAlertController.xcodeproj/xcuserdata/shengping_le.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
--------------------------------------------------------------------------------
/Example/SPAlertController.xcodeproj/xcuserdata/shengping_le.xcuserdatad/xcschemes/xcschememanagement.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | SchemeUserState
6 |
7 | SPAlertController.xcscheme_^#shared#^_
8 |
9 | orderHint
10 | 0
11 |
12 |
13 |
14 |
15 |
--------------------------------------------------------------------------------
/Example/SPAlertController/.DS_Store:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SPStore/SPAlertController/b472fd0338825b485c3b3d46cb68e5a2f0022414/Example/SPAlertController/.DS_Store
--------------------------------------------------------------------------------
/Example/SPAlertController/AppDelegate.h:
--------------------------------------------------------------------------------
1 | //
2 | // AppDelegate.h
3 | // SPAlertController
4 | //
5 | // Created by 乐升平 on 2018/12/4.
6 | // Copyright © 2018 乐升平. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @interface AppDelegate : UIResponder
12 |
13 | @property (strong, nonatomic) UIWindow *window;
14 |
15 |
16 | @end
17 |
18 |
--------------------------------------------------------------------------------
/Example/SPAlertController/AppDelegate.m:
--------------------------------------------------------------------------------
1 | //
2 | // AppDelegate.m
3 | // SPAlertController
4 | //
5 | // Created by 乐升平 on 2018/12/4.
6 | // Copyright © 2018 乐升平. All rights reserved.
7 | //
8 |
9 | #import "AppDelegate.h"
10 |
11 | @interface AppDelegate ()
12 |
13 | @end
14 |
15 | @implementation AppDelegate
16 |
17 |
18 | - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
19 |
20 | return YES;
21 | }
22 |
23 |
24 | - (void)applicationWillResignActive:(UIApplication *)application {
25 | // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
26 | // Use this method to pause ongoing tasks, disable timers, and invalidate graphics rendering callbacks. Games should use this method to pause the game.
27 | }
28 |
29 |
30 | - (void)applicationDidEnterBackground:(UIApplication *)application {
31 | // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.
32 | // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
33 | }
34 |
35 |
36 | - (void)applicationWillEnterForeground:(UIApplication *)application {
37 | // Called as part of the transition from the background to the active state; here you can undo many of the changes made on entering the background.
38 | }
39 |
40 |
41 | - (void)applicationDidBecomeActive:(UIApplication *)application {
42 | // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
43 | }
44 |
45 |
46 | - (void)applicationWillTerminate:(UIApplication *)application {
47 | // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
48 | }
49 |
50 |
51 | @end
52 |
--------------------------------------------------------------------------------
/Example/SPAlertController/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 | }
--------------------------------------------------------------------------------
/Example/SPAlertController/Assets.xcassets/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "info" : {
3 | "version" : 1,
4 | "author" : "xcode"
5 | }
6 | }
--------------------------------------------------------------------------------
/Example/SPAlertController/Assets.xcassets/publish_0.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "scale" : "1x"
6 | },
7 | {
8 | "idiom" : "universal",
9 | "filename" : "publish_0@2x.png",
10 | "scale" : "2x"
11 | },
12 | {
13 | "idiom" : "universal",
14 | "filename" : "publish_0@3x.png",
15 | "scale" : "3x"
16 | }
17 | ],
18 | "info" : {
19 | "version" : 1,
20 | "author" : "xcode"
21 | }
22 | }
--------------------------------------------------------------------------------
/Example/SPAlertController/Assets.xcassets/publish_0.imageset/publish_0@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SPStore/SPAlertController/b472fd0338825b485c3b3d46cb68e5a2f0022414/Example/SPAlertController/Assets.xcassets/publish_0.imageset/publish_0@2x.png
--------------------------------------------------------------------------------
/Example/SPAlertController/Assets.xcassets/publish_0.imageset/publish_0@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SPStore/SPAlertController/b472fd0338825b485c3b3d46cb68e5a2f0022414/Example/SPAlertController/Assets.xcassets/publish_0.imageset/publish_0@3x.png
--------------------------------------------------------------------------------
/Example/SPAlertController/Assets.xcassets/publish_1.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "scale" : "1x"
6 | },
7 | {
8 | "idiom" : "universal",
9 | "filename" : "publish_1@2x.png",
10 | "scale" : "2x"
11 | },
12 | {
13 | "idiom" : "universal",
14 | "filename" : "publish_1@3x.png",
15 | "scale" : "3x"
16 | }
17 | ],
18 | "info" : {
19 | "version" : 1,
20 | "author" : "xcode"
21 | }
22 | }
--------------------------------------------------------------------------------
/Example/SPAlertController/Assets.xcassets/publish_1.imageset/publish_1@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SPStore/SPAlertController/b472fd0338825b485c3b3d46cb68e5a2f0022414/Example/SPAlertController/Assets.xcassets/publish_1.imageset/publish_1@2x.png
--------------------------------------------------------------------------------
/Example/SPAlertController/Assets.xcassets/publish_1.imageset/publish_1@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SPStore/SPAlertController/b472fd0338825b485c3b3d46cb68e5a2f0022414/Example/SPAlertController/Assets.xcassets/publish_1.imageset/publish_1@3x.png
--------------------------------------------------------------------------------
/Example/SPAlertController/Assets.xcassets/publish_10.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "scale" : "1x"
6 | },
7 | {
8 | "idiom" : "universal",
9 | "filename" : "publish_10@2x.png",
10 | "scale" : "2x"
11 | },
12 | {
13 | "idiom" : "universal",
14 | "filename" : "publish_10@3x.png",
15 | "scale" : "3x"
16 | }
17 | ],
18 | "info" : {
19 | "version" : 1,
20 | "author" : "xcode"
21 | }
22 | }
--------------------------------------------------------------------------------
/Example/SPAlertController/Assets.xcassets/publish_10.imageset/publish_10@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SPStore/SPAlertController/b472fd0338825b485c3b3d46cb68e5a2f0022414/Example/SPAlertController/Assets.xcassets/publish_10.imageset/publish_10@2x.png
--------------------------------------------------------------------------------
/Example/SPAlertController/Assets.xcassets/publish_10.imageset/publish_10@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SPStore/SPAlertController/b472fd0338825b485c3b3d46cb68e5a2f0022414/Example/SPAlertController/Assets.xcassets/publish_10.imageset/publish_10@3x.png
--------------------------------------------------------------------------------
/Example/SPAlertController/Assets.xcassets/publish_11.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "scale" : "1x"
6 | },
7 | {
8 | "idiom" : "universal",
9 | "filename" : "publish_11@2x.png",
10 | "scale" : "2x"
11 | },
12 | {
13 | "idiom" : "universal",
14 | "filename" : "publish_11@3x.png",
15 | "scale" : "3x"
16 | }
17 | ],
18 | "info" : {
19 | "version" : 1,
20 | "author" : "xcode"
21 | }
22 | }
--------------------------------------------------------------------------------
/Example/SPAlertController/Assets.xcassets/publish_11.imageset/publish_11@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SPStore/SPAlertController/b472fd0338825b485c3b3d46cb68e5a2f0022414/Example/SPAlertController/Assets.xcassets/publish_11.imageset/publish_11@2x.png
--------------------------------------------------------------------------------
/Example/SPAlertController/Assets.xcassets/publish_11.imageset/publish_11@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SPStore/SPAlertController/b472fd0338825b485c3b3d46cb68e5a2f0022414/Example/SPAlertController/Assets.xcassets/publish_11.imageset/publish_11@3x.png
--------------------------------------------------------------------------------
/Example/SPAlertController/Assets.xcassets/publish_2.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "scale" : "1x"
6 | },
7 | {
8 | "idiom" : "universal",
9 | "filename" : "publish_2@2x.png",
10 | "scale" : "2x"
11 | },
12 | {
13 | "idiom" : "universal",
14 | "filename" : "publish_2@3x.png",
15 | "scale" : "3x"
16 | }
17 | ],
18 | "info" : {
19 | "version" : 1,
20 | "author" : "xcode"
21 | }
22 | }
--------------------------------------------------------------------------------
/Example/SPAlertController/Assets.xcassets/publish_2.imageset/publish_2@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SPStore/SPAlertController/b472fd0338825b485c3b3d46cb68e5a2f0022414/Example/SPAlertController/Assets.xcassets/publish_2.imageset/publish_2@2x.png
--------------------------------------------------------------------------------
/Example/SPAlertController/Assets.xcassets/publish_2.imageset/publish_2@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SPStore/SPAlertController/b472fd0338825b485c3b3d46cb68e5a2f0022414/Example/SPAlertController/Assets.xcassets/publish_2.imageset/publish_2@3x.png
--------------------------------------------------------------------------------
/Example/SPAlertController/Assets.xcassets/publish_3.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "scale" : "1x"
6 | },
7 | {
8 | "idiom" : "universal",
9 | "filename" : "publish_3@2x.png",
10 | "scale" : "2x"
11 | },
12 | {
13 | "idiom" : "universal",
14 | "filename" : "publish_3@3x.png",
15 | "scale" : "3x"
16 | }
17 | ],
18 | "info" : {
19 | "version" : 1,
20 | "author" : "xcode"
21 | }
22 | }
--------------------------------------------------------------------------------
/Example/SPAlertController/Assets.xcassets/publish_3.imageset/publish_3@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SPStore/SPAlertController/b472fd0338825b485c3b3d46cb68e5a2f0022414/Example/SPAlertController/Assets.xcassets/publish_3.imageset/publish_3@2x.png
--------------------------------------------------------------------------------
/Example/SPAlertController/Assets.xcassets/publish_3.imageset/publish_3@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SPStore/SPAlertController/b472fd0338825b485c3b3d46cb68e5a2f0022414/Example/SPAlertController/Assets.xcassets/publish_3.imageset/publish_3@3x.png
--------------------------------------------------------------------------------
/Example/SPAlertController/Assets.xcassets/publish_4.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "scale" : "1x"
6 | },
7 | {
8 | "idiom" : "universal",
9 | "filename" : "publish_4@2x.png",
10 | "scale" : "2x"
11 | },
12 | {
13 | "idiom" : "universal",
14 | "filename" : "publish_4@3x.png",
15 | "scale" : "3x"
16 | }
17 | ],
18 | "info" : {
19 | "version" : 1,
20 | "author" : "xcode"
21 | }
22 | }
--------------------------------------------------------------------------------
/Example/SPAlertController/Assets.xcassets/publish_4.imageset/publish_4@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SPStore/SPAlertController/b472fd0338825b485c3b3d46cb68e5a2f0022414/Example/SPAlertController/Assets.xcassets/publish_4.imageset/publish_4@2x.png
--------------------------------------------------------------------------------
/Example/SPAlertController/Assets.xcassets/publish_4.imageset/publish_4@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SPStore/SPAlertController/b472fd0338825b485c3b3d46cb68e5a2f0022414/Example/SPAlertController/Assets.xcassets/publish_4.imageset/publish_4@3x.png
--------------------------------------------------------------------------------
/Example/SPAlertController/Assets.xcassets/publish_5.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "scale" : "1x"
6 | },
7 | {
8 | "idiom" : "universal",
9 | "filename" : "publish_5@2x.png",
10 | "scale" : "2x"
11 | },
12 | {
13 | "idiom" : "universal",
14 | "filename" : "publish_5@3x.png",
15 | "scale" : "3x"
16 | }
17 | ],
18 | "info" : {
19 | "version" : 1,
20 | "author" : "xcode"
21 | }
22 | }
--------------------------------------------------------------------------------
/Example/SPAlertController/Assets.xcassets/publish_5.imageset/publish_5@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SPStore/SPAlertController/b472fd0338825b485c3b3d46cb68e5a2f0022414/Example/SPAlertController/Assets.xcassets/publish_5.imageset/publish_5@2x.png
--------------------------------------------------------------------------------
/Example/SPAlertController/Assets.xcassets/publish_5.imageset/publish_5@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SPStore/SPAlertController/b472fd0338825b485c3b3d46cb68e5a2f0022414/Example/SPAlertController/Assets.xcassets/publish_5.imageset/publish_5@3x.png
--------------------------------------------------------------------------------
/Example/SPAlertController/Assets.xcassets/publish_6.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "scale" : "1x"
6 | },
7 | {
8 | "idiom" : "universal",
9 | "filename" : "publish_6@2x.png",
10 | "scale" : "2x"
11 | },
12 | {
13 | "idiom" : "universal",
14 | "filename" : "publish_6@3x.png",
15 | "scale" : "3x"
16 | }
17 | ],
18 | "info" : {
19 | "version" : 1,
20 | "author" : "xcode"
21 | }
22 | }
--------------------------------------------------------------------------------
/Example/SPAlertController/Assets.xcassets/publish_6.imageset/publish_6@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SPStore/SPAlertController/b472fd0338825b485c3b3d46cb68e5a2f0022414/Example/SPAlertController/Assets.xcassets/publish_6.imageset/publish_6@2x.png
--------------------------------------------------------------------------------
/Example/SPAlertController/Assets.xcassets/publish_6.imageset/publish_6@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SPStore/SPAlertController/b472fd0338825b485c3b3d46cb68e5a2f0022414/Example/SPAlertController/Assets.xcassets/publish_6.imageset/publish_6@3x.png
--------------------------------------------------------------------------------
/Example/SPAlertController/Assets.xcassets/publish_7.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "scale" : "1x"
6 | },
7 | {
8 | "idiom" : "universal",
9 | "filename" : "publish_7@2x.png",
10 | "scale" : "2x"
11 | },
12 | {
13 | "idiom" : "universal",
14 | "filename" : "publish_7@3x.png",
15 | "scale" : "3x"
16 | }
17 | ],
18 | "info" : {
19 | "version" : 1,
20 | "author" : "xcode"
21 | }
22 | }
--------------------------------------------------------------------------------
/Example/SPAlertController/Assets.xcassets/publish_7.imageset/publish_7@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SPStore/SPAlertController/b472fd0338825b485c3b3d46cb68e5a2f0022414/Example/SPAlertController/Assets.xcassets/publish_7.imageset/publish_7@2x.png
--------------------------------------------------------------------------------
/Example/SPAlertController/Assets.xcassets/publish_7.imageset/publish_7@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SPStore/SPAlertController/b472fd0338825b485c3b3d46cb68e5a2f0022414/Example/SPAlertController/Assets.xcassets/publish_7.imageset/publish_7@3x.png
--------------------------------------------------------------------------------
/Example/SPAlertController/Assets.xcassets/publish_8.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "scale" : "1x"
6 | },
7 | {
8 | "idiom" : "universal",
9 | "filename" : "publish_8@2x.png",
10 | "scale" : "2x"
11 | },
12 | {
13 | "idiom" : "universal",
14 | "filename" : "publish_8@3x.png",
15 | "scale" : "3x"
16 | }
17 | ],
18 | "info" : {
19 | "version" : 1,
20 | "author" : "xcode"
21 | }
22 | }
--------------------------------------------------------------------------------
/Example/SPAlertController/Assets.xcassets/publish_8.imageset/publish_8@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SPStore/SPAlertController/b472fd0338825b485c3b3d46cb68e5a2f0022414/Example/SPAlertController/Assets.xcassets/publish_8.imageset/publish_8@2x.png
--------------------------------------------------------------------------------
/Example/SPAlertController/Assets.xcassets/publish_8.imageset/publish_8@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SPStore/SPAlertController/b472fd0338825b485c3b3d46cb68e5a2f0022414/Example/SPAlertController/Assets.xcassets/publish_8.imageset/publish_8@3x.png
--------------------------------------------------------------------------------
/Example/SPAlertController/Assets.xcassets/publish_9.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "scale" : "1x"
6 | },
7 | {
8 | "idiom" : "universal",
9 | "filename" : "publish_9@2x.png",
10 | "scale" : "2x"
11 | },
12 | {
13 | "idiom" : "universal",
14 | "filename" : "publish_9@3x.png",
15 | "scale" : "3x"
16 | }
17 | ],
18 | "info" : {
19 | "version" : 1,
20 | "author" : "xcode"
21 | }
22 | }
--------------------------------------------------------------------------------
/Example/SPAlertController/Assets.xcassets/publish_9.imageset/publish_9@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SPStore/SPAlertController/b472fd0338825b485c3b3d46cb68e5a2f0022414/Example/SPAlertController/Assets.xcassets/publish_9.imageset/publish_9@2x.png
--------------------------------------------------------------------------------
/Example/SPAlertController/Assets.xcassets/publish_9.imageset/publish_9@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SPStore/SPAlertController/b472fd0338825b485c3b3d46cb68e5a2f0022414/Example/SPAlertController/Assets.xcassets/publish_9.imageset/publish_9@3x.png
--------------------------------------------------------------------------------
/Example/SPAlertController/Assets.xcassets/success.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "filename" : "勾.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 | }
--------------------------------------------------------------------------------
/Example/SPAlertController/Assets.xcassets/success.imageset/勾.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SPStore/SPAlertController/b472fd0338825b485c3b3d46cb68e5a2f0022414/Example/SPAlertController/Assets.xcassets/success.imageset/勾.png
--------------------------------------------------------------------------------
/Example/SPAlertController/Assets.xcassets/telephone.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "scale" : "1x"
6 | },
7 | {
8 | "idiom" : "universal",
9 | "filename" : "telephone@2x.png",
10 | "scale" : "2x"
11 | },
12 | {
13 | "idiom" : "universal",
14 | "filename" : "telephone@3x.png",
15 | "scale" : "3x"
16 | }
17 | ],
18 | "info" : {
19 | "version" : 1,
20 | "author" : "xcode"
21 | }
22 | }
--------------------------------------------------------------------------------
/Example/SPAlertController/Assets.xcassets/telephone.imageset/telephone@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SPStore/SPAlertController/b472fd0338825b485c3b3d46cb68e5a2f0022414/Example/SPAlertController/Assets.xcassets/telephone.imageset/telephone@2x.png
--------------------------------------------------------------------------------
/Example/SPAlertController/Assets.xcassets/telephone.imageset/telephone@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SPStore/SPAlertController/b472fd0338825b485c3b3d46cb68e5a2f0022414/Example/SPAlertController/Assets.xcassets/telephone.imageset/telephone@3x.png
--------------------------------------------------------------------------------
/Example/SPAlertController/Assets.xcassets/video.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "scale" : "1x"
6 | },
7 | {
8 | "idiom" : "universal",
9 | "filename" : "video@2x.png",
10 | "scale" : "2x"
11 | },
12 | {
13 | "idiom" : "universal",
14 | "filename" : "video@3x.png",
15 | "scale" : "3x"
16 | }
17 | ],
18 | "info" : {
19 | "version" : 1,
20 | "author" : "xcode"
21 | }
22 | }
--------------------------------------------------------------------------------
/Example/SPAlertController/Assets.xcassets/video.imageset/video@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SPStore/SPAlertController/b472fd0338825b485c3b3d46cb68e5a2f0022414/Example/SPAlertController/Assets.xcassets/video.imageset/video@2x.png
--------------------------------------------------------------------------------
/Example/SPAlertController/Assets.xcassets/video.imageset/video@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SPStore/SPAlertController/b472fd0338825b485c3b3d46cb68e5a2f0022414/Example/SPAlertController/Assets.xcassets/video.imageset/video@3x.png
--------------------------------------------------------------------------------
/Example/SPAlertController/Assets.xcassets/wechatLogo.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "scale" : "1x"
6 | },
7 | {
8 | "idiom" : "universal",
9 | "filename" : "wechatLogo@2x.png",
10 | "scale" : "2x"
11 | },
12 | {
13 | "idiom" : "universal",
14 | "filename" : "wechatLogo@3x.png",
15 | "scale" : "3x"
16 | }
17 | ],
18 | "info" : {
19 | "version" : 1,
20 | "author" : "xcode"
21 | }
22 | }
--------------------------------------------------------------------------------
/Example/SPAlertController/Assets.xcassets/wechatLogo.imageset/wechatLogo@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SPStore/SPAlertController/b472fd0338825b485c3b3d46cb68e5a2f0022414/Example/SPAlertController/Assets.xcassets/wechatLogo.imageset/wechatLogo@2x.png
--------------------------------------------------------------------------------
/Example/SPAlertController/Assets.xcassets/wechatLogo.imageset/wechatLogo@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SPStore/SPAlertController/b472fd0338825b485c3b3d46cb68e5a2f0022414/Example/SPAlertController/Assets.xcassets/wechatLogo.imageset/wechatLogo@3x.png
--------------------------------------------------------------------------------
/Example/SPAlertController/Assets.xcassets/zhiwen.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "scale" : "1x"
6 | },
7 | {
8 | "idiom" : "universal",
9 | "filename" : "zhiwen@2x.png",
10 | "scale" : "2x"
11 | },
12 | {
13 | "idiom" : "universal",
14 | "filename" : "zhiwen@3x.png",
15 | "scale" : "3x"
16 | }
17 | ],
18 | "info" : {
19 | "version" : 1,
20 | "author" : "xcode"
21 | }
22 | }
--------------------------------------------------------------------------------
/Example/SPAlertController/Assets.xcassets/zhiwen.imageset/zhiwen@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SPStore/SPAlertController/b472fd0338825b485c3b3d46cb68e5a2f0022414/Example/SPAlertController/Assets.xcassets/zhiwen.imageset/zhiwen@2x.png
--------------------------------------------------------------------------------
/Example/SPAlertController/Assets.xcassets/zhiwen.imageset/zhiwen@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SPStore/SPAlertController/b472fd0338825b485c3b3d46cb68e5a2f0022414/Example/SPAlertController/Assets.xcassets/zhiwen.imageset/zhiwen@3x.png
--------------------------------------------------------------------------------
/Example/SPAlertController/Assets.xcassets/减号.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "filename" : "减号.png",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "filename" : "减号-1.png",
11 | "scale" : "2x"
12 | },
13 | {
14 | "idiom" : "universal",
15 | "filename" : "减号-2.png",
16 | "scale" : "3x"
17 | }
18 | ],
19 | "info" : {
20 | "version" : 1,
21 | "author" : "xcode"
22 | }
23 | }
--------------------------------------------------------------------------------
/Example/SPAlertController/Assets.xcassets/减号.imageset/减号-1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SPStore/SPAlertController/b472fd0338825b485c3b3d46cb68e5a2f0022414/Example/SPAlertController/Assets.xcassets/减号.imageset/减号-1.png
--------------------------------------------------------------------------------
/Example/SPAlertController/Assets.xcassets/减号.imageset/减号-2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SPStore/SPAlertController/b472fd0338825b485c3b3d46cb68e5a2f0022414/Example/SPAlertController/Assets.xcassets/减号.imageset/减号-2.png
--------------------------------------------------------------------------------
/Example/SPAlertController/Assets.xcassets/减号.imageset/减号.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SPStore/SPAlertController/b472fd0338825b485c3b3d46cb68e5a2f0022414/Example/SPAlertController/Assets.xcassets/减号.imageset/减号.png
--------------------------------------------------------------------------------
/Example/SPAlertController/Assets.xcassets/加号.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "filename" : "加号-1.png",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "filename" : "加号-3.png",
11 | "scale" : "2x"
12 | },
13 | {
14 | "idiom" : "universal",
15 | "filename" : "加号-4.png",
16 | "scale" : "3x"
17 | }
18 | ],
19 | "info" : {
20 | "version" : 1,
21 | "author" : "xcode"
22 | }
23 | }
--------------------------------------------------------------------------------
/Example/SPAlertController/Assets.xcassets/加号.imageset/加号-1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SPStore/SPAlertController/b472fd0338825b485c3b3d46cb68e5a2f0022414/Example/SPAlertController/Assets.xcassets/加号.imageset/加号-1.png
--------------------------------------------------------------------------------
/Example/SPAlertController/Assets.xcassets/加号.imageset/加号-3.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SPStore/SPAlertController/b472fd0338825b485c3b3d46cb68e5a2f0022414/Example/SPAlertController/Assets.xcassets/加号.imageset/加号-3.png
--------------------------------------------------------------------------------
/Example/SPAlertController/Assets.xcassets/加号.imageset/加号-4.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SPStore/SPAlertController/b472fd0338825b485c3b3d46cb68e5a2f0022414/Example/SPAlertController/Assets.xcassets/加号.imageset/加号-4.png
--------------------------------------------------------------------------------
/Example/SPAlertController/Assets.xcassets/取消.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "filename" : "叉-1.png",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "filename" : "叉-2.png",
11 | "scale" : "2x"
12 | },
13 | {
14 | "idiom" : "universal",
15 | "filename" : "叉-3.png",
16 | "scale" : "3x"
17 | }
18 | ],
19 | "info" : {
20 | "version" : 1,
21 | "author" : "xcode"
22 | }
23 | }
--------------------------------------------------------------------------------
/Example/SPAlertController/Assets.xcassets/取消.imageset/叉-1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SPStore/SPAlertController/b472fd0338825b485c3b3d46cb68e5a2f0022414/Example/SPAlertController/Assets.xcassets/取消.imageset/叉-1.png
--------------------------------------------------------------------------------
/Example/SPAlertController/Assets.xcassets/取消.imageset/叉-2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SPStore/SPAlertController/b472fd0338825b485c3b3d46cb68e5a2f0022414/Example/SPAlertController/Assets.xcassets/取消.imageset/叉-2.png
--------------------------------------------------------------------------------
/Example/SPAlertController/Assets.xcassets/取消.imageset/叉-3.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SPStore/SPAlertController/b472fd0338825b485c3b3d46cb68e5a2f0022414/Example/SPAlertController/Assets.xcassets/取消.imageset/叉-3.png
--------------------------------------------------------------------------------
/Example/SPAlertController/Assets.xcassets/苹果logo.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "filename" : "苹果logo.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 | }
--------------------------------------------------------------------------------
/Example/SPAlertController/Assets.xcassets/苹果logo.imageset/苹果logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SPStore/SPAlertController/b472fd0338825b485c3b3d46cb68e5a2f0022414/Example/SPAlertController/Assets.xcassets/苹果logo.imageset/苹果logo.png
--------------------------------------------------------------------------------
/Example/SPAlertController/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 |
27 |
28 |
29 |
30 |
31 |
32 |
--------------------------------------------------------------------------------
/Example/SPAlertController/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 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
--------------------------------------------------------------------------------
/Example/SPAlertController/CustomViews/CustomView1/SPTextView.h:
--------------------------------------------------------------------------------
1 | //
2 | // SPTextView.h
3 | // SPTextView
4 | //
5 | // Created by 乐升平 on 2018/7/31.
6 | // Copyright © 2018 乐升平. All rights reserved.
7 | // github地址:https://github.com/SPStore/SPTextView
8 |
9 | #import
10 |
11 | @interface SPTextView : UITextView
12 |
13 | /** 占位文字 */
14 | @property (nonatomic, copy) NSString *placeholder;
15 | /** 占位文字的颜色 */
16 | @property (nonatomic, strong) UIColor *placeholderColor;
17 |
18 | // 占位文字的字体永远跟textView的字体保持一致,因此该自定义控件不提供单独设置占位文字字体的属性,因为textView的光标高度依赖于textview的字体,如果占位文字跟textView的字体不一致,会导致光标跟占位文字无法对齐
19 | @end
20 |
--------------------------------------------------------------------------------
/Example/SPAlertController/CustomViews/CustomView1/SPTextView.m:
--------------------------------------------------------------------------------
1 | //
2 | // SPTextView.m
3 | // SPTextView
4 | //
5 | // Created by 乐升平 on 2018/7/31.
6 | // Copyright © 2018 乐升平. All rights reserved.
7 | //
8 |
9 | #import "SPTextView.h"
10 | #import
11 | #import
12 | #import
13 |
14 | @interface SPTextView()
15 | @property(nonatomic, strong) UILabel *placeholderLabel;
16 | @end
17 |
18 | @implementation SPTextView
19 |
20 | @synthesize placeholder = _placeholder;
21 | @synthesize placeholderLabel = _placeholderLabel;
22 | @synthesize placeholderColor = _placeholderColor;
23 |
24 | - (void)initialize {
25 | [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(refreshPlaceholder) name:UITextViewTextDidChangeNotification object:self];
26 | }
27 |
28 | - (void)dealloc {
29 | [_placeholderLabel removeFromSuperview];
30 | _placeholderLabel = nil;
31 | [[NSNotificationCenter defaultCenter] removeObserver:self];
32 | }
33 |
34 | - (instancetype)init {
35 | self = [super init];
36 | if (self) {
37 | [self initialize];
38 | }
39 | return self;
40 | }
41 |
42 | - (void)awakeFromNib {
43 | [super awakeFromNib];
44 | [self initialize];
45 | }
46 |
47 | - (void)refreshPlaceholder {
48 | _placeholderLabel.alpha = ![self hasText];
49 |
50 | [self setNeedsLayout];
51 | [self layoutIfNeeded];
52 | }
53 |
54 | - (void)setText:(NSString *)text {
55 | [super setText:text];
56 | [self refreshPlaceholder];
57 | }
58 |
59 | - (void)setAttributedText:(NSAttributedString *)attributedText {
60 | [super setAttributedText:attributedText];
61 | [self refreshPlaceholder];
62 | }
63 |
64 | - (void)setFont:(UIFont *)font {
65 | [super setFont:font];
66 | self.placeholderLabel.font = self.font;
67 |
68 | [self setNeedsLayout];
69 | [self layoutIfNeeded];
70 | }
71 |
72 | - (void)setTextAlignment:(NSTextAlignment)textAlignment {
73 | [super setTextAlignment:textAlignment];
74 | self.placeholderLabel.textAlignment = textAlignment;
75 |
76 | [self setNeedsLayout];
77 | [self layoutIfNeeded];
78 | }
79 |
80 | - (void)layoutSubviews {
81 | [super layoutSubviews];
82 | self.placeholderLabel.frame = [self placeholderExpectedFrame];
83 | }
84 |
85 | - (void)setPlaceholder:(NSString *)placeholder {
86 | _placeholder = placeholder;
87 |
88 | self.placeholderLabel.text = placeholder;
89 | [self refreshPlaceholder];
90 | }
91 |
92 | - (void)setPlaceholderColor:(UIColor *)placeholderColor {
93 | _placeholderColor = placeholderColor;
94 | self.placeholderLabel.textColor = placeholderColor;
95 | }
96 |
97 | - (UIEdgeInsets)placeholderInsets {
98 | return UIEdgeInsetsMake(self.textContainerInset.top, self.textContainerInset.left + self.textContainer.lineFragmentPadding, self.textContainerInset.bottom, self.textContainerInset.right + self.textContainer.lineFragmentPadding);
99 | }
100 |
101 | - (CGRect)placeholderExpectedFrame {
102 | UIEdgeInsets placeholderInsets = [self placeholderInsets];
103 | CGFloat maxWidth = CGRectGetWidth(self.frame)-placeholderInsets.left-placeholderInsets.right;
104 |
105 | CGSize expectedSize = [self.placeholderLabel sizeThatFits:CGSizeMake(maxWidth, CGRectGetHeight(self.frame)-placeholderInsets.top-placeholderInsets.bottom)];
106 |
107 | return CGRectMake(placeholderInsets.left, placeholderInsets.top, maxWidth, expectedSize.height);
108 | }
109 |
110 | - (UILabel*)placeholderLabel {
111 | if (_placeholderLabel == nil) {
112 | _placeholderLabel = [[UILabel alloc] init];
113 | _placeholderLabel.autoresizingMask = (UIViewAutoresizingFlexibleWidth|UIViewAutoresizingFlexibleHeight);
114 | _placeholderLabel.lineBreakMode = NSLineBreakByWordWrapping;
115 | _placeholderLabel.numberOfLines = 0;
116 | _placeholderLabel.font = [UIFont systemFontOfSize:12]; // UITextView的默认字体是12pt
117 | _placeholderLabel.textAlignment = self.textAlignment;
118 | _placeholderLabel.backgroundColor = [UIColor clearColor];
119 | _placeholderLabel.textColor = [UIColor colorWithWhite:0.7 alpha:1.0];
120 | _placeholderLabel.alpha = 0;
121 | [self addSubview:_placeholderLabel];
122 | }
123 |
124 | return _placeholderLabel;
125 | }
126 |
127 | //When any text changes on textField, the delegate getter is called. At this time we refresh the textView's placeholder
128 | - (id)delegate {
129 | [self refreshPlaceholder];
130 | return [super delegate];
131 | }
132 |
133 | - (CGSize)intrinsicContentSize {
134 | if (self.hasText) {
135 | return [super intrinsicContentSize];
136 | }
137 |
138 | UIEdgeInsets placeholderInsets = [self placeholderInsets];
139 | CGSize newSize = [super intrinsicContentSize];
140 |
141 | newSize.height = [self placeholderExpectedFrame].size.height + placeholderInsets.top + placeholderInsets.bottom;
142 |
143 | return newSize;
144 | }
145 |
146 | @end
147 |
--------------------------------------------------------------------------------
/Example/SPAlertController/CustomViews/CustomView1/SendAlertView.h:
--------------------------------------------------------------------------------
1 | //
2 | // SendAlertView.h
3 | // SPAlertController
4 | //
5 | // Created by 乐升平 on 2018/12/24.
6 | // Copyright © 2018 乐升平. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | NS_ASSUME_NONNULL_BEGIN
12 |
13 | @interface SendAlertView : UIView
14 |
15 | + (instancetype)shareSendAlertView;
16 |
17 | @property (nonatomic, copy) UIImage *contentImage;
18 |
19 | @property (nonatomic, copy) void(^keyboardWillShow)(CGFloat value);
20 | @property (nonatomic, copy) void(^textViewHeightDidChange)(CGFloat offset);
21 | @property (nonatomic, copy) void(^textViewDidEndEditting)(void);
22 |
23 |
24 | @end
25 |
26 | NS_ASSUME_NONNULL_END
27 |
--------------------------------------------------------------------------------
/Example/SPAlertController/CustomViews/CustomView1/SendAlertView.m:
--------------------------------------------------------------------------------
1 | //
2 | // SendAlertView.m
3 | // SPAlertController
4 | //
5 | // Created by 乐升平 on 2018/12/24.
6 | // Copyright © 2018 乐升平. All rights reserved.
7 | //
8 |
9 | #import "SendAlertView.h"
10 | #import "SPTextView.h"
11 | #import "UIColor+DarkMode.h"
12 |
13 | @interface SendAlertView()
14 | @property (weak, nonatomic) IBOutlet UIImageView *userIconView;
15 | @property (weak, nonatomic) IBOutlet UILabel *nameLabel;
16 | @property (weak, nonatomic) IBOutlet UIImageView *contentImageView;
17 | @property (weak, nonatomic) IBOutlet SPTextView *textView;
18 | @property (weak, nonatomic) IBOutlet NSLayoutConstraint *contentHeightConstraint;
19 | @property (weak, nonatomic) IBOutlet NSLayoutConstraint *textViewHeightConstraint;
20 | @property (nonatomic, assign) CGFloat textH;
21 |
22 | @end
23 |
24 | @implementation SendAlertView
25 |
26 | + (instancetype)shareSendAlertView {
27 | return [[[NSBundle mainBundle] loadNibNamed:NSStringFromClass([self class]) owner:nil options:nil] lastObject];
28 | }
29 |
30 | - (void)awakeFromNib {
31 | [super awakeFromNib];
32 | self.backgroundColor = [UIColor colorPairsWithLightColor:[UIColor whiteColor] darkColor:[UIColor colorWithRed:44.0 / 255.0 green:44.0 / 255.0 blue:44.0 / 255.0 alpha:1.0]];
33 | self.userIconView.layer.cornerRadius = 4.0;
34 | self.userIconView.layer.masksToBounds = YES;
35 | self.textView.delegate = self;
36 | self.textView.layer.borderWidth = 0.5/[UIScreen mainScreen].scale;
37 | self.textView.layer.borderColor = [[UIColor grayColor] colorWithAlphaComponent:0.3].CGColor;
38 | self.textView.placeholder = @"给朋友留言";
39 | self.textView.placeholderColor = [UIColor lightGrayColor];
40 | self.textView.backgroundColor = [UIColor colorPairsWithLightColor:[UIColor colorWithRed:247.0 / 255.0 green:247.0 / 255.0 blue:247.0 / 255.0 alpha:1.0] darkColor:[UIColor colorWithRed:54.0 / 255.0 green:54.0 / 255.0 blue:54.0 / 255.0 alpha:1.0]];
41 | _textH = ceil(self.textView.font.lineHeight) + self.textView.textContainerInset.top + self.textView.textContainerInset.bottom;
42 |
43 | }
44 |
45 | - (instancetype)initWithCoder:(NSCoder *)aDecoder {
46 | if (self = [super initWithCoder:aDecoder]) {
47 | [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillShow:) name:UIKeyboardWillShowNotification object:nil];
48 | }
49 | return self;
50 | }
51 |
52 | - (void)setContentImage:(UIImage *)contentImage {
53 | _contentImage = contentImage;
54 | self.contentImageView.image = contentImage;
55 | if (_contentImage) {
56 | CGFloat contentH;
57 | CGFloat imgRatio = _contentImage.size.height/_contentImage.size.width;
58 | CGFloat contentW = self.bounds.size.width-30; // 30是contentImageView的左右间距之和
59 | if (_contentImage.size.height < contentW) {
60 | contentH = _contentImage.size.height;
61 | } else {
62 | contentH = imgRatio * contentW;
63 | }
64 | if (contentH > [UIScreen mainScreen].bounds.size.height-300) { // 300是一个大概写的数字
65 | contentH = [UIScreen mainScreen].bounds.size.height-300;
66 | }
67 | // 更新图片的高度约束
68 | self.contentHeightConstraint.constant = contentH;
69 | }
70 | }
71 |
72 | - (void)textViewDidBeginEditing:(UITextView *)textView {
73 |
74 | }
75 |
76 | - (void)textViewDidChange:(UITextView *)textView {
77 |
78 | CGFloat maxHeight = textView.font.lineHeight * 3 + textView.textContainerInset.top + textView.textContainerInset.bottom;
79 |
80 | NSInteger height = ceilf([textView sizeThatFits:CGSizeMake(textView.bounds.size.width, MAXFLOAT)].height);
81 |
82 | if (_textH != height) { // 高度不一样,就改变了高度
83 |
84 | // 最大高度,可以滚动
85 | if (height > maxHeight && maxHeight > 0) {
86 | self.textView.scrollEnabled = YES;
87 | height = maxHeight;
88 | } else {
89 | self.textView.scrollEnabled = NO;
90 | }
91 | if (self.textViewHeightDidChange) {
92 | self.textViewHeightConstraint.constant = height;
93 | self.textViewHeightDidChange(height - _textH);
94 | }
95 | _textH = height;
96 | }
97 | }
98 |
99 | - (void)textViewDidEndEditing:(UITextView *)textView {
100 | if (self.textViewDidEndEditting) {
101 | self.textViewDidEndEditting();
102 | }
103 | }
104 |
105 | - (void)keyboardWillShow:(NSNotification *)note {
106 | CGRect keyboardEndFrame = [note.userInfo[UIKeyboardFrameEndUserInfoKey] CGRectValue];
107 | CGFloat keyboardEndY = keyboardEndFrame.origin.y; // 200
108 | CGFloat textViewMaxY = CGRectGetMaxY([self.textView.superview convertRect:self.textView.frame toView:nil]);
109 | CGFloat diff = textViewMaxY - keyboardEndY + 80;
110 | if (self.keyboardWillShow) {
111 | self.keyboardWillShow(diff);
112 | }
113 | }
114 |
115 | - (void)dealloc {
116 | [[NSNotificationCenter defaultCenter] removeObserver:self];
117 | }
118 |
119 | @end
120 |
--------------------------------------------------------------------------------
/Example/SPAlertController/CustomViews/CustomView1/SendAlertView.xib:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
--------------------------------------------------------------------------------
/Example/SPAlertController/CustomViews/CustomView17/HCSStarRatingView.h:
--------------------------------------------------------------------------------
1 | // HCSStarRatingView.h
2 | //
3 | // Copyright (c) 2015 Hugo Sousa
4 | //
5 | // Permission is hereby granted, free of charge, to any person obtaining a copy
6 | // of this software and associated documentation files (the "Software"), to deal
7 | // in the Software without restriction, including without limitation the rights
8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | // copies of the Software, and to permit persons to whom the Software is
10 | // furnished to do so, subject to the following conditions:
11 | //
12 | // The above copyright notice and this permission notice shall be included in
13 | // all copies or substantial portions of the Software.
14 | //
15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21 | // THE SOFTWARE.
22 |
23 | @import UIKit;
24 |
25 | typedef BOOL(^HCSStarRatingViewShouldBeginGestureRecognizerBlock)(UIGestureRecognizer *gestureRecognizer);
26 |
27 | IB_DESIGNABLE
28 | @interface HCSStarRatingView : UIControl
29 | @property (nonatomic) IBInspectable NSUInteger maximumValue;
30 | @property (nonatomic) IBInspectable CGFloat minimumValue;
31 | @property (nonatomic) IBInspectable CGFloat value;
32 | @property (nonatomic) IBInspectable CGFloat spacing;
33 | @property (nonatomic) IBInspectable BOOL allowsHalfStars;
34 | @property (nonatomic) IBInspectable BOOL accurateHalfStars;
35 | @property (nonatomic) IBInspectable BOOL continuous;
36 |
37 | @property (nonatomic) BOOL shouldBecomeFirstResponder;
38 |
39 | // Optional: if `nil` method will return `NO`.
40 | @property (nonatomic, copy) HCSStarRatingViewShouldBeginGestureRecognizerBlock shouldBeginGestureRecognizerBlock;
41 |
42 | @property (nonatomic, strong) IBInspectable UIColor *starBorderColor;
43 | @property (nonatomic) IBInspectable CGFloat starBorderWidth;
44 |
45 | @property (nonatomic, strong) IBInspectable UIColor *emptyStarColor;
46 |
47 | @property (nonatomic, strong) IBInspectable UIImage *emptyStarImage;
48 | @property (nonatomic, strong) IBInspectable UIImage *halfStarImage;
49 | @property (nonatomic, strong) IBInspectable UIImage *filledStarImage;
50 | @end
51 |
52 |
--------------------------------------------------------------------------------
/Example/SPAlertController/CustomViews/CustomView17/HCSStarRatingView.m:
--------------------------------------------------------------------------------
1 | // HCSStarRatingView.m
2 | //
3 | // Copyright (c) 2015 Hugo Sousa
4 | //
5 | // Permission is hereby granted, free of charge, to any person obtaining a copy
6 | // of this software and associated documentation files (the "Software"), to deal
7 | // in the Software without restriction, including without limitation the rights
8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | // copies of the Software, and to permit persons to whom the Software is
10 | // furnished to do so, subject to the following conditions:
11 | //
12 | // The above copyright notice and this permission notice shall be included in
13 | // all copies or substantial portions of the Software.
14 | //
15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21 | // THE SOFTWARE.
22 |
23 | #import "HCSStarRatingView.h"
24 |
25 | @interface HCSStarRatingView ()
26 | @property (nonatomic, readonly) BOOL shouldUseImages;
27 | @end
28 |
29 | @implementation HCSStarRatingView {
30 | CGFloat _minimumValue;
31 | NSUInteger _maximumValue;
32 | CGFloat _value;
33 | UIColor *_starBorderColor;
34 | }
35 |
36 | @dynamic minimumValue;
37 | @dynamic maximumValue;
38 | @dynamic value;
39 | @dynamic shouldUseImages;
40 | @dynamic starBorderColor;
41 |
42 | #pragma mark - Initialization
43 |
44 | - (instancetype)initWithFrame:(CGRect)frame {
45 | self = [super initWithFrame:frame];
46 | if (self) {
47 | [self _customInit];
48 | }
49 | return self;
50 | }
51 |
52 | - (id)initWithCoder:(NSCoder *)aDecoder {
53 | self = [super initWithCoder:aDecoder];
54 | if (self) {
55 | [self _customInit];
56 | }
57 | return self;
58 | }
59 |
60 | - (void)_customInit {
61 | self.exclusiveTouch = YES;
62 | _minimumValue = 0;
63 | _maximumValue = 5;
64 | _value = 0;
65 | _spacing = 5.f;
66 | _continuous = YES;
67 | _starBorderWidth = 1.0f;
68 | _emptyStarColor = [UIColor clearColor];
69 |
70 | [self _updateAppearanceForState:self.enabled];
71 | }
72 |
73 | - (void)setNeedsLayout {
74 | [super setNeedsLayout];
75 | [self setNeedsDisplay];
76 | }
77 |
78 | #pragma mark - Properties
79 |
80 | - (UIColor *)backgroundColor {
81 | if ([super backgroundColor]) {
82 | return [super backgroundColor];
83 | } else {
84 | return self.isOpaque ? [UIColor whiteColor] : [UIColor clearColor];
85 | };
86 | }
87 |
88 | - (CGFloat)minimumValue {
89 | return MAX(_minimumValue, 0);
90 | }
91 |
92 | - (void)setMinimumValue:(CGFloat)minimumValue {
93 | if (_minimumValue != minimumValue) {
94 | _minimumValue = minimumValue;
95 | [self setNeedsDisplay];
96 | }
97 | }
98 |
99 | - (NSUInteger)maximumValue {
100 | return MAX(_minimumValue, _maximumValue);
101 | }
102 |
103 | - (void)setMaximumValue:(NSUInteger)maximumValue {
104 | if (_maximumValue != maximumValue) {
105 | _maximumValue = maximumValue;
106 | [self setNeedsDisplay];
107 | [self invalidateIntrinsicContentSize];
108 | }
109 | }
110 |
111 | - (CGFloat)value {
112 | return MIN(MAX(_value, _minimumValue), _maximumValue);
113 | }
114 |
115 | - (void)setValue:(CGFloat)value {
116 | [self setValue:value sendValueChangedAction:NO];
117 | }
118 |
119 | - (void)setValue:(CGFloat)value sendValueChangedAction:(BOOL)sendAction {
120 | [self willChangeValueForKey:NSStringFromSelector(@selector(value))];
121 | if (_value != value && value >= _minimumValue && value <= _maximumValue) {
122 | _value = value;
123 | if (sendAction) [self sendActionsForControlEvents:UIControlEventValueChanged];
124 | [self setNeedsDisplay];
125 | }
126 | [self didChangeValueForKey:NSStringFromSelector(@selector(value))];
127 | }
128 |
129 | - (void)setSpacing:(CGFloat)spacing {
130 | _spacing = MAX(spacing, 0);
131 | [self setNeedsDisplay];
132 | }
133 |
134 | - (void)setAllowsHalfStars:(BOOL)allowsHalfStars {
135 | if (_allowsHalfStars != allowsHalfStars) {
136 | _allowsHalfStars = allowsHalfStars;
137 | [self setNeedsDisplay];
138 | }
139 | }
140 |
141 | - (void)setAccurateHalfStars:(BOOL)accurateHalfStars {
142 | if (_accurateHalfStars != accurateHalfStars) {
143 | _accurateHalfStars = accurateHalfStars;
144 | [self setNeedsDisplay];
145 | }
146 | }
147 |
148 | - (void)setEmptyStarImage:(UIImage *)emptyStarImage {
149 | if (_emptyStarImage != emptyStarImage) {
150 | _emptyStarImage = emptyStarImage;
151 | [self setNeedsDisplay];
152 | }
153 | }
154 |
155 | - (void)setHalfStarImage:(UIImage *)halfStarImage {
156 | if (_halfStarImage != halfStarImage) {
157 | _halfStarImage = halfStarImage;
158 | [self setNeedsDisplay];
159 | }
160 | }
161 |
162 | - (void)setFilledStarImage:(UIImage *)filledStarImage {
163 | if (_filledStarImage != filledStarImage) {
164 | _filledStarImage = filledStarImage;
165 | [self setNeedsDisplay];
166 | }
167 | }
168 |
169 | - (void)setEmptyStarColor:(UIColor *)emptyStarColor {
170 | if (_emptyStarColor != emptyStarColor) {
171 | _emptyStarColor = emptyStarColor;
172 | [self setNeedsDisplay];
173 | }
174 | }
175 |
176 | - (void)setStarBorderColor:(UIColor *)starBorderColor {
177 | if (_starBorderColor != starBorderColor) {
178 | _starBorderColor = starBorderColor;
179 | [self setNeedsDisplay];
180 | }
181 | }
182 |
183 | - (UIColor *)starBorderColor {
184 | if (_starBorderColor == nil) {
185 | return self.tintColor;
186 | } else {
187 | return _starBorderColor;
188 | }
189 | }
190 |
191 | - (void)setStarBorderWidth:(CGFloat)starBorderWidth {
192 | _starBorderWidth = MAX(0, starBorderWidth);
193 | [self setNeedsDisplay];
194 | }
195 |
196 |
197 | - (BOOL)shouldUseImages {
198 | return (self.emptyStarImage!=nil && self.filledStarImage!=nil);
199 | }
200 |
201 | #pragma mark - State
202 |
203 | - (void)setEnabled:(BOOL)enabled
204 | {
205 | [self _updateAppearanceForState:enabled];
206 | [super setEnabled:enabled];
207 | }
208 |
209 | - (void)_updateAppearanceForState:(BOOL)enabled
210 | {
211 | self.alpha = enabled ? 1.f : .5f;
212 | }
213 |
214 | #pragma mark - Image Drawing
215 |
216 | - (void)_drawStarImageWithFrame:(CGRect)frame tintColor:(UIColor*)tintColor highlighted:(BOOL)highlighted {
217 | UIImage *image = highlighted ? self.filledStarImage : self.emptyStarImage;
218 | [self _drawImage:image frame:frame tintColor:tintColor];
219 | }
220 |
221 | - (void)_drawHalfStarImageWithFrame:(CGRect)frame tintColor:(UIColor *)tintColor {
222 | [self _drawAccurateHalfStarImageWithFrame:frame tintColor:tintColor progress:.5f];
223 | }
224 |
225 | - (void)_drawAccurateHalfStarImageWithFrame:(CGRect)frame tintColor:(UIColor *)tintColor progress:(CGFloat)progress {
226 | UIImage *image = self.halfStarImage;
227 | if (image == nil) {
228 | // first draw star outline
229 | [self _drawStarImageWithFrame:frame tintColor:tintColor highlighted:NO];
230 |
231 | image = self.filledStarImage;
232 | CGRect imageFrame = CGRectMake(0, 0, image.size.width * image.scale * progress, image.size.height * image.scale);
233 | frame.size.width *= progress;
234 | CGImageRef imageRef = CGImageCreateWithImageInRect(image.CGImage, imageFrame);
235 | UIImage *halfImage = [UIImage imageWithCGImage:imageRef scale:image.scale orientation:image.imageOrientation];
236 | image = [halfImage imageWithRenderingMode:image.renderingMode];
237 | CGImageRelease(imageRef);
238 | }
239 | [self _drawImage:image frame:frame tintColor:tintColor];
240 | }
241 |
242 | - (void)_drawImage:(UIImage *)image frame:(CGRect)frame tintColor:(UIColor *)tintColor {
243 | if (image.renderingMode == UIImageRenderingModeAlwaysTemplate) {
244 | [tintColor setFill];
245 | }
246 | [image drawInRect:frame];
247 | }
248 |
249 | #pragma mark - Shape Drawing
250 |
251 | - (void)_drawStarShapeWithFrame:(CGRect)frame tintColor:(UIColor*)tintColor highlighted:(BOOL)highlighted {
252 | [self _drawAccurateHalfStarShapeWithFrame:frame tintColor:tintColor progress:highlighted ? 1.f : 0.f];
253 | }
254 |
255 | - (void)_drawHalfStarShapeWithFrame:(CGRect)frame tintColor:(UIColor *)tintColor {
256 | [self _drawAccurateHalfStarShapeWithFrame:frame tintColor:tintColor progress:.5f];
257 | }
258 |
259 | - (void)_drawAccurateHalfStarShapeWithFrame:(CGRect)frame tintColor:(UIColor *)tintColor progress:(CGFloat)progress {
260 | UIBezierPath* starShapePath = UIBezierPath.bezierPath;
261 | [starShapePath moveToPoint: CGPointMake(CGRectGetMinX(frame) + 0.62723 * CGRectGetWidth(frame), CGRectGetMinY(frame) + 0.37309 * CGRectGetHeight(frame))];
262 | [starShapePath addLineToPoint: CGPointMake(CGRectGetMinX(frame) + 0.50000 * CGRectGetWidth(frame), CGRectGetMinY(frame) + 0.02500 * CGRectGetHeight(frame))];
263 | [starShapePath addLineToPoint: CGPointMake(CGRectGetMinX(frame) + 0.37292 * CGRectGetWidth(frame), CGRectGetMinY(frame) + 0.37309 * CGRectGetHeight(frame))];
264 | [starShapePath addLineToPoint: CGPointMake(CGRectGetMinX(frame) + 0.02500 * CGRectGetWidth(frame), CGRectGetMinY(frame) + 0.39112 * CGRectGetHeight(frame))];
265 | [starShapePath addLineToPoint: CGPointMake(CGRectGetMinX(frame) + 0.30504 * CGRectGetWidth(frame), CGRectGetMinY(frame) + 0.62908 * CGRectGetHeight(frame))];
266 | [starShapePath addLineToPoint: CGPointMake(CGRectGetMinX(frame) + 0.20642 * CGRectGetWidth(frame), CGRectGetMinY(frame) + 0.97500 * CGRectGetHeight(frame))];
267 | [starShapePath addLineToPoint: CGPointMake(CGRectGetMinX(frame) + 0.50000 * CGRectGetWidth(frame), CGRectGetMinY(frame) + 0.78265 * CGRectGetHeight(frame))];
268 | [starShapePath addLineToPoint: CGPointMake(CGRectGetMinX(frame) + 0.79358 * CGRectGetWidth(frame), CGRectGetMinY(frame) + 0.97500 * CGRectGetHeight(frame))];
269 | [starShapePath addLineToPoint: CGPointMake(CGRectGetMinX(frame) + 0.69501 * CGRectGetWidth(frame), CGRectGetMinY(frame) + 0.62908 * CGRectGetHeight(frame))];
270 | [starShapePath addLineToPoint: CGPointMake(CGRectGetMinX(frame) + 0.97500 * CGRectGetWidth(frame), CGRectGetMinY(frame) + 0.39112 * CGRectGetHeight(frame))];
271 | [starShapePath addLineToPoint: CGPointMake(CGRectGetMinX(frame) + 0.62723 * CGRectGetWidth(frame), CGRectGetMinY(frame) + 0.37309 * CGRectGetHeight(frame))];
272 | [starShapePath closePath];
273 | starShapePath.miterLimit = 4;
274 |
275 | CGFloat frameWidth = frame.size.width;
276 | CGRect rightRectOfStar = CGRectMake(frame.origin.x + progress * frameWidth, frame.origin.y, frameWidth - progress * frameWidth, frame.size.height);
277 | UIBezierPath *clipPath = [UIBezierPath bezierPathWithRect:CGRectInfinite];
278 | [clipPath appendPath:[UIBezierPath bezierPathWithRect:rightRectOfStar]];
279 | clipPath.usesEvenOddFillRule = YES;
280 |
281 | [_emptyStarColor setFill];
282 | [starShapePath fill];
283 |
284 | CGContextSaveGState(UIGraphicsGetCurrentContext()); {
285 | [clipPath addClip];
286 | [tintColor setFill];
287 | [starShapePath fill];
288 | }
289 | CGContextRestoreGState(UIGraphicsGetCurrentContext());
290 |
291 | [self.starBorderColor setStroke];
292 | starShapePath.lineWidth = _starBorderWidth;
293 | [starShapePath stroke];
294 | }
295 |
296 | #pragma mark - Drawing
297 |
298 | - (void)drawRect:(CGRect)rect {
299 | CGContextRef context = UIGraphicsGetCurrentContext();
300 | CGContextSetFillColorWithColor(context, self.backgroundColor.CGColor);
301 | CGContextFillRect(context, rect);
302 |
303 | CGFloat availableWidth = rect.size.width - (_spacing * (_maximumValue - 1)) - 2;
304 | CGFloat cellWidth = (availableWidth / _maximumValue);
305 | CGFloat starSide = (cellWidth <= rect.size.height) ? cellWidth : rect.size.height;
306 | starSide = (self.shouldUseImages) ? starSide : (starSide - _starBorderWidth);
307 |
308 | for (int idx = 0; idx < _maximumValue; idx++) {
309 | CGPoint center = CGPointMake(cellWidth*idx + cellWidth/2 + _spacing*idx + 1, rect.size.height/2);
310 | CGRect frame = CGRectMake(center.x - starSide/2, center.y - starSide/2, starSide, starSide);
311 | BOOL highlighted = (idx+1 <= ceilf(_value));
312 | if (_allowsHalfStars && highlighted && (idx+1 > _value)) {
313 | if (_accurateHalfStars) {
314 | [self _drawAccurateStarWithFrame:frame tintColor:self.tintColor progress:_value - idx];
315 | }
316 | else {
317 | [self _drawHalfStarWithFrame:frame tintColor:self.tintColor];
318 | }
319 | } else {
320 | [self _drawStarWithFrame:frame tintColor:self.tintColor highlighted:highlighted];
321 | }
322 | }
323 | }
324 |
325 | - (void)_drawStarWithFrame:(CGRect)frame tintColor:(UIColor *)tintColor highlighted:(BOOL)highlighted {
326 | if (self.shouldUseImages) {
327 | [self _drawStarImageWithFrame:frame tintColor:tintColor highlighted:highlighted];
328 | } else {
329 | [self _drawStarShapeWithFrame:frame tintColor:tintColor highlighted:highlighted];
330 | }
331 | }
332 |
333 | - (void)_drawHalfStarWithFrame:(CGRect)frame tintColor:(UIColor *)tintColor {
334 | if (self.shouldUseImages) {
335 | [self _drawHalfStarImageWithFrame:frame tintColor:tintColor];
336 | } else {
337 | [self _drawHalfStarShapeWithFrame:frame tintColor:tintColor];
338 | }
339 | }
340 | - (void)_drawAccurateStarWithFrame:(CGRect)frame tintColor:(UIColor *)tintColor progress:(CGFloat)progress {
341 | if (self.shouldUseImages) {
342 | [self _drawAccurateHalfStarImageWithFrame:frame tintColor:tintColor progress:progress];
343 | } else {
344 | [self _drawAccurateHalfStarShapeWithFrame:frame tintColor:tintColor progress:progress];
345 | }
346 | }
347 | #pragma mark - Touches
348 |
349 | - (BOOL)beginTrackingWithTouch:(UITouch *)touch withEvent:(UIEvent *)event {
350 | if (self.isEnabled) {
351 | [super beginTrackingWithTouch:touch withEvent:event];
352 | if (_shouldBecomeFirstResponder && ![self isFirstResponder]) {
353 | [self becomeFirstResponder];
354 | }
355 | [self _handleTouch:touch];
356 | return YES;
357 | } else {
358 | return NO;
359 | }
360 | }
361 |
362 | - (BOOL)continueTrackingWithTouch:(UITouch *)touch withEvent:(UIEvent *)event {
363 | if (self.isEnabled) {
364 | [super continueTrackingWithTouch:touch withEvent:event];
365 | [self _handleTouch:touch];
366 | return YES;
367 | } else {
368 | return NO;
369 | }
370 | }
371 |
372 | - (void)endTrackingWithTouch:(UITouch *)touch withEvent:(UIEvent *)event {
373 | [super endTrackingWithTouch:touch withEvent:event];
374 | if (_shouldBecomeFirstResponder && [self isFirstResponder]) {
375 | [self resignFirstResponder];
376 | }
377 | [self _handleTouch:touch];
378 | if (!_continuous) {
379 | [self sendActionsForControlEvents:UIControlEventValueChanged];
380 | }
381 | }
382 |
383 | - (void)cancelTrackingWithEvent:(UIEvent *)event {
384 | [super cancelTrackingWithEvent:event];
385 | if (_shouldBecomeFirstResponder && [self isFirstResponder]) {
386 | [self resignFirstResponder];
387 | }
388 | }
389 |
390 | - (BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer {
391 | if ([gestureRecognizer.view isEqual:self]) {
392 | return !self.isUserInteractionEnabled;
393 | }
394 | return self.shouldBeginGestureRecognizerBlock ? self.shouldBeginGestureRecognizerBlock(gestureRecognizer) : NO;
395 | }
396 |
397 | - (void)_handleTouch:(UITouch *)touch {
398 | CGFloat cellWidth = self.bounds.size.width / _maximumValue;
399 | CGPoint location = [touch locationInView:self];
400 | CGFloat value = location.x / cellWidth;
401 | if (_allowsHalfStars) {
402 | if (_accurateHalfStars) {
403 | value = value;
404 | }
405 | else {
406 | if (value+.5f < ceilf(value)) {
407 | value = floor(value)+.5f;
408 | } else {
409 | value = ceilf(value);
410 | }
411 | }
412 | } else {
413 | value = ceilf(value);
414 | }
415 | [self setValue:value sendValueChangedAction:_continuous];
416 | }
417 |
418 | #pragma mark - First responder
419 |
420 | - (BOOL)canBecomeFirstResponder {
421 | return _shouldBecomeFirstResponder;
422 | }
423 |
424 | #pragma mark - Intrinsic Content Size
425 |
426 | - (CGSize)intrinsicContentSize {
427 | CGFloat height = 44.f;
428 | return CGSizeMake(_maximumValue * height + (_maximumValue-1) * _spacing, height);
429 | }
430 |
431 | #pragma mark - Accessibility
432 |
433 | - (BOOL)isAccessibilityElement {
434 | return YES;
435 | }
436 |
437 | - (NSString *)accessibilityLabel {
438 | return [super accessibilityLabel] ?: NSLocalizedString(@"Rating", @"Accessibility label for star rating control.");
439 | }
440 |
441 | - (UIAccessibilityTraits)accessibilityTraits {
442 | return ([super accessibilityTraits] | UIAccessibilityTraitAdjustable);
443 | }
444 |
445 | - (NSString *)accessibilityValue {
446 | return [@(self.value) description];
447 | }
448 |
449 | - (BOOL)accessibilityActivate {
450 | return YES;
451 | }
452 |
453 | - (void)accessibilityIncrement {
454 | CGFloat value = self.value + (self.allowsHalfStars ? .5f : 1.f);
455 | [self setValue:value sendValueChangedAction:YES];
456 | }
457 |
458 | - (void)accessibilityDecrement {
459 | CGFloat value = self.value - (self.allowsHalfStars ? .5f : 1.f);
460 | [self setValue:value sendValueChangedAction:YES];
461 | }
462 |
463 | @end
464 |
--------------------------------------------------------------------------------
/Example/SPAlertController/CustomViews/CustomView17/ScoreView.h:
--------------------------------------------------------------------------------
1 | //
2 | // ScoreView.h
3 | // SPAlertController
4 | //
5 | // Created by 乐升平 on 2018/12/24.
6 | // Copyright © 2018 乐升平. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | NS_ASSUME_NONNULL_BEGIN
12 |
13 | @interface ScoreView : UIView
14 | @property (nonatomic, copy) void(^finishButtonBlock)(void);
15 |
16 | @end
17 |
18 | NS_ASSUME_NONNULL_END
19 |
--------------------------------------------------------------------------------
/Example/SPAlertController/CustomViews/CustomView17/ScoreView.m:
--------------------------------------------------------------------------------
1 | //
2 | // ScoreView.m
3 | // SPAlertController
4 | //
5 | // Created by 乐升平 on 2018/12/24.
6 | // Copyright © 2018 乐升平. All rights reserved.
7 | //
8 |
9 | #import "ScoreView.h"
10 | #import "HCSStarRatingView.h"
11 | #import "UIColor+DarkMode.h"
12 |
13 | @interface ScoreView()
14 |
15 | @property (nonatomic, weak) HCSStarRatingView *starRatingView;
16 | @property (nonatomic, weak) UIView *line;
17 | @property (nonatomic, weak) UIButton *finishButton;
18 | @property (nonatomic, strong) NSMutableArray *subViewContraints;
19 | @end
20 |
21 | @implementation ScoreView
22 |
23 | - (instancetype)initWithFrame:(CGRect)frame {
24 | if (self = [super initWithFrame:frame]) {
25 |
26 | self.backgroundColor = [UIColor alertBackgroundColor];
27 |
28 | HCSStarRatingView *starRatingView = [[HCSStarRatingView alloc] init];
29 | starRatingView.translatesAutoresizingMaskIntoConstraints = NO;
30 | starRatingView.maximumValue = 5;
31 | starRatingView.minimumValue = 0;
32 | starRatingView.value = 2;
33 | starRatingView.spacing = 20;
34 | starRatingView.tintColor = [UIColor colorWithRed:0.0 green:0.48 blue:1.0 alpha:1.0];
35 | starRatingView.allowsHalfStars = YES;
36 | starRatingView.backgroundColor = [UIColor alertBackgroundColor];
37 | [starRatingView addTarget:self action:@selector(starRatingViewDidChangeValue:) forControlEvents:UIControlEventValueChanged];
38 | [self addSubview:starRatingView];
39 | _starRatingView = starRatingView;
40 |
41 | UIView *line = [UIView new];
42 | line.translatesAutoresizingMaskIntoConstraints = NO;
43 | line.backgroundColor = [[UIColor grayColor] colorWithAlphaComponent:0.3];
44 | [self addSubview:line];
45 | _line = line;
46 |
47 | UIButton *finishButton = [UIButton buttonWithType:UIButtonTypeCustom];
48 | finishButton.translatesAutoresizingMaskIntoConstraints = NO;
49 | finishButton.backgroundColor = [UIColor alertBackgroundColor];
50 | [finishButton setTitle:@"完成" forState:UIControlStateNormal];
51 | [finishButton setTitleColor:[UIColor colorWithRed:0.0 green:0.48 blue:1.0 alpha:1.0] forState:UIControlStateNormal];
52 | [finishButton addTarget:self action:@selector(finishButtonAction) forControlEvents:UIControlEventTouchUpInside];
53 | [self addSubview:finishButton];
54 | _finishButton = finishButton;
55 | }
56 | return self;
57 | }
58 |
59 | - (void)starRatingViewDidChangeValue:(HCSStarRatingView *)starRatingView {
60 |
61 | }
62 |
63 | - (void)finishButtonAction {
64 | if (self.finishButtonBlock) {
65 | self.finishButtonBlock();
66 | }
67 | }
68 |
69 | - (void)updateConstraints {
70 | [super updateConstraints];
71 | CGFloat lineH = 1.0/[UIScreen mainScreen].scale;
72 |
73 | HCSStarRatingView *starRatingView = self.starRatingView;
74 | UIView *line = self.line;
75 | UIButton *finishButton = self.finishButton;
76 |
77 | NSMutableArray *subViewContraints = [NSMutableArray array];
78 | if (self.subViewContraints) {
79 | [NSLayoutConstraint deactivateConstraints:self.subViewContraints];
80 | subViewContraints = nil;
81 | }
82 | [subViewContraints addObject:[NSLayoutConstraint constraintWithItem:starRatingView attribute:NSLayoutAttributeLeft relatedBy:NSLayoutRelationEqual toItem:self attribute:NSLayoutAttributeLeft multiplier:1.0f constant:40]];
83 | [subViewContraints addObject:[NSLayoutConstraint constraintWithItem:starRatingView attribute:NSLayoutAttributeRight relatedBy:NSLayoutRelationEqual toItem:self attribute:NSLayoutAttributeRight multiplier:1.0f constant:-40]];
84 | [subViewContraints addObject:[NSLayoutConstraint constraintWithItem:starRatingView attribute:NSLayoutAttributeTop relatedBy:NSLayoutRelationEqual toItem:self attribute:NSLayoutAttributeTop multiplier:1.0f constant:0]];
85 | [subViewContraints addObject:[NSLayoutConstraint constraintWithItem:starRatingView attribute:NSLayoutAttributeBottom relatedBy:NSLayoutRelationEqual toItem:line attribute:NSLayoutAttributeTop multiplier:1.0f constant:0]];
86 | [subViewContraints addObject:[NSLayoutConstraint constraintWithItem:starRatingView attribute:NSLayoutAttributeHeight relatedBy:NSLayoutRelationEqual toItem:nil attribute:NSLayoutAttributeNotAnAttribute multiplier:1.0f constant:50]];
87 |
88 | [subViewContraints addObject:[NSLayoutConstraint constraintWithItem:line attribute:NSLayoutAttributeLeft relatedBy:NSLayoutRelationEqual toItem:self attribute:NSLayoutAttributeLeft multiplier:1.0f constant:0]];
89 | [subViewContraints addObject:[NSLayoutConstraint constraintWithItem:line attribute:NSLayoutAttributeRight relatedBy:NSLayoutRelationEqual toItem:self attribute:NSLayoutAttributeRight multiplier:1.0f constant:0]];
90 | [subViewContraints addObject:[NSLayoutConstraint constraintWithItem:line attribute:NSLayoutAttributeBottom relatedBy:NSLayoutRelationEqual toItem:finishButton attribute:NSLayoutAttributeTop multiplier:1.0f constant:0]];
91 | [subViewContraints addObject:[NSLayoutConstraint constraintWithItem:line attribute:NSLayoutAttributeHeight relatedBy:NSLayoutRelationEqual toItem:nil attribute:NSLayoutAttributeNotAnAttribute multiplier:1.0f constant:lineH]];
92 |
93 | [subViewContraints addObject:[NSLayoutConstraint constraintWithItem:finishButton attribute:NSLayoutAttributeLeft relatedBy:NSLayoutRelationEqual toItem:self attribute:NSLayoutAttributeLeft multiplier:1.0f constant:0]];
94 | [subViewContraints addObject:[NSLayoutConstraint constraintWithItem:finishButton attribute:NSLayoutAttributeRight relatedBy:NSLayoutRelationEqual toItem:self attribute:NSLayoutAttributeRight multiplier:1.0f constant:0]];
95 | [subViewContraints addObject:[NSLayoutConstraint constraintWithItem:finishButton attribute:NSLayoutAttributeBottom relatedBy:NSLayoutRelationEqual toItem:self attribute:NSLayoutAttributeBottom multiplier:1.0f constant:0]];
96 | [subViewContraints addObject:[NSLayoutConstraint constraintWithItem:finishButton attribute:NSLayoutAttributeHeight relatedBy:NSLayoutRelationEqual toItem:nil attribute:NSLayoutAttributeNotAnAttribute multiplier:1.0f constant:50]];
97 | [NSLayoutConstraint activateConstraints:subViewContraints];
98 | self.subViewContraints = subViewContraints;
99 | }
100 |
101 | //- (void)layoutSubviews {
102 | // [super layoutSubviews];
103 | // CGFloat lineH = 1.0/[UIScreen mainScreen].scale;
104 | // self.starRatingView.frame = CGRectMake((self.bounds.size.width-200)/2.0, 0, 200, (self.bounds.size.height - lineH) / 2.0);
105 | // self.line.frame = CGRectMake(0, CGRectGetMaxY(self.starRatingView.frame), self.bounds.size.width, lineH);
106 | // self.finishButton.frame = CGRectMake(0, CGRectGetMaxY(self.line.frame), self.bounds.size.width, (self.bounds.size.height - lineH) / 2.0);
107 | //}
108 |
109 | @end
110 |
--------------------------------------------------------------------------------
/Example/SPAlertController/CustomViews/CustomView2/MyView.h:
--------------------------------------------------------------------------------
1 | //
2 | // MyView.h
3 | // SPAlertController
4 | //
5 | // Created by 乐升平 on 17/10/21.
6 | // Copyright © 2017年 iDress. All rights reserved.
7 | //
8 |
9 | #import
10 | #import "PassWordView.h"
11 |
12 | @interface MyView : UIView
13 |
14 | + (instancetype)shareMyView;
15 |
16 | @property (weak, nonatomic) IBOutlet PassWordView *passwordView;
17 | @property (weak, nonatomic) IBOutlet UIButton *cancelButton;
18 |
19 | @end
20 |
--------------------------------------------------------------------------------
/Example/SPAlertController/CustomViews/CustomView2/MyView.m:
--------------------------------------------------------------------------------
1 | //
2 | // MyView.m
3 | // SPAlertController
4 | //
5 | // Created by 乐升平 on 17/10/21.
6 | // Copyright © 2017年 iDress. All rights reserved.
7 | //
8 |
9 | #import "MyView.h"
10 | #import "UIColor+DarkMode.h"
11 |
12 | @interface MyView()
13 | @property (weak, nonatomic) IBOutlet UIView *topView;
14 | @property (weak, nonatomic) IBOutlet UIView *infoView;
15 |
16 | @end
17 |
18 | @implementation MyView
19 |
20 | - (instancetype)initWithCoder:(NSCoder *)aDecoder {
21 | if (self = [super initWithCoder:aDecoder]) {
22 | }
23 | return self;
24 | }
25 |
26 | - (void)awakeFromNib {
27 | [super awakeFromNib];
28 |
29 | self.backgroundColor = [UIColor colorPairsWithLightColor:[UIColor whiteColor] darkColor:[UIColor blackColor]];
30 |
31 | self.passwordView.pointColor = [UIColor colorPairsWithLightColor:[UIColor blackColor] darkColor:[UIColor whiteColor]];
32 | self.topView.backgroundColor = [UIColor alertBackgroundColor];
33 | self.infoView.backgroundColor = [UIColor alertBackgroundColor];
34 | }
35 |
36 |
37 | + (instancetype)shareMyView {
38 | return [[[NSBundle mainBundle] loadNibNamed:NSStringFromClass([self class]) owner:nil options:nil] lastObject];
39 | }
40 |
41 |
42 | @end
43 |
--------------------------------------------------------------------------------
/Example/SPAlertController/CustomViews/CustomView2/MyView.xib:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
27 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 |
110 |
111 |
112 |
113 |
114 |
115 |
116 |
117 |
118 |
119 |
120 |
121 |
122 |
123 |
124 |
125 |
126 |
127 |
128 |
129 |
130 |
131 |
132 |
133 |
134 |
135 |
136 |
137 |
138 |
139 |
140 |
141 |
142 |
143 |
144 |
145 |
146 |
147 |
148 |
149 |
150 |
151 |
152 |
153 |
154 |
155 |
156 |
157 |
158 |
159 |
160 |
--------------------------------------------------------------------------------
/Example/SPAlertController/CustomViews/CustomView2/PassWordView.h:
--------------------------------------------------------------------------------
1 | //
2 | // WCLPassWordView.h
3 | // Youqun
4 | //
5 | // Created by 乐升平 on 16/6/1.
6 | // Copyright © 2016年 iDress. All rights reserved.
7 | //
8 |
9 | #import
10 | @class PassWordView;
11 |
12 | @protocol PassWordViewDelegate
13 |
14 | @optional
15 | /**
16 | * 监听输入的改变
17 | */
18 | - (void)passWordDidChange:(PassWordView *)passWord;
19 |
20 | /**
21 | * 监听输入的完成时
22 | */
23 | - (void)passWordCompleteInput:(PassWordView *)passWord;
24 |
25 | /**
26 | * 监听开始输入
27 | */
28 | - (void)passWordBeginInput:(PassWordView *)passWord;
29 |
30 |
31 | @end
32 |
33 | IB_DESIGNABLE
34 |
35 | @interface PassWordView : UIView
36 |
37 | @property (assign, nonatomic) IBInspectable NSUInteger passWordNum;//密码的位数
38 | @property (assign, nonatomic) IBInspectable CGFloat squareWidth;//正方形的大小
39 | @property (assign, nonatomic) IBInspectable CGFloat pointRadius;//黑点的半径
40 | @property (strong, nonatomic) IBInspectable UIColor *pointColor;//黑点的颜色
41 | @property (strong, nonatomic) IBInspectable UIColor *rectColor;//边框的颜色
42 | @property (weak, nonatomic) IBOutlet id delegate;
43 | @property (strong, nonatomic, readonly) NSMutableString *textStore;//保存密码的字符串
44 |
45 | @end
46 |
47 |
--------------------------------------------------------------------------------
/Example/SPAlertController/CustomViews/CustomView2/PassWordView.m:
--------------------------------------------------------------------------------
1 | //
2 | // WCLPassWordView.m
3 | // Youqun
4 | //
5 | // Created by 乐升平 on 16/6/1.
6 | // Copyright © 2016年 iDress. All rights reserved.
7 | //
8 |
9 | #import "PassWordView.h"
10 |
11 | @interface PassWordView ()
12 |
13 | @property (strong, nonatomic) NSMutableString *textStore;// 保存密码的字符串
14 |
15 | @end
16 |
17 | @implementation PassWordView
18 |
19 | static NSString * const MONEYNUMBERS = @"0123456789";
20 |
21 | - (instancetype)initWithCoder:(NSCoder *)coder {
22 | self = [super initWithCoder:coder];
23 | if (self) {
24 | self.textStore = [NSMutableString string];
25 | self.squareWidth = 45;
26 | self.passWordNum = 6;
27 | self.pointRadius = 6;
28 | self.backgroundColor = [self colorPairsWithLightColor:[UIColor whiteColor]
29 | darkColor:[UIColor colorWithRed:44.0 / 255.0 green:44.0 / 255.0 blue:44.0 / 255.0 alpha:1.0]];
30 | self.rectColor = [self colorPairsWithLightColor:[UIColor colorWithRed:51.0/255.0 green:51.0/255.0 blue:51.0/255.0 alpha:1.0] darkColor:[UIColor redColor]];
31 | self.pointColor = [self colorPairsWithLightColor:[UIColor colorWithRed:223.0/255.0 green:223.0/255.0 blue:223.0/255.0 alpha:1.0] darkColor:[UIColor yellowColor]];
32 | [self becomeFirstResponder];
33 | }
34 | return self;
35 | }
36 |
37 | /**
38 | * 设置正方形的边长
39 | */
40 | - (void)setSquareWidth:(CGFloat)squareWidth {
41 | _squareWidth = squareWidth;
42 | [self setNeedsDisplay];
43 | }
44 |
45 | /**
46 | * 设置键盘的类型
47 | */
48 | - (UIKeyboardType)keyboardType {
49 | return UIKeyboardTypeNumberPad;
50 | }
51 |
52 | /**
53 | * 设置密码的位数
54 | */
55 | - (void)setPassWordNum:(NSUInteger)passWordNum {
56 | _passWordNum = passWordNum;
57 | [self setNeedsDisplay];
58 | }
59 |
60 | - (BOOL)becomeFirstResponder {
61 | if ([self.delegate respondsToSelector:@selector(passWordBeginInput:)]) {
62 | [self.delegate passWordBeginInput:self];
63 | }
64 | return [super becomeFirstResponder];
65 | }
66 |
67 | /**
68 | * 是否能成为第一响应者
69 | */
70 | - (BOOL)canBecomeFirstResponder {
71 | return YES;
72 | }
73 |
74 | - (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
75 | if (![self isFirstResponder]) {
76 | [self becomeFirstResponder];
77 | }
78 | }
79 |
80 | #pragma mark - UIKeyInput
81 | /**
82 | * 用于显示的文本对象是否有任何文本
83 | */
84 | - (BOOL)hasText {
85 | return self.textStore.length > 0;
86 | }
87 |
88 | /**
89 | * 插入文本
90 | */
91 | - (void)insertText:(NSString *)text {
92 | if (self.textStore.length < self.passWordNum) {
93 | //判断是否是数字
94 | NSCharacterSet *cs = [[NSCharacterSet characterSetWithCharactersInString:MONEYNUMBERS] invertedSet];
95 | NSString*filtered = [[text componentsSeparatedByCharactersInSet:cs] componentsJoinedByString:@""];
96 | BOOL basicTest = [text isEqualToString:filtered];
97 | if(basicTest) {
98 | [self.textStore appendString:text];
99 | if ([self.delegate respondsToSelector:@selector(passWordDidChange:)]) {
100 | [self.delegate passWordDidChange:self];
101 | }
102 | if (self.textStore.length == self.passWordNum) {
103 | if ([self.delegate respondsToSelector:@selector(passWordCompleteInput:)]) {
104 | [self.delegate passWordCompleteInput:self];
105 | }
106 | }
107 | [self setNeedsDisplay];
108 | }
109 | }
110 | }
111 |
112 | /**
113 | * 删除文本
114 | */
115 | - (void)deleteBackward {
116 | if (self.textStore.length > 0) {
117 | [self.textStore deleteCharactersInRange:NSMakeRange(self.textStore.length - 1, 1)];
118 | if ([self.delegate respondsToSelector:@selector(passWordDidChange:)]) {
119 | [self.delegate passWordDidChange:self];
120 | }
121 | }
122 | [self setNeedsDisplay];
123 | }
124 |
125 | // Only override drawRect: if you perform custom drawing.
126 | - (void)drawRect:(CGRect)rect {
127 | CGFloat height = rect.size.height;
128 | CGFloat width = rect.size.width;
129 | CGFloat x = (width - self.squareWidth*self.passWordNum)/2.0;
130 | CGFloat y = (height - self.squareWidth)/2.0;
131 | CGContextRef context = UIGraphicsGetCurrentContext();
132 | //画外框
133 | CGContextAddRect(context, CGRectMake( x, y, self.squareWidth * self.passWordNum, self.squareWidth));
134 | CGContextSetLineWidth(context, 1);
135 | CGContextSetStrokeColorWithColor(context, self.rectColor.CGColor);
136 | CGContextSetFillColorWithColor(context, self.backgroundColor.CGColor);
137 | //画竖条
138 | for (int i = 1; i <= self.passWordNum; i++) {
139 | CGContextMoveToPoint(context, x + i * self.squareWidth, y);
140 | CGContextAddLineToPoint(context, x + i * self.squareWidth, y + self.squareWidth);
141 | CGContextClosePath(context);
142 | }
143 | CGContextDrawPath(context, kCGPathFillStroke);
144 | CGContextSetFillColorWithColor(context, self.pointColor.CGColor);
145 | //画黑点
146 | for (int i = 1; i <= self.textStore.length; i++) {
147 | CGContextAddArc(context, x + i * self.squareWidth - self.squareWidth/2.0, y + self.squareWidth / 2, self.pointRadius, 0, M_PI * 2, YES);
148 | CGContextDrawPath(context, kCGPathFill);
149 | }
150 | }
151 |
152 | - (UIColor *)colorPairsWithLightColor:(UIColor *)lightColor darkColor:(UIColor *)darkColor {
153 | if (@available(iOS 13.0, *)) {
154 | return [UIColor colorWithDynamicProvider:^UIColor * _Nonnull(UITraitCollection * _Nonnull traitCollection) {
155 | if(traitCollection.userInterfaceStyle == UIUserInterfaceStyleDark) {
156 | return darkColor;
157 | } else {
158 | return lightColor;
159 | }
160 | }];
161 | } else {
162 | return lightColor;
163 | }
164 | }
165 |
166 | @end
167 |
168 |
--------------------------------------------------------------------------------
/Example/SPAlertController/CustomViews/CustomView3/ShoppingCartCell.h:
--------------------------------------------------------------------------------
1 | //
2 | // ShoppingCartCell.h
3 | // SPAlertController
4 | //
5 | // Created by 乐升平 on 17/10/21.
6 | // Copyright © 2017年 iDress. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @class ShoppingCartItem;
12 |
13 | @interface ShoppingCartCell : UITableViewCell
14 | @property (nonatomic, strong) ShoppingCartItem *item;
15 | @end
16 |
17 |
--------------------------------------------------------------------------------
/Example/SPAlertController/CustomViews/CustomView3/ShoppingCartCell.m:
--------------------------------------------------------------------------------
1 | //
2 | // ShoppingCartCell.m
3 | // SPAlertController
4 | //
5 | // Created by 乐升平 on 17/10/21.
6 | // Copyright © 2017年 iDress. All rights reserved.
7 | //
8 |
9 | #import "ShoppingCartCell.h"
10 | #import "ShoppingCartItem.h"
11 |
12 | @interface ShoppingCartCell()
13 | @property (weak, nonatomic) IBOutlet UILabel *foodNmaeLabel;
14 | @property (weak, nonatomic) IBOutlet UILabel *priceLabel;
15 | @property (weak, nonatomic) IBOutlet UILabel *countLabel;
16 |
17 | @end
18 |
19 | @implementation ShoppingCartCell
20 |
21 | - (void)awakeFromNib {
22 | [super awakeFromNib];
23 | // Initialization code
24 |
25 | }
26 |
27 | - (void)setItem:(ShoppingCartItem *)item {
28 | _item = item;
29 | self.foodNmaeLabel.text = item.foodName;
30 | self.priceLabel.text = [self finallyFoodPrice:item.price];
31 | }
32 |
33 | - (IBAction)reduce:(UIButton *)sender {
34 | NSInteger i = [self.countLabel.text integerValue];
35 | i--;
36 | if (i < 1) {
37 | i = 1;
38 | } else {
39 | self.item.price = self.item.price - self.item.price / (i+1);
40 | }
41 | self.countLabel.text = [NSString stringWithFormat:@"%zd",i];
42 | self.priceLabel.text = [self finallyFoodPrice:self.item.price];
43 |
44 | }
45 |
46 | - (IBAction)add:(UIButton *)sender {
47 | NSInteger i = [self.countLabel.text integerValue];
48 | i++;
49 | self.item.price = self.item.price + self.item.price / (i-1);
50 | self.countLabel.text = [NSString stringWithFormat:@"%zd",i];
51 | self.priceLabel.text = [self finallyFoodPrice:self.item.price];
52 | }
53 |
54 | - (void)setSelected:(BOOL)selected animated:(BOOL)animated {
55 | [super setSelected:selected animated:animated];
56 |
57 | // Configure the view for the selected state
58 | }
59 |
60 | // 最终的价格
61 | - (NSString *)finallyFoodPrice:(float)price {
62 |
63 | // 新价格保留maxDecimalPlaces为位小数转成字符串
64 | NSString *priceString = [NSString stringWithFormat:@"%.5f",price];
65 | // 通过小数点进行分割,然后取小数部分
66 | NSArray *parts = [priceString componentsSeparatedByString:@"."];
67 | if (parts.count > 1) {
68 | // 取小数部分
69 | NSString *dot = parts[1];
70 |
71 | if ([dot hasSuffix:@"00000"]) {
72 | return [NSString stringWithFormat:@"¥%.0f",price];
73 | } else if ([dot hasSuffix:@"0000"]) {
74 | return [NSString stringWithFormat:@"¥%.1f",price];
75 | } else if ([dot hasSuffix:@"000"]) {
76 | return [NSString stringWithFormat:@"¥%.2f",price];
77 | } else if ([dot hasSuffix:@"00"]) {
78 | return [NSString stringWithFormat:@"¥%.3f",price];
79 | } else if ([dot hasSuffix:@"0"]) {
80 | return [NSString stringWithFormat:@"¥%.4f",price];
81 | } else {
82 | return priceString;
83 | }
84 | }
85 | return nil;
86 | }
87 |
88 |
89 | @end
90 |
--------------------------------------------------------------------------------
/Example/SPAlertController/CustomViews/CustomView3/ShoppingCartCell.xib:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
35 |
44 |
51 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
83 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 |
110 |
111 |
112 |
113 |
114 |
115 |
116 |
117 |
--------------------------------------------------------------------------------
/Example/SPAlertController/CustomViews/CustomView3/ShoppingCartItem.h:
--------------------------------------------------------------------------------
1 | //
2 | // ShoppingCartItem.h
3 | // SPAlertController
4 | //
5 | // Created by 乐升平 on 17/10/21.
6 | // Copyright © 2017年 iDress. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @interface ShoppingCartItem : NSObject
12 | @property (nonatomic, copy) NSString *foodName;
13 | @property (nonatomic, assign) double price;
14 | @end
15 |
--------------------------------------------------------------------------------
/Example/SPAlertController/CustomViews/CustomView3/ShoppingCartItem.m:
--------------------------------------------------------------------------------
1 | //
2 | // ShoppingCartItem.m
3 | // SPAlertController
4 | //
5 | // Created by 乐升平 on 17/10/21.
6 | // Copyright © 2017年 iDress. All rights reserved.
7 | //
8 |
9 | #import "ShoppingCartItem.h"
10 |
11 | @implementation ShoppingCartItem
12 |
13 | @end
14 |
--------------------------------------------------------------------------------
/Example/SPAlertController/CustomViews/CustomView3/ShoppingCartView.h:
--------------------------------------------------------------------------------
1 | //
2 | // ShoppingCartView.h
3 | // SPAlertController
4 | //
5 | // Created by 乐升平 on 17/10/21.
6 | // Copyright © 2017年 iDress. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @interface ShoppingCartView : UIView
12 |
13 | @end
14 |
--------------------------------------------------------------------------------
/Example/SPAlertController/CustomViews/CustomView3/ShoppingCartView.m:
--------------------------------------------------------------------------------
1 | //
2 | // ShoppingCartView.m
3 | // SPAlertController
4 | //
5 | // Created by 乐升平 on 17/10/21.
6 | // Copyright © 2017年 iDress. All rights reserved.
7 | //
8 |
9 | #import "ShoppingCartView.h"
10 | #import "ShoppingCartCell.h"
11 | #import "ShoppingCartItem.h"
12 | #import "UIColor+DarkMode.h"
13 |
14 | @interface ShoppingCartView()
15 | @property (nonatomic, strong) UITableView *tableView;
16 | @property (nonatomic, strong) NSMutableArray *dataSource;
17 | @property (nonatomic, strong) UILabel *topLabel;
18 | @end
19 |
20 | @implementation ShoppingCartView
21 |
22 | - (instancetype)initWithFrame:(CGRect)frame {
23 | if (self = [super initWithFrame:frame]) {
24 |
25 | [self initialize];
26 |
27 | }
28 | return self;
29 | }
30 |
31 | - (instancetype)initWithCoder:(NSCoder *)aDecoder {
32 | if (self = [super initWithCoder:aDecoder]) {
33 | [self initialize];
34 | }
35 | return self;
36 | }
37 |
38 | - (void)initialize {
39 |
40 | self.backgroundColor = [UIColor colorPairsWithLightColor:[UIColor colorWithRed:244.0 / 255.0 green:244.0 / 255.0 blue:244.0 / 255.0 alpha:1.0]
41 | darkColor:[UIColor colorWithRed:44.0 / 255.0 green:44.0 / 255.0 blue:44.0 / 255.0 alpha:1.0]];
42 |
43 | [self addSubview:self.topLabel];
44 | [self addSubview:self.tableView];
45 |
46 | NSArray *dataArr = [self getData];
47 |
48 | for (int i = 0; i < dataArr.count; i++) {
49 | ShoppingCartItem *item = [[ShoppingCartItem alloc] init];
50 | [item setValuesForKeysWithDictionary:dataArr[i]];
51 | [self.dataSource addObject:item];
52 | }
53 | }
54 |
55 | - (void)hideTopView {
56 |
57 | }
58 |
59 | - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
60 | return self.dataSource.count;
61 | }
62 |
63 | - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
64 |
65 | ShoppingCartCell *cell = [tableView dequeueReusableCellWithIdentifier:@"shoppingCartCell" forIndexPath:indexPath];
66 | cell.item = self.dataSource[indexPath.row];
67 | return cell;
68 |
69 | }
70 |
71 | - (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
72 | return 50;
73 | }
74 |
75 | - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
76 | [tableView deselectRowAtIndexPath:indexPath animated:NO];
77 | NSLog(@"----点到了cell");
78 | }
79 |
80 | - (UITableView *)tableView {
81 | if (!_tableView) {
82 | _tableView = [[UITableView alloc] initWithFrame:CGRectZero style:UITableViewStylePlain];
83 | _tableView.dataSource = self;
84 | _tableView.delegate = self;
85 | _tableView.showsVerticalScrollIndicator = NO;
86 | [_tableView registerNib:[UINib nibWithNibName:NSStringFromClass([ShoppingCartCell class]) bundle:nil] forCellReuseIdentifier:@"shoppingCartCell"];
87 | }
88 | return _tableView;
89 | }
90 |
91 | - (UILabel *)topLabel {
92 | if (!_topLabel) {
93 | _topLabel = [[UILabel alloc] init];
94 | _topLabel.textAlignment = NSTextAlignmentCenter;
95 | _topLabel.text = @"购物车";
96 | }
97 | return _topLabel;
98 | }
99 |
100 | - (NSMutableArray *)dataSource {
101 |
102 | if (!_dataSource) {
103 | _dataSource = [NSMutableArray array];
104 | }
105 | return _dataSource;
106 | }
107 |
108 | - (void)layoutSubviews {
109 | [super layoutSubviews];
110 |
111 | CGFloat topLabelY = 0.;
112 | if (@available(iOS 11.0, *)) {
113 | topLabelY = self.safeAreaInsets.top;
114 | } else {
115 | topLabelY = 20;
116 | }
117 | self.topLabel.frame = CGRectMake(0, topLabelY, self.bounds.size.width, 44);
118 | CGFloat tableViewY = CGRectGetMaxY(self.topLabel.frame);
119 | self.tableView.frame = CGRectMake(0, tableViewY, self.frame.size.width, self.frame.size.height-tableViewY);
120 |
121 | }
122 |
123 | - (NSArray *)getData {
124 | NSArray *dataArr = @[@{
125 | @"foodName":@"鱼香肉丝",
126 | @"price":@(21.5),
127 | },
128 | @{
129 | @"foodName":@"辣椒炒肉",
130 | @"price":@(18),
131 | },
132 | @{
133 | @"foodName":@"梅干菜",
134 | @"price":@(20.1),
135 | },
136 | @{
137 | @"foodName":@"西红柿蛋汤",
138 | @"price":@(12.306),
139 | },
140 | @{
141 | @"foodName":@"红烧鲫鱼",
142 | @"price":@(35.8),
143 | },
144 | @{
145 | @"foodName":@"啤酒鸭",
146 | @"price":@(29),
147 | },
148 | @{
149 | @"foodName":@"宫爆鸡丁",
150 | @"price":@(28),
151 | },
152 | @{
153 | @"foodName":@"湖南一碗香",
154 | @"price":@(37.5),
155 | },
156 | @{
157 | @"foodName":@"鸡汤",
158 | @"price":@(16),
159 | },
160 | @{
161 | @"foodName":@"鸽子汤",
162 | @"price":@(18.5),
163 | },
164 | @{
165 | @"foodName":@"王老吉",
166 | @"price":@(8),
167 | },
168 | @{
169 | @"foodName":@"米饭",
170 | @"price":@(2),
171 | },
172 | ];
173 |
174 | return dataArr;
175 | }
176 |
177 | @end
178 |
179 |
180 |
181 |
--------------------------------------------------------------------------------
/Example/SPAlertController/CustomViews/CustomView4/CommodityListView.h:
--------------------------------------------------------------------------------
1 | //
2 | // CommodityListView.h
3 | // SPAlertController
4 | //
5 | // Created by 乐升平 on 17/10/22.
6 | // Copyright © 2017年 iDress. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @interface CommodityListView : UIView
12 |
13 | @end
14 |
--------------------------------------------------------------------------------
/Example/SPAlertController/CustomViews/CustomView4/CommodityListView.m:
--------------------------------------------------------------------------------
1 | //
2 | // CommodityListView.m
3 | // SPAlertController
4 | //
5 | // Created by 乐升平 on 17/10/22.
6 | // Copyright © 2017年 iDress. All rights reserved.
7 | //
8 |
9 | #import "CommodityListView.h"
10 | #import "UIColor+DarkMode.h"
11 |
12 | @interface CommodityListView()
13 | @property (nonatomic, weak) UIScrollView *scrollView;
14 | @property (nonatomic, strong) NSMutableArray *imageViews;
15 | @end
16 |
17 | @implementation CommodityListView
18 |
19 | - (instancetype)initWithFrame:(CGRect)frame {
20 | if (self = [super initWithFrame:frame]) {
21 | [self initialize];
22 | }
23 | return self;
24 | }
25 |
26 | - (instancetype)initWithCoder:(NSCoder *)aDecoder {
27 | if (self = [super initWithCoder:aDecoder]) {
28 | [self initialize];
29 | }
30 | return self;
31 | }
32 |
33 | - (void)initialize {
34 |
35 | self.backgroundColor = [UIColor alertBackgroundColor];
36 |
37 | NSArray *images = @[@"image0.jpg",@"image1.jpg",@"image2.jpg",@"image3.jpg",@"image4.jpg",@"image5.jpg",@"image6.jpg",@"image7.jpg",@"image8.jpg",@"image9.jpg"];
38 |
39 | UIScrollView *scrollView = [[UIScrollView alloc] init];
40 | scrollView.backgroundColor = [UIColor alertBackgroundColor];
41 | scrollView.showsVerticalScrollIndicator = NO;
42 | [self addSubview:scrollView];
43 | _scrollView = scrollView;
44 |
45 | for (int i = 0; i < images.count; i++) {
46 | UIImageView *imageView = [[UIImageView alloc] init];
47 | imageView.image = [UIImage imageNamed:images[i]];
48 | imageView.backgroundColor = [UIColor redColor];
49 | [scrollView addSubview:imageView];
50 | [self.imageViews addObject:imageView];
51 | }
52 | }
53 |
54 | - (NSMutableArray *)imageViews {
55 |
56 | if (!_imageViews) {
57 | _imageViews = [NSMutableArray array];
58 |
59 | }
60 | return _imageViews;
61 | }
62 |
63 |
64 | - (void)layoutSubviews {
65 | [super layoutSubviews];
66 | self.scrollView.frame = self.bounds;
67 |
68 | CGFloat imageViewW = self.bounds.size.width/2-20;
69 | CGFloat imageViewH = self.bounds.size.height;
70 | CGFloat imageViewY = 0;
71 | if (@available(iOS 11.0, *)) {
72 | imageViewY = self.safeAreaInsets.top;
73 | }
74 | UIImageView *lastImageView;
75 | for (int i = 0; i < self.imageViews.count; i++) {
76 | UIImageView *imageView = self.imageViews[i];
77 | imageView.frame = CGRectMake((imageViewW +10) * i, imageViewY, imageViewW, imageViewH);
78 | if (i == self.imageViews.count-1) {
79 | lastImageView = imageView;
80 | }
81 | }
82 | self.scrollView.contentSize = CGSizeMake(CGRectGetMaxX(lastImageView.frame), 0);
83 | }
84 |
85 | @end
86 |
--------------------------------------------------------------------------------
/Example/SPAlertController/CustomViews/CustomView5/PickerView.h:
--------------------------------------------------------------------------------
1 | //
2 | // PickerView.h
3 | // SPAlertController
4 | //
5 | // Created by Libo on 2017/11/15.
6 | // Copyright © 2017年 iDress. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @interface PickerView : UIView
12 |
13 | @property (nonatomic, copy) void(^cancelClickedBlock)(void);
14 | @property (nonatomic, copy) void(^doneClickedBlock)(void);
15 |
16 | @end
17 |
--------------------------------------------------------------------------------
/Example/SPAlertController/CustomViews/CustomView5/PickerView.m:
--------------------------------------------------------------------------------
1 | //
2 | // MyTitleView.m
3 | // SPAlertController
4 | //
5 | // Created by Libo on 2017/11/5.
6 | // Copyright © 2017年 iDress. All rights reserved.
7 | //
8 |
9 | #import "PickerView.h"
10 | #import "UIColor+DarkMode.h"
11 |
12 | @interface PickerView()
13 |
14 | @property (nonatomic, strong) UIPickerView *pickerView;
15 | @property (nonatomic, strong) UIToolbar *toolbar;
16 |
17 | @end
18 |
19 | @implementation PickerView
20 |
21 | - (instancetype)initWithFrame:(CGRect)frame {
22 | if (self = [super initWithFrame:frame]) {
23 | [self initialize];
24 | }
25 | return self;
26 | }
27 |
28 | - (instancetype)initWithCoder:(NSCoder *)aDecoder {
29 | if (self = [super initWithCoder:aDecoder]) {
30 | [self initialize];
31 | }
32 | return self;
33 | }
34 |
35 | - (void)initialize {
36 | [self addSubview:self.toolbar];
37 | [self addSubview:self.pickerView];
38 | }
39 |
40 | - (void)doneClick {
41 | if (self.doneClickedBlock) {
42 | self.doneClickedBlock();
43 | }
44 | }
45 |
46 | - (void)cancelClick {
47 | if (self.cancelClickedBlock) {
48 | self.cancelClickedBlock();
49 | }
50 | }
51 |
52 | - (NSInteger)numberOfComponentsInPickerView:(UIPickerView *)pickerView {
53 | return 1;
54 | }
55 |
56 | - (NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component {
57 | return 2;
58 | }
59 |
60 | - (NSString *)pickerView:(UIPickerView *)pickerView titleForRow:(NSInteger)row forComponent:(NSInteger)component {
61 | return @[@"男",@"女"][row];
62 | }
63 |
64 | - (UIView *)pickerView:(UIPickerView *)pickerView viewForRow:(NSInteger)row forComponent:(NSInteger)component reusingView:(UIView *)view {
65 | UILabel *pickerLabel = (UILabel *)view;
66 | if (!pickerLabel) {
67 | pickerLabel = [[UILabel alloc] init];
68 | pickerLabel.adjustsFontSizeToFitWidth = YES;
69 | pickerLabel.textAlignment = NSTextAlignmentCenter;
70 | [pickerLabel setFont:[UIFont boldSystemFontOfSize:18]];
71 | }
72 | pickerLabel.text = [self pickerView:pickerView titleForRow:row forComponent:component];
73 | return pickerLabel;
74 | }
75 |
76 | - (CGFloat)pickerView:(UIPickerView *)pickerView rowHeightForComponent:(NSInteger)component {
77 | return 50;
78 | }
79 |
80 | - (UIPickerView *)pickerView {
81 | if (!_pickerView) {
82 | _pickerView = [[UIPickerView alloc] init];
83 | _pickerView.delegate = self;
84 | _pickerView.dataSource = self;
85 | _pickerView.backgroundColor = [UIColor colorPairsWithLightColor:[UIColor colorWithRed:239.0 / 255.0 green:239.0 / 255.0 blue:239.0 / 255.0 alpha:1.0] darkColor:[UIColor colorWithRed:44.0 / 255.0 green:44.0 / 255.0 blue:44.0 / 255.0 alpha:1.0]];
86 | }
87 | return _pickerView;
88 | }
89 |
90 | - (UIToolbar *)toolbar {
91 |
92 | if (!_toolbar) {
93 | UIBarButtonItem *doneBBI = [[UIBarButtonItem alloc]
94 | initWithTitle:@"确定"
95 | style:UIBarButtonItemStyleDone
96 | target:self
97 | action:@selector(doneClick)];
98 |
99 | UIBarButtonItem *cancelBBI = [[UIBarButtonItem alloc] initWithTitle:@"取消" style:UIBarButtonItemStylePlain target:self action:@selector(cancelClick)];
100 | UIBarButtonItem *flexibleBBI = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace target:nil action:nil];
101 | _toolbar = [[UIToolbar alloc] init];
102 | // 设置tollbar的背景色
103 | _toolbar.barTintColor = [UIColor alertBackgroundColor];
104 | NSArray *toolbarItems = [NSArray arrayWithObjects:cancelBBI, flexibleBBI, doneBBI, nil];
105 | [_toolbar setItems:toolbarItems];
106 | }
107 | return _toolbar;
108 | }
109 |
110 | - (void)layoutSubviews {
111 | [super layoutSubviews];
112 | self.toolbar.frame = CGRectMake(0, 0, self.bounds.size.width, 40);
113 | self.pickerView.frame = CGRectMake(0, CGRectGetMaxY(self.toolbar.frame), self.bounds.size.width, self.bounds.size.height-40);
114 | }
115 |
116 | @end
117 |
118 |
119 |
120 |
121 |
--------------------------------------------------------------------------------
/Example/SPAlertController/CustomViews/CustomView6/MyCenterView.h:
--------------------------------------------------------------------------------
1 | //
2 | // MyCenterView.h
3 | // SPAlertController
4 | //
5 | // Created by Libo on 2017/11/5.
6 | // Copyright © 2017年 iDress. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @interface MyCenterView : UIView
12 |
13 | @end
14 |
--------------------------------------------------------------------------------
/Example/SPAlertController/CustomViews/CustomView6/MyCenterView.m:
--------------------------------------------------------------------------------
1 | //
2 | // MyCenterView.m
3 | // SPAlertController
4 | //
5 | // Created by Libo on 2017/11/5.
6 | // Copyright © 2017年 iDress. All rights reserved.
7 | //
8 |
9 | #import "MyCenterView.h"
10 |
11 | @interface MyCenterView()
12 | @property (nonatomic, strong) UITableView *tableView;
13 |
14 | @end
15 |
16 | @implementation MyCenterView
17 |
18 | - (instancetype)initWithFrame:(CGRect)frame {
19 | if (self = [super initWithFrame:frame]) {
20 | [self initialize];
21 | }
22 | return self;
23 | }
24 |
25 | - (instancetype)initWithCoder:(NSCoder *)aDecoder {
26 | if (self = [super initWithCoder:aDecoder]) {
27 | [self initialize];
28 | }
29 | return self;
30 | }
31 |
32 | - (void)initialize {
33 | [self addSubview:self.tableView];
34 | }
35 |
36 | - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
37 | return 10;
38 | }
39 |
40 | - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
41 | UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"myCell"];
42 | if (cell == nil) {
43 | cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:@"myCell"];
44 | }
45 | cell.textLabel.text = [NSString stringWithFormat:@"第%zd行",indexPath.row];
46 | cell.textLabel.font = [UIFont systemFontOfSize:14];
47 | cell.detailTextLabel.text = @"这是自定义tableView";
48 | cell.detailTextLabel.font = [UIFont systemFontOfSize:12];
49 | return cell;
50 | }
51 |
52 | - (UITableView *)tableView {
53 |
54 | if (!_tableView) {
55 | _tableView = [[UITableView alloc] initWithFrame:CGRectZero style:UITableViewStylePlain];
56 | _tableView.dataSource = self;
57 | _tableView.delegate = self;
58 | }
59 | return _tableView;
60 | }
61 |
62 | - (void)layoutSubviews {
63 | [super layoutSubviews];
64 | self.tableView.frame = self.bounds;
65 | }
66 |
67 |
68 | @end
69 |
--------------------------------------------------------------------------------
/Example/SPAlertController/CustomViews/CustomView7/PopView.h:
--------------------------------------------------------------------------------
1 | //
2 | // PopView.h
3 | // SPAlertController
4 | //
5 | // Created by Libo on 2018/12/23.
6 | // Copyright © 2018 乐升平. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | NS_ASSUME_NONNULL_BEGIN
12 |
13 | @interface PopView : UIView
14 |
15 | - (instancetype)initWithImages:(NSArray *)images
16 | titles:(NSArray *)titles
17 | clickedButtonBlock:(void(^)(NSInteger index))clickedButtonBlock
18 | cancelBlock:(void(^)(PopView *popView))cancelBlock;
19 |
20 | @property (nonatomic, copy) void(^tapBackgroundBlock)(PopView *popView);
21 |
22 | - (void)open;
23 |
24 | - (void)close;
25 |
26 | @end
27 |
28 | NS_ASSUME_NONNULL_END
29 |
--------------------------------------------------------------------------------
/Example/SPAlertController/CustomViews/CustomView7/PopView.m:
--------------------------------------------------------------------------------
1 | //
2 | // PopView.m
3 | // SPAlertController
4 | //
5 | // Created by Libo on 2018/12/23.
6 | // Copyright © 2018 乐升平. All rights reserved.
7 | //
8 |
9 | #import "PopView.h"
10 | #import "SPButton.h" // SPButton的github地址:https://github.com/SPStore/SPButton
11 |
12 | static NSInteger const kColumnCount = 4; // 每一页的列数
13 | static NSInteger const kRowCount = 2; // 每一页的行数
14 | static CGFloat const kColSpacing = 15; // 列间距
15 | static CGFloat const kRowSpacing = 20; // 行间距
16 | static NSTimeInterval kAnimationDuration = 0.7; // 动画总时长
17 | static NSTimeInterval kDelay = 0.0618; // 按钮接着上一个按钮的延时时间
18 |
19 | @interface PopView()
20 | @property (nonatomic, strong) UIScrollView *scrollView;
21 | @property (nonatomic, strong) UIPageControl *pageControl;
22 | @property (nonatomic, strong) UIButton *cancelButton;
23 | @property (nonatomic, strong) UIView *line;
24 | @property (nonatomic, copy) void (^clickedButtonBlock)(NSInteger);
25 | @property (nonatomic, copy) void (^cancelBlock)(PopView *popView);
26 | @end
27 |
28 | @implementation PopView
29 | {
30 | NSInteger buttonCount;
31 | }
32 |
33 | - (instancetype)initWithImages:(NSArray *)images
34 | titles:(NSArray *)titles
35 | clickedButtonBlock:(void (^)(NSInteger))clickedButtonBlock
36 | cancelBlock:(void (^)(PopView *popView))cancelBlock {
37 |
38 | _clickedButtonBlock = clickedButtonBlock;
39 | _cancelBlock = cancelBlock;
40 |
41 | UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(tapAction)];
42 | [self addGestureRecognizer:tap];
43 |
44 | CGFloat screenWidth = [UIScreen mainScreen].bounds.size.width;
45 | CGFloat screenHeight = [UIScreen mainScreen].bounds.size.height;
46 |
47 | if (self = [self initWithFrame:CGRectMake(0, 0, screenWidth, screenHeight)]) {
48 | buttonCount = MIN(images.count, titles.count);
49 | for (int i = 0; i < buttonCount; i++) {
50 | SPButton *button = [[SPButton alloc] initWithImagePosition:SPButtonImagePositionTop];
51 | [button setImage:[UIImage imageNamed:images[i]] forState:UIControlStateNormal];
52 | [button setTitle:titles[i] forState:UIControlStateNormal];
53 | button.titleLabel.font = [UIFont systemFontOfSize:14];
54 | [button setTitleColor:[UIColor grayColor] forState:UIControlStateNormal];
55 | button.imageView.contentMode = UIViewContentModeScaleAspectFit;
56 | button.imageTitleSpace = 5;
57 | [button addTarget:self action:@selector(buttonAction:) forControlEvents:UIControlEventTouchUpInside];
58 | button.tag = i+100;
59 | [self.scrollView addSubview:button];
60 | }
61 | }
62 | return self;
63 | }
64 |
65 | - (instancetype)initWithFrame:(CGRect)frame {
66 | if (self = [super initWithFrame:frame]) {
67 |
68 | }
69 | return self;
70 | }
71 |
72 | - (void)open {
73 |
74 | for (int i = 0; i < buttonCount; i++) {
75 | SPButton *button = [self.scrollView viewWithTag:i + 100];
76 | CGFloat buttonH = button.bounds.size.height;
77 | CGFloat totalH = (buttonH * kRowCount + kRowSpacing * (kRowCount - 1));
78 | CGFloat buttonEndY = button.frame.origin.y - totalH - buttonH;
79 | // delay参数计算出来的意思是:每一列比它的上一列延时kDelay秒
80 | [UIView animateWithDuration:kAnimationDuration
81 | delay:i % kColumnCount * kDelay
82 | usingSpringWithDamping:0.6
83 | initialSpringVelocity:0
84 | options:UIViewAnimationOptionCurveEaseIn animations:^{
85 | CGRect buttonFrame = button.frame;
86 | buttonFrame.origin.y = buttonEndY;
87 | button.frame = buttonFrame;
88 | } completion:^(BOOL finished) {
89 | }];
90 | }
91 | }
92 |
93 | - (void)close {
94 | for (int i = 0; i < buttonCount; i++) {
95 | SPButton *button = [self.scrollView viewWithTag:i+100];
96 | CGFloat buttonH = button.bounds.size.height;
97 | CGFloat totalH = (buttonH * kRowCount + kRowSpacing * (kRowCount - 1));
98 | CGFloat buttonBeginY = button.frame.origin.y + buttonH + totalH;
99 |
100 | // delay参数计算出来的意思是:第一行每个按钮都比第二行的每个按钮延时0.1秒,同时每列比它的下一列延时kDelay秒
101 | [UIView animateWithDuration:kAnimationDuration
102 | delay:(1 - i / kColumnCount) / 10.0 + (kDelay * kColumnCount - i % kColumnCount * kDelay - kDelay)
103 | usingSpringWithDamping:0.6
104 | initialSpringVelocity:0
105 | options:UIViewAnimationOptionCurveEaseOut animations:^{
106 | CGRect buttonFrame = button.frame;
107 | buttonFrame.origin.y = buttonBeginY;
108 | button.frame = buttonFrame;
109 | } completion:^(BOOL finished) {
110 | [self removeFromSuperview];
111 | }];
112 | }
113 | }
114 |
115 | - (void)buttonAction:(UIButton *)sender {
116 | if (self.clickedButtonBlock) {
117 | self.clickedButtonBlock(sender.tag-100);
118 | }
119 | }
120 |
121 | - (void)tapAction {
122 | if (self.tapBackgroundBlock) {
123 | self.tapBackgroundBlock(self);
124 | }
125 | }
126 |
127 | - (void)cancelButtonAction {
128 | if (self.cancelBlock) {
129 | self.cancelBlock(self);
130 | }
131 | }
132 |
133 | - (void)scrollViewDidScroll:(UIScrollView *)scrollView {
134 | CGFloat offsetX = scrollView.contentOffset.x;
135 | self.pageControl.currentPage = (NSInteger)(offsetX / self.bounds.size.width + 0.5);
136 | }
137 |
138 | - (void)layoutSubviews {
139 | [super layoutSubviews];
140 |
141 | CGFloat bottom = 0;
142 | if (@available(iOS 11.0, *)) {
143 | bottom = self.safeAreaInsets.bottom;
144 | }
145 |
146 | CGFloat superWidth = self.frame.size.width;
147 | CGFloat superHeight = self.frame.size.height;
148 |
149 | CGFloat cancelButtonW = superWidth;
150 | CGFloat cancelButtonH = 40;
151 | CGFloat cancelButtonX = 0;
152 | CGFloat cancelButtonY = superHeight-cancelButtonH-bottom;
153 | self.cancelButton.frame = CGRectMake(cancelButtonX, cancelButtonY, cancelButtonW, cancelButtonH);
154 |
155 | CGFloat lineW = superWidth;
156 | CGFloat lineH = 1.0/[UIScreen mainScreen].scale;
157 | CGFloat lineX = 0;
158 | CGFloat lineY = superHeight-cancelButtonH-lineH-bottom;
159 | self.line.frame = CGRectMake(lineX, lineY, lineW, lineH);
160 |
161 | CGFloat scrollViewH = superHeight-cancelButtonH-lineH-bottom;
162 | self.scrollView.frame = CGRectMake(0, 0, superWidth, scrollViewH);
163 | self.pageControl.frame = CGRectMake(0, superHeight-cancelButtonH-lineH-bottom-30, superWidth, 30);
164 |
165 | // 先计算好每个按钮的动画前的frame,等执行动画的时候只要改变y值即可
166 | NSInteger buttonCountEveryPage = kColumnCount * kRowCount; // 每一页的按钮个数
167 | NSInteger pageCount = (buttonCount-1) / buttonCountEveryPage + 1; // 总页数
168 | self.pageControl.numberOfPages = pageCount;
169 |
170 | for (int i = 0; i < buttonCount; i++) {
171 | SPButton *button = [self.scrollView viewWithTag:i+100];
172 | NSInteger page = i / buttonCountEveryPage; // 第几页
173 | NSInteger row = (i - buttonCountEveryPage * page) / kColumnCount; // 第几页的第几行
174 | NSInteger col = i % kColumnCount; // 第几列
175 | CGFloat buttonW = (superWidth - kColSpacing * (kColumnCount + 1)) / kColumnCount;
176 | CGFloat buttonH = MIN(buttonW, button.currentImage.size.width)+30;
177 | CGFloat buttonX = kColSpacing + (buttonW + kColSpacing) * col + page * superWidth;
178 | CGFloat buttonBeginY = scrollViewH + (buttonH + kRowSpacing) * row;
179 | button.frame = CGRectMake(buttonX, buttonBeginY, buttonW, buttonH);
180 | }
181 | self.scrollView.contentSize = CGSizeMake(superWidth * pageCount, 0);
182 | }
183 |
184 | - (UIScrollView *)scrollView {
185 |
186 | if (!_scrollView) {
187 | _scrollView = [[UIScrollView alloc] init];
188 | _scrollView.showsVerticalScrollIndicator = NO;
189 | _scrollView.showsHorizontalScrollIndicator = NO;
190 | _scrollView.scrollsToTop = NO;
191 | _scrollView.bounces = NO;
192 | _scrollView.pagingEnabled = YES;
193 | _scrollView.delegate = self;
194 | [self addSubview:_scrollView];
195 | }
196 | return _scrollView;
197 | }
198 |
199 | - (UIPageControl *)pageControl {
200 | if (!_pageControl) {
201 | _pageControl = [[UIPageControl alloc] init];
202 | _pageControl.currentPageIndicatorTintColor = [UIColor orangeColor];
203 | _pageControl.pageIndicatorTintColor = [UIColor lightGrayColor];
204 | [self addSubview:_pageControl];
205 | }
206 | return _pageControl;
207 | }
208 |
209 | - (UIButton *)cancelButton {
210 |
211 | if (!_cancelButton) {
212 | _cancelButton = [UIButton buttonWithType:UIButtonTypeCustom];
213 | _cancelButton.backgroundColor = [UIColor clearColor];
214 | [_cancelButton setImage:[UIImage imageNamed:@"取消"] forState:UIControlStateNormal];
215 | [_cancelButton addTarget:self action:@selector(cancelButtonAction) forControlEvents:UIControlEventTouchUpInside];
216 | [self addSubview:_cancelButton];
217 | }
218 | return _cancelButton;
219 | }
220 |
221 | - (UIView *)line {
222 |
223 | if (!_line) {
224 | _line = [[UIView alloc] init];
225 | _line.backgroundColor = [[UIColor lightGrayColor] colorWithAlphaComponent:0.3];
226 | [self addSubview:_line];
227 | }
228 | return _line;
229 | }
230 |
231 | @end
232 |
--------------------------------------------------------------------------------
/Example/SPAlertController/CustomViews/CustomView7/SPButton.h:
--------------------------------------------------------------------------------
1 | //
2 | // SPButton.h
3 | // SPButton
4 | //
5 | // Created by 乐升平 on 2018/11/20.
6 | // Copyright © 2018 乐升平. All rights reserved.
7 | // github:https://github.com/SPStore/SPButton
8 |
9 | #import
10 |
11 | NS_ASSUME_NONNULL_BEGIN
12 |
13 |
14 | typedef NS_ENUM(NSInteger, SPButtonImagePosition) {
15 | SPButtonImagePositionLeft = 0, // 图片在文字左侧
16 | SPButtonImagePositionRight = 1, // 图片在文字右侧
17 | SPButtonImagePositionTop = 2, // 图片在文字上侧
18 | SPButtonImagePositionBottom = 3 // 图片在文字下侧
19 | };
20 |
21 | IB_DESIGNABLE
22 | @interface SPButton : UIButton
23 |
24 | - (instancetype)initWithImagePosition:(SPButtonImagePosition)imagePosition;
25 |
26 | #if TARGET_INTERFACE_BUILDER // storyBoard/xib中设置
27 | @property (nonatomic,assign) IBInspectable NSInteger imagePosition; // 图片位置
28 | @property (nonatomic, assign) IBInspectable CGFloat imageTitleSpace; // 图片和文字之间的间距
29 | #else // 纯代码设置
30 | @property (nonatomic) SPButtonImagePosition imagePosition; // 图片位置
31 | @property (nonatomic, assign) CGFloat imageTitleSpace; // 图片和文字之间的间距
32 | #endif
33 |
34 |
35 | @end
36 |
37 |
38 | NS_ASSUME_NONNULL_END
39 |
--------------------------------------------------------------------------------
/Example/SPAlertController/Images/image0.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SPStore/SPAlertController/b472fd0338825b485c3b3d46cb68e5a2f0022414/Example/SPAlertController/Images/image0.jpg
--------------------------------------------------------------------------------
/Example/SPAlertController/Images/image1.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SPStore/SPAlertController/b472fd0338825b485c3b3d46cb68e5a2f0022414/Example/SPAlertController/Images/image1.jpg
--------------------------------------------------------------------------------
/Example/SPAlertController/Images/image2.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SPStore/SPAlertController/b472fd0338825b485c3b3d46cb68e5a2f0022414/Example/SPAlertController/Images/image2.jpg
--------------------------------------------------------------------------------
/Example/SPAlertController/Images/image3.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SPStore/SPAlertController/b472fd0338825b485c3b3d46cb68e5a2f0022414/Example/SPAlertController/Images/image3.jpg
--------------------------------------------------------------------------------
/Example/SPAlertController/Images/image4.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SPStore/SPAlertController/b472fd0338825b485c3b3d46cb68e5a2f0022414/Example/SPAlertController/Images/image4.jpg
--------------------------------------------------------------------------------
/Example/SPAlertController/Images/image5.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SPStore/SPAlertController/b472fd0338825b485c3b3d46cb68e5a2f0022414/Example/SPAlertController/Images/image5.jpg
--------------------------------------------------------------------------------
/Example/SPAlertController/Images/image6.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SPStore/SPAlertController/b472fd0338825b485c3b3d46cb68e5a2f0022414/Example/SPAlertController/Images/image6.jpg
--------------------------------------------------------------------------------
/Example/SPAlertController/Images/image7.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SPStore/SPAlertController/b472fd0338825b485c3b3d46cb68e5a2f0022414/Example/SPAlertController/Images/image7.jpg
--------------------------------------------------------------------------------
/Example/SPAlertController/Images/image8.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SPStore/SPAlertController/b472fd0338825b485c3b3d46cb68e5a2f0022414/Example/SPAlertController/Images/image8.jpg
--------------------------------------------------------------------------------
/Example/SPAlertController/Images/image9.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SPStore/SPAlertController/b472fd0338825b485c3b3d46cb68e5a2f0022414/Example/SPAlertController/Images/image9.jpg
--------------------------------------------------------------------------------
/Example/SPAlertController/Images/send0.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SPStore/SPAlertController/b472fd0338825b485c3b3d46cb68e5a2f0022414/Example/SPAlertController/Images/send0.jpeg
--------------------------------------------------------------------------------
/Example/SPAlertController/Images/send1.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SPStore/SPAlertController/b472fd0338825b485c3b3d46cb68e5a2f0022414/Example/SPAlertController/Images/send1.jpeg
--------------------------------------------------------------------------------
/Example/SPAlertController/Images/背景1.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SPStore/SPAlertController/b472fd0338825b485c3b3d46cb68e5a2f0022414/Example/SPAlertController/Images/背景1.jpg
--------------------------------------------------------------------------------
/Example/SPAlertController/Images/背景2.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SPStore/SPAlertController/b472fd0338825b485c3b3d46cb68e5a2f0022414/Example/SPAlertController/Images/背景2.jpg
--------------------------------------------------------------------------------
/Example/SPAlertController/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 | $(MARKETING_VERSION)
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 |
--------------------------------------------------------------------------------
/Example/SPAlertController/SPAlertController/SPAlertController.h:
--------------------------------------------------------------------------------
1 | //
2 | // SPAlertController.h
3 | // SPAlertController
4 | //
5 | // Created by 乐升平 on 18/10/12. https://github.com/SPStore/SPAlertController
6 | // Copyright © 2018-2019 leshengping (lesp163@163.com). All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | NS_ASSUME_NONNULL_BEGIN
12 |
13 | typedef NS_ENUM(NSInteger, SPAlertControllerStyle) {
14 | SPAlertControllerStyleActionSheet = 0, // 从单侧弹出(顶/左/底/右)
15 | SPAlertControllerStyleAlert, // 从中间弹出
16 | };
17 |
18 | typedef NS_ENUM(NSInteger, SPAlertAnimationType) {
19 | SPAlertAnimationTypeDefault = 0, // 默认动画,如果是SPAlertControllerStyleActionSheet样式,默认动画等效于SPAlertAnimationTypeFromBottom,如果是SPAlertControllerStyleAlert样式,默认动画等效于SPAlertAnimationTypeShrink
20 | SPAlertAnimationTypeFromBottom, // 从底部弹出
21 | SPAlertAnimationTypeFromTop, // 从顶部弹出
22 | SPAlertAnimationTypeFromRight, // 从右边弹出
23 | SPAlertAnimationTypeFromLeft, // 从左边弹出
24 |
25 | SPAlertAnimationTypeShrink, // 收缩动画
26 | SPAlertAnimationTypeExpand, // 发散动画
27 | SPAlertAnimationTypeFade, // 渐变动画
28 |
29 | SPAlertAnimationTypeNone, // 无动画
30 | SPAlertAnimationTypeAlpha NS_ENUM_DEPRECATED_IOS(8_0, 8_0, "Use SPAlertAnimationTypeFade instead"), // 渐变动画
31 | SPAlertAnimationTypeRaiseUp NS_ENUM_DEPRECATED_IOS(8_0, 8_0, "Use SPAlertAnimationTypeFromBottom instead"), // 从底部弹出
32 | SPAlertAnimationTypeDropDown NS_ENUM_DEPRECATED_IOS(8_0, 8_0, "Use SPAlertAnimationTypeFromTop instead"), // 从顶部弹出
33 | };
34 |
35 | typedef NS_ENUM(NSInteger, SPAlertActionStyle) {
36 | SPAlertActionStyleDefault = 0, // 默认样式
37 | SPAlertActionStyleCancel, // 取消样式,字体加粗
38 | SPAlertActionStyleDestructive // 红色字体样式
39 | };
40 |
41 | // ===================================================== SPAlertAction =====================================================
42 |
43 | @interface SPAlertAction : NSObject
44 |
45 | + (instancetype)actionWithTitle:(nullable NSString *)title style:(SPAlertActionStyle)style handler:(void (^ __nullable)(SPAlertAction *action))handler;
46 |
47 | /** action的标题 */
48 | @property(nullable, nonatomic, copy) NSString *title;
49 | /** action的富文本标题 */
50 | @property(nullable, nonatomic, copy) NSAttributedString *attributedTitle;
51 | /** action的图标,位于title的左边 */
52 | @property(nullable, nonatomic, copy) UIImage *image;
53 | /** title跟image之间的间距 */
54 | @property (nonatomic, assign) CGFloat imageTitleSpacing;
55 | /** 渲染颜色,当外部的图片使用了UIImageRenderingModeAlwaysTemplate时,使用该属性可改变图片的颜色 */
56 | @property (nonatomic, strong) UIColor *tintColor;
57 | /** 是否能点击,默认为YES */
58 | @property(nonatomic, getter=isEnabled) BOOL enabled;
59 | /** action的标题颜色,这个颜色只是普通文本的颜色,富文本颜色需要用NSForegroundColorAttributeName */
60 | @property(nonatomic, strong) UIColor *titleColor;
61 | /** action的标题字体,如果文字太长显示不全,会自动改变字体自适应按钮宽度,最多压缩文字为原来的0.5倍封顶 */
62 | @property(nonatomic, strong) UIFont *titleFont;
63 | /** action的标题的内边距,如果在不改变字体的情况下想增大action的高度,可以设置该属性的top和bottom值,默认UIEdgeInsetsMake(0, 15, 0, 15) */
64 | @property(nonatomic, assign) UIEdgeInsets titleEdgeInsets;
65 |
66 | /** 样式 */
67 | @property(nonatomic, readonly) SPAlertActionStyle style;
68 |
69 | @end
70 |
71 | // ===================================================== SPAlertController =====================================================
72 |
73 | @protocol SPAlertControllerDelegate;
74 | @interface SPAlertController : UIViewController
75 |
76 | + (instancetype)alertControllerWithTitle:(nullable NSString *)title message:(nullable NSString *)message preferredStyle:(SPAlertControllerStyle)preferredStyle;
77 | + (instancetype)alertControllerWithTitle:(nullable NSString *)title message:(nullable NSString *)message preferredStyle:(SPAlertControllerStyle)preferredStyle animationType:(SPAlertAnimationType)animationType;
78 |
79 | - (void)addAction:(SPAlertAction *)action;
80 | @property (nonatomic, readonly) NSArray *actions;
81 |
82 | /* 添加文本输入框
83 | * 一旦添加后就会回调一次(仅回调一次,因此可以在这个block块里面自由定制textFiled,如设置textField的属性,设置代理,添加addTarget,监听通知等);
84 | */
85 | - (void)addTextFieldWithConfigurationHandler:(void (^ __nullable)(UITextField *textField))configurationHandler;
86 | @property(nullable, nonatomic, readonly) NSArray *textFields;
87 |
88 | /** 主标题 */
89 | @property(nullable, nonatomic, copy) NSString *title;
90 | /** 副标题 */
91 | @property(nullable, nonatomic, copy) NSString *message;
92 | /** 主标题(富文本) */
93 | @property(nullable, nonatomic, copy) NSAttributedString *attributedTitle;
94 | /** 副标题(富文本) */
95 | @property(nullable, nonatomic, copy) NSAttributedString *attributedMessage;
96 | /** 头部图标,位置处于title之上,大小取决于图片本身大小 */
97 | @property(nullable,nonatomic, copy) UIImage *image;
98 |
99 | /** 主标题颜色 */
100 | @property(nonatomic, strong) UIColor *titleColor;
101 | /** 主标题字体,默认18,加粗 */
102 | @property(nonatomic, strong) UIFont *titleFont;
103 | /** 副标题颜色 */
104 | @property(nonatomic, strong) UIColor *messageColor;
105 | /** 副标题字体,默认16,未加粗 */
106 | @property(nonatomic, strong) UIFont *messageFont;
107 | /** 对齐方式(包括主标题和副标题) */
108 | @property(nonatomic, assign) NSTextAlignment textAlignment;
109 | /** 头部图标的限制大小,默认无穷大 */
110 | @property (nonatomic, assign) CGSize imageLimitSize;
111 | /** 图片的tintColor,当外部的图片使用了UIImageRenderingModeAlwaysTemplate时,该属性可起到作用 */
112 | @property (nonatomic, strong) UIColor *imageTintColor;
113 |
114 | /*
115 | * action水平排列还是垂直排列
116 | * actionSheet样式下:默认为UILayoutConstraintAxisVertical(垂直排列), 如果设置为UILayoutConstraintAxisHorizontal(水平排列),则除去取消样式action之外的其余action将水平排列
117 | * alert样式下:当actions的个数大于2,或者某个action的title显示不全时为UILayoutConstraintAxisVertical(垂直排列),否则默认为UILayoutConstraintAxisHorizontal(水平排列),此样式下设置该属性可以修改所有action的排列方式
118 | * 不论哪种样式,只要外界设置了该属性,永远以外界设置的优先
119 | */
120 | @property(nonatomic) UILayoutConstraintAxis actionAxis;
121 |
122 | /* 距离屏幕边缘的最小间距
123 | * alert样式下该属性是指对话框四边与屏幕边缘之间的距离,此样式下默认值随设备变化,actionSheet样式下是指弹出边的对立边与屏幕之间的距离,比如如果从右边弹出,那么该属性指的就是对话框左边与屏幕之间的距离,此样式下默认值为70
124 | */
125 | @property(nonatomic, assign) CGFloat minDistanceToEdges;
126 |
127 | /** SPAlertControllerStyleAlert样式下默认6.0f,SPAlertControllerStyleActionSheet样式下默认13.0f,去除半径设置为0即可 */
128 | @property(nonatomic, assign) CGFloat cornerRadius;
129 |
130 | /** 对话框的偏移量,y值为正向下偏移,为负向上偏移;x值为正向右偏移,为负向左偏移,该属性只对SPAlertControllerStyleAlert样式有效,键盘的frame改变会自动偏移,如果手动设置偏移只会取手动设置的 */
131 | @property(nonatomic, assign) CGPoint offsetForAlert;
132 | /** 设置alert样式下的偏移量,动画为NO则跟属性offsetForAlert等效 */
133 | - (void)setOffsetForAlert:(CGPoint)offsetForAlert animated:(BOOL)animated;
134 |
135 | /** 是否需要对话框拥有毛玻璃,默认为YES */
136 | @property(nonatomic, assign) BOOL needDialogBlur;
137 |
138 | /** 是否单击背景退出对话框,默认为YES */
139 | @property(nonatomic, assign) BOOL tapBackgroundViewDismiss;
140 |
141 | @property(nonatomic, weak) id delegate;
142 |
143 | @property(nonatomic, readonly) SPAlertControllerStyle preferredStyle;
144 | @property(nonatomic, readonly) SPAlertAnimationType animationType;
145 |
146 | /** 设置action与下一个action之间的间距, action仅限于非取消样式,必须在'-addAction:'之后设置,iOS11或iOS11以上才能使用 */
147 | - (void)setCustomSpacing:(CGFloat)spacing afterAction:(SPAlertAction *)action API_AVAILABLE(ios(11.0));
148 | - (CGFloat)customSpacingAfterAction:(SPAlertAction *)action API_AVAILABLE(ios(11.0));
149 |
150 | /** 设置蒙层的外观样式,可通过alpha调整透明度 */
151 | - (void)setBackgroundViewAppearanceStyle:(UIBlurEffectStyle)style alpha:(CGFloat)alpha;
152 |
153 | // 插入一个组件view,位置处于头部和action部分之间,要求头部和action部分同时存在
154 | - (void)insertComponentView:(nonnull UIView *)componentView;
155 |
156 |
157 | // ---------------------------------------------- custom -----------------------------------------------------
158 | /**
159 | 创建控制器(自定义整个对话框)
160 |
161 | @param customAlertView 整个对话框的自定义view
162 | @param preferredStyle 对话框样式
163 | @param animationType 动画类型
164 | @return 控制器对象
165 | */
166 | + (instancetype)alertControllerWithCustomAlertView:(nonnull UIView *)customAlertView preferredStyle:(SPAlertControllerStyle)preferredStyle animationType:(SPAlertAnimationType)animationType;
167 | /**
168 | 创建控制器(自定义对话框的头部)
169 |
170 | @param customHeaderView 头部自定义view
171 | @param preferredStyle 对话框样式
172 | @param animationType 动画类型
173 | @return 控制器对象
174 | */
175 | + (instancetype)alertControllerWithCustomHeaderView:(nonnull UIView *)customHeaderView preferredStyle:(SPAlertControllerStyle)preferredStyle animationType:(SPAlertAnimationType)animationType;
176 | /**
177 | 创建控制器(自定义对话框的action部分)
178 |
179 | @param customActionSequenceView action部分的自定义view
180 | @param title 大标题
181 | @param message 副标题
182 | @param preferredStyle 对话框样式
183 | @param animationType 动画类型
184 | @return 控制器对象
185 | */
186 | + (instancetype)alertControllerWithCustomActionSequenceView:(nonnull UIView *)customActionSequenceView title:(nullable NSString *)title message:(nullable NSString *)message preferredStyle:(SPAlertControllerStyle)preferredStyle animationType:(SPAlertAnimationType)animationType;
187 |
188 | /** 更新自定义view的size,比如屏幕旋转,自定义view的大小发生了改变,可通过该方法更新size */
189 | - (void)updateCustomViewSize:(CGSize)size;
190 |
191 | @property(nonatomic, assign) CGFloat cornerRadiusForAlert NS_DEPRECATED_IOS(8_0, 8_0,"Use cornerRadius instead");
192 | @property (nonatomic, assign) CGFloat maxTopMarginForActionSheet NS_DEPRECATED_IOS(8_0, 8_0,"Use minDistanceToEdges instead");
193 | @property(nonatomic, assign) CGFloat maxMarginForAlert NS_DEPRECATED_IOS(8_0, 8_0,"Use minDistanceToEdges instead");
194 | @property(nonatomic, assign) NSInteger maxNumberOfActionHorizontalArrangementForAlert NS_DEPRECATED_IOS(8_0, 8_0,"Use actionAxis instead");
195 | @property(nonatomic, assign) CGFloat offsetYForAlert NS_DEPRECATED_IOS(8_0, 8_0,"Use offsetForAlert instead");
196 | + (instancetype)alertControllerWithTitle:(nullable NSString *)title message:(nullable NSString *)message preferredStyle:(SPAlertControllerStyle)preferredStyle animationType:(SPAlertAnimationType)animationType customView:(nullable UIView *)customView NS_DEPRECATED_IOS(8_0, 8_0,"Use +alertControllerWithCustomAlertView:preferredStyle:animationType:");
197 | + (instancetype)alertControllerWithPreferredStyle:(SPAlertControllerStyle)preferredStyle animationType:(SPAlertAnimationType)animationType customHeaderView:(nullable UIView *)customHeaderView NS_DEPRECATED_IOS(8_0, 8_0,"Use +alertControllerWithCustomHeaderView:preferredStyle:animationType:");
198 | + (instancetype)alertControllerWithTitle:(nullable NSString *)title message:(nullable NSString *)message preferredStyle:(SPAlertControllerStyle)preferredStyle animationType:(SPAlertAnimationType)animationType customCenterView:(nullable UIView *)customCenterView NS_DEPRECATED_IOS(8_0, 8_0,"Use -insertComponentView:");
199 | + (instancetype)alertControllerWithTitle:(nullable NSString *)title message:(nullable NSString *)message preferredStyle:(SPAlertControllerStyle)preferredStyle animationType:(SPAlertAnimationType)animationType customFooterView:(nullable UIView *)customFooterView NS_DEPRECATED_IOS(8_0, 8_0,"Use +alertControllerWithCustomActionSequenceView:title:message:preferredStyle:animationType:");
200 | @end
201 |
202 | @protocol SPAlertControllerDelegate
203 | @optional;
204 | - (void)willPresentAlertController:(SPAlertController *)alertController; // 将要present
205 | - (void)didPresentAlertController:(SPAlertController *)alertController; // 已经present
206 | - (void)willDismissAlertController:(SPAlertController *)alertController; // 将要dismiss
207 | - (void)didDismissAlertController:(SPAlertController *)alertController; // 已经dismiss
208 |
209 |
210 | - (void)sp_alertControllerWillShow:(SPAlertController *)alertController NS_DEPRECATED_IOS(8_0, 8_0,"Use -willPresentAlertController:");
211 | - (void)sp_alertControllerDidShow:(SPAlertController *)alertController NS_DEPRECATED_IOS(8_0, 8_0,"Use -DidPresentAlertController:");
212 | - (void)sp_alertControllerWillHide:(SPAlertController *)alertController NS_DEPRECATED_IOS(8_0, 8_0,"Use -willDismissAlertController:");
213 | - (void)sp_alertControllerDidHide:(SPAlertController *)alertController NS_DEPRECATED_IOS(8_0, 8_0,"Use -DidDismissAlertController:");
214 | @end
215 |
216 | @interface SPAlertPresentationController : UIPresentationController
217 | @end
218 |
219 | @interface SPAlertAnimation : NSObject
220 | + (instancetype)animationIsPresenting:(BOOL)presenting;
221 | @end
222 |
223 | NS_ASSUME_NONNULL_END
224 |
--------------------------------------------------------------------------------
/Example/SPAlertController/UIColor+DarkMode.h:
--------------------------------------------------------------------------------
1 | //
2 | // UIColor+DarkMode.h
3 | // SPAlertController
4 | //
5 | // Created by 乐升平 on 2020/4/26.
6 | // Copyright © 2020 乐升平. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | NS_ASSUME_NONNULL_BEGIN
12 |
13 | @interface UIColor (DarkMode)
14 |
15 | + (UIColor *)alertBackgroundColor;
16 |
17 | /// 创建颜色对
18 | /// @param lightColor iOS13以下的系统显示的颜色或未开启深色模式下显示的颜色
19 | /// @param darkColor 深色模式下显示的颜色
20 | + (UIColor *) colorPairsWithLightColor:(UIColor *) lightColor darkColor:(UIColor *) darkColor;
21 |
22 | @end
23 |
24 | NS_ASSUME_NONNULL_END
25 |
--------------------------------------------------------------------------------
/Example/SPAlertController/UIColor+DarkMode.m:
--------------------------------------------------------------------------------
1 | //
2 | // UIColor+DarkMode.m
3 | // SPAlertController
4 | //
5 | // Created by 乐升平 on 2020/4/26.
6 | // Copyright © 2020 乐升平. All rights reserved.
7 | //
8 |
9 | #import "UIColor+DarkMode.h"
10 |
11 | @implementation UIColor (DarkMode)
12 |
13 | + (UIColor *)alertBackgroundColor {
14 | return [self colorPairsWithLightColor:[[UIColor whiteColor] colorWithAlphaComponent:0.7]
15 | darkColor:[UIColor colorWithRed:44.0 / 255.0 green:44.0 / 255.0 blue:44.0 / 255.0 alpha:1.0]];
16 | }
17 |
18 | + (UIColor *)colorPairsWithLightColor:(UIColor *)lightColor darkColor:(UIColor *)darkColor {
19 | if (@available(iOS 13.0, *)) {
20 | return [UIColor colorWithDynamicProvider:^UIColor * _Nonnull(UITraitCollection * _Nonnull traitCollection) {
21 | if(traitCollection.userInterfaceStyle == UIUserInterfaceStyleDark) {
22 | return darkColor;
23 | } else {
24 | return lightColor;
25 | }
26 | }];
27 | } else {
28 | return lightColor;
29 | }
30 | }
31 |
32 | @end
33 |
--------------------------------------------------------------------------------
/Example/SPAlertController/ViewController.h:
--------------------------------------------------------------------------------
1 | //
2 | // ViewController.h
3 | // SPAlertController
4 | //
5 | // Created by 乐升平 on 2018/12/4.
6 | // Copyright © 2018 乐升平. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @interface ViewController : UIViewController
12 |
13 |
14 | @end
15 |
16 |
--------------------------------------------------------------------------------
/Example/SPAlertControllerTests/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 |
--------------------------------------------------------------------------------
/Example/SPAlertControllerTests/SPAlertControllerTests.m:
--------------------------------------------------------------------------------
1 | //
2 | // SPAlertControllerTests.m
3 | // SPAlertControllerTests
4 | //
5 | // Created by 乐升平 on 2018/12/4.
6 | // Copyright © 2018 乐升平. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @interface SPAlertControllerTests : XCTestCase
12 |
13 | @end
14 |
15 | @implementation SPAlertControllerTests
16 |
17 | - (void)setUp {
18 | // Put setup code here. This method is called before the invocation of each test method in the class.
19 | }
20 |
21 | - (void)tearDown {
22 | // Put teardown code here. This method is called after the invocation of each test method in the class.
23 | }
24 |
25 | - (void)testExample {
26 | // This is an example of a functional test case.
27 | // Use XCTAssert and related functions to verify your tests produce the correct results.
28 | }
29 |
30 | - (void)testPerformanceExample {
31 | // This is an example of a performance test case.
32 | [self measureBlock:^{
33 | // Put the code you want to measure the time of here.
34 | }];
35 | }
36 |
37 | @end
38 |
--------------------------------------------------------------------------------
/Example/SPAlertControllerTests/main.m:
--------------------------------------------------------------------------------
1 | //
2 | // main.m
3 | // SPAlertController
4 | //
5 | // Created by 乐升平 on 2018/12/4.
6 | // Copyright © 2018 乐升平. All rights reserved.
7 | //
8 |
9 | #import
10 | #import "AppDelegate.h"
11 |
12 | int main(int argc, char * argv[]) {
13 | @autoreleasepool {
14 | return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/Example/SPAlertControllerUITests/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 |
--------------------------------------------------------------------------------
/Example/SPAlertControllerUITests/SPAlertControllerUITests.m:
--------------------------------------------------------------------------------
1 | //
2 | // SPAlertControllerUITests.m
3 | // SPAlertControllerUITests
4 | //
5 | // Created by 乐升平 on 2018/12/4.
6 | // Copyright © 2018 乐升平. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @interface SPAlertControllerUITests : XCTestCase
12 |
13 | @end
14 |
15 | @implementation SPAlertControllerUITests
16 |
17 | - (void)setUp {
18 | // Put setup code here. This method is called before the invocation of each test method in the class.
19 |
20 | // In UI tests it is usually best to stop immediately when a failure occurs.
21 | self.continueAfterFailure = NO;
22 |
23 | // UI tests must launch the application that they test. Doing this in setup will make sure it happens for each test method.
24 | [[[XCUIApplication alloc] init] launch];
25 |
26 | // 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.
27 | }
28 |
29 | - (void)tearDown {
30 | // Put teardown code here. This method is called after the invocation of each test method in the class.
31 | }
32 |
33 | - (void)testExample {
34 | // Use recording to get started writing UI tests.
35 | // Use XCTAssert and related functions to verify your tests produce the correct results.
36 | }
37 |
38 | @end
39 |
--------------------------------------------------------------------------------
/Images/.DS_Store:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SPStore/SPAlertController/b472fd0338825b485c3b3d46cb68e5a2f0022414/Images/.DS_Store
--------------------------------------------------------------------------------
/Images/3006981-0b23494c3ba2a6fc.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SPStore/SPAlertController/b472fd0338825b485c3b3d46cb68e5a2f0022414/Images/3006981-0b23494c3ba2a6fc.jpg
--------------------------------------------------------------------------------
/Images/3006981-3cd4a2b6ff4da206.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SPStore/SPAlertController/b472fd0338825b485c3b3d46cb68e5a2f0022414/Images/3006981-3cd4a2b6ff4da206.jpg
--------------------------------------------------------------------------------
/Images/3006981-41170beb443f32f0.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SPStore/SPAlertController/b472fd0338825b485c3b3d46cb68e5a2f0022414/Images/3006981-41170beb443f32f0.jpg
--------------------------------------------------------------------------------
/Images/3006981-6f3752d49e579460.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SPStore/SPAlertController/b472fd0338825b485c3b3d46cb68e5a2f0022414/Images/3006981-6f3752d49e579460.jpg
--------------------------------------------------------------------------------
/Images/3006981-9544748007937417.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SPStore/SPAlertController/b472fd0338825b485c3b3d46cb68e5a2f0022414/Images/3006981-9544748007937417.jpg
--------------------------------------------------------------------------------
/Images/3006981-9ed0416190e155dc.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SPStore/SPAlertController/b472fd0338825b485c3b3d46cb68e5a2f0022414/Images/3006981-9ed0416190e155dc.jpg
--------------------------------------------------------------------------------
/Images/3006981-a12eae25bc1061d6.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SPStore/SPAlertController/b472fd0338825b485c3b3d46cb68e5a2f0022414/Images/3006981-a12eae25bc1061d6.jpg
--------------------------------------------------------------------------------
/Images/3006981-b35b79b657815756.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SPStore/SPAlertController/b472fd0338825b485c3b3d46cb68e5a2f0022414/Images/3006981-b35b79b657815756.jpg
--------------------------------------------------------------------------------
/Images/3CB7E93FDA241F253BFE156D0B4AA7E2.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SPStore/SPAlertController/b472fd0338825b485c3b3d46cb68e5a2f0022414/Images/3CB7E93FDA241F253BFE156D0B4AA7E2.jpg
--------------------------------------------------------------------------------
/Images/6AAAA07F90853F52CA6166D815F619A9.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SPStore/SPAlertController/b472fd0338825b485c3b3d46cb68e5a2f0022414/Images/6AAAA07F90853F52CA6166D815F619A9.jpg
--------------------------------------------------------------------------------
/Images/F4FB539593B4CC499E65735E4F1E8227.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SPStore/SPAlertController/b472fd0338825b485c3b3d46cb68e5a2f0022414/Images/F4FB539593B4CC499E65735E4F1E8227.jpg
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | Copyright © 2018-2019 leshengping (lesp163@163.com)
2 |
3 | Permission is hereby granted, free of charge, to any person obtaining a copy
4 | of this software and associated documentation files (the "Software"), to deal
5 | in the Software without restriction, including without limitation the rights
6 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7 | copies of the Software, and to permit persons to whom the Software is furnished
8 | to do so, subject to the following conditions:
9 |
10 | The above copyright notice and this permission notice shall be included in all
11 | copies or substantial portions of the Software.
12 |
13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19 | THE SOFTWARE.
20 |
21 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # 重大更新:4.0.0版本适配深色模式
2 | # SPAlertController
3 | [](https://travis-ci.org/SPStore/SPAlertController)
4 | [](http://cocoadocs.org/docsets/SPAlertController/)
5 | [](http://cocoadocs.org/docsets/SPAlertController/)
6 | 
7 | [](https://www.apache.org/licenses/LICENSE-2.0.html)
8 | [](https://github.com/SPStore/SPAlertController)
9 | # 目录
10 | * [CocoaPods](#CocoaPods)
11 | * [使用示例](#使用示例)
12 | * [API及属性详解](#API及属性详解)
13 | * [自定义View](#自定义View)
14 | * [深色模式预览](#深色模式预览)
15 | * [历史版本](#历史版本)
16 |
17 | ## 功能特点
18 | - [x] 采用VFL布局,3.0版本开始,核心控件为UIStackView,风格与微信几乎零误差
19 | - [x] 3.0版本开始,对话框头部新增图片设置
20 | - [x] 3.0版本开始,action支持图片设置
21 | - [x] 3.0版本开始,iOS11及其以上系统可单独设置指定action后的间距
22 | - [x] 3.0版本开始,支持富文本
23 | - [x] action的排列可灵活设置垂直排列和水平排列
24 | - [x] 每个action的高度自适应
25 | - [x] 支持旋转(横竖屏)
26 | - [x] 可以自定义各种UIView
27 | - [x] 支持对话框毛玻璃和背景蒙层毛玻璃
28 | - [x] 全面适配iPhoneX,iPhoneXR,iPhoneXS,iPhoneXS MAX
29 | - [x] 全面适配深色模式
30 | ## CocoaPods
31 | ##### 版本4.0.0
32 | ```
33 | platform:ios,'9.0'
34 | target 'MyApp' do
35 | pod 'SPAlertController', '~> 4.0.0'
36 | end
37 | ```
38 |
39 | ## 使用示例
40 | ```
41 | SPAlertController *alert = [SPAlertController alertControllerWithTitle:@"我是主标题" message:@"我是副标题" preferredStyle:SPAlertControllerStyleActionSheet];
42 |
43 | SPAlertAction *action1 = [SPAlertAction actionWithTitle:@"Default" style:SPAlertActionStyleDefault handler:^(SPAlertAction * _Nonnull action) {}];
44 | SPAlertAction *action2 = [SPAlertAction actionWithTitle:@"Destructive" style:SPAlertActionStyleDestructive handler:^(SPAlertAction * _Nonnull action) {}];
45 | SPAlertAction *action3 = [SPAlertAction actionWithTitle:@"Cancel" style:SPAlertActionStyleCancel handler:^(SPAlertAction * _Nonnull action) {}];
46 |
47 | [alert addAction:action1];
48 | [alert addAction:action2];
49 | [alert addAction:action3];
50 | [self presentViewController: alert animated:YES completion:^{}];
51 | ```
52 |
53 | ## API及属性详解
54 | ### 创建SPAlertController
55 | ```
56 | + (instancetype)alertControllerWithTitle:(nullable NSString *)title message:(nullable NSString *)message preferredStyle:(SPAlertControllerStyle)preferredStyle;
57 | ```
58 | ```
59 | + (instancetype)alertControllerWithTitle:(nullable NSString *)title message:(nullable NSString *)message preferredStyle:(SPAlertControllerStyle)preferredStyle animationType:(SPAlertAnimationType)animationType;
60 | ```
61 | 上面2种创建方式唯一的区别就是:第2种方式多了一个animationType参数,该参数可以设置弹出动画。如果以第一种方式创建,会采用默认动画,默认动画跟preferredStyle 有关,如果是SPAlertControllerStyleActionSheet样式,默认动画为从底部弹出,如果是SPAlertControllerStyleAlert样式,默认动画为从中间弹出
62 | ### SPAlertController的头部配置
63 | * title,对话框的主标题
64 | * message,对话框的副标题
65 | * attributedTitle,对话框的主标题,富文本
66 | * attributedMessage,对话框的副标题,富文本
67 | * image,对话框的头部上的图标,位置处于主标题之上
68 | * titleColor,对话框主标题的颜色
69 | * titleFont,对话框主标题的字体
70 | * messageColor,对话框副标题的颜色
71 | * messageFont,对话框副标题的字体
72 | * textAlignment,对话框标题的对齐方式(标题指主标题和副标题)
73 | * imageLimitSize,对话框头部图标的限制大小,默认是无穷大
74 |
75 | 
76 |
77 | ### SPAlertController的action配置
78 | ```
79 | // 添加action,actions里面存放的就是添加的所有action
80 |
81 | - (void)addAction:(SPAlertAction *)action;
82 |
83 | @property (nonatomic, readonly) NSArray *actions;
84 | ```
85 |
86 | ```
87 | // 添加文本输入框,textFields存放的就是添加的所有textField
88 |
89 | - (void)addTextFieldWithConfigurationHandler:(void (^ __nullable)(UITextField *textField))configurationHandler;
90 |
91 | @property(nullable, nonatomic, readonly) NSArray *textFields;
92 | ```
93 |
94 | 
95 |
96 | ```
97 | // SPAlertControllerStyleActionSheet样式下:默认为UILayoutConstraintAxisVertical(垂直排列), 如果设置为UILayoutConstraintAxisHorizontal(水平排列),则除去取消样式action之外的其余action将水平排列;SPAlertControllerStyleAlert样式下:当actions的个数大于2,或者某个action的title显示不全时为UILayoutConstraintAxisVertical(垂直排列),否则默认为UILayoutConstraintAxisHorizontal(水平排列),此样式下设置该属性可以修改所有action的排列方式;不论哪种样式,只要外界设置了该属性,永远以外界设置的优先
98 |
99 | @property(nonatomic) UILayoutConstraintAxis actionAxis;
100 | ```
101 | * SPAlertControllerStyleActionSheet样式下的垂直排列和水平排列
102 |
103 | 
104 |
105 | * SPAlertControllerStyleAlert样式下的垂直排列和水平排列
106 |
107 | 
108 |
109 | ```
110 | // 该属性配置的是距离屏幕边缘的最小间距;SPAlertControllerStyleAlert样式下该属性是指对话框四边与屏幕边缘之间的距离,此样式下默认值随设备变化,SPAlertControllerStyleActionSheet样式下是指弹出边的对立边与屏幕之间的距离,比如如果从右边弹出,那么该属性指的就是对话框左边与屏幕之间的距离,此样式下默认值为70
111 |
112 | @property(nonatomic, assign) CGFloat minDistanceToEdges;
113 | ```
114 | * 图中红色画线都是指minDistanceToEdges
115 |
116 | 
117 |
118 | ```
119 | // 该属性是制造对话框的毛玻璃效果,3.0版本开始采用的是系统私有类_UIDimmingKnockoutBackdropView所实现
120 |
121 | @property(nonatomic, assign) BOOL needDialogBlur;
122 | ```
123 | ```
124 | // SPAlertControllerStyleAlert下的偏移量配置 ,CGPoint类型,y值为正向下偏移,为负向上偏移;x值为正向右偏移,为负向左偏移,该属性只对SPAlertControllerStyleAlert样式有效,键盘的frame改变会自动偏移,如果外界手动设置偏移只会取手动设置的
125 |
126 | @property(nonatomic, assign) CGPoint offsetForAlert;
127 |
128 | - (void)setOffsetForAlert:(CGPoint)offsetForAlert animated:(BOOL)animated;
129 | ```
130 |
131 | ```
132 | // 该API是设置和获取指定action后面的间距,如图中箭头所指,iOS11及其以上才支持
133 |
134 | - (void)setCustomSpacing:(CGFloat)spacing afterAction:(SPAlertAction *)action API_AVAILABLE(ios(11.0));
135 |
136 | - (CGFloat)customSpacingAfterAction:(SPAlertAction *)action API_AVAILABLE(ios(11.0));
137 | ```
138 | 
139 |
140 | ```
141 | // 该API是设置背景蒙层的样式,分为半透明和毛玻璃效果,毛玻璃又细分为Dark,ExtraLight,Light3种样式
142 |
143 | - (void)setBackgroundViewAppearanceStyle:(SPBackgroundViewAppearanceStyle)style alpha:(CGFloat)alpha;
144 | ```
145 | 
146 |
147 | ```
148 | // 单击背景蒙层是否退出对话框,默认YES
149 |
150 | @property(nonatomic, assign) BOOL tapBackgroundViewDismiss;
151 | ```
152 | ```
153 | @property(nonatomic, assign) CGFloat cornerRadiusForAlert;
154 | ```
155 | SPAlertControllerStyleAlert下的圆角半径
156 |
157 | ### 创建action
158 | ```
159 | // 其中,title为action的标题,创建的时候仅支持普通文本,如果要使用富文本,可以另外设置action的属性attributedTitle,设置后会覆盖普通文本
160 |
161 | + (instancetype)actionWithTitle:(nullable NSString *)title style:(SPAlertActionStyle)style handler:(void (^ __nullable)(SPAlertAction *action))handler;
162 | ```
163 | ### 配置action
164 | * title,action的标题
165 | * attributedTitle,action的富文本标题,普通文本和富文本同时设置时,只会显示富文本
166 | * image,action上的图片,文字和图片都存在时,图片在左,文字在右
167 | * imageTitleSpacing,图片与文字之间的间距
168 | * titleColor,action标题的颜色
169 | * titleFont,action标题的字体
170 | * titleEdgeInsets,action标题的内边距,此属性能够改变action的高度
171 | * enabled,action是否能被点击
172 |
173 | 
174 |
175 | ## 自定义View
176 | * 自定义对话框的头部
177 | ```
178 | + (instancetype)alertControllerWithCustomHeaderView:(nullable UIView *)customHeaderView preferredStyle:(SPAlertControllerStyle)preferredStyle animationType:(SPAlertAnimationType)animationType;
179 | ```
180 |
181 | 
182 |
183 | * 自定义整个对话框
184 | ```
185 | + (instancetype)alertControllerWithCustomAlertView:(nullable UIView *)customAlertView preferredStyle:(SPAlertControllerStyle)preferredStyle animationType:(SPAlertAnimationType)animationType;
186 | ```
187 | 
188 |
189 | * 自定义对话框的action部分
190 | ```
191 | + (instancetype)alertControllerWithCustomActionSequenceView:(nullable UIView *)customActionSequenceView title:(nullable NSString *)title message:(nullable NSString *)message preferredStyle:(SPAlertControllerStyle)preferredStyle animationType:(SPAlertAnimationType)animationType;
192 | ```
193 | 
194 | ## 关于自定义view的大小
195 | * 非自动布局,在传入自定义view之前,应该为自定义的view设置好frame,也可以在传入自定义view之后,调用API```- (void)updateCustomViewSize:(CGSize)size```设置其大小;
196 | * 自动布局,如果宽度和高度都能由子控件撑起来,那么你不需要设置frame,否则,宽度和高度只要有其中一个无法由子控件撑起,那么就必须设置其值,比如高度能被子控件撑起来,而宽度不能,那么你就必须手动设置一个宽度,高度可以不用设置或者设置为0都可。如果是xib或者storyboard,若自定义的view无法由子控件撑起来,SPAlertController会读取xib/storyboard中的默认frame,如果不合适,那么你应该修改xib/storyboard中的默认frame或者用纯代码重新设置frame。如果自定义view的宽度能够被子控件撑起,但同时又手动设置了自定义view的宽度,那么SPAlertController会取自动撑起的宽度和手动设置的宽度中较大的那个,高度同理。有一种情况要值得注意:如果子控件类似按钮这种不设置大小就自动会产生大小的子控件,同时该按钮设置了左右间距,那么它就能将自定义的view的宽度撑起,但是这种撑起来的宽度可能并非你想要的,因为按钮宽度是由内容自动产生,不是你设置的,这时你应该手动设置按钮的宽度,以便自定义的view的宽度被撑起的恰到好处,或者手动设置自定义view的宽度,这个手动设置的宽度,应该要比没有手动设置宽度的按钮将自定义view撑起来的宽度要大。
197 | * 当自定义的view的大小在对话框显示期间发生了变化,你应该调用```- (void)updateCustomViewSize:(CGSize)size```通知SPAlertController更新其大小
198 |
199 | ## 深色模式预览
200 | [](https://raw.githubusercontent.com/wiki/SPStore/SPAlertController/Screetshots/1.jpg)
201 | [](https://raw.githubusercontent.com/wiki/SPStore/SPAlertController/Screetshots/2.jpg)
202 | [](https://raw.githubusercontent.com/wiki/SPStore/SPAlertController/Screetshots/3.jpg)
203 | [](https://raw.githubusercontent.com/wiki/SPStore/SPAlertController/Screetshots/4.jpg)
204 | [](https://raw.githubusercontent.com/wiki/SPStore/SPAlertController/Screetshots/5.jpg)
205 | [](https://raw.githubusercontent.com/wiki/SPStore/SPAlertController/Screetshots/6.jpg)
206 | [](https://raw.githubusercontent.com/wiki/SPStore/SPAlertController/Screetshots/7.jpg)
207 | [](https://raw.githubusercontent.com/wiki/SPStore/SPAlertController/Screetshots/8.jpg)
208 | [](https://raw.githubusercontent.com/wiki/SPStore/SPAlertController/Screetshots/9.jpg)
209 | [](https://raw.githubusercontent.com/wiki/SPStore/SPAlertController/Screetshots/10.jpg)
210 | [](https://raw.githubusercontent.com/wiki/SPStore/SPAlertController/Screetshots/11.jpg)
211 | [](https://raw.githubusercontent.com/wiki/SPStore/SPAlertController/Screetshots/12.jpg)
212 | [](https://raw.githubusercontent.com/wiki/SPStore/SPAlertController/Screetshots/13.jpg)
213 | [](https://raw.githubusercontent.com/wiki/SPStore/SPAlertController/Screetshots/14.jpg)
214 | ## 历史版本
215 | | 版本 | 更新日期 | 支持最低系统版本 |更新内容 |
216 | | :------------:| :------------:| :------------:|------------|
217 | |v4.0.0|2020.04.27|iOS9.0|适配深色模式|
218 | |v3.1.0|2019.08.08|iOS9.0|1、actionSheet样式加了单边圆角效果
2、毛玻璃默认为NO
3、当不需要毛玻璃效果时,actionButton的选中背景色修改(灰度0.1),属于bug修复
4、“取消action”上的分割线背景色修改(灰度由0.3变为0.2),高度由6增加为8
5、每个actionButton的最小高度由49变为55|
219 | |v3.0.4|2019.06.03|iOS9.0|修复了tapBackgroundViewDismiss属性无效问题|
220 | |v3.0.3|2019.05.30|iOS9.0|修复了action点击的回调为nil时闪退问题|
221 | |v3.0.2|2019.05.09|iOS9.0|修复了内存泄漏问题|
222 | |v3.0.1|2019.01.03|iOS9.0|背景蒙层动画更加的柔和|
223 | |v3.0.0|2018.12.29|iOS9.0|全方位的大重构|
224 | |v2.5.2|2018.12.03|iOS8.0|1、按钮处于最底部时长按touchDown事件的延时现象采用新方式解决
2、修复了内存泄露问题|
225 | |v2.5.1|2018.11.07|iOS8.0|1、修改了action的选中效果
2、解决iOS11之后,按钮处于最底部时长按touchDown事件的延时现象|
226 | |v2.5.0|2018.11.07|iOS8.0|1、毛玻璃思路另辟蹊径,毛玻璃效果不会受到背景遮罩的影响,同时背景遮罩不再被镂空
2、增加动画枚举,可以从左右弹出
3、自定义view时的背景色改为透明色
4、增加actionHeight属性,修复maxNumberOfActionHorizontalArrangementForAlert属性
5、去除了中间tableView的最后一条分割线
6、修改了分割线的颜色,更加接近微信原生
7、修复centerView上有textView/textField,旋转屏幕后不可见问题
8、优化代码|
227 | |v2.1.1|2018.11.01|iOS8.0||
228 | |v2.1.0|2018.10.18|iOS8.0||
229 | |v2.0.0|2017.11.19|iOS8.0||
230 | |v1.7.0|2017.11.06|iOS8.0||
231 | |v1.5.0|2017.11.06|iOS8.0||
232 | |v1.0.1|2017.10.24|iOS8.0||
233 | |v1.0.0|2017.10.24|iOS8.0|||
234 |
235 | [回到顶部](#目录)
236 |
--------------------------------------------------------------------------------
/SPAlertController.podspec:
--------------------------------------------------------------------------------
1 | #
2 | # Be sure to run `pod spec lint SPAlertController.podspec' to ensure this is a
3 | # valid spec and to remove all comments including this before submitting the spec.
4 | #
5 | # To learn more about Podspec attributes see http://docs.cocoapods.org/specification.html
6 | # To see working Podspecs in the CocoaPods repo see https://github.com/CocoaPods/Specs/
7 | #
8 |
9 | Pod::Spec.new do |s|
10 |
11 | # ――― Spec Metadata ―――――――――――――――――――――――――――――――――――――――――――――――――――――――――― #
12 | #
13 | # These will help people to find your library, and whilst it
14 | # can feel like a chore to fill in it's definitely to your advantage. The
15 | # summary should be tweet-length, and the description more in depth.
16 | #
17 |
18 | s.name = "SPAlertController"
19 | s.version = "4.0.0"
20 | s.summary = "提醒对话框."
21 |
22 | # This description is used to generate tags and improve search results.
23 | # * Think: What does it do? Why did you write it? What is the focus?
24 | # * Try to keep it short, snappy and to the point.
25 | # * Write the description between the DESC delimiters below.
26 | # * Finally, don't worry about the indent, CocoaPods strips it!
27 | s.description = <<-DESC
28 | 说明:4.0.0适配了深色模式
29 | DESC
30 |
31 | s.homepage = "https://github.com/SPStore/SPAlertController"
32 | # s.screenshots = "www.example.com/screenshots_1.gif", "www.example.com/screenshots_2.gif"
33 |
34 |
35 | # ――― Spec License ――――――――――――――――――――――――――――――――――――――――――――――――――――――――――― #
36 | #
37 | # Licensing your code is important. See http://choosealicense.com for more info.
38 | # CocoaPods will detect a license file if there is a named LICENSE*
39 | # Popular ones are 'MIT', 'BSD' and 'Apache License, Version 2.0'.
40 | #
41 |
42 | s.license = "MIT"
43 | # s.license = { :type => "MIT", :file => "FILE_LICENSE" }
44 |
45 |
46 | # ――― Author Metadata ――――――――――――――――――――――――――――――――――――――――――――――――――――――――― #
47 | #
48 | # Specify the authors of the library, with email addresses. Email addresses
49 | # of the authors are extracted from the SCM log. E.g. $ git log. CocoaPods also
50 | # accepts just a name if you'd rather not provide an email address.
51 | #
52 | # Specify a social_media_url where others can refer to, for example a twitter
53 | # profile URL.
54 | #
55 |
56 | s.author = { "SPStore" => "lesp163@163.com" }
57 | # Or just: s.author = "SPStore"
58 | # s.authors = { "SPStore" => "" }
59 | # s.social_media_url = "http://twitter.com/SPStore"
60 |
61 | # ――― Platform Specifics ――――――――――――――――――――――――――――――――――――――――――――――――――――――― #
62 | #
63 | # If this Pod runs only on iOS or OS X, then specify the platform and
64 | # the deployment target. You can optionally include the target after the platform.
65 | #
66 |
67 | s.platform = :ios
68 | s.platform = :ios, "9.0"
69 |
70 | # When using multiple platforms
71 | s.ios.deployment_target = "9.0"
72 | # s.osx.deployment_target = "10.7"
73 | # s.watchos.deployment_target = "2.0"
74 | # s.tvos.deployment_target = "9.0"
75 |
76 |
77 | # ――― Source Location ―――――――――――――――――――――――――――――――――――――――――――――――――――――――――― #
78 | #
79 | # Specify the location from where the source should be retrieved.
80 | # Supports git, hg, bzr, svn and HTTP.
81 | #
82 |
83 | s.source = { :git => "https://github.com/SPStore/SPAlertController.git", :tag => s.version }
84 |
85 |
86 | # ――― Source Code ―――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――― #
87 | #
88 | # CocoaPods is smart about how it includes source code. For source files
89 | # giving a folder will include any swift, h, m, mm, c & cpp files.
90 | # For header files it will include any header in the folder.
91 | # Not including the public_header_files will make all headers public.
92 | #
93 |
94 | s.source_files = "SPAlertController"
95 | s.exclude_files = "Classes/Exclude"
96 |
97 | # s.public_header_files = "Classes/**/*.h"
98 |
99 |
100 | # ――― Resources ―――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――― #
101 | #
102 | # A list of resources included with the Pod. These are copied into the
103 | # target bundle with a build phase script. Anything else will be cleaned.
104 | # You can preserve files from being cleaned, please don't preserve
105 | # non-essential files like tests, examples and documentation.
106 | #
107 |
108 | # s.resource = "icon.png"
109 | # s.resources = "Resources/*.png"
110 |
111 | # s.preserve_paths = "FilesToSave", "MoreFilesToSave"
112 |
113 |
114 | # ――― Project Linking ―――――――――――――――――――――――――――――――――――――――――――――――――――――――――― #
115 | #
116 | # Link your library with frameworks, or libraries. Libraries do not include
117 | # the lib prefix of their name.
118 | #
119 |
120 | # s.framework = "SomeFramework"
121 | # s.frameworks = "SomeFramework", "AnotherFramework"
122 |
123 | # s.library = "iconv"
124 | # s.libraries = "iconv", "xml2"
125 |
126 |
127 | # ――― Project Settings ――――――――――――――――――――――――――――――――――――――――――――――――――――――――― #
128 | #
129 | # If your library depends on compiler flags you can set them in the xcconfig hash
130 | # where they will only apply to your library. If you depend on other Podspecs
131 | # you can include multiple dependencies to ensure it works.
132 |
133 | # s.requires_arc = true
134 |
135 | # s.xcconfig = { "HEADER_SEARCH_PATHS" => "$(SDKROOT)/usr/include/libxml2" }
136 | # s.dependency "JSONKit", "~> 1.4"
137 |
138 | end
139 |
--------------------------------------------------------------------------------
/SPAlertController/SPAlertController.h:
--------------------------------------------------------------------------------
1 | //
2 | // SPAlertController.h
3 | // SPAlertController
4 | //
5 | // Created by 乐升平 on 18/10/12. https://github.com/SPStore/SPAlertController
6 | // Copyright © 2018-2019 leshengping (lesp163@163.com). All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | NS_ASSUME_NONNULL_BEGIN
12 |
13 | typedef NS_ENUM(NSInteger, SPAlertControllerStyle) {
14 | SPAlertControllerStyleActionSheet = 0, // 从单侧弹出(顶/左/底/右)
15 | SPAlertControllerStyleAlert, // 从中间弹出
16 | };
17 |
18 | typedef NS_ENUM(NSInteger, SPAlertAnimationType) {
19 | SPAlertAnimationTypeDefault = 0, // 默认动画,如果是SPAlertControllerStyleActionSheet样式,默认动画等效于SPAlertAnimationTypeFromBottom,如果是SPAlertControllerStyleAlert样式,默认动画等效于SPAlertAnimationTypeShrink
20 | SPAlertAnimationTypeFromBottom, // 从底部弹出
21 | SPAlertAnimationTypeFromTop, // 从顶部弹出
22 | SPAlertAnimationTypeFromRight, // 从右边弹出
23 | SPAlertAnimationTypeFromLeft, // 从左边弹出
24 |
25 | SPAlertAnimationTypeShrink, // 收缩动画
26 | SPAlertAnimationTypeExpand, // 发散动画
27 | SPAlertAnimationTypeFade, // 渐变动画
28 |
29 | SPAlertAnimationTypeNone, // 无动画
30 | SPAlertAnimationTypeAlpha NS_ENUM_DEPRECATED_IOS(8_0, 8_0, "Use SPAlertAnimationTypeFade instead"), // 渐变动画
31 | SPAlertAnimationTypeRaiseUp NS_ENUM_DEPRECATED_IOS(8_0, 8_0, "Use SPAlertAnimationTypeFromBottom instead"), // 从底部弹出
32 | SPAlertAnimationTypeDropDown NS_ENUM_DEPRECATED_IOS(8_0, 8_0, "Use SPAlertAnimationTypeFromTop instead"), // 从顶部弹出
33 | };
34 |
35 | typedef NS_ENUM(NSInteger, SPAlertActionStyle) {
36 | SPAlertActionStyleDefault = 0, // 默认样式
37 | SPAlertActionStyleCancel, // 取消样式,字体加粗
38 | SPAlertActionStyleDestructive // 红色字体样式
39 | };
40 |
41 | // ===================================================== SPAlertAction =====================================================
42 |
43 | @interface SPAlertAction : NSObject
44 |
45 | + (instancetype)actionWithTitle:(nullable NSString *)title style:(SPAlertActionStyle)style handler:(void (^ __nullable)(SPAlertAction *action))handler;
46 |
47 | /** action的标题 */
48 | @property(nullable, nonatomic, copy) NSString *title;
49 | /** action的富文本标题 */
50 | @property(nullable, nonatomic, copy) NSAttributedString *attributedTitle;
51 | /** action的图标,位于title的左边 */
52 | @property(nullable, nonatomic, copy) UIImage *image;
53 | /** title跟image之间的间距 */
54 | @property (nonatomic, assign) CGFloat imageTitleSpacing;
55 | /** 渲染颜色,当外部的图片使用了UIImageRenderingModeAlwaysTemplate时,使用该属性可改变图片的颜色 */
56 | @property (nonatomic, strong) UIColor *tintColor;
57 | /** 是否能点击,默认为YES */
58 | @property(nonatomic, getter=isEnabled) BOOL enabled;
59 | /** action的标题颜色,这个颜色只是普通文本的颜色,富文本颜色需要用NSForegroundColorAttributeName */
60 | @property(nonatomic, strong) UIColor *titleColor;
61 | /** action的标题字体,如果文字太长显示不全,会自动改变字体自适应按钮宽度,最多压缩文字为原来的0.5倍封顶 */
62 | @property(nonatomic, strong) UIFont *titleFont;
63 | /** action的标题的内边距,如果在不改变字体的情况下想增大action的高度,可以设置该属性的top和bottom值,默认UIEdgeInsetsMake(0, 15, 0, 15) */
64 | @property(nonatomic, assign) UIEdgeInsets titleEdgeInsets;
65 |
66 | /** 样式 */
67 | @property(nonatomic, readonly) SPAlertActionStyle style;
68 |
69 | @end
70 |
71 | // ===================================================== SPAlertController =====================================================
72 |
73 | @protocol SPAlertControllerDelegate;
74 | @interface SPAlertController : UIViewController
75 |
76 | + (instancetype)alertControllerWithTitle:(nullable NSString *)title message:(nullable NSString *)message preferredStyle:(SPAlertControllerStyle)preferredStyle;
77 | + (instancetype)alertControllerWithTitle:(nullable NSString *)title message:(nullable NSString *)message preferredStyle:(SPAlertControllerStyle)preferredStyle animationType:(SPAlertAnimationType)animationType;
78 |
79 | - (void)addAction:(SPAlertAction *)action;
80 | @property (nonatomic, readonly) NSArray *actions;
81 |
82 | /* 添加文本输入框
83 | * 一旦添加后就会回调一次(仅回调一次,因此可以在这个block块里面自由定制textFiled,如设置textField的属性,设置代理,添加addTarget,监听通知等);
84 | */
85 | - (void)addTextFieldWithConfigurationHandler:(void (^ __nullable)(UITextField *textField))configurationHandler;
86 | @property(nullable, nonatomic, readonly) NSArray *textFields;
87 |
88 | /** 主标题 */
89 | @property(nullable, nonatomic, copy) NSString *title;
90 | /** 副标题 */
91 | @property(nullable, nonatomic, copy) NSString *message;
92 | /** 主标题(富文本) */
93 | @property(nullable, nonatomic, copy) NSAttributedString *attributedTitle;
94 | /** 副标题(富文本) */
95 | @property(nullable, nonatomic, copy) NSAttributedString *attributedMessage;
96 | /** 头部图标,位置处于title之上,大小取决于图片本身大小 */
97 | @property(nullable,nonatomic, copy) UIImage *image;
98 |
99 | /** 主标题颜色 */
100 | @property(nonatomic, strong) UIColor *titleColor;
101 | /** 主标题字体,默认18,加粗 */
102 | @property(nonatomic, strong) UIFont *titleFont;
103 | /** 副标题颜色 */
104 | @property(nonatomic, strong) UIColor *messageColor;
105 | /** 副标题字体,默认16,未加粗 */
106 | @property(nonatomic, strong) UIFont *messageFont;
107 | /** 对齐方式(包括主标题和副标题) */
108 | @property(nonatomic, assign) NSTextAlignment textAlignment;
109 | /** 头部图标的限制大小,默认无穷大 */
110 | @property (nonatomic, assign) CGSize imageLimitSize;
111 | /** 图片的tintColor,当外部的图片使用了UIImageRenderingModeAlwaysTemplate时,该属性可起到作用 */
112 | @property (nonatomic, strong) UIColor *imageTintColor;
113 |
114 | /*
115 | * action水平排列还是垂直排列
116 | * actionSheet样式下:默认为UILayoutConstraintAxisVertical(垂直排列), 如果设置为UILayoutConstraintAxisHorizontal(水平排列),则除去取消样式action之外的其余action将水平排列
117 | * alert样式下:当actions的个数大于2,或者某个action的title显示不全时为UILayoutConstraintAxisVertical(垂直排列),否则默认为UILayoutConstraintAxisHorizontal(水平排列),此样式下设置该属性可以修改所有action的排列方式
118 | * 不论哪种样式,只要外界设置了该属性,永远以外界设置的优先
119 | */
120 | @property(nonatomic) UILayoutConstraintAxis actionAxis;
121 |
122 | /* 距离屏幕边缘的最小间距
123 | * alert样式下该属性是指对话框四边与屏幕边缘之间的距离,此样式下默认值随设备变化,actionSheet样式下是指弹出边的对立边与屏幕之间的距离,比如如果从右边弹出,那么该属性指的就是对话框左边与屏幕之间的距离,此样式下默认值为70
124 | */
125 | @property(nonatomic, assign) CGFloat minDistanceToEdges;
126 |
127 | /** SPAlertControllerStyleAlert样式下默认6.0f,SPAlertControllerStyleActionSheet样式下默认13.0f,去除半径设置为0即可 */
128 | @property(nonatomic, assign) CGFloat cornerRadius;
129 |
130 | /** 对话框的偏移量,y值为正向下偏移,为负向上偏移;x值为正向右偏移,为负向左偏移,该属性只对SPAlertControllerStyleAlert样式有效,键盘的frame改变会自动偏移,如果手动设置偏移只会取手动设置的 */
131 | @property(nonatomic, assign) CGPoint offsetForAlert;
132 | /** 设置alert样式下的偏移量,动画为NO则跟属性offsetForAlert等效 */
133 | - (void)setOffsetForAlert:(CGPoint)offsetForAlert animated:(BOOL)animated;
134 |
135 | /** 是否需要对话框拥有毛玻璃,默认为YES */
136 | @property(nonatomic, assign) BOOL needDialogBlur;
137 |
138 | /** 是否单击背景退出对话框,默认为YES */
139 | @property(nonatomic, assign) BOOL tapBackgroundViewDismiss;
140 |
141 | @property(nonatomic, weak) id delegate;
142 |
143 | @property(nonatomic, readonly) SPAlertControllerStyle preferredStyle;
144 | @property(nonatomic, readonly) SPAlertAnimationType animationType;
145 |
146 | /** 设置action与下一个action之间的间距, action仅限于非取消样式,必须在'-addAction:'之后设置,iOS11或iOS11以上才能使用 */
147 | - (void)setCustomSpacing:(CGFloat)spacing afterAction:(SPAlertAction *)action API_AVAILABLE(ios(11.0));
148 | - (CGFloat)customSpacingAfterAction:(SPAlertAction *)action API_AVAILABLE(ios(11.0));
149 |
150 | /** 设置蒙层的外观样式,可通过alpha调整透明度 */
151 | - (void)setBackgroundViewAppearanceStyle:(UIBlurEffectStyle)style alpha:(CGFloat)alpha;
152 |
153 | // 插入一个组件view,位置处于头部和action部分之间,要求头部和action部分同时存在
154 | - (void)insertComponentView:(nonnull UIView *)componentView;
155 |
156 |
157 | // ---------------------------------------------- custom -----------------------------------------------------
158 | /**
159 | 创建控制器(自定义整个对话框)
160 |
161 | @param customAlertView 整个对话框的自定义view
162 | @param preferredStyle 对话框样式
163 | @param animationType 动画类型
164 | @return 控制器对象
165 | */
166 | + (instancetype)alertControllerWithCustomAlertView:(nonnull UIView *)customAlertView preferredStyle:(SPAlertControllerStyle)preferredStyle animationType:(SPAlertAnimationType)animationType;
167 | /**
168 | 创建控制器(自定义对话框的头部)
169 |
170 | @param customHeaderView 头部自定义view
171 | @param preferredStyle 对话框样式
172 | @param animationType 动画类型
173 | @return 控制器对象
174 | */
175 | + (instancetype)alertControllerWithCustomHeaderView:(nonnull UIView *)customHeaderView preferredStyle:(SPAlertControllerStyle)preferredStyle animationType:(SPAlertAnimationType)animationType;
176 | /**
177 | 创建控制器(自定义对话框的action部分)
178 |
179 | @param customActionSequenceView action部分的自定义view
180 | @param title 大标题
181 | @param message 副标题
182 | @param preferredStyle 对话框样式
183 | @param animationType 动画类型
184 | @return 控制器对象
185 | */
186 | + (instancetype)alertControllerWithCustomActionSequenceView:(nonnull UIView *)customActionSequenceView title:(nullable NSString *)title message:(nullable NSString *)message preferredStyle:(SPAlertControllerStyle)preferredStyle animationType:(SPAlertAnimationType)animationType;
187 |
188 | /** 更新自定义view的size,比如屏幕旋转,自定义view的大小发生了改变,可通过该方法更新size */
189 | - (void)updateCustomViewSize:(CGSize)size;
190 |
191 | @property(nonatomic, assign) CGFloat cornerRadiusForAlert NS_DEPRECATED_IOS(8_0, 8_0,"Use cornerRadius instead");
192 | @property (nonatomic, assign) CGFloat maxTopMarginForActionSheet NS_DEPRECATED_IOS(8_0, 8_0,"Use minDistanceToEdges instead");
193 | @property(nonatomic, assign) CGFloat maxMarginForAlert NS_DEPRECATED_IOS(8_0, 8_0,"Use minDistanceToEdges instead");
194 | @property(nonatomic, assign) NSInteger maxNumberOfActionHorizontalArrangementForAlert NS_DEPRECATED_IOS(8_0, 8_0,"Use actionAxis instead");
195 | @property(nonatomic, assign) CGFloat offsetYForAlert NS_DEPRECATED_IOS(8_0, 8_0,"Use offsetForAlert instead");
196 | + (instancetype)alertControllerWithTitle:(nullable NSString *)title message:(nullable NSString *)message preferredStyle:(SPAlertControllerStyle)preferredStyle animationType:(SPAlertAnimationType)animationType customView:(nullable UIView *)customView NS_DEPRECATED_IOS(8_0, 8_0,"Use +alertControllerWithCustomAlertView:preferredStyle:animationType:");
197 | + (instancetype)alertControllerWithPreferredStyle:(SPAlertControllerStyle)preferredStyle animationType:(SPAlertAnimationType)animationType customHeaderView:(nullable UIView *)customHeaderView NS_DEPRECATED_IOS(8_0, 8_0,"Use +alertControllerWithCustomHeaderView:preferredStyle:animationType:");
198 | + (instancetype)alertControllerWithTitle:(nullable NSString *)title message:(nullable NSString *)message preferredStyle:(SPAlertControllerStyle)preferredStyle animationType:(SPAlertAnimationType)animationType customCenterView:(nullable UIView *)customCenterView NS_DEPRECATED_IOS(8_0, 8_0,"Use -insertComponentView:");
199 | + (instancetype)alertControllerWithTitle:(nullable NSString *)title message:(nullable NSString *)message preferredStyle:(SPAlertControllerStyle)preferredStyle animationType:(SPAlertAnimationType)animationType customFooterView:(nullable UIView *)customFooterView NS_DEPRECATED_IOS(8_0, 8_0,"Use +alertControllerWithCustomActionSequenceView:title:message:preferredStyle:animationType:");
200 | @end
201 |
202 | @protocol SPAlertControllerDelegate
203 | @optional;
204 | - (void)willPresentAlertController:(SPAlertController *)alertController; // 将要present
205 | - (void)didPresentAlertController:(SPAlertController *)alertController; // 已经present
206 | - (void)willDismissAlertController:(SPAlertController *)alertController; // 将要dismiss
207 | - (void)didDismissAlertController:(SPAlertController *)alertController; // 已经dismiss
208 |
209 |
210 | - (void)sp_alertControllerWillShow:(SPAlertController *)alertController NS_DEPRECATED_IOS(8_0, 8_0,"Use -willPresentAlertController:");
211 | - (void)sp_alertControllerDidShow:(SPAlertController *)alertController NS_DEPRECATED_IOS(8_0, 8_0,"Use -DidPresentAlertController:");
212 | - (void)sp_alertControllerWillHide:(SPAlertController *)alertController NS_DEPRECATED_IOS(8_0, 8_0,"Use -willDismissAlertController:");
213 | - (void)sp_alertControllerDidHide:(SPAlertController *)alertController NS_DEPRECATED_IOS(8_0, 8_0,"Use -DidDismissAlertController:");
214 | @end
215 |
216 | @interface SPAlertPresentationController : UIPresentationController
217 | @end
218 |
219 | @interface SPAlertAnimation : NSObject
220 | + (instancetype)animationIsPresenting:(BOOL)presenting;
221 | @end
222 |
223 | NS_ASSUME_NONNULL_END
224 |
--------------------------------------------------------------------------------