├── .gitignore
├── .swift-version
├── Demo
├── AppDelegate.swift
├── Assets.xcassets
│ └── AppIcon.appiconset
│ │ ├── Contents.json
│ │ ├── Icon-29.0@1x.png
│ │ ├── Icon-29.0@2x.png
│ │ ├── Icon-29.0@3x.png
│ │ ├── Icon-40.0@1x.png
│ │ ├── Icon-40.0@2x.png
│ │ ├── Icon-40.0@3x.png
│ │ ├── Icon-50.0@1x.png
│ │ ├── Icon-50.0@2x.png
│ │ ├── Icon-57.0@1x.png
│ │ ├── Icon-57.0@2x.png
│ │ ├── Icon-60.0@2x.png
│ │ ├── Icon-60.0@3x.png
│ │ ├── Icon-72.0@1x.png
│ │ ├── Icon-72.0@2x.png
│ │ ├── Icon-76.0@1x.png
│ │ ├── Icon-76.0@2x.png
│ │ └── Icon-83.5@2x.png
├── Base.lproj
│ └── Main.storyboard
├── Info.plist
├── Launch Screen.storyboard
└── ViewController.swift
├── LICENSE
├── README.md
├── WCLImagePickerController.podspec
├── WCLImagePickerController.xcodeproj
├── project.pbxproj
├── project.xcworkspace
│ └── contents.xcworkspacedata
└── xcuserdata
│ └── wangchonglei.xcuserdatad
│ └── xcschemes
│ ├── Demo.xcscheme
│ ├── WCLImagePickerController.xcscheme
│ └── xcschememanagement.plist
├── WCLImagePickerController
├── Info.plist
└── WCLImagePickerController
│ ├── Cells
│ ├── WCLAblumListCell.swift
│ ├── WCLAblumListCell.xib
│ ├── photoBrowserCells
│ │ ├── WCLPhotoCVCell.swift
│ │ ├── WCLPhotoCVCell.xib
│ │ └── WCLPhotoCellContext.swift
│ └── pickerCells
│ │ ├── WCLCameraCVCell.swift
│ │ ├── WCLCameraCVCell.xib
│ │ ├── WCLPickerCVCell.swift
│ │ ├── WCLPickerCVCell.xib
│ │ ├── WCLPickerCellContext.swift
│ │ ├── WCLSelecteCVCell.swift
│ │ └── WCLSelecteCVCell.xib
│ ├── Others
│ ├── WCLBaseImagePickerController.swift
│ ├── WCLError.swift
│ ├── WCLImagePickerBundle.swift
│ ├── WCLImagePickerNotify.swift
│ ├── WCLImagePickerOptions.swift
│ ├── WCLImagePikcerDelegate.swift
│ ├── WCLNavigationController.swift
│ ├── WCLPickerExtension.swift
│ └── WCLPickerManager.swift
│ ├── ViewControllers
│ ├── WCLImagePickerController.swift
│ ├── WCLImagePickerController.xib
│ ├── WCLPhotoBrowserController.swift
│ └── WCLPhotoBrowserController.xib
│ ├── Views
│ ├── WCLAblumCenterView.swift
│ ├── WCLAblumListView.swift
│ ├── WCLAblumListView.xib
│ ├── WCLLaunchView.swift
│ ├── WCLPhotoSelectView.swift
│ ├── WCLPhotoSelectView.xib
│ ├── WCLSelectView.swift
│ └── WCLSelectView.xib
│ └── WCLImagePickerController.bundle
│ ├── Images
│ ├── image_ablumSelectBackGround@2x.png
│ ├── image_ablumSelectBackGround@3x.png
│ ├── image_buffer@2x.png
│ ├── image_buffer@3x.png
│ ├── image_camera@2x.png
│ ├── image_camera@3x.png
│ ├── image_photoAlbum@2x.png
│ ├── image_photoAlbum@3x.png
│ ├── image_pickerArrow@2x.png
│ ├── image_pickerArrow@3x.png
│ ├── image_pickerDefault@2x.png
│ ├── image_pickerDefault@3x.png
│ ├── image_selectPlaceholder@2x.png
│ └── image_selectPlaceholder@3x.png
│ ├── en.lproj
│ └── Localizable.strings
│ └── zh.lproj
│ └── Localizable.strings
└── wcl.gif
/.gitignore:
--------------------------------------------------------------------------------
1 | # Xcode
2 | #
3 | # gitignore contributors: remember to update Global/Xcode.gitignore, Objective-C.gitignore & Swift.gitignore
4 |
5 | ## Build generated
6 | build/
7 | DerivedData/
8 |
9 | ## Various settings
10 | *.pbxuser
11 | !default.pbxuser
12 | *.mode1v3
13 | !default.mode1v3
14 | *.mode2v3
15 | !default.mode2v3
16 | *.perspectivev3
17 | !default.perspectivev3
18 | xcuserdata/
19 |
20 | ## Other
21 | *.moved-aside
22 | *.xcuserstate
23 | .DS_Store
24 |
25 | ## Obj-C/Swift specific
26 | *.hmap
27 | *.ipa
28 | *.dSYM.zip
29 | *.dSYM
30 |
31 | ## Playgrounds
32 | timeline.xctimeline
33 | playground.xcworkspace
34 |
35 | # Swift Package Manager
36 | #
37 | # Add this line if you want to avoid checking in source code from Swift Package Manager dependencies.
38 | # Packages/
39 | .build/
40 |
41 | # CocoaPods
42 | #
43 | # We recommend against adding the Pods directory to your .gitignore. However
44 | # you should judge for yourself, the pros and cons are mentioned at:
45 | # https://guides.cocoapods.org/using/using-cocoapods.html#should-i-check-the-pods-directory-into-source-control
46 | #
47 | # Pods/
48 |
49 | # Carthage
50 | #
51 | # Add this line if you want to avoid checking in source code from Carthage dependencies.
52 | # Carthage/Checkouts
53 |
54 | Carthage/Build
55 |
56 | # fastlane
57 | #
58 | # It is recommended to not store the screenshots in the git repo. Instead, use fastlane to re-generate the
59 | # screenshots whenever they are needed.
60 | # For more information about the recommended setup visit:
61 | # https://github.com/fastlane/fastlane/blob/master/fastlane/docs/Gitignore.md
62 |
63 | fastlane/report.xml
64 | fastlane/Preview.html
65 | fastlane/screenshots
66 | fastlane/test_output
67 |
--------------------------------------------------------------------------------
/.swift-version:
--------------------------------------------------------------------------------
1 | 3.0
2 |
--------------------------------------------------------------------------------
/Demo/AppDelegate.swift:
--------------------------------------------------------------------------------
1 | //
2 | // AppDelegate.swift
3 | // Demo
4 | //
5 | // Created by 王崇磊 on 2017/1/10.
6 | // Copyright © 2017年 王崇磊. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | @UIApplicationMain
12 | class AppDelegate: UIResponder, UIApplicationDelegate {
13 |
14 | var window: UIWindow?
15 |
16 |
17 | func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
18 | // Override point for customization after application launch.
19 | return true
20 | }
21 |
22 | func applicationWillResignActive(_ application: UIApplication) {
23 | // 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.
24 | // Use this method to pause ongoing tasks, disable timers, and invalidate graphics rendering callbacks. Games should use this method to pause the game.
25 | }
26 |
27 | func applicationDidEnterBackground(_ application: UIApplication) {
28 | // 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.
29 | // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
30 | }
31 |
32 | func applicationWillEnterForeground(_ application: UIApplication) {
33 | // 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.
34 | }
35 |
36 | func applicationDidBecomeActive(_ application: UIApplication) {
37 | // 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.
38 | }
39 |
40 | func applicationWillTerminate(_ application: UIApplication) {
41 | // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
42 | }
43 |
44 |
45 | }
46 |
47 |
--------------------------------------------------------------------------------
/Demo/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 | "size" : "29x29",
15 | "idiom" : "iphone",
16 | "filename" : "Icon-29.0@1x.png",
17 | "scale" : "1x"
18 | },
19 | {
20 | "size" : "29x29",
21 | "idiom" : "iphone",
22 | "filename" : "Icon-29.0@2x.png",
23 | "scale" : "2x"
24 | },
25 | {
26 | "size" : "29x29",
27 | "idiom" : "iphone",
28 | "filename" : "Icon-29.0@3x.png",
29 | "scale" : "3x"
30 | },
31 | {
32 | "size" : "40x40",
33 | "idiom" : "iphone",
34 | "filename" : "Icon-40.0@2x.png",
35 | "scale" : "2x"
36 | },
37 | {
38 | "size" : "40x40",
39 | "idiom" : "iphone",
40 | "filename" : "Icon-40.0@3x.png",
41 | "scale" : "3x"
42 | },
43 | {
44 | "size" : "57x57",
45 | "idiom" : "iphone",
46 | "filename" : "Icon-57.0@1x.png",
47 | "scale" : "1x"
48 | },
49 | {
50 | "size" : "57x57",
51 | "idiom" : "iphone",
52 | "filename" : "Icon-57.0@2x.png",
53 | "scale" : "2x"
54 | },
55 | {
56 | "size" : "60x60",
57 | "idiom" : "iphone",
58 | "filename" : "Icon-60.0@2x.png",
59 | "scale" : "2x"
60 | },
61 | {
62 | "size" : "60x60",
63 | "idiom" : "iphone",
64 | "filename" : "Icon-60.0@3x.png",
65 | "scale" : "3x"
66 | },
67 | {
68 | "idiom" : "ipad",
69 | "size" : "20x20",
70 | "scale" : "1x"
71 | },
72 | {
73 | "idiom" : "ipad",
74 | "size" : "20x20",
75 | "scale" : "2x"
76 | },
77 | {
78 | "size" : "29x29",
79 | "idiom" : "ipad",
80 | "filename" : "Icon-29.0@1x.png",
81 | "scale" : "1x"
82 | },
83 | {
84 | "size" : "29x29",
85 | "idiom" : "ipad",
86 | "filename" : "Icon-29.0@2x.png",
87 | "scale" : "2x"
88 | },
89 | {
90 | "size" : "40x40",
91 | "idiom" : "ipad",
92 | "filename" : "Icon-40.0@1x.png",
93 | "scale" : "1x"
94 | },
95 | {
96 | "size" : "40x40",
97 | "idiom" : "ipad",
98 | "filename" : "Icon-40.0@2x.png",
99 | "scale" : "2x"
100 | },
101 | {
102 | "size" : "50x50",
103 | "idiom" : "ipad",
104 | "filename" : "Icon-50.0@1x.png",
105 | "scale" : "1x"
106 | },
107 | {
108 | "size" : "50x50",
109 | "idiom" : "ipad",
110 | "filename" : "Icon-50.0@2x.png",
111 | "scale" : "2x"
112 | },
113 | {
114 | "size" : "72x72",
115 | "idiom" : "ipad",
116 | "filename" : "Icon-72.0@1x.png",
117 | "scale" : "1x"
118 | },
119 | {
120 | "size" : "72x72",
121 | "idiom" : "ipad",
122 | "filename" : "Icon-72.0@2x.png",
123 | "scale" : "2x"
124 | },
125 | {
126 | "size" : "76x76",
127 | "idiom" : "ipad",
128 | "filename" : "Icon-76.0@1x.png",
129 | "scale" : "1x"
130 | },
131 | {
132 | "size" : "76x76",
133 | "idiom" : "ipad",
134 | "filename" : "Icon-76.0@2x.png",
135 | "scale" : "2x"
136 | },
137 | {
138 | "size" : "83.5x83.5",
139 | "idiom" : "ipad",
140 | "filename" : "Icon-83.5@2x.png",
141 | "scale" : "2x"
142 | }
143 | ],
144 | "info" : {
145 | "version" : 1,
146 | "author" : "xcode"
147 | }
148 | }
--------------------------------------------------------------------------------
/Demo/Assets.xcassets/AppIcon.appiconset/Icon-29.0@1x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/imwcl/WCLImagePickerController/a5b9328d09d399e6c4384b940f4bcca8fbe53ff7/Demo/Assets.xcassets/AppIcon.appiconset/Icon-29.0@1x.png
--------------------------------------------------------------------------------
/Demo/Assets.xcassets/AppIcon.appiconset/Icon-29.0@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/imwcl/WCLImagePickerController/a5b9328d09d399e6c4384b940f4bcca8fbe53ff7/Demo/Assets.xcassets/AppIcon.appiconset/Icon-29.0@2x.png
--------------------------------------------------------------------------------
/Demo/Assets.xcassets/AppIcon.appiconset/Icon-29.0@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/imwcl/WCLImagePickerController/a5b9328d09d399e6c4384b940f4bcca8fbe53ff7/Demo/Assets.xcassets/AppIcon.appiconset/Icon-29.0@3x.png
--------------------------------------------------------------------------------
/Demo/Assets.xcassets/AppIcon.appiconset/Icon-40.0@1x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/imwcl/WCLImagePickerController/a5b9328d09d399e6c4384b940f4bcca8fbe53ff7/Demo/Assets.xcassets/AppIcon.appiconset/Icon-40.0@1x.png
--------------------------------------------------------------------------------
/Demo/Assets.xcassets/AppIcon.appiconset/Icon-40.0@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/imwcl/WCLImagePickerController/a5b9328d09d399e6c4384b940f4bcca8fbe53ff7/Demo/Assets.xcassets/AppIcon.appiconset/Icon-40.0@2x.png
--------------------------------------------------------------------------------
/Demo/Assets.xcassets/AppIcon.appiconset/Icon-40.0@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/imwcl/WCLImagePickerController/a5b9328d09d399e6c4384b940f4bcca8fbe53ff7/Demo/Assets.xcassets/AppIcon.appiconset/Icon-40.0@3x.png
--------------------------------------------------------------------------------
/Demo/Assets.xcassets/AppIcon.appiconset/Icon-50.0@1x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/imwcl/WCLImagePickerController/a5b9328d09d399e6c4384b940f4bcca8fbe53ff7/Demo/Assets.xcassets/AppIcon.appiconset/Icon-50.0@1x.png
--------------------------------------------------------------------------------
/Demo/Assets.xcassets/AppIcon.appiconset/Icon-50.0@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/imwcl/WCLImagePickerController/a5b9328d09d399e6c4384b940f4bcca8fbe53ff7/Demo/Assets.xcassets/AppIcon.appiconset/Icon-50.0@2x.png
--------------------------------------------------------------------------------
/Demo/Assets.xcassets/AppIcon.appiconset/Icon-57.0@1x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/imwcl/WCLImagePickerController/a5b9328d09d399e6c4384b940f4bcca8fbe53ff7/Demo/Assets.xcassets/AppIcon.appiconset/Icon-57.0@1x.png
--------------------------------------------------------------------------------
/Demo/Assets.xcassets/AppIcon.appiconset/Icon-57.0@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/imwcl/WCLImagePickerController/a5b9328d09d399e6c4384b940f4bcca8fbe53ff7/Demo/Assets.xcassets/AppIcon.appiconset/Icon-57.0@2x.png
--------------------------------------------------------------------------------
/Demo/Assets.xcassets/AppIcon.appiconset/Icon-60.0@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/imwcl/WCLImagePickerController/a5b9328d09d399e6c4384b940f4bcca8fbe53ff7/Demo/Assets.xcassets/AppIcon.appiconset/Icon-60.0@2x.png
--------------------------------------------------------------------------------
/Demo/Assets.xcassets/AppIcon.appiconset/Icon-60.0@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/imwcl/WCLImagePickerController/a5b9328d09d399e6c4384b940f4bcca8fbe53ff7/Demo/Assets.xcassets/AppIcon.appiconset/Icon-60.0@3x.png
--------------------------------------------------------------------------------
/Demo/Assets.xcassets/AppIcon.appiconset/Icon-72.0@1x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/imwcl/WCLImagePickerController/a5b9328d09d399e6c4384b940f4bcca8fbe53ff7/Demo/Assets.xcassets/AppIcon.appiconset/Icon-72.0@1x.png
--------------------------------------------------------------------------------
/Demo/Assets.xcassets/AppIcon.appiconset/Icon-72.0@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/imwcl/WCLImagePickerController/a5b9328d09d399e6c4384b940f4bcca8fbe53ff7/Demo/Assets.xcassets/AppIcon.appiconset/Icon-72.0@2x.png
--------------------------------------------------------------------------------
/Demo/Assets.xcassets/AppIcon.appiconset/Icon-76.0@1x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/imwcl/WCLImagePickerController/a5b9328d09d399e6c4384b940f4bcca8fbe53ff7/Demo/Assets.xcassets/AppIcon.appiconset/Icon-76.0@1x.png
--------------------------------------------------------------------------------
/Demo/Assets.xcassets/AppIcon.appiconset/Icon-76.0@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/imwcl/WCLImagePickerController/a5b9328d09d399e6c4384b940f4bcca8fbe53ff7/Demo/Assets.xcassets/AppIcon.appiconset/Icon-76.0@2x.png
--------------------------------------------------------------------------------
/Demo/Assets.xcassets/AppIcon.appiconset/Icon-83.5@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/imwcl/WCLImagePickerController/a5b9328d09d399e6c4384b940f4bcca8fbe53ff7/Demo/Assets.xcassets/AppIcon.appiconset/Icon-83.5@2x.png
--------------------------------------------------------------------------------
/Demo/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 |
31 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
105 |
106 |
107 |
108 |
109 |
110 |
111 |
112 |
113 |
114 |
115 |
116 |
117 |
118 |
127 |
128 |
129 |
130 |
131 |
132 |
133 |
134 |
135 |
136 |
137 |
138 |
139 |
140 |
141 |
150 |
151 |
152 |
153 |
154 |
155 |
156 |
157 |
158 |
159 |
160 |
161 |
162 |
163 |
164 |
165 |
166 |
167 |
168 |
169 |
170 |
171 |
172 |
173 |
174 |
175 |
176 |
177 |
178 |
179 |
180 |
181 |
182 |
183 |
184 |
185 |
186 |
187 |
188 |
189 |
190 |
191 |
192 |
193 |
194 |
195 |
196 |
197 |
198 |
199 |
200 |
201 |
--------------------------------------------------------------------------------
/Demo/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | zh_CN
7 | CFBundleExecutable
8 | $(EXECUTABLE_NAME)
9 | CFBundleIdentifier
10 | $(PRODUCT_BUNDLE_IDENTIFIER)
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | $(PRODUCT_NAME)
15 | CFBundlePackageType
16 | APPL
17 | CFBundleShortVersionString
18 | 1.0
19 | CFBundleVersion
20 | 1
21 | LSRequiresIPhoneOS
22 |
23 | NSCameraUsageDescription
24 |
25 | NSPhotoLibraryUsageDescription
26 |
27 | UILaunchStoryboardName
28 | Launch Screen
29 | UIMainStoryboardFile
30 | Main
31 | UIRequiredDeviceCapabilities
32 |
33 | armv7
34 |
35 | UISupportedInterfaceOrientations
36 |
37 | UIInterfaceOrientationPortrait
38 | UIInterfaceOrientationLandscapeLeft
39 | UIInterfaceOrientationLandscapeRight
40 |
41 | UISupportedInterfaceOrientations~ipad
42 |
43 | UIInterfaceOrientationPortrait
44 | UIInterfaceOrientationPortraitUpsideDown
45 | UIInterfaceOrientationLandscapeLeft
46 | UIInterfaceOrientationLandscapeRight
47 |
48 |
49 |
50 |
--------------------------------------------------------------------------------
/Demo/Launch Screen.storyboard:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
26 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
--------------------------------------------------------------------------------
/Demo/ViewController.swift:
--------------------------------------------------------------------------------
1 | //
2 | // ViewController.swift
3 | // Demo
4 | //
5 | // Created by 王崇磊 on 2017/1/10.
6 | // Copyright © 2017年 王崇磊. All rights reserved.
7 | //
8 |
9 | import UIKit
10 | import WCLImagePickerController
11 |
12 | class ViewController: UIViewController, WCLImagePikcerDelegate {
13 |
14 | override func viewDidLoad() {
15 | super.viewDidLoad()
16 | // Do any additional setup after loading the view, typically from a nib.
17 | }
18 |
19 | @IBAction func buttonAction(_ sender: Any) {
20 | /// 初始化,直接present出WCLImagePickerController
21 | WCLImagePickerController.present(inVC: self, delegate: self)
22 | /// 或者只初始化WCLImagePickerController.init
23 | /// WCLImagePickerController.init(delegate: self)
24 | }
25 |
26 | func wclImagePickerCancel(_ picker: WCLImagePickerController) {
27 | picker.dismiss(animated: true, completion: nil)
28 | }
29 |
30 | func wclImagePickerComplete(_ picker: WCLImagePickerController, imageArr: [UIImage]) {
31 | picker.dismiss(animated: true, completion: nil)
32 | print(imageArr)
33 | }
34 |
35 | func wclImagePickerError(_ picker: WCLImagePickerController, error: WCLError) {
36 | let al = UIAlertController.init(title: nil, message: error.lcalizable, preferredStyle: .alert)
37 | let cancel = UIAlertAction.init(title: "取消", style: .cancel, handler: nil)
38 | al.addAction(cancel)
39 | picker.present(al, animated: true, completion: nil)
40 | }
41 |
42 | @IBAction func lineChange(_ sender: UISegmentedControl) {
43 | let line = sender.selectedSegmentIndex + 3
44 | WCLImagePickerOptions.photoLineNum = line
45 | }
46 |
47 |
48 | @IBAction func tintColorChange(_ sender: UISegmentedControl) {
49 | let color = [UIColor(red: 49/255, green: 47/255, blue: 47/255, alpha: 1), UIColor.blue, UIColor.yellow][sender.selectedSegmentIndex]
50 | WCLImagePickerOptions.tintColor = color
51 | }
52 |
53 |
54 | @IBAction func hideBottom(_ sender: UISegmentedControl) {
55 | let need = sender.selectedSegmentIndex == 0 ? true : false
56 | WCLImagePickerOptions.isShowSelecView = need
57 | }
58 |
59 | @IBAction func statsBarChange(_ sender: UISegmentedControl) {
60 | if sender.selectedSegmentIndex == 0 {
61 | WCLImagePickerOptions.statusBarStyle = .lightContent
62 | }else {
63 | WCLImagePickerOptions.statusBarStyle = .default
64 | }
65 | }
66 |
67 | @IBAction func maxSelectNum(_ sender: UISegmentedControl) {
68 | let max = [3, 4, 5][sender.selectedSegmentIndex]
69 | WCLImagePickerOptions.maxPhotoSelectNum = max
70 | }
71 |
72 | @IBAction func needCamare(_ sender: UISegmentedControl) {
73 | let need = sender.selectedSegmentIndex == 0 ? true : false
74 | WCLImagePickerOptions.needPickerCamera = need
75 | }
76 |
77 |
78 | override func didReceiveMemoryWarning() {
79 | super.didReceiveMemoryWarning()
80 | // Dispose of any resources that can be recreated.
81 | }
82 |
83 |
84 | }
85 |
86 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 |
2 | WCLImagePickerController license
3 | =========================
4 |
5 | The MIT License (MIT)
6 |
7 | Copyright (c) 2017 W_C__L
8 |
9 | Permission is hereby granted, free of charge, to any person obtaining a copy
10 | of this software and associated documentation files (the "Software"), to deal
11 | in the Software without restriction, including without limitation the rights
12 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
13 | copies of the Software, and to permit persons to whom the Software is
14 | furnished to do so, subject to the following conditions:
15 |
16 | The above copyright notice and this permission notice shall be included in
17 | all copies or substantial portions of the Software.
18 |
19 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
22 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
23 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
24 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
25 | THE SOFTWARE.
26 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 |
2 |
3 | # WCLImagePickerController
4 |
5 | 
6 | [](http://cocoapods.org/pods/WCLImagePickerController)
7 | [](http://cocoapods.org/pods/WCLImagePickerController)
8 | [](http://cocoapods.org/pods/WCLImagePickerController)
9 |
10 | `WCLImagePickerController`是一个自定义的图片选择器
11 |
12 | 
13 |
14 | # Demo
15 |
16 | 可以通过[Appetize.io](https://appetize.io/app/hue1a1gmunhh46dtcxuj8ycfd4?device=iphone5s&scale=75&orientation=portrait&osVersion=9.3)运行我的Demo,非常方便~
17 |
18 | # **Features**
19 |
20 | - [x] 支持多选图片
21 | - [x] 支持图片预览
22 | - [x] 可以高度自定义界面,包括颜色和其他功能
23 | - [x] 支持拍照功能
24 | - [x] 支持本地化(中、英)
25 |
26 | # 安装
27 |
28 | 必须iOS 8.0+ Swift3
29 |
30 | ## CocoaPods
31 |
32 | 如果没有安装你可以用下面的命令安装[CocoaPods](http://cocoapods.org):
33 |
34 | ```shell
35 | $ gem install cocoapods
36 | ```
37 |
38 | 使用CocoaPods将`WCLImagePickerController`添加到您的`Xcode`项目,在`Podfile`中添加一下代码:
39 |
40 | ```ruby
41 | source 'https://github.com/CocoaPods/Specs.git'
42 | platform :ios, '8.0'
43 | use_frameworks!
44 |
45 | pod 'WCLImagePickerController'
46 | ```
47 |
48 | 然后,运行以下命令:
49 |
50 | ```shell
51 | $ pod install
52 | ```
53 |
54 | # 使用
55 |
56 | 首先因为权限问题需要加入照片权限和摄像头的权限:
57 |
58 | 在项目的`info.plist`添加一下字段
59 |
60 | `NSPhotoLibraryUsageDescription`和`NSCameraUsageDescription`
61 |
62 | 可以下载项目查看demo:
63 |
64 | ```swift
65 | // 推出WCLImagePickerController
66 | WCLImagePickerController.present(inVC: self, delegate: self)
67 |
68 | // 实现代理
69 | func wclImagePickerCancel(_ picker: WCLImagePickerController) {
70 | picker.dismiss(animated: true, completion: nil)
71 | }
72 |
73 | func wclImagePickerComplete(_ picker: WCLImagePickerController, imageArr: [UIImage]) {
74 | picker.dismiss(animated: true, completion: nil)
75 | }
76 |
77 | func wclImagePickerError(_ picker: WCLImagePickerController, error: WCLError) {
78 | let al = UIAlertController.init(title: nil, message: error.lcalizable, preferredStyle: .alert)
79 | let cancel = UIAlertAction.init(title: WCLImagePickerBundle.localizedString(key: "取消"), style: .cancel, handler: nil)
80 | al.addAction(cancel)
81 | self.vc?.present(al, animated: true, completion: nil)
82 | }
83 | ```
84 |
85 | # 自定义
86 |
87 | 以下属性都是可以自定义的,下面是一下默认的配置
88 |
89 | ```swift
90 | public struct WCLImagePickerOptions {
91 | //字体设置,默认苹方字体
92 | static var fontLightName: String = "PingFangSC-Light"
93 | static var fontRegularName: String = "PingFangSC-Regular"
94 | static var fontMediumName: String = "PingFangSC-Medium"
95 |
96 | //MARK: 图片选择器的选项
97 | //是否需要拍照功能
98 | static var needPickerCamera: Bool = true
99 | //相册页每行的照片数,默认每行3张
100 | static var photoLineNum: Int = 3
101 | //相册选择页照片的间隔,默认3,最小为2
102 | static var photoInterval: Int = 3
103 | //相册选择器最大选择的照片数
104 | static var maxPhotoSelectNum: Int = 9
105 | //是否显示selectView
106 | static var isShowSelecView: Bool = true
107 |
108 | //MARK: launchImage的配置
109 | //相册启动图片和启动颜色,二选一,launchImage优先级高
110 | static var launchImage: UIImage? = nil
111 | //没有设置默认用imageTintColor
112 | static var launchColor: UIColor? = nil
113 |
114 | //MARK: 状态栏的样式
115 | static var statusBarStyle: UIStatusBarStyle = .lightContent
116 |
117 | //MARK: 图片的配置
118 | static var imageBuffer: UIImage? = WCLImagePickerBundle.imageFromBundle("image_buffer")
119 | static var ablumSelectBackGround: UIImage? = WCLImagePickerBundle.imageFromBundle("image_ablumSelectBackGround")
120 | static var cameraImage: UIImage? = WCLImagePickerBundle.imageFromBundle("image_camera")
121 | static var pickerArrow: UIImage? = WCLImagePickerBundle.imageFromBundle("image_pickerArrow")
122 | static var pickerDefault: UIImage? = WCLImagePickerBundle.imageFromBundle("image_pickerDefault")
123 | static var selectPlaceholder: UIImage? = WCLImagePickerBundle.imageFromBundle("image_selectPlaceholder")
124 |
125 | //MARK: 颜色的配置
126 | static var tintColor: UIColor = UIColor(red: 49/255, green: 47/255, blue: 47/255, alpha: 1)
127 | //没有设置默认用imageTintColor
128 | static var pickerSelectColor: UIColor? = UIColor(red: 255/255, green: 0/255, blue: 27/255, alpha: 1)
129 | //没有设置默认用imageTintColor
130 | static var selectViewBackColor: UIColor? = nil
131 | }
132 | ```
133 |
134 | # blog
135 |
136 | [photos框架的相关介绍](http://blog.csdn.net/wang631106979/article/details/54343860)
137 |
138 |
--------------------------------------------------------------------------------
/WCLImagePickerController.podspec:
--------------------------------------------------------------------------------
1 | #
2 | # Be sure to run `pod spec lint WCLImagePickerController.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 | s.name = "WCLImagePickerController"
12 | s.version = "1.0.5"
13 | s.summary = "由swift实现可自定义的图片选择器。"
14 |
15 | s.homepage = "https://github.com/631106979/WCLImagePickerController"
16 | s.license = 'MIT'
17 | s.author = { "W_C__L" => "wangchonglei93@icloud.com" }
18 | s.platform = :ios, "8.0"
19 | s.source = { :git => "https://github.com/631106979/WCLImagePickerController.git", :tag => "1.0.5" }
20 | s.source_files = 'WCLImagePickerController/**/*.{swift,xib}'
21 | s.resources = 'WCLImagePickerController/WCLImagePickerController/WCLImagePickerController.bundle'
22 | s.frameworks = "UIKit", "Photos"
23 | s.requires_arc = true
24 |
25 | end
26 |
--------------------------------------------------------------------------------
/WCLImagePickerController.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/WCLImagePickerController.xcodeproj/xcuserdata/wangchonglei.xcuserdatad/xcschemes/Demo.xcscheme:
--------------------------------------------------------------------------------
1 |
2 |
5 |
8 |
9 |
15 |
21 |
22 |
23 |
24 |
25 |
30 |
31 |
32 |
33 |
39 |
40 |
41 |
42 |
43 |
44 |
54 |
56 |
62 |
63 |
64 |
65 |
66 |
67 |
73 |
75 |
81 |
82 |
83 |
84 |
86 |
87 |
90 |
91 |
92 |
--------------------------------------------------------------------------------
/WCLImagePickerController.xcodeproj/xcuserdata/wangchonglei.xcuserdatad/xcschemes/WCLImagePickerController.xcscheme:
--------------------------------------------------------------------------------
1 |
2 |
5 |
8 |
9 |
15 |
21 |
22 |
23 |
24 |
25 |
30 |
31 |
32 |
33 |
34 |
35 |
45 |
46 |
52 |
53 |
54 |
55 |
56 |
57 |
63 |
64 |
70 |
71 |
72 |
73 |
75 |
76 |
79 |
80 |
81 |
--------------------------------------------------------------------------------
/WCLImagePickerController.xcodeproj/xcuserdata/wangchonglei.xcuserdatad/xcschemes/xcschememanagement.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | SchemeUserState
6 |
7 | Demo.xcscheme
8 |
9 | orderHint
10 | 1
11 |
12 | WCLImagePickerController.xcscheme
13 |
14 | orderHint
15 | 0
16 |
17 |
18 | SuppressBuildableAutocreation
19 |
20 | 9717A1B11E2517C90075D33E
21 |
22 | primary
23 |
24 |
25 | 9717A1C01E2518360075D33E
26 |
27 | primary
28 |
29 |
30 |
31 |
32 |
33 |
--------------------------------------------------------------------------------
/WCLImagePickerController/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | en
7 | CFBundleExecutable
8 | $(EXECUTABLE_NAME)
9 | CFBundleIdentifier
10 | $(PRODUCT_BUNDLE_IDENTIFIER)
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | $(PRODUCT_NAME)
15 | CFBundlePackageType
16 | FMWK
17 | CFBundleShortVersionString
18 | 1.0
19 | CFBundleVersion
20 | $(CURRENT_PROJECT_VERSION)
21 | NSPrincipalClass
22 |
23 |
24 |
25 |
--------------------------------------------------------------------------------
/WCLImagePickerController/WCLImagePickerController/Cells/WCLAblumListCell.swift:
--------------------------------------------------------------------------------
1 | //
2 | // WCLAblumListCell.swift
3 | // WCLImagePickrController-swift
4 | //
5 | // **************************************************
6 | // * _____ *
7 | // * __ _ __ ___ \ / *
8 | // * \ \/ \/ / / __\ / / *
9 | // * \ _ / | (__ / / *
10 | // * \/ \/ \___/ / /__ *
11 | // * /_____/ *
12 | // * *
13 | // **************************************************
14 | // Github :https://github.com/631106979
15 | // HomePage:http://imwcl.com
16 | // CSDN :http://blog.csdn.net/wang631106979
17 | //
18 | // Created by 王崇磊 on 16/9/14.
19 | // Copyright © 2016年 王崇磊. All rights reserved.
20 | //
21 | // @class WCLAblumListCell
22 | // @abstract 相册列表的TableViewCell
23 | // @discussion 相册列表的TableViewCell
24 |
25 | import UIKit
26 |
27 | class WCLAblumListCell: UITableViewCell,
28 | WCLCellIdentfier {
29 |
30 | @IBOutlet weak var ablumNameLabel: UILabel!
31 | @IBOutlet weak var ablumImageView: UIImageView!
32 | @IBOutlet weak var selectImageView: UIImageView!
33 | //MARK: Public Methods
34 |
35 |
36 | //MARK: Override
37 | override func awakeFromNib() {
38 | super.awakeFromNib()
39 | // Initialization code
40 | ablumImageView.image = WCLImagePickerOptions.imageBuffer
41 | selectImageView.highlightedImage = WCLImagePickerOptions.ablumSelectBackGround
42 | }
43 |
44 | override func setSelected(_ selected: Bool, animated: Bool) {
45 | super.setSelected(selected, animated: animated)
46 |
47 | // Configure the view for the selected state
48 | }
49 | }
50 |
--------------------------------------------------------------------------------
/WCLImagePickerController/WCLImagePickerController/Cells/WCLAblumListCell.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 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
--------------------------------------------------------------------------------
/WCLImagePickerController/WCLImagePickerController/Cells/photoBrowserCells/WCLPhotoCVCell.swift:
--------------------------------------------------------------------------------
1 | //
2 | // WCLPhotoCVCell.swift
3 | // WCLImagePickrController-swift
4 | //
5 | // **************************************************
6 | // * _____ *
7 | // * __ _ __ ___ \ / *
8 | // * \ \/ \/ / / __\ / / *
9 | // * \ _ / | (__ / / *
10 | // * \/ \/ \___/ / /__ *
11 | // * /_____/ *
12 | // * *
13 | // **************************************************
14 | // Github :https://github.com/631106979
15 | // HomePage:http://imwcl.com
16 | // CSDN :http://blog.csdn.net/wang631106979
17 | //
18 | // Created by 王崇磊 on 16/9/14.
19 | // Copyright © 2016年 王崇磊. All rights reserved.
20 | //
21 | // @class WCLPhotoCVCell
22 | // @abstract 图片浏览器的CollectionViewCell
23 | // @discussion 图片浏览器的CollectionViewCell
24 |
25 | import UIKit
26 |
27 | class WCLPhotoCVCell: UICollectionViewCell,
28 | WCLCellIdentfier,
29 | UIScrollViewDelegate {
30 |
31 | @IBOutlet weak var photoSrcollView: UIScrollView!
32 | @IBOutlet weak var photoImageView: UIImageView!
33 | @IBOutlet weak var imageWidth: NSLayoutConstraint!
34 | @IBOutlet weak var imageHeight: NSLayoutConstraint!
35 | @IBOutlet weak var imageTop: NSLayoutConstraint!
36 | @IBOutlet weak var imageRight: NSLayoutConstraint!
37 | @IBOutlet weak var imageBottom: NSLayoutConstraint!
38 | @IBOutlet weak var imageLeft: NSLayoutConstraint!
39 |
40 | deinit {
41 | NotificationCenter.default.removeObserver(self)
42 | }
43 |
44 | override func awakeFromNib() {
45 | NotificationCenter.default.addObserver(self, selector: #selector(zoomChage), name: WCLImagePickerNotify.selectPickerZoom, object: nil)
46 | }
47 |
48 | @objc private func zoomChage() {
49 | photoSrcollView.zoomScale = 1.0
50 | }
51 |
52 | //MARK: UIScrollViewDelegate
53 | func viewForZooming(in scrollView: UIScrollView) -> UIView? {
54 | return photoImageView
55 | }
56 |
57 | func scrollViewDidZoom(_ scrollView: UIScrollView) {
58 | var c = (scrollView.frame.height - photoImageView.frame.height) / 2
59 | if c <= 0 {c = 0}
60 | imageTop.constant = c
61 | imageBottom.constant = c
62 | }
63 | }
64 |
--------------------------------------------------------------------------------
/WCLImagePickerController/WCLImagePickerController/Cells/photoBrowserCells/WCLPhotoCVCell.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 |
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 |
--------------------------------------------------------------------------------
/WCLImagePickerController/WCLImagePickerController/Cells/photoBrowserCells/WCLPhotoCellContext.swift:
--------------------------------------------------------------------------------
1 | //
2 | // WCLPhotoCellContext.swift
3 | // WCLImagePickrController-swift
4 | //
5 | // **************************************************
6 | // * _____ *
7 | // * __ _ __ ___ \ / *
8 | // * \ \/ \/ / / __\ / / *
9 | // * \ _ / | (__ / / *
10 | // * \/ \/ \___/ / /__ *
11 | // * /_____/ *
12 | // * *
13 | // **************************************************
14 | // Github :https://github.com/631106979
15 | // HomePage:https://imwcl.com
16 | // CSDN :http://blog.csdn.net/wang631106979
17 | //
18 | // Created by 王崇磊 on 16/9/14.
19 | // Copyright © 2016年 王崇磊. All rights reserved.
20 | //
21 | // @class WCLPhotoCellContext
22 | // @abstract PhotoBrowserCell的context
23 | // @discussion PhotoBrowserCell的context
24 | //
25 |
26 | import UIKit
27 | import Photos
28 |
29 | class WCLPhotoCellContext: NSObject {
30 |
31 | private var pickerManager: WCLPickerManager
32 |
33 | init(pickerManager: WCLPickerManager) {
34 | self.pickerManager = pickerManager
35 | super.init()
36 | }
37 |
38 | //MARK: Public Methods
39 | func register(collectionView: UICollectionView) {
40 | collectionView.register(UINib.init(nibName: WCLPhotoCVCell.identfier , bundle: WCLImagePickerBundle.bundle), forCellWithReuseIdentifier: WCLPhotoCVCell.identfier)
41 | }
42 |
43 | func getCell(asset: PHAsset, collectionView: UICollectionView, indexPath: IndexPath) -> UICollectionViewCell {
44 | let cell = collectionView.dequeueReusableCell(withReuseIdentifier: WCLPhotoCVCell.identfier, for: indexPath) as! WCLPhotoCVCell
45 | let size = CGSize(width: collectionView.frame.width, height: collectionView.frame.height)
46 | pickerManager.getPhoto(size, alasset: asset) { (image, info) in
47 | if let image = image {
48 | let size = image.size
49 | let scale = CGFloat(size.width/size.height)
50 | let deviceScale = cell.photoSrcollView.bounds.width/cell.photoSrcollView.bounds.height
51 | if scale >= deviceScale {
52 | cell.imageWidth.constant = cell.photoSrcollView.bounds.width
53 | cell.imageHeight.constant = cell.imageWidth.constant/scale
54 | let interval = cell.photoSrcollView.bounds.height - cell.imageHeight.constant
55 | cell.imageBottom.constant = interval/2
56 | cell.imageTop.constant = interval/2
57 | cell.imageRight.constant = 0
58 | cell.imageLeft.constant = 0
59 | }else {
60 | cell.imageHeight.constant = cell.photoSrcollView.bounds.height
61 | cell.imageWidth.constant = cell.imageHeight.constant*scale
62 | let interval = cell.photoSrcollView.bounds.width - cell.imageWidth.constant
63 | cell.imageRight.constant = interval/2
64 | cell.imageLeft.constant = interval/2
65 | cell.imageTop.constant = 0
66 | cell.imageBottom.constant = 0
67 | }
68 | }
69 | cell.photoImageView.image = image
70 | }
71 | return cell
72 | }
73 | }
74 |
--------------------------------------------------------------------------------
/WCLImagePickerController/WCLImagePickerController/Cells/pickerCells/WCLCameraCVCell.swift:
--------------------------------------------------------------------------------
1 | //
2 | // WCLCameraCVCell.swift
3 | // WCLImagePickrController-swift
4 | //
5 | // **************************************************
6 | // * _____ *
7 | // * __ _ __ ___ \ / *
8 | // * \ \/ \/ / / __\ / / *
9 | // * \ _ / | (__ / / *
10 | // * \/ \/ \___/ / /__ *
11 | // * /_____/ *
12 | // * *
13 | // **************************************************
14 | // Github :https://github.com/631106979
15 | // HomePage:http://imwcl.com
16 | // CSDN :http://blog.csdn.net/wang631106979
17 | //
18 | // Created by 王崇磊 on 16/9/14.
19 | // Copyright © 2016年 王崇磊. All rights reserved.
20 | //
21 | // @class WCLCameraCVCell
22 | // @abstract 图片选择器的摄像的CollectionViewCell
23 | // @discussion 图片选择器的摄像的CollectionViewCell
24 |
25 | import UIKit
26 |
27 | class WCLCameraCVCell: UICollectionViewCell,
28 | WCLCellIdentfier {
29 |
30 | @IBOutlet weak var imageCameraView: UIImageView!
31 |
32 | //MARK: Override
33 | override func awakeFromNib() {
34 | super.awakeFromNib()
35 | // Initialization code
36 | imageCameraView.image = WCLImagePickerOptions.cameraImage
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/WCLImagePickerController/WCLImagePickerController/Cells/pickerCells/WCLCameraCVCell.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 |
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 |
--------------------------------------------------------------------------------
/WCLImagePickerController/WCLImagePickerController/Cells/pickerCells/WCLPickerCVCell.swift:
--------------------------------------------------------------------------------
1 | //
2 | // WCLPickerCVCell.swift
3 | // WCLImagePickrController-swift
4 | //
5 | // **************************************************
6 | // * _____ *
7 | // * __ _ __ ___ \ / *
8 | // * \ \/ \/ / / __\ / / *
9 | // * \ _ / | (__ / / *
10 | // * \/ \/ \___/ / /__ *
11 | // * /_____/ *
12 | // * *
13 | // **************************************************
14 | // Github :https://github.com/631106979
15 | // HomePage:http://imwcl.com
16 | // CSDN :http://blog.csdn.net/wang631106979
17 | //
18 | // Created by 王崇磊 on 16/9/14.
19 | // Copyright © 2016年 王崇磊. All rights reserved.
20 | //
21 | // @class WCLPickerCVCell
22 | // @abstract 图片选择器的CollectionViewCell
23 | // @discussion 图片选择器的CollectionViewCell
24 |
25 | import UIKit
26 |
27 | class WCLPickerCVCell: UICollectionViewCell,
28 | WCLCellIdentfier {
29 |
30 | @IBOutlet weak var selectNumBt: UIButton!
31 | @IBOutlet weak var photoImageView: UIImageView!
32 | var selectBlock:(()->Void)?
33 |
34 | //MARK: - Override
35 | override func awakeFromNib() {
36 | super.awakeFromNib()
37 | // Initialization code
38 | selectNumBt.setBackgroundImage(WCLImagePickerOptions.pickerDefault, for: .normal)
39 |
40 | let size = WCLImagePickerOptions.pickerDefault?.size ?? CGSize.zero
41 | UIGraphicsBeginImageContextWithOptions(size, false, UIScreen.main.scale)
42 | let context = UIGraphicsGetCurrentContext()
43 | if let color = WCLImagePickerOptions.pickerSelectColor {
44 | color.setFill()
45 | }else {
46 | WCLImagePickerOptions.tintColor.setFill()
47 | }
48 | context?.addArc(center: CGPoint.init(x: size.width / 2, y: size.height / 2), radius: size.width / 2, startAngle: 0, endAngle: CGFloat(Double.pi * 2), clockwise: true)
49 | context?.fillPath()
50 | let selectImage = UIGraphicsGetImageFromCurrentImageContext()
51 | UIGraphicsEndImageContext()
52 | selectNumBt.setBackgroundImage(selectImage, for: .selected)
53 | }
54 |
55 | //MARK: - Public Methods
56 | @discardableResult
57 | func animation() -> WCLPickerCVCell {
58 | let animation = CAKeyframeAnimation.init(keyPath: "transform.scale")
59 | animation.duration = 0.35
60 | animation.calculationMode = kCAAnimationCubic
61 | animation.values = [1.0 ,1.4, 0.9, 1.15, 0.95, 1.02, 1.0]
62 | self.selectNumBt.layer.add(animation, forKey: "scaleAnimation")
63 | return self
64 | }
65 |
66 | //MARK: - Target Methods
67 | @IBAction func selectAction(_ sender: UIButton) {
68 | if selectBlock != nil {
69 | selectBlock!()
70 | }
71 | }
72 | }
73 |
--------------------------------------------------------------------------------
/WCLImagePickerController/WCLImagePickerController/Cells/pickerCells/WCLPickerCVCell.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 |
36 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
--------------------------------------------------------------------------------
/WCLImagePickerController/WCLImagePickerController/Cells/pickerCells/WCLPickerCellContext.swift:
--------------------------------------------------------------------------------
1 | //
2 | // WCLPickerCellContext.swift
3 | // WCLImagePickrController-swift
4 | //
5 | // **************************************************
6 | // * _____ *
7 | // * __ _ __ ___ \ / *
8 | // * \ \/ \/ / / __\ / / *
9 | // * \ _ / | (__ / / *
10 | // * \/ \/ \___/ / /__ *
11 | // * /_____/ *
12 | // * *
13 | // **************************************************
14 | // Github :https://github.com/631106979
15 | // HomePage:https://imwcl.com
16 | // CSDN :http://blog.csdn.net/wang631106979
17 | //
18 | // Created by 王崇磊 on 16/9/14.
19 | // Copyright © 2016年 王崇磊. All rights reserved.
20 | //
21 | // @class WCLPickerCellContext
22 | // @abstract 图片选择器cell的Context
23 | // @discussion 图片选择器cell的Context
24 | //
25 |
26 | import UIKit
27 | import Photos
28 |
29 | class WCLPickerCellContext: NSObject {
30 |
31 | private var pickerManager: WCLPickerManager
32 |
33 | //MARK: Initial Methods
34 | init(pickerManager: WCLPickerManager) {
35 | self.pickerManager = pickerManager
36 | super.init()
37 | }
38 |
39 | //MARK: Public Methods
40 | func register(collectionView: UICollectionView) {
41 | collectionView.register(UINib.init(nibName: WCLCameraCVCell.identfier , bundle: WCLImagePickerBundle.bundle), forCellWithReuseIdentifier: WCLCameraCVCell.identfier)
42 | collectionView.register(UINib.init(nibName: WCLPickerCVCell.identfier, bundle: WCLImagePickerBundle.bundle), forCellWithReuseIdentifier: WCLPickerCVCell.identfier)
43 | }
44 |
45 | func getPikcerCellNumber(ablumIndex: Int) -> Int {
46 | var count = pickerManager.getAblumCount(ablumIndex)
47 | if WCLImagePickerOptions.needPickerCamera {
48 | count = count + 1
49 | }
50 | return count
51 | }
52 |
53 | func getPickerCell(_ collectionView: UICollectionView, ablumIndex: Int, photoIndex: Int) -> UICollectionViewCell {
54 | if WCLImagePickerOptions.needPickerCamera && photoIndex == 0 {
55 | return getCameraCell(collectionView, ablumIndex: ablumIndex, cellForItemAtIndexPath: IndexPath(item: photoIndex, section: 0))
56 | }else {
57 | return getPhotoCell(collectionView, ablumIndex: ablumIndex, cellForItemAtIndexPath: IndexPath(item: photoIndex, section: 0))
58 | }
59 | }
60 |
61 | //MARK: Private Methods
62 | /**
63 | 返回WCLCameraCVCell,拍照的cell
64 | */
65 | private func getCameraCell(_ collectionView: UICollectionView, ablumIndex: Int, cellForItemAtIndexPath indexPath: IndexPath) -> UICollectionViewCell {
66 | let cell = collectionView.dequeueReusableCell(withReuseIdentifier: WCLCameraCVCell.identfier, for: indexPath)
67 | return cell
68 | }
69 |
70 | /**
71 | 返回WCLPickerCVCell,照片的cell
72 | */
73 | private func getPhotoCell(_ collectionView: UICollectionView, ablumIndex: Int, cellForItemAtIndexPath indexPath: IndexPath) -> UICollectionViewCell {
74 | let cell = collectionView.dequeueReusableCell(withReuseIdentifier: WCLPickerCVCell.identfier, for: indexPath) as! WCLPickerCVCell
75 | //加载图片
76 | var photoIndexPath = indexPath.row
77 | if WCLImagePickerOptions.needPickerCamera == true {
78 | photoIndexPath = photoIndexPath - 1
79 | }
80 | weak var weakCell = cell
81 | if let photoAsset = pickerManager.getPHAsset(ablumIndex, photoIndex: photoIndexPath) {
82 | pickerManager.getPhotoDefalutSize(ablumIndex, photoIndex: photoIndexPath, resultHandler: { (image, infoDic) in
83 | weakCell?.photoImageView.image = image
84 | })
85 | //改变状态
86 | if let photoIndex = pickerManager.index(ofSelect: photoAsset) {
87 | weakCell?.selectNumBt.isSelected = true
88 | cell.selectNumBt.setTitle("\(photoIndex+1)", for: .selected)
89 | }else {
90 | weakCell?.selectNumBt.isSelected = false
91 | cell.selectNumBt.setTitle("", for: .normal)
92 | }
93 | setPickerSelectBlock(cell: cell, photoAsset: photoAsset, ablumIndex: ablumIndex, photoIndex: photoIndexPath)
94 | }
95 | return cell
96 | }
97 |
98 | private func setPickerSelectBlock(cell: WCLPickerCVCell, photoAsset: PHAsset, ablumIndex: Int, photoIndex: Int) {
99 | weak var weakCell = cell
100 | //判断selectCV是需要加入还是删除
101 | cell.selectBlock = { [weak self] () in
102 | let selectCount = self?.pickerManager.selectPhotoArr.count ?? 0
103 | if self?.pickerManager.isContains(formSelect: photoAsset) ?? false {
104 | let photoIndex = self?.pickerManager.index(ofSelect: photoAsset) ?? 0
105 | let index = photoIndex
106 | self?.pickerManager.remove(formSelect: photoAsset)
107 | NotificationCenter.default.post(name: WCLImagePickerNotify.deleteSelectCell, object: IndexPath.init(item: index, section: 0))
108 | NotificationCenter.default.post(name: WCLImagePickerNotify.reloadImagePicker, object: nil)
109 | }else {
110 | if selectCount >= WCLImagePickerOptions.maxPhotoSelectNum {
111 | guard self != nil else {
112 | return
113 | }
114 | NotificationCenter.default.post(name: WCLImagePickerNotify.imagePickerError, object: WCLError.noMoreThanImages)
115 | return
116 | }else {
117 | //添加selectCV的cell
118 | self?.pickerManager.append(toSelect: photoAsset)
119 | let selectCount = self?.pickerManager.selectPhotoArr.count ?? 0
120 | weakCell?.selectNumBt.isSelected = true
121 | weakCell?.selectNumBt.setTitle("\(selectCount)", for: .selected)
122 | weakCell?.animation()
123 | NotificationCenter.default.post(name: WCLImagePickerNotify.insertSelectCell, object: IndexPath.init(item: selectCount - 1, section: 0))
124 | }
125 | }
126 | NotificationCenter.default.post(name: WCLImagePickerNotify.reloadSelectTotalNum, object: nil)
127 | }
128 | }
129 | }
130 |
--------------------------------------------------------------------------------
/WCLImagePickerController/WCLImagePickerController/Cells/pickerCells/WCLSelecteCVCell.swift:
--------------------------------------------------------------------------------
1 | //
2 | // WCLSelecteCVCell.swift
3 | // WCLImagePickrController-swift
4 | //
5 | // **************************************************
6 | // * _____ *
7 | // * __ _ __ ___ \ / *
8 | // * \ \/ \/ / / __\ / / *
9 | // * \ _ / | (__ / / *
10 | // * \/ \/ \___/ / /__ *
11 | // * /_____/ *
12 | // * *
13 | // **************************************************
14 | // Github :https://github.com/631106979
15 | // HomePage:http://imwcl.com
16 | // CSDN :http://blog.csdn.net/wang631106979
17 | //
18 | // Created by 王崇磊 on 16/9/14.
19 | // Copyright © 2016年 王崇磊. All rights reserved.
20 | //
21 | // @class WCLSelecteCVCell
22 | // @abstract WCLSelecteView的cell
23 | // @discussion WCLSelecteView的cell
24 | //
25 |
26 | import UIKit
27 |
28 | class WCLSelecteCVCell: UICollectionViewCell,
29 | WCLCellIdentfier {
30 |
31 | @IBOutlet weak var selectImageView: UIImageView!
32 |
33 | }
34 |
--------------------------------------------------------------------------------
/WCLImagePickerController/WCLImagePickerController/Cells/pickerCells/WCLSelecteCVCell.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 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
--------------------------------------------------------------------------------
/WCLImagePickerController/WCLImagePickerController/Others/WCLBaseImagePickerController.swift:
--------------------------------------------------------------------------------
1 | //
2 | // WCLImagePickerController.swift
3 | // WCLImagePickrController-swift
4 | //
5 | // **************************************************
6 | // * _____ *
7 | // * __ _ __ ___ \ / *
8 | // * \ \/ \/ / / __\ / / *
9 | // * \ _ / | (__ / / *
10 | // * \/ \/ \___/ / /__ *
11 | // * /_____/ *
12 | // * *
13 | // **************************************************
14 | // Github :https://github.com/631106979
15 | // HomePage:http://imwcl.com
16 | // CSDN :http://blog.csdn.net/wang631106979
17 | //
18 | // Created by 王崇磊 on 16/9/14.
19 | // Copyright © 2016年 王崇磊. All rights reserved.
20 | //
21 | // @class WCLImagePickerController
22 | // @abstract WCLBaseImagePickerController
23 | // @discussion WCLBaseImagePickerController
24 | //
25 |
26 | import UIKit
27 |
28 | internal class WCLBaseImagePickerController: UIImagePickerController {
29 |
30 | override var preferredStatusBarStyle: UIStatusBarStyle {
31 | return WCLImagePickerOptions.statusBarStyle
32 | }
33 |
34 | //MARK: Override
35 | override func viewDidLoad() {
36 | super.viewDidLoad()
37 | // Do any additional setup after loading the view.
38 | }
39 |
40 | override func didReceiveMemoryWarning() {
41 | super.didReceiveMemoryWarning()
42 | // Dispose of any resources that can be recreated.
43 | }
44 |
45 | }
46 |
--------------------------------------------------------------------------------
/WCLImagePickerController/WCLImagePickerController/Others/WCLError.swift:
--------------------------------------------------------------------------------
1 | //
2 | // WCLError.swift
3 | // WclImagePickerController
4 | //
5 | // **************************************************
6 | // * _____ *
7 | // * __ _ __ ___ \ / *
8 | // * \ \/ \/ / / __\ / / *
9 | // * \ _ / | (__ / / *
10 | // * \/ \/ \___/ / /__ *
11 | // * /_____/ *
12 | // * *
13 | // **************************************************
14 | // Github :https://github.com/631106979
15 | // HomePage:https://imwcl.com
16 | // CSDN :http://blog.csdn.net/wang631106979
17 | //
18 | // Created by 王崇磊 on 16/9/14.
19 | // Copyright © 2016年 王崇磊. All rights reserved.
20 | //
21 | // @class WCLError
22 | // @abstract 错误提示
23 | // @discussion 错误提示
24 | //
25 |
26 | import UIKit
27 |
28 | public enum WCLError {
29 | /// 没有相册访问权限
30 | case noAlbumPermissions
31 | /// 没有摄像头访问权限
32 | case noCameraPermissions
33 | /// 超过选择最大数
34 | case noMoreThanImages
35 | public var lcalizable: String? {
36 | if self == .noAlbumPermissions {
37 | return WCLImagePickerBundle.localizedString(key: "没有相册访问权限")
38 | }
39 | if self == .noCameraPermissions {
40 | return WCLImagePickerBundle.localizedString(key: "没有摄像头访问权限")
41 | }
42 | if self == .noMoreThanImages {
43 | return String(format: WCLImagePickerBundle.localizedString(key: "最多选择%d张照片") , WCLImagePickerOptions.maxPhotoSelectNum)
44 | }
45 | return nil
46 | }
47 | }
48 |
--------------------------------------------------------------------------------
/WCLImagePickerController/WCLImagePickerController/Others/WCLImagePickerBundle.swift:
--------------------------------------------------------------------------------
1 | //
2 | // WCLImagePickerBundle.swift
3 | // WCLImagePickrController-swift
4 | //
5 | // **************************************************
6 | // * _____ *
7 | // * __ _ __ ___ \ / *
8 | // * \ \/ \/ / / __\ / / *
9 | // * \ _ / | (__ / / *
10 | // * \/ \/ \___/ / /__ *
11 | // * /_____/ *
12 | // * *
13 | // **************************************************
14 | // Github :https://github.com/631106979
15 | // HomePage:https://imwcl.com
16 | // CSDN :http://blog.csdn.net/wang631106979
17 | //
18 | // Created by 王崇磊 on 16/9/14.
19 | // Copyright © 2016年 王崇磊. All rights reserved.
20 | //
21 | // @class WCLImagePickerBundle
22 | // @abstract WCLImagePickerBundle
23 | // @discussion WCLImagePickerBundle
24 | //
25 |
26 | import UIKit
27 |
28 | internal struct WCLImagePickerBundle {
29 |
30 | // 当前的bundle
31 | static var bundle: Bundle {
32 | let bundle = Bundle(for: WCLImagePickerController.self)
33 | return bundle
34 | }
35 |
36 | // 存放资源的bundle
37 | static var wclBundle: Bundle {
38 | let bundle = Bundle(path: self.bundle.path(forResource: "WCLImagePickerController", ofType: "bundle")!)
39 | return bundle!
40 | }
41 |
42 | static func imageFromBundle(_ imageName: String) -> UIImage? {
43 | var imageName = imageName
44 | if UIScreen.main.scale == 2 {
45 | imageName = imageName + "@2x"
46 | }else if UIScreen.main.scale == 3 {
47 | imageName = imageName + "@3x"
48 | }
49 | let bundle = Bundle(path: wclBundle.bundlePath + "/Images")
50 | if let path = bundle?.path(forResource: imageName, ofType: "png") {
51 | let image = UIImage(contentsOfFile: path)
52 | return image
53 | }
54 | return nil
55 | }
56 |
57 | static func localizedString(key: String) -> String {
58 | if let current = Locale.current.languageCode {
59 | var language = ""
60 | switch current {
61 | case "zh":
62 | language = "zh"
63 | default:
64 | language = "en"
65 | }
66 | if let path = wclBundle.path(forResource: language, ofType: "lproj") {
67 | if let bundle = Bundle(path: path) {
68 | let value = bundle.localizedString(forKey: key, value: nil, table: nil)
69 | return Bundle.main.localizedString(forKey: key, value: value, table: nil)
70 | }
71 | }
72 | }
73 | return key
74 | }
75 | }
76 |
--------------------------------------------------------------------------------
/WCLImagePickerController/WCLImagePickerController/Others/WCLImagePickerNotify.swift:
--------------------------------------------------------------------------------
1 | //
2 | // WCLImagePickerNotify.swift
3 | // WCLImagePickrController-swift
4 | //
5 | // **************************************************
6 | // * _____ *
7 | // * __ _ __ ___ \ / *
8 | // * \ \/ \/ / / __\ / / *
9 | // * \ _ / | (__ / / *
10 | // * \/ \/ \___/ / /__ *
11 | // * /_____/ *
12 | // * *
13 | // **************************************************
14 | // Github :https://github.com/631106979
15 | // HomePage:https://imwcl.com
16 | // CSDN :http://blog.csdn.net/wang631106979
17 | //
18 | // Created by 王崇磊 on 16/9/14.
19 | // Copyright © 2016年 王崇磊. All rights reserved.
20 | //
21 | // @class WCLImagePickerNotify
22 | // @abstract WCLImagePicker的通知类
23 | // @discussion WCLImagePicker的通知类
24 | //
25 |
26 | import Foundation
27 |
28 | internal struct WCLImagePickerNotify {
29 | // 刷新imagePicker
30 | static let reloadImagePicker = Notification.Name("WCLReloadImagePickerNotify")
31 |
32 | // 刷新imagePicker的selectView
33 | static let reloadSelect = Notification.Name("WCLReloadSelectPickerNotify")
34 | // 删除imagePicker的selectView的cell
35 | static let deleteSelectCell = Notification.Name("WCLDeleteSelectPickerCellNotofy")
36 | // 插入imagePicker的selectView的cell
37 | static let insertSelectCell = Notification.Name("WCLInsertSelectPickerCellNotofy")
38 |
39 | // 刷新imagePicker的selectView的TotalNum
40 | static let reloadSelectTotalNum = Notification.Name("WCLReloadSelectTotalNumNotofy")
41 |
42 | // imagePicker的error通知
43 | static let imagePickerError = Notification.Name("WCLImagePickerErrorNotify")
44 |
45 | // selectPicker的zoom通知
46 | static let selectPickerZoom = Notification.Name("WCLSelectPickerZoom")
47 | }
48 |
49 |
50 |
51 |
52 |
--------------------------------------------------------------------------------
/WCLImagePickerController/WCLImagePickerController/Others/WCLImagePickerOptions.swift:
--------------------------------------------------------------------------------
1 | //
2 | // WCLImagePickerOptions.swift
3 | // WCLImagePickrController-swift
4 | //
5 | // **************************************************
6 | // * _____ *
7 | // * __ _ __ ___ \ / *
8 | // * \ \/ \/ / / __\ / / *
9 | // * \ _ / | (__ / / *
10 | // * \/ \/ \___/ / /__ *
11 | // * /_____/ *
12 | // * *
13 | // **************************************************
14 | // Github :https://github.com/631106979
15 | // HomePage:https://imwcl.com
16 | // CSDN :http://blog.csdn.net/wang631106979
17 | //
18 | // Created by 王崇磊 on 16/9/14.
19 | // Copyright © 2016年 王崇磊. All rights reserved.
20 | //
21 | // @class WCLImagePickerOptions
22 | // @abstract WCLImagePicker的选项类
23 | // @discussion WCLImagePicker的选项类
24 | //
25 |
26 | import UIKit
27 |
28 | public struct WCLImagePickerOptions {
29 |
30 | /// 字体设置,默认苹方字体
31 | public static var fontLightName: String = "PingFangSC-Light"
32 | public static var fontRegularName: String = "PingFangSC-Regular"
33 | public static var fontMediumName: String = "PingFangSC-Medium"
34 |
35 | /// 是否需要拍照功能
36 | public static var needPickerCamera: Bool = true
37 | /// 相册页每行的照片数,默认每行3张
38 | public static var photoLineNum: Int = 3
39 | /// 相册选择页照片的间隔,默认3,最小为2
40 | public static var photoInterval: Int = 3
41 | /// 相册选择器最大选择的照片数
42 | public static var maxPhotoSelectNum: Int = 9
43 | /// 是否显示selectView
44 | public static var isShowSelecView: Bool = true
45 |
46 | /// launchImage的配置
47 | /// 相册启动图片和启动颜色,二选一,launchImage优先级高
48 | public static var launchImage: UIImage? = nil
49 | /// 没有设置默认用imageTintColor
50 | public static var launchColor: UIColor? = nil
51 |
52 | /// 状态栏的样式
53 | public static var statusBarStyle: UIStatusBarStyle = .lightContent
54 |
55 | /// 图片的配置
56 | public static var imageBuffer: UIImage? = WCLImagePickerBundle.imageFromBundle("image_buffer")
57 | public static var ablumSelectBackGround: UIImage? = WCLImagePickerBundle.imageFromBundle("image_ablumSelectBackGround")
58 | public static var cameraImage: UIImage? = WCLImagePickerBundle.imageFromBundle("image_camera")
59 | public static var pickerArrow: UIImage? = WCLImagePickerBundle.imageFromBundle("image_pickerArrow")
60 | public static var pickerDefault: UIImage? = WCLImagePickerBundle.imageFromBundle("image_pickerDefault")
61 | public static var selectPlaceholder: UIImage? = WCLImagePickerBundle.imageFromBundle("image_selectPlaceholder")
62 |
63 | /// 颜色的配置
64 | public static var tintColor: UIColor = UIColor(red: 49/255, green: 47/255, blue: 47/255, alpha: 1)
65 | /// 没有设置默认用imageTintColor
66 | public static var pickerSelectColor: UIColor? = UIColor(red: 255/255, green: 0/255, blue: 27/255, alpha: 1)
67 | /// 没有设置默认用imageTintColor
68 | public static var selectViewBackColor: UIColor? = nil
69 | }
70 |
--------------------------------------------------------------------------------
/WCLImagePickerController/WCLImagePickerController/Others/WCLImagePikcerDelegate.swift:
--------------------------------------------------------------------------------
1 | //
2 | // WCLImagePikcerDelegate.swift
3 | // WCLImagePickrController-swift
4 | //
5 | // **************************************************
6 | // * _____ *
7 | // * __ _ __ ___ \ / *
8 | // * \ \/ \/ / / __\ / / *
9 | // * \ _ / | (__ / / *
10 | // * \/ \/ \___/ / /__ *
11 | // * /_____/ *
12 | // * *
13 | // **************************************************
14 | // Github :https://github.com/631106979
15 | // HomePage:https://imwcl.com
16 | // CSDN :http://blog.csdn.net/wang631106979
17 | //
18 | // Created by 王崇磊 on 16/9/14.
19 | // Copyright © 2016年 王崇磊. All rights reserved.
20 | //
21 | // @class WCLImagePikcerDelegate
22 | // @abstract WCLImagePikcerVC的Delegate
23 | // @discussion WCLImagePikcerVC的Delegate
24 | //
25 |
26 | import UIKit
27 |
28 | public protocol WCLImagePikcerDelegate: class {
29 | /// 点击取消按钮的回调方法
30 | func wclImagePickerCancel(_ picker: WCLImagePickerController) -> Void
31 | /// 选择完成后的回调方法
32 | func wclImagePickerComplete(_ picker: WCLImagePickerController, imageArr: [UIImage]) -> Void
33 | /// 反馈错误信息的回调方法
34 | func wclImagePickerError(_ picker: WCLImagePickerController, error: WCLError) -> Void
35 | }
36 |
37 | extension WCLImagePikcerDelegate {
38 | public func wclImagePickerCancel(_ picker: WCLImagePickerController) -> Void {}
39 | public func wclImagePickerComplete(_ picker: WCLImagePickerController, imageArr: [UIImage]) -> Void {}
40 | public func wclImagePickerError(_ picker: WCLImagePickerController, error: WCLError) -> Void {}
41 | }
42 |
--------------------------------------------------------------------------------
/WCLImagePickerController/WCLImagePickerController/Others/WCLNavigationController.swift:
--------------------------------------------------------------------------------
1 | //
2 | // WCLNavigationController.swift
3 | // WCLImagePickrController-swift
4 | //
5 | // **************************************************
6 | // * _____ *
7 | // * __ _ __ ___ \ / *
8 | // * \ \/ \/ / / __\ / / *
9 | // * \ _ / | (__ / / *
10 | // * \/ \/ \___/ / /__ *
11 | // * /_____/ *
12 | // * *
13 | // **************************************************
14 | // Github :https://github.com/631106979
15 | // HomePage:http://imwcl.com
16 | // CSDN :http://blog.csdn.net/wang631106979
17 | //
18 | // Created by 王崇磊 on 16/9/14.
19 | // Copyright © 2016年 王崇磊. All rights reserved.
20 | //
21 | // @class WCLNavigationController
22 | // @abstract WCLNavigationController
23 | // @discussion WCLNavigationController
24 | //
25 |
26 | import UIKit
27 |
28 | public class WCLNavigationController: UINavigationController,
29 | UINavigationControllerDelegate {
30 |
31 | override public var preferredStatusBarStyle: UIStatusBarStyle {
32 | return WCLImagePickerOptions.statusBarStyle
33 | }
34 |
35 | //MARK: Public Methods
36 |
37 |
38 | //MARK: Override
39 | override public func viewDidLoad() {
40 | super.viewDidLoad()
41 | // Do any additional setup after loading the view.
42 | navigationBar.isTranslucent = false
43 | delegate = self
44 | modalPresentationCapturesStatusBarAppearance = true
45 | }
46 |
47 | override public func didReceiveMemoryWarning() {
48 | super.didReceiveMemoryWarning()
49 | // Dispose of any resources that can be recreated.
50 | }
51 |
52 | override public func pushViewController(_ viewController: UIViewController, animated: Bool) {
53 | if self.responds(to: #selector(getter: UINavigationController.interactivePopGestureRecognizer)) {
54 | self.interactivePopGestureRecognizer?.isEnabled = false
55 | }
56 | super.pushViewController(viewController, animated: animated)
57 | }
58 |
59 | //MARK: UINavigationControllerDelegate
60 | public func navigationController(_ navigationController: UINavigationController, didShow viewController: UIViewController, animated: Bool) {
61 | if navigationController.responds(to: #selector(getter: UINavigationController.interactivePopGestureRecognizer)) {
62 | navigationController.interactivePopGestureRecognizer?.isEnabled = true
63 | }
64 | if navigationController.viewControllers.count == 1 {
65 | navigationController.interactivePopGestureRecognizer?.isEnabled = false
66 | navigationController.interactivePopGestureRecognizer?.delegate = nil
67 | }
68 | }
69 |
70 |
71 | //MARK: Initial Methods
72 | convenience init(rootViewController: UIViewController, navBarColor: UIColor) {
73 | self.init(rootViewController: rootViewController)
74 | setNavImage(bgColor: navBarColor, shadowColor: UIColor.clear)
75 | }
76 |
77 | //MARK: Setter Getter Methods
78 |
79 |
80 | //MARK: Privater Methods
81 | /**
82 | 设置navBar的颜色
83 |
84 | - parameter bgColor: 背景色
85 | - parameter shadowColor: 阴影色
86 |
87 | - returns: self
88 | */
89 | func setNavImage(bgColor: UIColor, shadowColor: UIColor) {
90 | let width = UIScreen.main.bounds.width
91 | let scale = UIScreen.main.scale
92 |
93 | UIGraphicsBeginImageContextWithOptions(CGSize.init(width: width, height: 64), false, scale)
94 | var context = UIGraphicsGetCurrentContext()!
95 | CGContext.setFillColor(context)(bgColor.cgColor)
96 | CGContext.addRect(context)(CGRect.init(x: 0, y: 0, width: width, height: 64))
97 | CGContext.drawPath(context)(using: .fill)
98 | let bgImage = UIGraphicsGetImageFromCurrentImageContext()
99 |
100 | UIGraphicsBeginImageContextWithOptions(CGSize.init(width: width, height: 1), false, scale)
101 | context = UIGraphicsGetCurrentContext()!
102 | CGContext.setLineWidth(context)(1)
103 | CGContext.setStrokeColor(context)(shadowColor.cgColor)
104 | CGContext.move(context)(to: CGPoint.zero)
105 | CGContext.addLine(context)(to: CGPoint.init(x: width, y: 0))
106 | CGContext.drawPath(context)(using: .stroke)
107 | let shadowImage = UIGraphicsGetImageFromCurrentImageContext()
108 |
109 | self.navigationBar.setBackgroundImage(bgImage, for: .default)
110 | self.navigationBar.shadowImage = shadowImage
111 | }
112 |
113 | }
114 |
--------------------------------------------------------------------------------
/WCLImagePickerController/WCLImagePickerController/Others/WCLPickerExtension.swift:
--------------------------------------------------------------------------------
1 | //
2 | // WCLPickerExtension.swift
3 | // WCLImagePickrController-swift
4 | //
5 | // **************************************************
6 | // * _____ *
7 | // * __ _ __ ___ \ / *
8 | // * \ \/ \/ / / __\ / / *
9 | // * \ _ / | (__ / / *
10 | // * \/ \/ \___/ / /__ *
11 | // * /_____/ *
12 | // * *
13 | // **************************************************
14 | // Github :https://github.com/631106979
15 | // HomePage:https://imwcl.com
16 | // CSDN :http://blog.csdn.net/wang631106979
17 | //
18 | // Created by 王崇磊 on 16/9/14.
19 | // Copyright © 2016年 王崇磊. All rights reserved.
20 | //
21 | // @class WCLPickerExtension
22 | // @abstract WCLPicker的扩展
23 | // @discussion WCLPicker的扩展
24 | //
25 |
26 | import UIKit
27 |
28 | internal extension UIViewController {
29 |
30 | /**
31 | 添加nav右侧按钮
32 | */
33 | @discardableResult
34 | func addWCLPhotoNavRightButton(_ btName:String) -> UIButton {
35 | let rightBt = UIButton()
36 | rightBt.contentHorizontalAlignment = .right
37 | rightBt.setTitle(btName, for: UIControlState())
38 | rightBt.setTitleColor(UIColor.white, for: UIControlState())
39 | rightBt.titleLabel?.font = UIFont.WCLRegularFontOfSize(15)
40 | rightBt.addTarget(self, action: #selector(photoRightAction(_:)), for: .touchUpInside)
41 | rightBt.frame.size = CGSize(width: 16*CGFloat(btName.characters.count), height: 20)
42 | navigationItem.rightBarButtonItem = UIBarButtonItem.init(customView: rightBt)
43 | return rightBt
44 | }
45 |
46 | /**
47 | 添加nav左侧按钮
48 | */
49 | @discardableResult
50 | func addWCLPhotoNavLeftButton(_ btName:String) -> UIButton {
51 | let leftBt = UIButton()
52 | leftBt.contentHorizontalAlignment = .left
53 | leftBt.setTitle(btName, for: UIControlState())
54 | leftBt.setTitleColor(UIColor.white, for: UIControlState())
55 | leftBt.titleLabel?.font = UIFont.WCLRegularFontOfSize(15)
56 | leftBt.frame.size = CGSize(width: 16*CGFloat(btName.characters.count), height: 20)
57 | leftBt.addTarget(self, action: #selector(photoLeftAction(_:)), for: .touchUpInside)
58 | leftBt.sizeToFit()
59 | navigationItem.leftBarButtonItem = UIBarButtonItem.init(customView: leftBt)
60 | return leftBt
61 | }
62 |
63 | /**
64 | 添加nav的titleView
65 | */
66 | @discardableResult
67 | func setWCLPhotoNavTitle(_ title:String) -> UILabel {
68 | let titleLable = UILabel()
69 | titleLable.text = title
70 | titleLable.textColor = UIColor.white
71 | titleLable.font = UIFont.WCLMediumFontOfSize(17)
72 | titleLable.sizeToFit()
73 | navigationItem.titleView = titleLable
74 | return titleLable
75 | }
76 |
77 | func photoLeftAction(_ sender: UIButton) {
78 |
79 | }
80 |
81 | func photoRightAction(_ sender: UIButton) {
82 |
83 | }
84 | }
85 |
86 | //MARK: 字体
87 | extension UIFont {
88 | /**
89 | 更具系统不同返回light字体
90 | */
91 | class func WCLLightFontOfSize(_ fontSize:CGFloat) -> UIFont {
92 | return UIFont.init(name: WCLImagePickerOptions.fontLightName, size: fontSize) ?? UIFont.systemFont(ofSize: fontSize)
93 | }
94 | /**
95 | 更具系统不同返回Regular字体
96 | */
97 | class func WCLRegularFontOfSize(_ fontSize:CGFloat) -> UIFont {
98 | return UIFont.init(name: WCLImagePickerOptions.fontRegularName, size: fontSize) ?? UIFont.systemFont(ofSize: fontSize)
99 | }
100 | /**
101 | 更具系统不同返回Medium字体
102 | */
103 | class func WCLMediumFontOfSize(_ fontSize:CGFloat) -> UIFont {
104 | return UIFont.init(name: WCLImagePickerOptions.fontMediumName, size: fontSize) ?? UIFont.systemFont(ofSize: fontSize)
105 | }
106 | }
107 |
108 | //MARK: 数组的扩展
109 | extension Array {
110 | subscript (wcl_safe index: Int) -> Element? {
111 | return (0.. Bool {
116 | if (0..]]()
33 | private(set) var selectPhotoArr = [PHAsset]()
34 |
35 | //是否同步请求图片
36 | public var isSynchronous: Bool = false {
37 | didSet{
38 | self.photoOption.isSynchronous = isSynchronous
39 | }
40 | }
41 |
42 | //pickerCell照片的size
43 | class public var pickerPhotoSize: CGSize {
44 | assert(WCLImagePickerOptions.photoLineNum > 2, "列数最小为2")
45 | let sreenBounds = UIScreen.main.bounds
46 | let screenWidth = sreenBounds.width > sreenBounds.height ? sreenBounds.height : sreenBounds.width
47 | let width = (screenWidth - CGFloat(WCLImagePickerOptions.photoInterval) * (CGFloat(WCLImagePickerOptions.photoLineNum) - 1)) / CGFloat(WCLImagePickerOptions.photoLineNum)
48 | return CGSize(width: width, height: width)
49 | }
50 |
51 | private var photoManage = PHCachingImageManager()
52 | private let photoOption = PHImageRequestOptions()
53 | private let photoCreationDate = "creationDate"
54 |
55 | //MARK: Override
56 | override init() {
57 | super.init()
58 | //图片请求设置成快速获取
59 | self.photoOption.resizeMode = .fast
60 | self.photoOption.deliveryMode = .opportunistic
61 | getPhotoAlbum()
62 | }
63 |
64 | //MARK: Public Methods
65 | /**
66 | 获取相册的title
67 |
68 | - parameter index: 相册的index
69 |
70 | - returns: 相册的title
71 | */
72 | public func getAblumTitle(_ ablumIndex: Int) -> String {
73 | if let ablum = self.photoAlbums[wcl_safe: ablumIndex] {
74 | if let result = ablum.keys.first {
75 | return "\(result)(\(getAblumCount(ablumIndex)))"
76 | }
77 | }
78 | return ""
79 | }
80 |
81 | //MARK: photo数据的操作
82 | /**
83 | 通过下标返回相册中照片的个数
84 |
85 | - parameter index: 选择的index
86 |
87 | - returns: 相册中照片的个数
88 | */
89 | public func getAblumCount(_ ablumIndex: Int) -> Int {
90 | if let ablum = self.photoAlbums[wcl_safe: ablumIndex] {
91 | if let result = ablum.values.first {
92 | return result.count
93 | }
94 | }
95 | return 0
96 | }
97 |
98 | /**
99 | 通过下标返回相册的PHFetchResult
100 |
101 | - parameter index: 选择相册的index
102 |
103 | - returns: 相册的PHFetchResult
104 | */
105 | public func getAblumResult(_ ablumIndex: Int) -> PHFetchResult? {
106 | if let ablum = self.photoAlbums[wcl_safe: ablumIndex] {
107 | if let result = ablum.values.first {
108 | return result
109 | }
110 | }
111 | return nil
112 | }
113 |
114 | /**
115 | 根据index获取PHAsset
116 |
117 | - parameter ablumIndex: 相册的index
118 | - parameter photoIndex: 相册里图片的index
119 |
120 | - returns: PHAsset
121 | */
122 | public func getPHAsset(_ ablumIndex: Int, photoIndex: Int) -> PHAsset? {
123 | let ablumResult = getAblumResult(ablumIndex)
124 | if ablumResult != nil {
125 | if ablumResult?.count != 0 {
126 | let photoAsset:PHAsset? = ablumResult![photoIndex]
127 | return photoAsset
128 | }
129 | }
130 | return nil
131 | }
132 |
133 | /**
134 | PHAsset是否已经在SelectPhotoArr里
135 |
136 | - parameter alasset: PHAsset对象
137 |
138 | - returns: 返回值
139 | */
140 | public func isContains(formSelect alasset: PHAsset) -> Bool {
141 | return selectPhotoArr.contains(alasset)
142 | }
143 |
144 | /**
145 | PHAsset在SelectPhotoArr的index
146 |
147 | - parameter alasset: PHAsset对象
148 |
149 | - returns: PHAsset在选择的数组的index
150 | */
151 | public func index(ofSelect alasset: PHAsset) -> Int? {
152 | return selectPhotoArr.index(of: alasset)
153 | }
154 |
155 | /**
156 | 删除SelectPhotoArr里的PHAsset
157 |
158 | - parameter alasset: PHAsset对象
159 | */
160 | func remove(formSelect alasset: PHAsset) {
161 | if let index = index(ofSelect: alasset) {
162 | selectPhotoArr.wcl_removeSafe(at: index)
163 | }
164 | }
165 |
166 | /**
167 | 添加PHAsset到SelectPhotoArr
168 |
169 | - parameter alasset: 要添加的PHAsset
170 | */
171 | public func append(toSelect alasset: PHAsset) {
172 | selectPhotoArr.append(alasset)
173 | }
174 |
175 | //MARK: 通过请求获取photo的数据
176 | /**
177 | 根据index获取photo
178 |
179 | - parameter ablumIndex: 相册的index
180 | - parameter photoIndex: 相册里图片的index
181 | - parameter photoSize: 图片的size
182 | - parameter resultHandler: 返回照片的回调
183 | */
184 | public func getPhoto(_ ablumIndex: Int, photoIndex: Int, photoSize: CGSize, resultHandler: ((UIImage?, [AnyHashable: Any]?) -> Void)?) {
185 | let photoAsset:PHAsset? = getPHAsset(ablumIndex, photoIndex: photoIndex)
186 | if photoAsset != nil {
187 | let scale = UIScreen.main.scale
188 | let photoScaleSize = CGSize(width: photoSize.width*scale, height: photoSize.height*scale)
189 | self.photoManage.requestImage(for: photoAsset!, targetSize: photoScaleSize, contentMode: .aspectFill, options: self.photoOption, resultHandler: { (image, infoDic) in
190 | if image != nil {
191 | resultHandler?(image, infoDic)
192 | }else {
193 | let image_buffer = WCLImagePickerBundle.imageFromBundle("image-buffer")
194 | resultHandler?(image_buffer, infoDic)
195 | }
196 | })
197 | }
198 | }
199 |
200 | /**
201 | 根据PHAsset获取photo
202 |
203 | - parameter ablumIndex: 相册的index
204 | - parameter alasset: 相册里图片的PHAsset
205 | - parameter photoSize: 图片的size
206 | - parameter resultHandler: 返回照片的回调
207 | */
208 | public func getPhoto(_ photoSize: CGSize, alasset: PHAsset?, resultHandler: ((UIImage?, [AnyHashable: Any]?) -> Void)?) {
209 | if alasset != nil {
210 | let scale = UIScreen.main.scale
211 | let photoScaleSize = CGSize(width: photoSize.width*scale, height: photoSize.height*scale)
212 | self.photoManage.requestImage(for: alasset!, targetSize: photoScaleSize, contentMode: .aspectFill, options: self.photoOption, resultHandler: { (image, infoDic) in
213 | if image != nil {
214 | resultHandler?(image, infoDic)
215 | }else {
216 | let image_buffer = WCLImagePickerBundle.imageFromBundle("image-buffer")
217 | resultHandler?(image_buffer, infoDic)
218 | }
219 | })
220 | }
221 | }
222 |
223 | /**
224 | 根据PHAsset获取photo的元数据
225 |
226 | - parameter alasset: 相册里图片的PHAsset
227 | - parameter resultHandler: 返回照片元数据的回调
228 | */
229 | public func getPhotoData(alasset: PHAsset?, resultHandler: ((Data?, UIImageOrientation) -> Void)?) {
230 | if alasset != nil {
231 | self.photoManage.requestImageData(for: alasset!, options: nil, resultHandler: { (data, str, orientation, hashable) in
232 | resultHandler?(data, orientation)
233 | })
234 | }
235 | }
236 |
237 | /**
238 | 获取默认大小的图片
239 | */
240 | public func getPhotoDefalutSize(_ ablumIndex: Int, photoIndex: Int, resultHandler: ((UIImage?, [AnyHashable: Any]?) -> Void)?) {
241 | getPhoto(ablumIndex, photoIndex: photoIndex, photoSize: WCLPickerManager.pickerPhotoSize, resultHandler: resultHandler)
242 | }
243 |
244 | //MARK: Private Methods
245 | /**
246 | 开始获取获取相册列表
247 | */
248 | private func getPhotoAlbum() {
249 | //创建一个PHFetchOptions对象检索照片
250 | let options = PHFetchOptions()
251 | //通过创建时间来检索
252 | options.sortDescriptors = [NSSortDescriptor.init(key: photoCreationDate, ascending: false)]
253 | //通过数据类型来检索,这里为只检索照片
254 | options.predicate = NSPredicate.init(format: "mediaType in %@", [PHAssetMediaType.image.rawValue])
255 | //通过检索条件检索出符合检索条件的所有数据,也就是所有的照片
256 | let allResult = PHAsset.fetchAssets(with: options)
257 | //获取用户创建的相册
258 | let userResult = PHAssetCollection.fetchTopLevelUserCollections(with: nil)
259 | //获取智能相册
260 | let smartResult = PHAssetCollection.fetchAssetCollections(with: .smartAlbum, subtype: .albumRegular, options: nil)
261 | //将获取的相册加入到相册的数组中
262 | photoAlbums.append([WCLImagePickerBundle.localizedString(key: "全部照片"): allResult])
263 |
264 | userResult.enumerateObjects(options: .concurrent) { (collection, index, stop) in
265 | let assetcollection = collection as! PHAssetCollection
266 | //通过检索条件从assetcollection中检索出结果
267 | let assetResult = PHAsset.fetchAssets(in: assetcollection, options: options)
268 | if assetResult.count != 0 {
269 | self.photoAlbums.append([assetcollection.localizedTitle!:assetResult])
270 | }
271 | }
272 |
273 | smartResult.enumerateObjects(options: .concurrent) { (collection, index, stop) in
274 | //通过检索条件从assetcollection中检索出结果
275 | let assetResult = PHAsset.fetchAssets(in: collection, options: options)
276 | if assetResult.count != 0 {
277 | self.photoAlbums.append([collection.localizedTitle!:assetResult])
278 | }
279 | }
280 | }
281 | }
282 |
--------------------------------------------------------------------------------
/WCLImagePickerController/WCLImagePickerController/ViewControllers/WCLImagePickerController.swift:
--------------------------------------------------------------------------------
1 | //
2 | // WCLImagePickerController.swift
3 | // WCLImagePickrController-swift
4 | //
5 | // **************************************************
6 | // * _____ *
7 | // * __ _ __ ___ \ / *
8 | // * \ \/ \/ / / __\ / / *
9 | // * \ _ / | (__ / / *
10 | // * \/ \/ \___/ / /__ *
11 | // * /_____/ *
12 | // * *
13 | // **************************************************
14 | // Github :https://github.com/631106979
15 | // HomePage:http://imwcl.com
16 | // CSDN :http://blog.csdn.net/wang631106979
17 | //
18 | // Created by 王崇磊 on 16/9/14.
19 | // Copyright © 2016年 王崇磊. All rights reserved.
20 | //
21 | // @class WCLImagePickerController
22 | // @abstract 图片选择器的VC
23 | // @discussion 图片选择器的VC
24 | //
25 |
26 | import UIKit
27 | import Photos
28 |
29 | public class WCLImagePickerController: UIViewController {
30 |
31 | @IBOutlet weak var photoAblumCV: UICollectionView!
32 | fileprivate var centerView: WCLAblumCenterView?
33 | fileprivate var ablumList: WCLAblumListView?
34 | fileprivate var photoSelectView: WCLPhotoSelectView?
35 | fileprivate var pickerManager: WCLPickerManager?
36 | fileprivate var cellContext: WCLPickerCellContext?
37 | fileprivate let pickerView = WCLBaseImagePickerController()
38 | weak var delegate: WCLImagePikcerDelegate?
39 | //选择的相册的index
40 | fileprivate var ablumSelectIndex = 0
41 | //是否是第一次启动
42 | fileprivate var firstLaunch:Bool = true
43 | //View是否DidLoad
44 | fileprivate var isViewDidLoad:Bool = false
45 | //相册启动的view
46 | fileprivate var launchView = WCLLaunchView.init(frame: UIScreen.main.bounds)
47 |
48 | deinit {
49 | NotificationCenter.default.removeObserver(self)
50 | }
51 |
52 | //MARK: Public Methods
53 | /// present出WCLImagePickerController
54 | @discardableResult
55 | class public func present(inVC: UIViewController?, delegate: WCLImagePikcerDelegate) -> (WCLImagePickerController, WCLNavigationController) {
56 | let vc = WCLImagePickerController.init(delegate: delegate)
57 | let nav = WCLNavigationController.init(rootViewController: vc, navBarColor: WCLImagePickerOptions.tintColor)
58 | inVC?.present(nav, animated: true, completion: nil)
59 | return (vc, nav)
60 | }
61 |
62 |
63 | //MARK: Override
64 | public override func viewDidAppear(_ animated: Bool) {
65 | super.viewDidAppear(animated)
66 | isViewDidLoad = true
67 | if firstLaunch == true && PHPhotoLibrary.authorizationStatus() == PHAuthorizationStatus.authorized {
68 | configPhotoVC()
69 | }
70 | }
71 |
72 | override public func viewDidLoad() {
73 | super.viewDidLoad()
74 | // Do any additional setup after loading the view.
75 | photoAuthorization()
76 | //添加launchView
77 | navigationController?.view.addSubview(launchView)
78 | configNav()
79 | addNotify()
80 | }
81 |
82 | override public func didReceiveMemoryWarning() {
83 | super.didReceiveMemoryWarning()
84 | // Dispose of any resources that can be recreated.
85 | }
86 |
87 | override func photoLeftAction(_ sender: UIButton) {
88 | delegate?.wclImagePickerCancel(self)
89 | }
90 |
91 | override func photoRightAction(_ sender: UIButton) {
92 | var imageArr = [UIImage]()
93 | if pickerManager != nil {
94 | let count = pickerManager!.selectPhotoArr.count
95 | if count == 0 {
96 | delegate?.wclImagePickerComplete(self, imageArr: imageArr)
97 | return
98 | }
99 | for asset in pickerManager!.selectPhotoArr {
100 | pickerManager!.getPhotoData(alasset: asset, resultHandler: { [weak self] (data, orientation) in
101 | if data != nil {
102 | let image = UIImage.init(data: data!)
103 | if image != nil {
104 | imageArr.append(image!)
105 | }
106 | if imageArr.count == count {
107 | DispatchQueue.main.async {
108 | self?.delegate?.wclImagePickerComplete(self!, imageArr: imageArr)
109 | }
110 | }
111 | }
112 | })
113 | }
114 | }
115 | }
116 |
117 |
118 | //MARK: Initial Methods
119 | public init(delegate: WCLImagePikcerDelegate) {
120 | super.init(nibName: "WCLImagePickerController", bundle: WCLImagePickerBundle.bundle)
121 | self.delegate = delegate
122 | }
123 |
124 | required public init?(coder aDecoder: NSCoder) {
125 | fatalError("init(coder:) has not been implemented")
126 | }
127 |
128 | //MARK: Private Methods
129 | private func addNotify() {
130 | NotificationCenter.default.addObserver(self, selector: #selector(reloadSelect), name: WCLImagePickerNotify.reloadSelect, object: nil)
131 | NotificationCenter.default.addObserver(self, selector: #selector(reloadPhoto), name: WCLImagePickerNotify.reloadImagePicker, object: nil)
132 | NotificationCenter.default.addObserver(self, selector: #selector(imagePickerError(_:)), name: WCLImagePickerNotify.imagePickerError, object: nil)
133 | }
134 |
135 | private func configNav() {
136 | addWCLPhotoNavLeftButton(WCLImagePickerBundle.localizedString(key: "取消"))
137 | addWCLPhotoNavRightButton(WCLImagePickerBundle.localizedString(key: "完成"))
138 | }
139 |
140 | /**
141 | 刷新PhotoCV
142 | */
143 | private func reloadPhotoCV() {
144 | pickerManager?.isSynchronous = true
145 | photoAblumCV.reloadData()
146 | //保证刷新的时候是同步刷新的,要不会有闪烁
147 | photoAblumCV.performBatchUpdates({
148 | }, completion: { [weak self] (finished) in
149 | self?.pickerManager?.isSynchronous = false
150 | })
151 | }
152 |
153 | /**
154 | 相册授权
155 | */
156 | private func photoAuthorization() {
157 | switch PHPhotoLibrary.authorizationStatus() {
158 | case .denied:
159 | NotificationCenter.default.post(name: WCLImagePickerNotify.imagePickerError, object: WCLError.noAlbumPermissions)
160 | break
161 | // 用户拒绝,提示开启
162 | case .notDetermined:
163 | // 尚未请求,立即请求
164 | PHPhotoLibrary.requestAuthorization({ (status) -> Void in
165 | if status == .authorized {
166 | // 用户同意
167 | DispatchQueue.main.async {
168 | self.configPhotoVC()
169 | }
170 | }
171 | })
172 | break
173 | case .restricted:
174 | NotificationCenter.default.post(name: WCLImagePickerNotify.imagePickerError, object: WCLError.noAlbumPermissions)
175 | break
176 | // 用户无法解决的无法访问
177 | case .authorized:
178 | // 用户已授权
179 | configPhotoVC()
180 | break
181 | }
182 | }
183 |
184 | private func configPhotoVC() {
185 | if isViewDidLoad == false {
186 | return
187 | }
188 | if firstLaunch {
189 | launchView.starAnimation()
190 | firstLaunch = false
191 | }
192 | pickerManager = WCLPickerManager()
193 | cellContext = WCLPickerCellContext.init(pickerManager: pickerManager!)
194 | cellContext?.register(collectionView: photoAblumCV)
195 | addSelectView()
196 | addCenterView()
197 | addAblumList()
198 | photoAblumCV.reloadData()
199 | }
200 |
201 | fileprivate func addCenterView() {
202 | centerView = WCLAblumCenterView.init(frame: CGRect(x: 0, y: 0, width: 200, height: 45), selectBlock: { [weak self] (select) in
203 | self?.ablumList?.dropAblbumList(select)
204 | })
205 | navigationItem.titleView = centerView
206 | centerView!.centerTitle = pickerManager?.getAblumTitle(ablumSelectIndex)
207 | }
208 |
209 | fileprivate func addAblumList() {
210 | ablumList = WCLAblumListView.show(inView: view, pickerManager: pickerManager!)
211 | ablumList?.select = { [weak self] (index) in
212 | self?.ablumSelectIndex = index
213 | self?.centerView?.isSelect = !(self?.centerView?.isSelect ?? false)
214 | self?.photoAblumCV.reloadData()
215 | self?.photoAblumCV.setContentOffset(CGPoint(x: 0, y: 0), animated: false)
216 | self?.centerView?.centerTitle = self?.pickerManager?.getAblumTitle(index)
217 | }
218 | ablumList?.cancle = { [weak self] in
219 | self?.centerView?.isSelect = !(self?.centerView?.isSelect ?? false)
220 | }
221 | }
222 |
223 | fileprivate func addSelectView() {
224 | if WCLImagePickerOptions.isShowSelecView {
225 | let bounds = UIScreen.main.bounds
226 | photoSelectView = WCLPhotoSelectView.init(frame: CGRect.init(origin: CGPoint.init(x: 0, y: bounds.height - 47 - 64), size: CGSize.init(width: bounds.width, height: 47)), pickerManager: pickerManager!)
227 | photoSelectView?.pushBlock = { [weak self] (vc) in
228 | self?.navigationController?.pushViewController(vc, animated: true)
229 | }
230 | photoAblumCV.contentInset = UIEdgeInsetsMake(0, 0, 47, 0)
231 | photoSelectView?.translatesAutoresizingMaskIntoConstraints = false
232 | view.addSubview(photoSelectView!)
233 | photoSelectView?.addConstraint(NSLayoutConstraint(item: photoSelectView!, attribute: .height, relatedBy: .equal, toItem: nil, attribute: .height, multiplier: 1.0, constant: 47))
234 | view.addConstraint(NSLayoutConstraint(item: photoSelectView!, attribute: .left, relatedBy: .equal, toItem: view, attribute: .left, multiplier: 1.0, constant: 0))
235 | view.addConstraint(NSLayoutConstraint(item: photoSelectView!, attribute: .right, relatedBy: .equal, toItem: view, attribute: .right, multiplier: 1.0, constant: 0))
236 | view.addConstraint(NSLayoutConstraint(item: photoSelectView!, attribute: .bottom, relatedBy: .equal, toItem: view, attribute: .bottom, multiplier: 1.0, constant: 0))
237 |
238 | }else {
239 | photoAblumCV.contentInset = UIEdgeInsetsMake(0, 0, 0, 0)
240 | }
241 | }
242 |
243 | fileprivate func imageCamereShow() {
244 | if cameraAuthorization() {
245 | pickerView.navigationBar.barTintColor = WCLImagePickerOptions.tintColor
246 | pickerView.navigationBar.tintColor = UIColor.white
247 | pickerView.navigationBar.titleTextAttributes = [NSForegroundColorAttributeName: UIColor.white]
248 | pickerView.delegate = self
249 | pickerView.sourceType = .camera
250 | self.present(pickerView, animated: true, completion: nil)
251 | }
252 | }
253 |
254 | fileprivate func cameraAuthorization() -> Bool {
255 | let mediaType = AVMediaTypeVideo
256 | let authorizationStatus = AVCaptureDevice.authorizationStatus(forMediaType: mediaType)
257 | /// 是否在模拟器
258 | #if (arch(i386) || arch(x86_64)) && os(iOS)
259 | NotificationCenter.default.post(name: WCLImagePickerNotify.imagePickerError, object: WCLError.noCameraPermissions)
260 | return false
261 | #else
262 | if authorizationStatus == .restricted || authorizationStatus == .denied {
263 | NotificationCenter.default.post(name: WCLImagePickerNotify.imagePickerError, object: WCLError.noCameraPermissions)
264 | AVCaptureDevice.requestAccess(forMediaType: mediaType, completionHandler: { (flag) in
265 | if flag {
266 | self.imageCamereShow()
267 | }
268 | })
269 | return false
270 | }
271 | return true
272 | #endif
273 | // if TARGET_OS_SIMULATOR != 0 {
274 | // NotificationCenter.default.post(name: WCLImagePickerNotify.imagePickerError, object: WCLError.noCameraPermissions)
275 | // return false
276 | // }
277 | }
278 |
279 | //MARK: Notification Methods
280 | //刷新选择的相册列表
281 | @objc private func reloadSelect() {
282 | reloadPhotoCV()
283 | photoSelectView?.selectCollectionView.reloadData()
284 | if let pickerManager = pickerManager {
285 | photoSelectView?.imageSelectNum.text = String.init(format: "%d", pickerManager.selectPhotoArr.count)
286 | }
287 | }
288 |
289 | //刷新相册列表
290 | @objc private func reloadPhoto() {
291 | reloadPhotoCV()
292 | }
293 |
294 | //错误提示
295 | @objc private func imagePickerError(_ not: Notification) {
296 | if let error = not.object as? WCLError {
297 | delegate?.wclImagePickerError(self, error: error)
298 | }
299 | }
300 | }
301 |
302 | //MARK: UICollectionView
303 | extension WCLImagePickerController: UICollectionViewDelegate,
304 | UICollectionViewDataSource,
305 | UICollectionViewDelegateFlowLayout {
306 | //MARK: UICollectionViewDelegate
307 | public func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
308 | collectionView.deselectItem(at: indexPath, animated: true)
309 | if WCLImagePickerOptions.needPickerCamera && indexPath.row == 0 {
310 | let conut = pickerManager?.selectPhotoArr.count ?? 0
311 | if conut >= WCLImagePickerOptions.maxPhotoSelectNum {
312 | NotificationCenter.default.post(name: WCLImagePickerNotify.imagePickerError, object: WCLError.noMoreThanImages)
313 | return
314 | }
315 | imageCamereShow()
316 | return
317 | }
318 | if let result = pickerManager?.getAblumResult(ablumSelectIndex) {
319 | var currentIndex = indexPath.row
320 | if WCLImagePickerOptions.needPickerCamera {
321 | currentIndex = currentIndex - 1
322 | }
323 | let browserVC = WCLPhotoBrowserController.init(pickerManager!, currentIndex: currentIndex, photoResult: result)
324 | navigationController?.pushViewController(browserVC, animated: true)
325 | }
326 | }
327 |
328 | public func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
329 | return WCLPickerManager.pickerPhotoSize
330 | }
331 |
332 | public func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumLineSpacingForSectionAt section: Int) -> CGFloat {
333 | return CGFloat(WCLImagePickerOptions.photoInterval)
334 | }
335 |
336 | public func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumInteritemSpacingForSectionAt section: Int) -> CGFloat {
337 | return CGFloat(WCLImagePickerOptions.photoInterval)
338 | }
339 |
340 | //MARK: UICollectionViewDataSource
341 | public func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
342 | guard cellContext != nil else {
343 | return 0
344 | }
345 | return cellContext!.getPikcerCellNumber(ablumIndex: ablumSelectIndex)
346 | }
347 |
348 | public func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
349 | guard cellContext != nil else {
350 | let cell = UICollectionViewCell()
351 | return cell
352 | }
353 | return cellContext!.getPickerCell(collectionView, ablumIndex: ablumSelectIndex, photoIndex: indexPath.row)
354 | }
355 | }
356 |
357 |
358 | //MARK: UIImagePickerController
359 | extension WCLImagePickerController: UIImagePickerControllerDelegate,
360 | UINavigationControllerDelegate {
361 | //MARK: UIImagePickerControllerDelegate
362 | public func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : Any]) {
363 | if let image = info[UIImagePickerControllerOriginalImage] as? UIImage {
364 | picker.dismiss(animated: true, completion: {
365 | DispatchQueue.main.async {
366 | self.delegate?.wclImagePickerComplete(self, imageArr: [image])
367 | }
368 | PHPhotoLibrary.shared().performChanges({
369 | PHAssetChangeRequest.creationRequestForAsset(from: image)
370 | }, completionHandler: { (flag, error) in
371 |
372 | })
373 | })
374 | }
375 | }
376 |
377 | public func imagePickerControllerDidCancel(_ picker: UIImagePickerController) {
378 | picker.dismiss(animated: true, completion: nil)
379 | }
380 | }
381 |
382 |
--------------------------------------------------------------------------------
/WCLImagePickerController/WCLImagePickerController/ViewControllers/WCLImagePickerController.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 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
--------------------------------------------------------------------------------
/WCLImagePickerController/WCLImagePickerController/ViewControllers/WCLPhotoBrowserController.swift:
--------------------------------------------------------------------------------
1 | //
2 | // WCLPhotoBrowserController.swift
3 | // WCLImagePickrController-swift
4 | //
5 | // **************************************************
6 | // * _____ *
7 | // * __ _ __ ___ \ / *
8 | // * \ \/ \/ / / __\ / / *
9 | // * \ _ / | (__ / / *
10 | // * \/ \/ \___/ / /__ *
11 | // * /_____/ *
12 | // * *
13 | // **************************************************
14 | // Github :https://github.com/631106979
15 | // HomePage:http://imwcl.com
16 | // CSDN :http://blog.csdn.net/wang631106979
17 | //
18 | // Created by 王崇磊 on 16/9/14.
19 | // Copyright © 2016年 王崇磊. All rights reserved.
20 | //
21 | // @class WCLPhotoBrowserController
22 | // @abstract 相册的图片浏览器的VC
23 | // @discussion 相册的图片浏览器的VC
24 | //
25 |
26 | import UIKit
27 | import Photos
28 |
29 | internal class WCLPhotoBrowserController: UIViewController {
30 |
31 | @IBOutlet weak var photoBrowserView: UICollectionView!
32 | //当前photo的index
33 | var currentIndex:Int = 0
34 |
35 | fileprivate var context: WCLPhotoCellContext?
36 |
37 | fileprivate var pickerManager: WCLPickerManager
38 | //选择的是否是selectAssetArr
39 | fileprivate var isSelect:Bool = false
40 | //选择的照片的数组
41 | fileprivate var selectAssetArr: [PHAsset]?
42 | //相册的PHFetchResult
43 | fileprivate var photoResult: PHFetchResult?
44 | //是否出现过
45 | fileprivate var isViewDidAppear: Bool = false
46 |
47 | fileprivate let selecView = WCLSelectView.initFormNib()
48 | //MARK: Public Methods
49 |
50 |
51 | //MARK: Override
52 | override func viewDidAppear(_ animated: Bool) {
53 | super.viewDidAppear(animated)
54 | isViewDidAppear = true
55 | }
56 |
57 | override func viewDidLoad() {
58 | super.viewDidLoad()
59 | // Do any additional setup after loading the view.
60 | context = WCLPhotoCellContext.init(pickerManager: pickerManager)
61 | context?.register(collectionView: photoBrowserView)
62 | addWCLPhotoNavLeftButton(WCLImagePickerBundle.localizedString(key: "返回"))
63 | countSelectIndex(currentIndex)
64 |
65 | pickerManager.isSynchronous = true
66 | photoBrowserView.performBatchUpdates(nil) { (finish) in
67 | let size = UIScreen.main.bounds.size
68 | self.photoBrowserView.setContentOffset(CGPoint.init(x: (size.width+20)*CGFloat(self.currentIndex), y: 0), animated: false)
69 | self.pickerManager.isSynchronous = false
70 | }
71 | navigationItem.rightBarButtonItem = UIBarButtonItem.init(customView: selecView)
72 | selecView.selectBt.addTarget(self, action: #selector(selectViewAction(_ :)), for: .touchUpInside)
73 | }
74 |
75 | override func photoLeftAction(_ sender: UIButton) {
76 | _ = navigationController?.popViewController(animated: true)
77 | }
78 |
79 | override func didReceiveMemoryWarning() {
80 | super.didReceiveMemoryWarning()
81 | // Dispose of any resources that can be recreated.
82 | }
83 |
84 |
85 | //MARK: Initial Methods
86 | init(_ pickerManager: WCLPickerManager, currentIndex: Int, selectAssetArr: [PHAsset]) {
87 | self.pickerManager = pickerManager
88 | super.init(nibName: "WCLPhotoBrowserController", bundle: WCLImagePickerBundle.bundle)
89 | self.currentIndex = currentIndex
90 | self.selectAssetArr = selectAssetArr
91 | self.isSelect = true
92 | }
93 |
94 | init(_ pickerManager: WCLPickerManager, currentIndex: Int, photoResult: PHFetchResult) {
95 | self.pickerManager = pickerManager
96 | super.init(nibName: "WCLPhotoBrowserController", bundle: WCLImagePickerBundle.bundle)
97 | self.currentIndex = currentIndex
98 | self.photoResult = photoResult
99 | self.isSelect = false
100 | }
101 |
102 | required init?(coder aDecoder: NSCoder) {
103 | fatalError("init(coder:) has not been implemented")
104 | }
105 |
106 | //MARK: Private Methods
107 | fileprivate func countSelectIndex(_ index: Int) {
108 | if isSelect {
109 | setWCLPhotoNavTitle("\(index+1)/\(selectAssetArr!.count)")
110 | selecView.selecrIndex = index+1
111 | }else {
112 | setWCLPhotoNavTitle("\(index+1)/\(photoResult!.count)")
113 | if let alasset = photoResult?[index] {
114 | let aindex = pickerManager.index(ofSelect: alasset)
115 | if aindex == nil {
116 | selecView.selecrIndex = 0
117 | }else {
118 | selecView.selecrIndex = aindex! + 1
119 | }
120 | }
121 | }
122 | }
123 |
124 |
125 | //MARK: Target Methods
126 | @objc private func selectViewAction(_ sender: UIButton) {
127 | defer {
128 | NotificationCenter.default.post(name: WCLImagePickerNotify.reloadSelect, object: nil, userInfo: nil)
129 | }
130 | let index = currentIndex
131 | if sender.isSelected {
132 | //删除
133 | if isSelect {
134 | self.photoBrowserView.performBatchUpdates({
135 | if let alasset = self.selectAssetArr?[index] {
136 | if self.pickerManager.index(ofSelect: alasset) != nil {
137 | self.pickerManager.remove(formSelect: alasset)
138 | }
139 | }
140 | self.selectAssetArr?.remove(at: index)
141 | if self.currentIndex != 0 {
142 | self.currentIndex = self.currentIndex - 1
143 | }
144 | self.countSelectIndex(self.currentIndex)
145 | self.photoBrowserView.deleteItems(at: [IndexPath.init(row: index, section: 0)])
146 | }, completion: { (complete) in
147 | if self.pickerManager.selectPhotoArr.count == 0 {
148 | _ = self.navigationController?.popViewController(animated: true)
149 | }
150 | })
151 | }else {
152 | if let alasset = photoResult?[index] {
153 | if self.pickerManager.index(ofSelect: alasset) != nil {
154 | self.pickerManager.remove(formSelect: alasset)
155 | selecView.selecrIndex = 0
156 | }
157 | }
158 | }
159 | }else {
160 | //添加
161 | if !isSelect {
162 | if pickerManager.selectPhotoArr.count >= WCLImagePickerOptions.maxPhotoSelectNum {
163 | NotificationCenter.default.post(name: WCLImagePickerNotify.imagePickerError, object: WCLError.noMoreThanImages)
164 | return
165 | }
166 | if let alasset = photoResult?[index] {
167 | self.pickerManager.append(toSelect: alasset)
168 | self.selecView.selecrIndex = self.pickerManager.selectPhotoArr.count
169 | }
170 | }
171 | }
172 | }
173 | }
174 |
175 |
176 | //MARK: UICollectionView
177 | extension WCLPhotoBrowserController: UICollectionViewDelegate,
178 | UICollectionViewDataSource,
179 | UICollectionViewDelegateFlowLayout{
180 | //MARK: UICollectionViewDelegate
181 | func scrollViewDidScroll(_ scrollView: UIScrollView) {
182 | guard isViewDidAppear else {
183 | return
184 | }
185 | let floatIndex:CGFloat = scrollView.contentOffset.x/scrollView.frame.width
186 | let intIndex:Int = Int(scrollView.contentOffset.x/scrollView.frame.width)
187 | if CGFloat(intIndex) == floatIndex {
188 | if intIndex != currentIndex {
189 | NotificationCenter.default.post(name: WCLImagePickerNotify.selectPickerZoom, object: nil)
190 | }
191 | countSelectIndex(intIndex)
192 | currentIndex = intIndex
193 | }
194 | }
195 |
196 | //MARK: UICollectionViewDelegateFlowLayout
197 | func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
198 | let bounds = UIScreen.main.bounds
199 | return CGSize(width: bounds.width + 20, height: bounds.height - 64)
200 | }
201 |
202 | //MARK: UICollectionViewDataSource
203 | func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
204 | var asset: PHAsset?
205 | if isSelect {
206 | asset = selectAssetArr![indexPath.row]
207 | }else {
208 | asset = photoResult![indexPath.row]
209 | }
210 | let cell = context!.getCell(asset: asset!, collectionView: collectionView, indexPath: indexPath)
211 | return cell
212 | }
213 |
214 | func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
215 | if isSelect {
216 | return selectAssetArr!.count
217 | }else {
218 | return photoResult!.count
219 | }
220 | }
221 | }
222 |
--------------------------------------------------------------------------------
/WCLImagePickerController/WCLImagePickerController/ViewControllers/WCLPhotoBrowserController.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 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
--------------------------------------------------------------------------------
/WCLImagePickerController/WCLImagePickerController/Views/WCLAblumCenterView.swift:
--------------------------------------------------------------------------------
1 | //
2 | // WCLAblumCenterView.swift
3 | // WCLImagePickrController-swift
4 | //
5 | // **************************************************
6 | // * _____ *
7 | // * __ _ __ ___ \ / *
8 | // * \ \/ \/ / / __\ / / *
9 | // * \ _ / | (__ / / *
10 | // * \/ \/ \___/ / /__ *
11 | // * /_____/ *
12 | // * *
13 | // **************************************************
14 | // Github :https://github.com/631106979
15 | // HomePage:https://imwcl.com
16 | // CSDN :http://blog.csdn.net/wang631106979
17 | //
18 | // Created by 王崇磊 on 16/9/14.
19 | // Copyright © 2016年 王崇磊. All rights reserved.
20 | //
21 | //
22 | // @class WCLAblumCenterView
23 | // @abstract 图片选择器nav上的titleView
24 | // @discussion 图片选择器nav上的titleView
25 | //
26 |
27 | import UIKit
28 |
29 | internal class WCLAblumCenterView: UIView {
30 |
31 | var centerTitle:String? {
32 | didSet {
33 | titleLabel.text = centerTitle
34 | }
35 | }
36 |
37 | var selectBlock:((Bool) ->Void)?
38 |
39 | var isSelect = false {
40 | didSet {
41 | UIView.animate(withDuration: 0.3, animations: {
42 | self.arrowImageView.layer.transform = CATransform3DRotate(self.arrowImageView.layer.transform, CGFloat(Double.pi), 1.0, 0.0, 0.0)
43 | })
44 | selectBlockAction()
45 | }
46 | }
47 |
48 | private let arrowImageView = UIImageView.init(image: WCLImagePickerOptions.pickerArrow)
49 | private let titleLabel = UILabel()
50 |
51 | //MARK: Override
52 | override init(frame: CGRect) {
53 | super.init(frame: frame)
54 |
55 | titleLabel.textColor = UIColor.white
56 | addSubview(arrowImageView)
57 | addSubview(titleLabel)
58 | //添加约束
59 | arrowImageView.translatesAutoresizingMaskIntoConstraints = false
60 | titleLabel.translatesAutoresizingMaskIntoConstraints = false
61 | addConstraint(NSLayoutConstraint.init(item: titleLabel, attribute: .centerX, relatedBy: .equal, toItem: self, attribute: .centerX, multiplier: 1.0, constant: -11.0))
62 | addConstraint(NSLayoutConstraint.init(item: titleLabel, attribute: .centerY, relatedBy: .equal, toItem: self, attribute: .centerY, multiplier: 1.0, constant: 0.0))
63 | addConstraint(NSLayoutConstraint.init(item: arrowImageView, attribute: .centerY, relatedBy: .equal, toItem: titleLabel, attribute: .centerY, multiplier: 1.0, constant: 0.0))
64 | addConstraint(NSLayoutConstraint.init(item: arrowImageView, attribute: .left, relatedBy: .equal, toItem: titleLabel, attribute: .right, multiplier: 1.0, constant: 7.0))
65 | }
66 |
67 | override func touchesEnded(_ touches: Set, with event: UIEvent?) {
68 | isSelect = !isSelect
69 | selectBlockAction()
70 | }
71 |
72 | func selectBlockAction() {
73 | if selectBlock != nil {
74 | selectBlock!(isSelect)
75 | }
76 | }
77 |
78 | //MARK: Initial Methods
79 | convenience init(frame: CGRect, selectBlock:@escaping (Bool) ->Void) {
80 | self.init(frame: frame)
81 | self.selectBlock = selectBlock
82 | }
83 |
84 | required init?(coder aDecoder: NSCoder) {
85 | fatalError("init(coder:) has not been implemented")
86 | }
87 | }
88 |
--------------------------------------------------------------------------------
/WCLImagePickerController/WCLImagePickerController/Views/WCLAblumListView.swift:
--------------------------------------------------------------------------------
1 | //
2 | // WCLAblumListView.swift
3 | // WCLImagePickrController-swift
4 | //
5 | // **************************************************
6 | // * _____ *
7 | // * __ _ __ ___ \ / *
8 | // * \ \/ \/ / / __\ / / *
9 | // * \ _ / | (__ / / *
10 | // * \/ \/ \___/ / /__ *
11 | // * /_____/ *
12 | // * *
13 | // **************************************************
14 | // Github :https://github.com/631106979
15 | // HomePage:http://imwcl.com
16 | // CSDN :http://blog.csdn.net/wang631106979
17 | //
18 | // Created by 王崇磊 on 16/9/14.
19 | // Copyright © 2016年 王崇磊. All rights reserved.
20 | //
21 | // @class WCLAblumListView
22 | // @abstract 相册列表的view
23 | // @discussion 相册列表的view
24 | //
25 |
26 | import UIKit
27 |
28 | internal class WCLAblumListView: UIView,
29 | UITableViewDelegate,
30 | UITableViewDataSource {
31 | //选择的相册的index
32 | var ablumSelectIndex = 0
33 | private var pickerManager: WCLPickerManager?
34 | @IBOutlet weak var ablumTableView: UITableView!
35 | @IBOutlet weak var maskBackView: UIView!
36 | @IBOutlet weak var ablumTableHeight: NSLayoutConstraint!
37 |
38 | var select: ((_ index: Int) -> Void)?
39 | var cancle: (() -> Void)?
40 |
41 | //MARK: Public Methods
42 | func dropAblbumList(_ select:Bool) {
43 | if select {
44 | isUserInteractionEnabled = true
45 | }else {
46 | isUserInteractionEnabled = false
47 | }
48 | UIView.animate(withDuration: 0.35, delay: 0.0, usingSpringWithDamping: 1.0, initialSpringVelocity: 1.0, options: .allowUserInteraction, animations: {
49 | if select {
50 | self.ablumTableHeight.constant = self.frame.size.height - 51
51 | self.maskBackView.alpha = 0.7
52 | }else {
53 | self.ablumTableHeight.constant = 0
54 | self.maskBackView.alpha = 0.0
55 | }
56 | self.layoutIfNeeded()
57 | }) { (complete) in
58 | self.ablumTableView.reloadData()
59 | }
60 | }
61 |
62 | //MARK: Override
63 | override func awakeFromNib() {
64 | super.awakeFromNib()
65 | ablumTableView.register(UINib.init(nibName: WCLAblumListCell.identfier, bundle: WCLImagePickerBundle.bundle), forCellReuseIdentifier: WCLAblumListCell.identfier)
66 | let tap = UITapGestureRecognizer.init(target: self, action: #selector(cancleAction))
67 | maskBackView.addGestureRecognizer(tap)
68 | }
69 |
70 | //MARK: Initial Methods
71 | class func `init`(pickerManager: WCLPickerManager) -> WCLAblumListView {
72 | let view = UINib.init(nibName: "WCLAblumListView", bundle: WCLImagePickerBundle.bundle).instantiate(withOwner: nil, options: nil).first as! WCLAblumListView
73 | view.pickerManager = pickerManager
74 | return view
75 | }
76 |
77 | class func show(inView: UIView, pickerManager: WCLPickerManager) -> WCLAblumListView {
78 | let view = WCLAblumListView.init(pickerManager: pickerManager)
79 | view.frame = inView.bounds
80 | inView.addSubview(view)
81 | view.isUserInteractionEnabled = false
82 | return view
83 | }
84 |
85 | //MARK: private Methods
86 | @objc private func cancleAction() {
87 | cancle?()
88 | }
89 |
90 | //MARK: UITableViewDelegate
91 | func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
92 | tableView.deselectRow(at: indexPath, animated: true)
93 | select?(indexPath.row)
94 | ablumSelectIndex = indexPath.row
95 | }
96 |
97 | func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
98 | return 90
99 | }
100 |
101 | //MARK: UITableViewDataSource
102 | func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
103 | //相册的数量
104 | if pickerManager != nil {
105 | return pickerManager!.photoAlbums.count
106 | }else {
107 | return 0
108 | }
109 | }
110 |
111 | func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
112 | let cell:WCLAblumListCell = tableView.dequeueReusableCell(withIdentifier: WCLAblumListCell.identfier, for: indexPath) as! WCLAblumListCell
113 | cell.ablumNameLabel.text = pickerManager?.getAblumTitle(indexPath.row)
114 | weak var weakCell = cell
115 | pickerManager?.getPhoto(indexPath.row, photoIndex: 0, photoSize: cell.ablumImageView.frame.size, resultHandler: { (image, infoDic) in
116 | weakCell?.ablumImageView.image = image
117 | })
118 | if (indexPath as NSIndexPath).row == ablumSelectIndex {
119 | cell.selectImageView.isHighlighted = true
120 | }else {
121 | cell.selectImageView.isHighlighted = false
122 | }
123 | return cell
124 | }
125 | }
126 |
--------------------------------------------------------------------------------
/WCLImagePickerController/WCLImagePickerController/Views/WCLAblumListView.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 |
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 |
--------------------------------------------------------------------------------
/WCLImagePickerController/WCLImagePickerController/Views/WCLLaunchView.swift:
--------------------------------------------------------------------------------
1 | //
2 | // WCLLaunchView.swift
3 | // WCLLaunchView
4 | //
5 | // **************************************************
6 | // * _____ *
7 | // * __ _ __ ___ \ / *
8 | // * \ \/ \/ / / __\ / / *
9 | // * \ _ / | (__ / / *
10 | // * \/ \/ \___/ / /__ *
11 | // * /_____/ *
12 | // * *
13 | // **************************************************
14 | // Github :https://github.com/631106979
15 | // HomePage:https://imwcl.com
16 | // CSDN :http://blog.csdn.net/wang631106979
17 | //
18 | // Created by 王崇磊 on 16/9/14.
19 | // Copyright © 2016年 王崇磊. All rights reserved.
20 | //
21 | // @class WCLLaunchView
22 | // @abstract 缓慢展开的启动图
23 | // @discussion 缓慢展开的启动图
24 | //
25 |
26 | import UIKit
27 |
28 | internal class WCLLaunchView: UIView, CAAnimationDelegate {
29 |
30 | fileprivate var topLayer: CALayer = CALayer()
31 | fileprivate var bottomLayer: CALayer = CALayer()
32 | fileprivate var launchImage: UIImage?
33 | //MARK: Public Methods
34 | /**
35 | 展开的动画
36 | */
37 | func starAnimation() {
38 | //创建一个CABasicAnimation作用于CALayer的anchorPoint
39 | let topAnimation = CABasicAnimation.init(keyPath: "anchorPoint")
40 | //设置移动路径
41 | topAnimation.toValue = NSValue.init(cgPoint: CGPoint(x: 1, y: 1))
42 | //动画时间
43 | topAnimation.duration = 0.6
44 | //设置代理,方便完成动画后移除当前view
45 | topAnimation.delegate = self
46 | //设置动画速度为匀速
47 | topAnimation.timingFunction = CAMediaTimingFunction.init(name: kCAMediaTimingFunctionLinear)
48 | //设置动画结束后不移除点,保持移动后的位置
49 | topAnimation.isRemovedOnCompletion = false
50 | topAnimation.fillMode = kCAFillModeForwards
51 | topLayer.add(topAnimation, forKey: "topAnimation")
52 |
53 | //创建一个CABasicAnimation作用于CALayer的anchorPoint
54 | let bottomAnimation = CABasicAnimation.init(keyPath: "anchorPoint")
55 | //设置移动路径
56 | bottomAnimation.toValue = NSValue.init(cgPoint: CGPoint(x: 0, y: 0))
57 | //动画时间
58 | bottomAnimation.duration = 0.6
59 | //设置动画速度为匀速
60 | bottomAnimation.timingFunction = CAMediaTimingFunction.init(name: kCAMediaTimingFunctionLinear)
61 | //设置动画结束后不移除点,保持移动后的位置
62 | bottomAnimation.isRemovedOnCompletion = false
63 | bottomAnimation.fillMode = kCAFillModeForwards
64 | bottomLayer.add(bottomAnimation, forKey: "topAnimation")
65 | }
66 |
67 | //MARK: Initial Methods
68 | init(frame: CGRect, launchImage: UIImage?) {
69 | super.init(frame: frame)
70 | self.launchImage = launchImage
71 | configTopShapeLayer()
72 | configBottomShapeLayer()
73 | }
74 |
75 | override init(frame: CGRect) {
76 | super.init(frame: frame)
77 | if WCLImagePickerOptions.launchImage == nil {
78 | launchImage = getDefaultLaunchImage()
79 | }else {
80 | launchImage = WCLImagePickerOptions.launchImage
81 | }
82 | configTopShapeLayer()
83 | configBottomShapeLayer()
84 | }
85 |
86 | required init?(coder aDecoder: NSCoder) {
87 | fatalError("init(coder:) has not been implemented")
88 | }
89 |
90 | //MARK: Private Methods
91 | /**
92 | 绘制上半部分的layer
93 | */
94 | private func configTopShapeLayer() {
95 | //绘制贝斯尔曲线
96 | let topBezier:UIBezierPath = UIBezierPath()
97 | topBezier.move(to: CGPoint(x: -1, y: -1))
98 | topBezier.addLine(to: CGPoint(x: bounds.width+1, y: -1))
99 | topBezier.addCurve(to: CGPoint(x: bounds.width/2.0+1, y: bounds.height/2.0+1), controlPoint1: CGPoint(x: bounds.width+1, y: 0+1), controlPoint2: CGPoint(x: 343.5+1, y: 242.5+1))
100 | topBezier.addCurve(to: CGPoint(x: -1, y: bounds.height+2), controlPoint1: CGPoint(x: 31.5+2, y: 424.5+2), controlPoint2: CGPoint(x: 0+2, y: bounds.height+2))
101 | topBezier.addLine(to: CGPoint(x: -1, y: -1))
102 | topBezier.close()
103 | //创建一个CAShapeLayer,将绘制的贝斯尔曲线的path给CAShapeLayer
104 | let topShape = CAShapeLayer()
105 | topShape.path = topBezier.cgPath
106 | //给topLayer设置contents为启动图
107 | topLayer.contents = launchImage?.cgImage
108 | topLayer.frame = bounds
109 | layer.addSublayer(topLayer)
110 | //将绘制后的CAShapeLayer做为topLayer的mask
111 | topLayer.mask = topShape
112 | }
113 |
114 | /**
115 | 绘制下半部分的layer
116 | */
117 | private func configBottomShapeLayer() {
118 | let width = bounds.width
119 | let height = bounds.height
120 | //绘制贝斯尔曲线
121 | let bottomBezier:UIBezierPath = UIBezierPath()
122 | bottomBezier.move(to: CGPoint(x: width, y: 0))
123 | bottomBezier.addCurve(to: CGPoint(x: width/2.0, y: height/2.0), controlPoint1: CGPoint(x: width, y: 0), controlPoint2: CGPoint(x: width * 0.915, y: height * 0.364))
124 | bottomBezier.addCurve(to: CGPoint(x: 0, y: bounds.height), controlPoint1: CGPoint(x: width * 0.084 , y: height * 0.636), controlPoint2: CGPoint(x: 0, y: bounds.height))
125 | bottomBezier.addLine(to: CGPoint(x: bounds.width, y: bounds.height))
126 | bottomBezier.addLine(to: CGPoint(x: bounds.width, y: 0))
127 | bottomBezier.close()
128 | //创建一个CAShapeLayer,将绘制的贝斯尔曲线的path给CAShapeLayer
129 | let bottomShape = CAShapeLayer()
130 | bottomShape.path = bottomBezier.cgPath
131 | //给bottomLayer设置contents为启动图
132 | bottomLayer.contents = launchImage?.cgImage
133 | bottomLayer.frame = bounds
134 | layer.addSublayer(bottomLayer)
135 | //将绘制后的CAShapeLayer做为bottomLayer的mask
136 | bottomLayer.mask = bottomShape
137 | }
138 |
139 | private func getDefaultLaunchImage() -> UIImage? {
140 | let screen = UIScreen.main
141 | UIGraphicsBeginImageContextWithOptions(screen.bounds.size, true, screen.scale)
142 | if let color = WCLImagePickerOptions.launchColor {
143 | color.setFill()
144 | }else {
145 | WCLImagePickerOptions.tintColor.setFill()
146 | }
147 | UIRectFill(screen.bounds)
148 | if let maskImage = WCLImagePickerBundle.imageFromBundle("image_photoAlbum") {
149 | maskImage.draw(at: CGPoint(x: screen.bounds.size.width/2 - maskImage.size.width/2, y: screen.bounds.size.height/2 - maskImage.size.height/2))
150 | }
151 | let originImage = UIGraphicsGetImageFromCurrentImageContext()
152 | UIGraphicsEndImageContext()
153 | return originImage
154 | }
155 |
156 | //MRAK: animationDelegate
157 | /**
158 | 动画完成后移除当前view
159 | */
160 | func animationDidStop(_ anim: CAAnimation, finished flag: Bool) {
161 | if flag {
162 | removeFromSuperview()
163 | }
164 | }
165 | }
166 |
--------------------------------------------------------------------------------
/WCLImagePickerController/WCLImagePickerController/Views/WCLPhotoSelectView.swift:
--------------------------------------------------------------------------------
1 | //
2 | // WCLPhotoSelectView.swift
3 | // WCLImagePickrController-swift
4 | //
5 | // **************************************************
6 | // * _____ *
7 | // * __ _ __ ___ \ / *
8 | // * \ \/ \/ / / __\ / / *
9 | // * \ _ / | (__ / / *
10 | // * \/ \/ \___/ / /__ *
11 | // * /_____/ *
12 | // * *
13 | // **************************************************
14 | // Github :https://github.com/631106979
15 | // HomePage:http://imwcl.com
16 | // CSDN :http://blog.csdn.net/wang631106979
17 | //
18 | // Created by 王崇磊 on 16/9/14.
19 | // Copyright © 2016年 王崇磊. All rights reserved.
20 | //
21 | // @class WCLPhotoSelectView
22 | // @abstract 相册中选择的照片的view
23 | // @discussion 相册中选择的照片的view
24 | //
25 |
26 | import UIKit
27 | import Photos
28 |
29 | internal class WCLPhotoSelectView: UIView,
30 | UICollectionViewDelegate,
31 | UICollectionViewDataSource {
32 |
33 | private var pickerManager: WCLPickerManager?
34 | @IBOutlet weak var imageSelectImage: UIImageView!
35 | @IBOutlet weak var imageSelectNum: UILabel!
36 | @IBOutlet weak var selectCollectionView: UICollectionView!
37 |
38 | var pushBlock: ((_: UIViewController) -> Void)?
39 |
40 | deinit {
41 | NotificationCenter.default.removeObserver(self)
42 | }
43 | //MARK: Public Methods
44 |
45 |
46 | //MARK: Override
47 | override func awakeFromNib() {
48 | super.awakeFromNib()
49 | if let color = WCLImagePickerOptions.selectViewBackColor {
50 | backgroundColor = color
51 | }else {
52 | backgroundColor = WCLImagePickerOptions.tintColor
53 | }
54 | selectCollectionView.register(UINib.init(nibName: WCLSelecteCVCell.identfier, bundle: WCLImagePickerBundle.bundle), forCellWithReuseIdentifier: WCLSelecteCVCell.identfier)
55 | NotificationCenter.default.addObserver(self, selector: #selector(reloadSelectTotalNum), name: WCLImagePickerNotify.reloadSelectTotalNum, object: nil)
56 | NotificationCenter.default.addObserver(self, selector: #selector(deleteSelectTotalNum(_ :)), name: WCLImagePickerNotify.deleteSelectCell, object: nil)
57 | NotificationCenter.default.addObserver(self, selector: #selector(insertSelectTotalNum(_ :)), name: WCLImagePickerNotify.insertSelectCell, object: nil)
58 |
59 | let size = CGSize.init(width: 26, height: 26)
60 | UIGraphicsBeginImageContextWithOptions(size, false, UIScreen.main.scale)
61 | let context = UIGraphicsGetCurrentContext()
62 | if let color = WCLImagePickerOptions.pickerSelectColor {
63 | color.setFill()
64 | }else {
65 | WCLImagePickerOptions.tintColor.setFill()
66 | }
67 | context?.addArc(center: CGPoint.init(x: size.width / 2, y: size.height / 2), radius: size.width / 2, startAngle: 0, endAngle: CGFloat(Double.pi * 2), clockwise: true)
68 | context?.fillPath()
69 | let selectImage = UIGraphicsGetImageFromCurrentImageContext()
70 | UIGraphicsEndImageContext()
71 | imageSelectImage.image = selectImage
72 | }
73 |
74 | override func layoutSubviews() {
75 | super.layoutSubviews()
76 | layoutIfNeeded()
77 | }
78 |
79 | //MARK: Initial Methods
80 | class func `init`(frame: CGRect, pickerManager: WCLPickerManager) -> WCLPhotoSelectView {
81 | let view = UINib.init(nibName: "WCLPhotoSelectView", bundle: WCLImagePickerBundle.bundle).instantiate(withOwner: nil, options: nil).first as! WCLPhotoSelectView
82 | view.frame = frame
83 | view.pickerManager = pickerManager
84 | return view
85 | }
86 |
87 | //MARK: Privater Methods
88 |
89 |
90 | //MARK: UICollectionViewDelegate
91 | func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
92 | collectionView.deselectItem(at: indexPath, animated: true)
93 | if let count = pickerManager?.selectPhotoArr.count {
94 | if count != indexPath.row {
95 | let browserVC = WCLPhotoBrowserController.init(pickerManager!, currentIndex: indexPath.row, selectAssetArr: pickerManager!.selectPhotoArr)
96 | pushBlock?(browserVC)
97 | }
98 | }
99 | }
100 |
101 | func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
102 | return CGSize(width: 36, height: 36)
103 | }
104 |
105 | //MARK: UICollectionViewDataSource
106 | func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
107 | return pickerManager!.selectPhotoArr.count+1
108 |
109 | }
110 |
111 | func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
112 | let cell = collectionView.dequeueReusableCell(withReuseIdentifier: WCLSelecteCVCell.identfier, for: indexPath) as! WCLSelecteCVCell
113 | if let pickerManager = pickerManager {
114 | if indexPath.row == pickerManager.selectPhotoArr.count {
115 | cell.selectImageView.image = WCLImagePickerOptions.selectPlaceholder
116 | }else {
117 | weak var weakCell = cell
118 | let assetArr: [PHAsset] = pickerManager.selectPhotoArr
119 | pickerManager.getPhoto(CGSize(width: 36, height: 36), alasset: assetArr[indexPath.row], resultHandler: { (image, infoDic) in
120 | weakCell?.selectImageView.image = image
121 | })
122 | }
123 | }else {
124 | cell.selectImageView.image = WCLImagePickerOptions.selectPlaceholder
125 | }
126 | return cell
127 | }
128 |
129 | //MARK: Notification Methods
130 | @objc private func reloadSelectTotalNum() {
131 | if let pickerManager = pickerManager {
132 | imageSelectNum.text = String.init(format: "%d", pickerManager.selectPhotoArr.count)
133 | }
134 | }
135 |
136 | @objc private func deleteSelectTotalNum(_ not: Notification) {
137 | if let index = not.object as? IndexPath {
138 | selectCollectionView.performBatchUpdates({ [weak self] in
139 | self?.selectCollectionView.deleteItems(at: [index])
140 | }, completion: nil)
141 | }
142 | }
143 |
144 | @objc private func insertSelectTotalNum(_ not: Notification) {
145 | if let index = not.object as? IndexPath {
146 | selectCollectionView.performBatchUpdates({ [weak self] in
147 | self?.selectCollectionView.insertItems(at: [index])
148 | }, completion: nil)
149 | }
150 | }
151 | }
152 |
153 |
154 |
--------------------------------------------------------------------------------
/WCLImagePickerController/WCLImagePickerController/Views/WCLPhotoSelectView.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 |
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 |
--------------------------------------------------------------------------------
/WCLImagePickerController/WCLImagePickerController/Views/WCLSelectView.swift:
--------------------------------------------------------------------------------
1 | //
2 | // WCLSelectView.swift
3 | // WarChat
4 | //
5 | // **************************************************
6 | // * _____ *
7 | // * __ _ __ ___ \ / *
8 | // * \ \/ \/ / / __\ / / *
9 | // * \ _ / | (__ / / *
10 | // * \/ \/ \___/ / /__ *
11 | // * /_____/ *
12 | // * *
13 | // **************************************************
14 | // Github :https://github.com/631106979
15 | // HomePage:https://imwcl.com
16 | // CSDN :http://blog.csdn.net/wang631106979
17 | //
18 | // Created by 王崇磊 on 16/9/14.
19 | // Copyright © 2016年 王崇磊. All rights reserved.
20 | //
21 | // @class WCLSelectView
22 | // @abstract WCLPhotoBrowserController页面的右上角的选择view
23 | // @discussion WCLPhotoBrowserController页面的右上角的选择view
24 | //
25 |
26 | import UIKit
27 |
28 | internal class WCLSelectView: UIView {
29 |
30 | @IBOutlet weak var selectLabel: UILabel!
31 | @IBOutlet weak var selectBt: UIButton!
32 |
33 | var selecrIndex: Int = 0 {
34 | willSet {
35 | if newValue == 0 {
36 | selectBt.isSelected = false
37 | selectLabel.isHidden = true
38 | }else {
39 | selectBt.isSelected = true
40 | selectLabel.isHidden = false
41 | selectLabel.text = "\(newValue)"
42 | }
43 | }
44 | }
45 |
46 | override func awakeFromNib() {
47 | super.awakeFromNib()
48 |
49 | let size = CGSize.init(width: 22, height: 22)
50 | UIGraphicsBeginImageContextWithOptions(size, false, UIScreen.main.scale)
51 | let context = UIGraphicsGetCurrentContext()
52 | if let color = WCLImagePickerOptions.pickerSelectColor {
53 | color.setFill()
54 | }else {
55 | WCLImagePickerOptions.tintColor.setFill()
56 | }
57 | context?.addArc(center: CGPoint.init(x: size.width / 2, y: size.height / 2), radius: size.width / 2, startAngle: 0, endAngle: CGFloat(Double.pi * 2), clockwise: true)
58 | context?.fillPath()
59 | let selectImage = UIGraphicsGetImageFromCurrentImageContext()
60 | UIGraphicsEndImageContext()
61 | selectBt.setImage(selectImage, for: .selected)
62 |
63 | selectBt.setImage(WCLImagePickerBundle.imageFromBundle("image_pickerDefault"), for: .normal)
64 | }
65 |
66 | //MARK: init Methods
67 | class func initFormNib() -> WCLSelectView {
68 | let view = UINib.init(nibName: "WCLSelectView", bundle: WCLImagePickerBundle.bundle).instantiate(withOwner: nil, options: nil).first as! WCLSelectView
69 | view.selectBt.isSelected = false
70 | view.selectLabel.isHidden = true
71 | return view
72 | }
73 |
74 | }
75 |
--------------------------------------------------------------------------------
/WCLImagePickerController/WCLImagePickerController/Views/WCLSelectView.xib:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
26 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
--------------------------------------------------------------------------------
/WCLImagePickerController/WCLImagePickerController/WCLImagePickerController.bundle/Images/image_ablumSelectBackGround@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/imwcl/WCLImagePickerController/a5b9328d09d399e6c4384b940f4bcca8fbe53ff7/WCLImagePickerController/WCLImagePickerController/WCLImagePickerController.bundle/Images/image_ablumSelectBackGround@2x.png
--------------------------------------------------------------------------------
/WCLImagePickerController/WCLImagePickerController/WCLImagePickerController.bundle/Images/image_ablumSelectBackGround@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/imwcl/WCLImagePickerController/a5b9328d09d399e6c4384b940f4bcca8fbe53ff7/WCLImagePickerController/WCLImagePickerController/WCLImagePickerController.bundle/Images/image_ablumSelectBackGround@3x.png
--------------------------------------------------------------------------------
/WCLImagePickerController/WCLImagePickerController/WCLImagePickerController.bundle/Images/image_buffer@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/imwcl/WCLImagePickerController/a5b9328d09d399e6c4384b940f4bcca8fbe53ff7/WCLImagePickerController/WCLImagePickerController/WCLImagePickerController.bundle/Images/image_buffer@2x.png
--------------------------------------------------------------------------------
/WCLImagePickerController/WCLImagePickerController/WCLImagePickerController.bundle/Images/image_buffer@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/imwcl/WCLImagePickerController/a5b9328d09d399e6c4384b940f4bcca8fbe53ff7/WCLImagePickerController/WCLImagePickerController/WCLImagePickerController.bundle/Images/image_buffer@3x.png
--------------------------------------------------------------------------------
/WCLImagePickerController/WCLImagePickerController/WCLImagePickerController.bundle/Images/image_camera@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/imwcl/WCLImagePickerController/a5b9328d09d399e6c4384b940f4bcca8fbe53ff7/WCLImagePickerController/WCLImagePickerController/WCLImagePickerController.bundle/Images/image_camera@2x.png
--------------------------------------------------------------------------------
/WCLImagePickerController/WCLImagePickerController/WCLImagePickerController.bundle/Images/image_camera@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/imwcl/WCLImagePickerController/a5b9328d09d399e6c4384b940f4bcca8fbe53ff7/WCLImagePickerController/WCLImagePickerController/WCLImagePickerController.bundle/Images/image_camera@3x.png
--------------------------------------------------------------------------------
/WCLImagePickerController/WCLImagePickerController/WCLImagePickerController.bundle/Images/image_photoAlbum@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/imwcl/WCLImagePickerController/a5b9328d09d399e6c4384b940f4bcca8fbe53ff7/WCLImagePickerController/WCLImagePickerController/WCLImagePickerController.bundle/Images/image_photoAlbum@2x.png
--------------------------------------------------------------------------------
/WCLImagePickerController/WCLImagePickerController/WCLImagePickerController.bundle/Images/image_photoAlbum@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/imwcl/WCLImagePickerController/a5b9328d09d399e6c4384b940f4bcca8fbe53ff7/WCLImagePickerController/WCLImagePickerController/WCLImagePickerController.bundle/Images/image_photoAlbum@3x.png
--------------------------------------------------------------------------------
/WCLImagePickerController/WCLImagePickerController/WCLImagePickerController.bundle/Images/image_pickerArrow@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/imwcl/WCLImagePickerController/a5b9328d09d399e6c4384b940f4bcca8fbe53ff7/WCLImagePickerController/WCLImagePickerController/WCLImagePickerController.bundle/Images/image_pickerArrow@2x.png
--------------------------------------------------------------------------------
/WCLImagePickerController/WCLImagePickerController/WCLImagePickerController.bundle/Images/image_pickerArrow@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/imwcl/WCLImagePickerController/a5b9328d09d399e6c4384b940f4bcca8fbe53ff7/WCLImagePickerController/WCLImagePickerController/WCLImagePickerController.bundle/Images/image_pickerArrow@3x.png
--------------------------------------------------------------------------------
/WCLImagePickerController/WCLImagePickerController/WCLImagePickerController.bundle/Images/image_pickerDefault@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/imwcl/WCLImagePickerController/a5b9328d09d399e6c4384b940f4bcca8fbe53ff7/WCLImagePickerController/WCLImagePickerController/WCLImagePickerController.bundle/Images/image_pickerDefault@2x.png
--------------------------------------------------------------------------------
/WCLImagePickerController/WCLImagePickerController/WCLImagePickerController.bundle/Images/image_pickerDefault@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/imwcl/WCLImagePickerController/a5b9328d09d399e6c4384b940f4bcca8fbe53ff7/WCLImagePickerController/WCLImagePickerController/WCLImagePickerController.bundle/Images/image_pickerDefault@3x.png
--------------------------------------------------------------------------------
/WCLImagePickerController/WCLImagePickerController/WCLImagePickerController.bundle/Images/image_selectPlaceholder@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/imwcl/WCLImagePickerController/a5b9328d09d399e6c4384b940f4bcca8fbe53ff7/WCLImagePickerController/WCLImagePickerController/WCLImagePickerController.bundle/Images/image_selectPlaceholder@2x.png
--------------------------------------------------------------------------------
/WCLImagePickerController/WCLImagePickerController/WCLImagePickerController.bundle/Images/image_selectPlaceholder@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/imwcl/WCLImagePickerController/a5b9328d09d399e6c4384b940f4bcca8fbe53ff7/WCLImagePickerController/WCLImagePickerController/WCLImagePickerController.bundle/Images/image_selectPlaceholder@3x.png
--------------------------------------------------------------------------------
/WCLImagePickerController/WCLImagePickerController/WCLImagePickerController.bundle/en.lproj/Localizable.strings:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/imwcl/WCLImagePickerController/a5b9328d09d399e6c4384b940f4bcca8fbe53ff7/WCLImagePickerController/WCLImagePickerController/WCLImagePickerController.bundle/en.lproj/Localizable.strings
--------------------------------------------------------------------------------
/WCLImagePickerController/WCLImagePickerController/WCLImagePickerController.bundle/zh.lproj/Localizable.strings:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/imwcl/WCLImagePickerController/a5b9328d09d399e6c4384b940f4bcca8fbe53ff7/WCLImagePickerController/WCLImagePickerController/WCLImagePickerController.bundle/zh.lproj/Localizable.strings
--------------------------------------------------------------------------------
/wcl.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/imwcl/WCLImagePickerController/a5b9328d09d399e6c4384b940f4bcca8fbe53ff7/wcl.gif
--------------------------------------------------------------------------------