├── .gitignore ├── Podfile ├── Podfile.lock ├── QQImagesPicker.xcodeproj ├── project.pbxproj ├── project.xcworkspace │ ├── contents.xcworkspacedata │ └── xcuserdata │ │ └── best.xcuserdatad │ │ └── UserInterfaceState.xcuserstate └── xcuserdata │ └── best.xcuserdatad │ └── xcschemes │ ├── QQImagesPicker.xcscheme │ └── xcschememanagement.plist ├── QQImagesPicker.xcworkspace ├── contents.xcworkspacedata └── xcuserdata │ └── best.xcuserdatad │ └── UserInterfaceState.xcuserstate ├── QQImagesPicker ├── AppDelegate.h ├── AppDelegate.m ├── Assets.xcassets │ ├── AppIcon.appiconset │ │ └── Contents.json │ ├── Contents.json │ ├── compose_photo_close.imageset │ │ ├── Contents.json │ │ └── compose_photo_close@2x.png │ └── compose_pic_add.imageset │ │ ├── Contents.json │ │ ├── compose_pic_add@2x.png │ │ └── compose_pic_add@3x.png ├── Base.lproj │ ├── LaunchScreen.storyboard │ └── Main.storyboard ├── ImagePicker │ ├── Assets │ │ ├── ImagesPicker.xcassets │ │ │ ├── compose_close.imageset │ │ │ │ ├── Contents.json │ │ │ │ └── close.png │ │ │ └── images │ │ │ │ ├── assets_placeholder_picture.imageset │ │ │ │ ├── Contents.json │ │ │ │ └── assets_placeholder_picture@2x.png │ │ │ │ ├── camera_edit_cut_cancel.imageset │ │ │ │ ├── Contents.json │ │ │ │ └── camera_edit_cut_cancel@2x.png │ │ │ │ ├── camera_edit_cut_cancel_highlighted.imageset │ │ │ │ ├── Contents.json │ │ │ │ └── camera_edit_cut_cancel_highlighted@2x.png │ │ │ │ ├── compose_photo_original.imageset │ │ │ │ ├── Contents.json │ │ │ │ ├── compose_photo_original@2x.png │ │ │ │ └── compose_photo_original@3x.png │ │ │ │ ├── compose_photo_original_highlighted.imageset │ │ │ │ ├── Contents.json │ │ │ │ ├── compose_photo_original_highlighted@2x.png │ │ │ │ └── compose_photo_original_highlighted@3x.png │ │ │ │ ├── compose_photograph.imageset │ │ │ │ ├── Contents.json │ │ │ │ ├── compose_photograph@2x.png │ │ │ │ └── compose_photograph@3x.png │ │ │ │ ├── compose_photograph_background.imageset │ │ │ │ ├── Contents.json │ │ │ │ └── compose_photograph_background@2x.png │ │ │ │ ├── compose_photograph_highlighted.imageset │ │ │ │ ├── Contents.json │ │ │ │ ├── compose_photograph_highlighted@2x.png │ │ │ │ └── compose_photograph_highlighted@3x.png │ │ │ │ ├── navigationbar_arrow_down.imageset │ │ │ │ ├── Contents.json │ │ │ │ └── navigationbar_arrow_down@2x.png │ │ │ │ ├── navigationbar_arrow_up.imageset │ │ │ │ ├── Contents.json │ │ │ │ └── navigationbar_arrow_up@2x.png │ │ │ │ ├── navigationbar_title_highlighted.imageset │ │ │ │ ├── Contents.json │ │ │ │ └── navigationbar_title_highlighted@2x.png │ │ │ │ ├── photo_check_default.imageset │ │ │ │ ├── Contents.json │ │ │ │ ├── photo_check_default@2x.png │ │ │ │ └── photo_check_default@3x.png │ │ │ │ ├── photo_check_selected.imageset │ │ │ │ ├── Contents.json │ │ │ │ ├── photo_check_selected@2x.png │ │ │ │ └── photo_check_selected@3x.png │ │ │ │ ├── picker_alert_sigh.imageset │ │ │ │ ├── Contents.json │ │ │ │ └── picker_alert_sigh@2x.png │ │ │ │ ├── picker_button_orange.imageset │ │ │ │ ├── Contents.json │ │ │ │ └── picker_button_orange@2x.png │ │ │ │ ├── picker_button_orange_highlighted.imageset │ │ │ │ ├── Contents.json │ │ │ │ └── picker_button_orange_highlighted@2x.png │ │ │ │ ├── picker_image_placeholder.imageset │ │ │ │ ├── Contents.json │ │ │ │ └── picker_image_placeholder@2x.png │ │ │ │ └── picker_photo_filter_checked.imageset │ │ │ │ ├── Contents.json │ │ │ │ └── picker_photo_filter_checked@2x.png │ │ ├── en.lproj │ │ │ └── JKImagePickerController.strings │ │ └── zh-Hans.lproj │ │ │ └── JKImagePickerController.strings │ └── Classes │ │ ├── JKAssets.h │ │ ├── JKAssets.m │ │ ├── JKAssetsCollectionFooterView.h │ │ ├── JKAssetsCollectionFooterView.m │ │ ├── JKAssetsGroupCell.h │ │ ├── JKAssetsGroupCell.m │ │ ├── JKAssetsGroupsView.h │ │ ├── JKAssetsGroupsView.m │ │ ├── JKAssetsThumbnailView.h │ │ ├── JKAssetsThumbnailView.m │ │ ├── JKAssetsViewCell.h │ │ ├── JKAssetsViewCell.m │ │ ├── JKImagePickerController.h │ │ ├── JKImagePickerController.m │ │ ├── JKPhotoBrowser.h │ │ ├── JKPhotoBrowser.m │ │ ├── JKPhotoBrowserCell.h │ │ ├── JKPhotoBrowserCell.m │ │ ├── JKPromptView.h │ │ ├── JKPromptView.m │ │ ├── JKUtil.h │ │ ├── JKUtil.m │ │ ├── PhotoAlbumManager.h │ │ ├── PhotoAlbumManager.m │ │ ├── UIView+JKPicker.h │ │ └── UIView+JKPicker.m ├── Info.plist ├── QQCompose │ ├── QQComposeAddPhotoViewCell.h │ ├── QQComposeAddPhotoViewCell.m │ ├── QQComposePhotoViewCell.h │ ├── QQComposePhotoViewCell.m │ ├── QQComposePhotosView.h │ └── QQComposePhotosView.m ├── QQNUploadManager │ ├── QQQNSystemService.h │ ├── QQQNSystemService.m │ ├── QQQNUploadHelper.h │ └── QQQNUploadHelper.m ├── UIView+Extension.h ├── UIView+Extension.m ├── ViewController.h ├── ViewController.m └── main.m └── README.md /.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 | 24 | ## Obj-C/Swift specific 25 | *.hmap 26 | *.ipa 27 | *.dSYM.zip 28 | *.dSYM 29 | 30 | # CocoaPods 31 | # 32 | # We recommend against adding the Pods directory to your .gitignore. However 33 | # you should judge for yourself, the pros and cons are mentioned at: 34 | # https://guides.cocoapods.org/using/using-cocoapods.html#should-i-check-the-pods-directory-into-source-control 35 | # 36 | # Pods/ 37 | 38 | # Carthage 39 | # 40 | # Add this line if you want to avoid checking in source code from Carthage dependencies. 41 | # Carthage/Checkouts 42 | 43 | Carthage/Build 44 | 45 | # fastlane 46 | # 47 | # It is recommended to not store the screenshots in the git repo. Instead, use fastlane to re-generate the 48 | # screenshots whenever they are needed. 49 | # For more information about the recommended setup visit: 50 | # https://github.com/fastlane/fastlane/blob/master/fastlane/docs/Gitignore.md 51 | 52 | fastlane/report.xml 53 | fastlane/screenshots 54 | 55 | #Code Injection 56 | # 57 | # After new code Injection tools there's a generated folder /iOSInjectionProject 58 | # https://github.com/johnno1962/injectionforxcode 59 | 60 | iOSInjectionProject/ 61 | -------------------------------------------------------------------------------- /Podfile: -------------------------------------------------------------------------------- 1 | # Uncomment the next line to define a global platform for your project 2 | # platform :ios, '9.0' 3 | 4 | target 'QQImagesPicker' do 5 | # Uncomment the next line if you're using Swift or would like to use dynamic frameworks 6 | # use_frameworks! 7 | 8 | # Pods for QQImagesPicker 9 | pod "Qiniu", "~> 7.1" 10 | pod "AFNetworking", "~> 3.x" 11 | end 12 | -------------------------------------------------------------------------------- /Podfile.lock: -------------------------------------------------------------------------------- 1 | PODS: 2 | - AFNetworking (3.1.0): 3 | - AFNetworking/NSURLSession (= 3.1.0) 4 | - AFNetworking/Reachability (= 3.1.0) 5 | - AFNetworking/Security (= 3.1.0) 6 | - AFNetworking/Serialization (= 3.1.0) 7 | - AFNetworking/UIKit (= 3.1.0) 8 | - AFNetworking/NSURLSession (3.1.0): 9 | - AFNetworking/Reachability 10 | - AFNetworking/Security 11 | - AFNetworking/Serialization 12 | - AFNetworking/Reachability (3.1.0) 13 | - AFNetworking/Security (3.1.0) 14 | - AFNetworking/Serialization (3.1.0) 15 | - AFNetworking/UIKit (3.1.0): 16 | - AFNetworking/NSURLSession 17 | - HappyDNS (0.3.10) 18 | - Qiniu (7.1.5): 19 | - AFNetworking (~> 3) 20 | - HappyDNS (~> 0.3) 21 | 22 | DEPENDENCIES: 23 | - AFNetworking (~> 3.x) 24 | - Qiniu (~> 7.1) 25 | 26 | SPEC CHECKSUMS: 27 | AFNetworking: 5e0e199f73d8626b11e79750991f5d173d1f8b67 28 | HappyDNS: 06a9fed2796663fd87626dbf02552933265bf059 29 | Qiniu: 77a3dba411556a383d72d17e842345a9d4c83252 30 | 31 | PODFILE CHECKSUM: 974fd123d712153fd7fdcd74f1aa1ca7bbd2f605 32 | 33 | COCOAPODS: 1.1.1 34 | -------------------------------------------------------------------------------- /QQImagesPicker.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 46; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 401EB0A01E8104920025009D /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 401EB09F1E8104920025009D /* main.m */; }; 11 | 401EB0A31E8104920025009D /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 401EB0A21E8104920025009D /* AppDelegate.m */; }; 12 | 401EB0A61E8104920025009D /* ViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 401EB0A51E8104920025009D /* ViewController.m */; }; 13 | 401EB0A91E8104920025009D /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 401EB0A71E8104920025009D /* Main.storyboard */; }; 14 | 401EB0AB1E8104920025009D /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 401EB0AA1E8104920025009D /* Assets.xcassets */; }; 15 | 401EB0AE1E8104920025009D /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 401EB0AC1E8104920025009D /* LaunchScreen.storyboard */; }; 16 | 401EB0D61E8105850025009D /* JKImagePickerController.strings in Resources */ = {isa = PBXBuildFile; fileRef = 401EB0B71E8105850025009D /* JKImagePickerController.strings */; }; 17 | 401EB0D71E8105850025009D /* ImagesPicker.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 401EB0B91E8105850025009D /* ImagesPicker.xcassets */; }; 18 | 401EB0D81E8105850025009D /* JKAssets.m in Sources */ = {isa = PBXBuildFile; fileRef = 401EB0BD1E8105850025009D /* JKAssets.m */; }; 19 | 401EB0D91E8105850025009D /* JKAssetsCollectionFooterView.m in Sources */ = {isa = PBXBuildFile; fileRef = 401EB0BF1E8105850025009D /* JKAssetsCollectionFooterView.m */; }; 20 | 401EB0DA1E8105850025009D /* JKAssetsGroupCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 401EB0C11E8105850025009D /* JKAssetsGroupCell.m */; }; 21 | 401EB0DB1E8105850025009D /* JKAssetsGroupsView.m in Sources */ = {isa = PBXBuildFile; fileRef = 401EB0C31E8105850025009D /* JKAssetsGroupsView.m */; }; 22 | 401EB0DC1E8105850025009D /* JKAssetsThumbnailView.m in Sources */ = {isa = PBXBuildFile; fileRef = 401EB0C51E8105850025009D /* JKAssetsThumbnailView.m */; }; 23 | 401EB0DD1E8105850025009D /* JKAssetsViewCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 401EB0C71E8105850025009D /* JKAssetsViewCell.m */; }; 24 | 401EB0DE1E8105850025009D /* JKImagePickerController.m in Sources */ = {isa = PBXBuildFile; fileRef = 401EB0C91E8105850025009D /* JKImagePickerController.m */; }; 25 | 401EB0DF1E8105850025009D /* JKPhotoBrowser.m in Sources */ = {isa = PBXBuildFile; fileRef = 401EB0CB1E8105850025009D /* JKPhotoBrowser.m */; }; 26 | 401EB0E01E8105850025009D /* JKPhotoBrowserCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 401EB0CD1E8105850025009D /* JKPhotoBrowserCell.m */; }; 27 | 401EB0E11E8105850025009D /* JKPromptView.m in Sources */ = {isa = PBXBuildFile; fileRef = 401EB0CF1E8105850025009D /* JKPromptView.m */; }; 28 | 401EB0E21E8105850025009D /* JKUtil.m in Sources */ = {isa = PBXBuildFile; fileRef = 401EB0D11E8105850025009D /* JKUtil.m */; }; 29 | 401EB0E31E8105850025009D /* PhotoAlbumManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 401EB0D31E8105850025009D /* PhotoAlbumManager.m */; }; 30 | 401EB0E41E8105850025009D /* UIView+JKPicker.m in Sources */ = {isa = PBXBuildFile; fileRef = 401EB0D51E8105850025009D /* UIView+JKPicker.m */; }; 31 | 401EB0EA1E81058F0025009D /* QQQNSystemService.m in Sources */ = {isa = PBXBuildFile; fileRef = 401EB0E71E81058F0025009D /* QQQNSystemService.m */; }; 32 | 401EB0EB1E81058F0025009D /* QQQNUploadHelper.m in Sources */ = {isa = PBXBuildFile; fileRef = 401EB0E91E81058F0025009D /* QQQNUploadHelper.m */; }; 33 | 401EB0F31E8105B80025009D /* QQComposeAddPhotoViewCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 401EB0EE1E8105B80025009D /* QQComposeAddPhotoViewCell.m */; }; 34 | 401EB0F41E8105B80025009D /* QQComposePhotosView.m in Sources */ = {isa = PBXBuildFile; fileRef = 401EB0F01E8105B80025009D /* QQComposePhotosView.m */; }; 35 | 401EB0F51E8105B80025009D /* QQComposePhotoViewCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 401EB0F21E8105B80025009D /* QQComposePhotoViewCell.m */; }; 36 | 401EB0F81E81067B0025009D /* UIView+Extension.m in Sources */ = {isa = PBXBuildFile; fileRef = 401EB0F71E81067B0025009D /* UIView+Extension.m */; }; 37 | F30311E1284796B496A931F1 /* libPods-QQImagesPicker.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 8337311E422C21D1C99043FE /* libPods-QQImagesPicker.a */; }; 38 | /* End PBXBuildFile section */ 39 | 40 | /* Begin PBXFileReference section */ 41 | 401EB09B1E8104920025009D /* QQImagesPicker.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = QQImagesPicker.app; sourceTree = BUILT_PRODUCTS_DIR; }; 42 | 401EB09F1E8104920025009D /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; 43 | 401EB0A11E8104920025009D /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; 44 | 401EB0A21E8104920025009D /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; 45 | 401EB0A41E8104920025009D /* ViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ViewController.h; sourceTree = ""; }; 46 | 401EB0A51E8104920025009D /* ViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ViewController.m; sourceTree = ""; }; 47 | 401EB0A81E8104920025009D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; 48 | 401EB0AA1E8104920025009D /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; 49 | 401EB0AD1E8104920025009D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; 50 | 401EB0AF1E8104920025009D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 51 | 401EB0B81E8105850025009D /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/JKImagePickerController.strings; sourceTree = ""; }; 52 | 401EB0B91E8105850025009D /* ImagesPicker.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = ImagesPicker.xcassets; sourceTree = ""; }; 53 | 401EB0BA1E8105850025009D /* zh-Hans */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "zh-Hans"; path = "zh-Hans.lproj/JKImagePickerController.strings"; sourceTree = ""; }; 54 | 401EB0BC1E8105850025009D /* JKAssets.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JKAssets.h; sourceTree = ""; }; 55 | 401EB0BD1E8105850025009D /* JKAssets.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = JKAssets.m; sourceTree = ""; }; 56 | 401EB0BE1E8105850025009D /* JKAssetsCollectionFooterView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JKAssetsCollectionFooterView.h; sourceTree = ""; }; 57 | 401EB0BF1E8105850025009D /* JKAssetsCollectionFooterView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = JKAssetsCollectionFooterView.m; sourceTree = ""; }; 58 | 401EB0C01E8105850025009D /* JKAssetsGroupCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JKAssetsGroupCell.h; sourceTree = ""; }; 59 | 401EB0C11E8105850025009D /* JKAssetsGroupCell.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = JKAssetsGroupCell.m; sourceTree = ""; }; 60 | 401EB0C21E8105850025009D /* JKAssetsGroupsView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JKAssetsGroupsView.h; sourceTree = ""; }; 61 | 401EB0C31E8105850025009D /* JKAssetsGroupsView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = JKAssetsGroupsView.m; sourceTree = ""; }; 62 | 401EB0C41E8105850025009D /* JKAssetsThumbnailView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JKAssetsThumbnailView.h; sourceTree = ""; }; 63 | 401EB0C51E8105850025009D /* JKAssetsThumbnailView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = JKAssetsThumbnailView.m; sourceTree = ""; }; 64 | 401EB0C61E8105850025009D /* JKAssetsViewCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JKAssetsViewCell.h; sourceTree = ""; }; 65 | 401EB0C71E8105850025009D /* JKAssetsViewCell.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = JKAssetsViewCell.m; sourceTree = ""; }; 66 | 401EB0C81E8105850025009D /* JKImagePickerController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JKImagePickerController.h; sourceTree = ""; }; 67 | 401EB0C91E8105850025009D /* JKImagePickerController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = JKImagePickerController.m; sourceTree = ""; }; 68 | 401EB0CA1E8105850025009D /* JKPhotoBrowser.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JKPhotoBrowser.h; sourceTree = ""; }; 69 | 401EB0CB1E8105850025009D /* JKPhotoBrowser.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = JKPhotoBrowser.m; sourceTree = ""; }; 70 | 401EB0CC1E8105850025009D /* JKPhotoBrowserCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JKPhotoBrowserCell.h; sourceTree = ""; }; 71 | 401EB0CD1E8105850025009D /* JKPhotoBrowserCell.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = JKPhotoBrowserCell.m; sourceTree = ""; }; 72 | 401EB0CE1E8105850025009D /* JKPromptView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JKPromptView.h; sourceTree = ""; }; 73 | 401EB0CF1E8105850025009D /* JKPromptView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = JKPromptView.m; sourceTree = ""; }; 74 | 401EB0D01E8105850025009D /* JKUtil.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JKUtil.h; sourceTree = ""; }; 75 | 401EB0D11E8105850025009D /* JKUtil.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = JKUtil.m; sourceTree = ""; }; 76 | 401EB0D21E8105850025009D /* PhotoAlbumManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PhotoAlbumManager.h; sourceTree = ""; }; 77 | 401EB0D31E8105850025009D /* PhotoAlbumManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = PhotoAlbumManager.m; sourceTree = ""; }; 78 | 401EB0D41E8105850025009D /* UIView+JKPicker.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "UIView+JKPicker.h"; sourceTree = ""; }; 79 | 401EB0D51E8105850025009D /* UIView+JKPicker.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "UIView+JKPicker.m"; sourceTree = ""; }; 80 | 401EB0E61E81058F0025009D /* QQQNSystemService.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = QQQNSystemService.h; sourceTree = ""; }; 81 | 401EB0E71E81058F0025009D /* QQQNSystemService.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = QQQNSystemService.m; sourceTree = ""; }; 82 | 401EB0E81E81058F0025009D /* QQQNUploadHelper.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = QQQNUploadHelper.h; sourceTree = ""; }; 83 | 401EB0E91E81058F0025009D /* QQQNUploadHelper.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = QQQNUploadHelper.m; sourceTree = ""; }; 84 | 401EB0ED1E8105B80025009D /* QQComposeAddPhotoViewCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = QQComposeAddPhotoViewCell.h; sourceTree = ""; }; 85 | 401EB0EE1E8105B80025009D /* QQComposeAddPhotoViewCell.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = QQComposeAddPhotoViewCell.m; sourceTree = ""; }; 86 | 401EB0EF1E8105B80025009D /* QQComposePhotosView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = QQComposePhotosView.h; sourceTree = ""; }; 87 | 401EB0F01E8105B80025009D /* QQComposePhotosView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = QQComposePhotosView.m; sourceTree = ""; }; 88 | 401EB0F11E8105B80025009D /* QQComposePhotoViewCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = QQComposePhotoViewCell.h; sourceTree = ""; }; 89 | 401EB0F21E8105B80025009D /* QQComposePhotoViewCell.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = QQComposePhotoViewCell.m; sourceTree = ""; }; 90 | 401EB0F61E81067B0025009D /* UIView+Extension.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "UIView+Extension.h"; sourceTree = ""; }; 91 | 401EB0F71E81067B0025009D /* UIView+Extension.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "UIView+Extension.m"; sourceTree = ""; }; 92 | 8337311E422C21D1C99043FE /* libPods-QQImagesPicker.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-QQImagesPicker.a"; sourceTree = BUILT_PRODUCTS_DIR; }; 93 | 8B46361EB68CDD96E0CAF1B1 /* Pods-QQImagesPicker.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-QQImagesPicker.release.xcconfig"; path = "Pods/Target Support Files/Pods-QQImagesPicker/Pods-QQImagesPicker.release.xcconfig"; sourceTree = ""; }; 94 | AD0114BAF97CFD969F2B6916 /* Pods-QQImagesPicker.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-QQImagesPicker.debug.xcconfig"; path = "Pods/Target Support Files/Pods-QQImagesPicker/Pods-QQImagesPicker.debug.xcconfig"; sourceTree = ""; }; 95 | /* End PBXFileReference section */ 96 | 97 | /* Begin PBXFrameworksBuildPhase section */ 98 | 401EB0981E8104920025009D /* Frameworks */ = { 99 | isa = PBXFrameworksBuildPhase; 100 | buildActionMask = 2147483647; 101 | files = ( 102 | F30311E1284796B496A931F1 /* libPods-QQImagesPicker.a in Frameworks */, 103 | ); 104 | runOnlyForDeploymentPostprocessing = 0; 105 | }; 106 | /* End PBXFrameworksBuildPhase section */ 107 | 108 | /* Begin PBXGroup section */ 109 | 1FECF44B325D6A7EEEF444BB /* Frameworks */ = { 110 | isa = PBXGroup; 111 | children = ( 112 | 8337311E422C21D1C99043FE /* libPods-QQImagesPicker.a */, 113 | ); 114 | name = Frameworks; 115 | sourceTree = ""; 116 | }; 117 | 401EB0921E8104920025009D = { 118 | isa = PBXGroup; 119 | children = ( 120 | 401EB09D1E8104920025009D /* QQImagesPicker */, 121 | 401EB09C1E8104920025009D /* Products */, 122 | 941C6D56EA8900CBF964B45F /* Pods */, 123 | 1FECF44B325D6A7EEEF444BB /* Frameworks */, 124 | ); 125 | sourceTree = ""; 126 | }; 127 | 401EB09C1E8104920025009D /* Products */ = { 128 | isa = PBXGroup; 129 | children = ( 130 | 401EB09B1E8104920025009D /* QQImagesPicker.app */, 131 | ); 132 | name = Products; 133 | sourceTree = ""; 134 | }; 135 | 401EB09D1E8104920025009D /* QQImagesPicker */ = { 136 | isa = PBXGroup; 137 | children = ( 138 | 401EB0A11E8104920025009D /* AppDelegate.h */, 139 | 401EB0A21E8104920025009D /* AppDelegate.m */, 140 | 401EB0A41E8104920025009D /* ViewController.h */, 141 | 401EB0A51E8104920025009D /* ViewController.m */, 142 | 401EB0EC1E8105B80025009D /* QQCompose */, 143 | 401EB0E51E81058F0025009D /* QQNUploadManager */, 144 | 401EB0B51E8105850025009D /* ImagePicker */, 145 | 401EB09E1E8104920025009D /* Supporting Files */, 146 | ); 147 | path = QQImagesPicker; 148 | sourceTree = ""; 149 | }; 150 | 401EB09E1E8104920025009D /* Supporting Files */ = { 151 | isa = PBXGroup; 152 | children = ( 153 | 401EB0F61E81067B0025009D /* UIView+Extension.h */, 154 | 401EB0F71E81067B0025009D /* UIView+Extension.m */, 155 | 401EB0A71E8104920025009D /* Main.storyboard */, 156 | 401EB0AA1E8104920025009D /* Assets.xcassets */, 157 | 401EB0AC1E8104920025009D /* LaunchScreen.storyboard */, 158 | 401EB0AF1E8104920025009D /* Info.plist */, 159 | 401EB09F1E8104920025009D /* main.m */, 160 | ); 161 | name = "Supporting Files"; 162 | sourceTree = ""; 163 | }; 164 | 401EB0B51E8105850025009D /* ImagePicker */ = { 165 | isa = PBXGroup; 166 | children = ( 167 | 401EB0B61E8105850025009D /* Assets */, 168 | 401EB0BB1E8105850025009D /* Classes */, 169 | ); 170 | path = ImagePicker; 171 | sourceTree = ""; 172 | }; 173 | 401EB0B61E8105850025009D /* Assets */ = { 174 | isa = PBXGroup; 175 | children = ( 176 | 401EB0B71E8105850025009D /* JKImagePickerController.strings */, 177 | 401EB0B91E8105850025009D /* ImagesPicker.xcassets */, 178 | ); 179 | path = Assets; 180 | sourceTree = ""; 181 | }; 182 | 401EB0BB1E8105850025009D /* Classes */ = { 183 | isa = PBXGroup; 184 | children = ( 185 | 401EB0BC1E8105850025009D /* JKAssets.h */, 186 | 401EB0BD1E8105850025009D /* JKAssets.m */, 187 | 401EB0BE1E8105850025009D /* JKAssetsCollectionFooterView.h */, 188 | 401EB0BF1E8105850025009D /* JKAssetsCollectionFooterView.m */, 189 | 401EB0C01E8105850025009D /* JKAssetsGroupCell.h */, 190 | 401EB0C11E8105850025009D /* JKAssetsGroupCell.m */, 191 | 401EB0C21E8105850025009D /* JKAssetsGroupsView.h */, 192 | 401EB0C31E8105850025009D /* JKAssetsGroupsView.m */, 193 | 401EB0C41E8105850025009D /* JKAssetsThumbnailView.h */, 194 | 401EB0C51E8105850025009D /* JKAssetsThumbnailView.m */, 195 | 401EB0C61E8105850025009D /* JKAssetsViewCell.h */, 196 | 401EB0C71E8105850025009D /* JKAssetsViewCell.m */, 197 | 401EB0C81E8105850025009D /* JKImagePickerController.h */, 198 | 401EB0C91E8105850025009D /* JKImagePickerController.m */, 199 | 401EB0CA1E8105850025009D /* JKPhotoBrowser.h */, 200 | 401EB0CB1E8105850025009D /* JKPhotoBrowser.m */, 201 | 401EB0CC1E8105850025009D /* JKPhotoBrowserCell.h */, 202 | 401EB0CD1E8105850025009D /* JKPhotoBrowserCell.m */, 203 | 401EB0CE1E8105850025009D /* JKPromptView.h */, 204 | 401EB0CF1E8105850025009D /* JKPromptView.m */, 205 | 401EB0D01E8105850025009D /* JKUtil.h */, 206 | 401EB0D11E8105850025009D /* JKUtil.m */, 207 | 401EB0D21E8105850025009D /* PhotoAlbumManager.h */, 208 | 401EB0D31E8105850025009D /* PhotoAlbumManager.m */, 209 | 401EB0D41E8105850025009D /* UIView+JKPicker.h */, 210 | 401EB0D51E8105850025009D /* UIView+JKPicker.m */, 211 | ); 212 | path = Classes; 213 | sourceTree = ""; 214 | }; 215 | 401EB0E51E81058F0025009D /* QQNUploadManager */ = { 216 | isa = PBXGroup; 217 | children = ( 218 | 401EB0E61E81058F0025009D /* QQQNSystemService.h */, 219 | 401EB0E71E81058F0025009D /* QQQNSystemService.m */, 220 | 401EB0E81E81058F0025009D /* QQQNUploadHelper.h */, 221 | 401EB0E91E81058F0025009D /* QQQNUploadHelper.m */, 222 | ); 223 | path = QQNUploadManager; 224 | sourceTree = ""; 225 | }; 226 | 401EB0EC1E8105B80025009D /* QQCompose */ = { 227 | isa = PBXGroup; 228 | children = ( 229 | 401EB0ED1E8105B80025009D /* QQComposeAddPhotoViewCell.h */, 230 | 401EB0EE1E8105B80025009D /* QQComposeAddPhotoViewCell.m */, 231 | 401EB0EF1E8105B80025009D /* QQComposePhotosView.h */, 232 | 401EB0F01E8105B80025009D /* QQComposePhotosView.m */, 233 | 401EB0F11E8105B80025009D /* QQComposePhotoViewCell.h */, 234 | 401EB0F21E8105B80025009D /* QQComposePhotoViewCell.m */, 235 | ); 236 | path = QQCompose; 237 | sourceTree = ""; 238 | }; 239 | 941C6D56EA8900CBF964B45F /* Pods */ = { 240 | isa = PBXGroup; 241 | children = ( 242 | AD0114BAF97CFD969F2B6916 /* Pods-QQImagesPicker.debug.xcconfig */, 243 | 8B46361EB68CDD96E0CAF1B1 /* Pods-QQImagesPicker.release.xcconfig */, 244 | ); 245 | name = Pods; 246 | sourceTree = ""; 247 | }; 248 | /* End PBXGroup section */ 249 | 250 | /* Begin PBXNativeTarget section */ 251 | 401EB09A1E8104920025009D /* QQImagesPicker */ = { 252 | isa = PBXNativeTarget; 253 | buildConfigurationList = 401EB0B21E8104920025009D /* Build configuration list for PBXNativeTarget "QQImagesPicker" */; 254 | buildPhases = ( 255 | DFE5E659E29C4E981383DD7F /* [CP] Check Pods Manifest.lock */, 256 | 401EB0971E8104920025009D /* Sources */, 257 | 401EB0981E8104920025009D /* Frameworks */, 258 | 401EB0991E8104920025009D /* Resources */, 259 | FAEA77223E2E7FCBCFDE18E4 /* [CP] Embed Pods Frameworks */, 260 | 63DC1A6DEF77D7BEAB119CDB /* [CP] Copy Pods Resources */, 261 | ); 262 | buildRules = ( 263 | ); 264 | dependencies = ( 265 | ); 266 | name = QQImagesPicker; 267 | productName = QQImagesPicker; 268 | productReference = 401EB09B1E8104920025009D /* QQImagesPicker.app */; 269 | productType = "com.apple.product-type.application"; 270 | }; 271 | /* End PBXNativeTarget section */ 272 | 273 | /* Begin PBXProject section */ 274 | 401EB0931E8104920025009D /* Project object */ = { 275 | isa = PBXProject; 276 | attributes = { 277 | LastUpgradeCheck = 0820; 278 | ORGANIZATIONNAME = baisiChina; 279 | TargetAttributes = { 280 | 401EB09A1E8104920025009D = { 281 | CreatedOnToolsVersion = 8.2.1; 282 | DevelopmentTeam = 8PF3YDNV98; 283 | ProvisioningStyle = Automatic; 284 | }; 285 | }; 286 | }; 287 | buildConfigurationList = 401EB0961E8104920025009D /* Build configuration list for PBXProject "QQImagesPicker" */; 288 | compatibilityVersion = "Xcode 3.2"; 289 | developmentRegion = English; 290 | hasScannedForEncodings = 0; 291 | knownRegions = ( 292 | en, 293 | Base, 294 | "zh-Hans", 295 | ); 296 | mainGroup = 401EB0921E8104920025009D; 297 | productRefGroup = 401EB09C1E8104920025009D /* Products */; 298 | projectDirPath = ""; 299 | projectRoot = ""; 300 | targets = ( 301 | 401EB09A1E8104920025009D /* QQImagesPicker */, 302 | ); 303 | }; 304 | /* End PBXProject section */ 305 | 306 | /* Begin PBXResourcesBuildPhase section */ 307 | 401EB0991E8104920025009D /* Resources */ = { 308 | isa = PBXResourcesBuildPhase; 309 | buildActionMask = 2147483647; 310 | files = ( 311 | 401EB0AE1E8104920025009D /* LaunchScreen.storyboard in Resources */, 312 | 401EB0D61E8105850025009D /* JKImagePickerController.strings in Resources */, 313 | 401EB0AB1E8104920025009D /* Assets.xcassets in Resources */, 314 | 401EB0A91E8104920025009D /* Main.storyboard in Resources */, 315 | 401EB0D71E8105850025009D /* ImagesPicker.xcassets in Resources */, 316 | ); 317 | runOnlyForDeploymentPostprocessing = 0; 318 | }; 319 | /* End PBXResourcesBuildPhase section */ 320 | 321 | /* Begin PBXShellScriptBuildPhase section */ 322 | 63DC1A6DEF77D7BEAB119CDB /* [CP] Copy Pods Resources */ = { 323 | isa = PBXShellScriptBuildPhase; 324 | buildActionMask = 2147483647; 325 | files = ( 326 | ); 327 | inputPaths = ( 328 | ); 329 | name = "[CP] Copy Pods Resources"; 330 | outputPaths = ( 331 | ); 332 | runOnlyForDeploymentPostprocessing = 0; 333 | shellPath = /bin/sh; 334 | shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-QQImagesPicker/Pods-QQImagesPicker-resources.sh\"\n"; 335 | showEnvVarsInLog = 0; 336 | }; 337 | DFE5E659E29C4E981383DD7F /* [CP] Check Pods Manifest.lock */ = { 338 | isa = PBXShellScriptBuildPhase; 339 | buildActionMask = 2147483647; 340 | files = ( 341 | ); 342 | inputPaths = ( 343 | ); 344 | name = "[CP] Check Pods Manifest.lock"; 345 | outputPaths = ( 346 | ); 347 | runOnlyForDeploymentPostprocessing = 0; 348 | shellPath = /bin/sh; 349 | shellScript = "diff \"${PODS_ROOT}/../Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n"; 350 | showEnvVarsInLog = 0; 351 | }; 352 | FAEA77223E2E7FCBCFDE18E4 /* [CP] Embed Pods Frameworks */ = { 353 | isa = PBXShellScriptBuildPhase; 354 | buildActionMask = 2147483647; 355 | files = ( 356 | ); 357 | inputPaths = ( 358 | ); 359 | name = "[CP] Embed Pods Frameworks"; 360 | outputPaths = ( 361 | ); 362 | runOnlyForDeploymentPostprocessing = 0; 363 | shellPath = /bin/sh; 364 | shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-QQImagesPicker/Pods-QQImagesPicker-frameworks.sh\"\n"; 365 | showEnvVarsInLog = 0; 366 | }; 367 | /* End PBXShellScriptBuildPhase section */ 368 | 369 | /* Begin PBXSourcesBuildPhase section */ 370 | 401EB0971E8104920025009D /* Sources */ = { 371 | isa = PBXSourcesBuildPhase; 372 | buildActionMask = 2147483647; 373 | files = ( 374 | 401EB0E31E8105850025009D /* PhotoAlbumManager.m in Sources */, 375 | 401EB0F31E8105B80025009D /* QQComposeAddPhotoViewCell.m in Sources */, 376 | 401EB0F81E81067B0025009D /* UIView+Extension.m in Sources */, 377 | 401EB0A61E8104920025009D /* ViewController.m in Sources */, 378 | 401EB0DC1E8105850025009D /* JKAssetsThumbnailView.m in Sources */, 379 | 401EB0E41E8105850025009D /* UIView+JKPicker.m in Sources */, 380 | 401EB0D91E8105850025009D /* JKAssetsCollectionFooterView.m in Sources */, 381 | 401EB0DD1E8105850025009D /* JKAssetsViewCell.m in Sources */, 382 | 401EB0E21E8105850025009D /* JKUtil.m in Sources */, 383 | 401EB0D81E8105850025009D /* JKAssets.m in Sources */, 384 | 401EB0DF1E8105850025009D /* JKPhotoBrowser.m in Sources */, 385 | 401EB0E01E8105850025009D /* JKPhotoBrowserCell.m in Sources */, 386 | 401EB0E11E8105850025009D /* JKPromptView.m in Sources */, 387 | 401EB0F41E8105B80025009D /* QQComposePhotosView.m in Sources */, 388 | 401EB0A31E8104920025009D /* AppDelegate.m in Sources */, 389 | 401EB0A01E8104920025009D /* main.m in Sources */, 390 | 401EB0EA1E81058F0025009D /* QQQNSystemService.m in Sources */, 391 | 401EB0F51E8105B80025009D /* QQComposePhotoViewCell.m in Sources */, 392 | 401EB0DB1E8105850025009D /* JKAssetsGroupsView.m in Sources */, 393 | 401EB0EB1E81058F0025009D /* QQQNUploadHelper.m in Sources */, 394 | 401EB0DE1E8105850025009D /* JKImagePickerController.m in Sources */, 395 | 401EB0DA1E8105850025009D /* JKAssetsGroupCell.m in Sources */, 396 | ); 397 | runOnlyForDeploymentPostprocessing = 0; 398 | }; 399 | /* End PBXSourcesBuildPhase section */ 400 | 401 | /* Begin PBXVariantGroup section */ 402 | 401EB0A71E8104920025009D /* Main.storyboard */ = { 403 | isa = PBXVariantGroup; 404 | children = ( 405 | 401EB0A81E8104920025009D /* Base */, 406 | ); 407 | name = Main.storyboard; 408 | sourceTree = ""; 409 | }; 410 | 401EB0AC1E8104920025009D /* LaunchScreen.storyboard */ = { 411 | isa = PBXVariantGroup; 412 | children = ( 413 | 401EB0AD1E8104920025009D /* Base */, 414 | ); 415 | name = LaunchScreen.storyboard; 416 | sourceTree = ""; 417 | }; 418 | 401EB0B71E8105850025009D /* JKImagePickerController.strings */ = { 419 | isa = PBXVariantGroup; 420 | children = ( 421 | 401EB0B81E8105850025009D /* en */, 422 | 401EB0BA1E8105850025009D /* zh-Hans */, 423 | ); 424 | name = JKImagePickerController.strings; 425 | sourceTree = ""; 426 | }; 427 | /* End PBXVariantGroup section */ 428 | 429 | /* Begin XCBuildConfiguration section */ 430 | 401EB0B01E8104920025009D /* Debug */ = { 431 | isa = XCBuildConfiguration; 432 | buildSettings = { 433 | ALWAYS_SEARCH_USER_PATHS = NO; 434 | CLANG_ANALYZER_NONNULL = YES; 435 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 436 | CLANG_CXX_LIBRARY = "libc++"; 437 | CLANG_ENABLE_MODULES = YES; 438 | CLANG_ENABLE_OBJC_ARC = YES; 439 | CLANG_WARN_BOOL_CONVERSION = YES; 440 | CLANG_WARN_CONSTANT_CONVERSION = YES; 441 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 442 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 443 | CLANG_WARN_EMPTY_BODY = YES; 444 | CLANG_WARN_ENUM_CONVERSION = YES; 445 | CLANG_WARN_INFINITE_RECURSION = YES; 446 | CLANG_WARN_INT_CONVERSION = YES; 447 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 448 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 449 | CLANG_WARN_UNREACHABLE_CODE = YES; 450 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 451 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 452 | COPY_PHASE_STRIP = NO; 453 | DEBUG_INFORMATION_FORMAT = dwarf; 454 | ENABLE_STRICT_OBJC_MSGSEND = YES; 455 | ENABLE_TESTABILITY = YES; 456 | GCC_C_LANGUAGE_STANDARD = gnu99; 457 | GCC_DYNAMIC_NO_PIC = NO; 458 | GCC_NO_COMMON_BLOCKS = YES; 459 | GCC_OPTIMIZATION_LEVEL = 0; 460 | GCC_PREPROCESSOR_DEFINITIONS = ( 461 | "DEBUG=1", 462 | "$(inherited)", 463 | ); 464 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 465 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 466 | GCC_WARN_UNDECLARED_SELECTOR = YES; 467 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 468 | GCC_WARN_UNUSED_FUNCTION = YES; 469 | GCC_WARN_UNUSED_VARIABLE = YES; 470 | IPHONEOS_DEPLOYMENT_TARGET = 10.2; 471 | MTL_ENABLE_DEBUG_INFO = YES; 472 | ONLY_ACTIVE_ARCH = YES; 473 | SDKROOT = iphoneos; 474 | TARGETED_DEVICE_FAMILY = "1,2"; 475 | }; 476 | name = Debug; 477 | }; 478 | 401EB0B11E8104920025009D /* Release */ = { 479 | isa = XCBuildConfiguration; 480 | buildSettings = { 481 | ALWAYS_SEARCH_USER_PATHS = NO; 482 | CLANG_ANALYZER_NONNULL = YES; 483 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 484 | CLANG_CXX_LIBRARY = "libc++"; 485 | CLANG_ENABLE_MODULES = YES; 486 | CLANG_ENABLE_OBJC_ARC = YES; 487 | CLANG_WARN_BOOL_CONVERSION = YES; 488 | CLANG_WARN_CONSTANT_CONVERSION = YES; 489 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 490 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 491 | CLANG_WARN_EMPTY_BODY = YES; 492 | CLANG_WARN_ENUM_CONVERSION = YES; 493 | CLANG_WARN_INFINITE_RECURSION = YES; 494 | CLANG_WARN_INT_CONVERSION = YES; 495 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 496 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 497 | CLANG_WARN_UNREACHABLE_CODE = YES; 498 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 499 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 500 | COPY_PHASE_STRIP = NO; 501 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 502 | ENABLE_NS_ASSERTIONS = NO; 503 | ENABLE_STRICT_OBJC_MSGSEND = YES; 504 | GCC_C_LANGUAGE_STANDARD = gnu99; 505 | GCC_NO_COMMON_BLOCKS = YES; 506 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 507 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 508 | GCC_WARN_UNDECLARED_SELECTOR = YES; 509 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 510 | GCC_WARN_UNUSED_FUNCTION = YES; 511 | GCC_WARN_UNUSED_VARIABLE = YES; 512 | IPHONEOS_DEPLOYMENT_TARGET = 10.2; 513 | MTL_ENABLE_DEBUG_INFO = NO; 514 | SDKROOT = iphoneos; 515 | TARGETED_DEVICE_FAMILY = "1,2"; 516 | VALIDATE_PRODUCT = YES; 517 | }; 518 | name = Release; 519 | }; 520 | 401EB0B31E8104920025009D /* Debug */ = { 521 | isa = XCBuildConfiguration; 522 | baseConfigurationReference = AD0114BAF97CFD969F2B6916 /* Pods-QQImagesPicker.debug.xcconfig */; 523 | buildSettings = { 524 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 525 | DEVELOPMENT_TEAM = 8PF3YDNV98; 526 | INFOPLIST_FILE = QQImagesPicker/Info.plist; 527 | IPHONEOS_DEPLOYMENT_TARGET = 9.0; 528 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 529 | PRODUCT_BUNDLE_IDENTIFIER = com.huizhong.QQImagesPicker; 530 | PRODUCT_NAME = "$(TARGET_NAME)"; 531 | }; 532 | name = Debug; 533 | }; 534 | 401EB0B41E8104920025009D /* Release */ = { 535 | isa = XCBuildConfiguration; 536 | baseConfigurationReference = 8B46361EB68CDD96E0CAF1B1 /* Pods-QQImagesPicker.release.xcconfig */; 537 | buildSettings = { 538 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 539 | DEVELOPMENT_TEAM = 8PF3YDNV98; 540 | INFOPLIST_FILE = QQImagesPicker/Info.plist; 541 | IPHONEOS_DEPLOYMENT_TARGET = 9.0; 542 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 543 | PRODUCT_BUNDLE_IDENTIFIER = com.huizhong.QQImagesPicker; 544 | PRODUCT_NAME = "$(TARGET_NAME)"; 545 | }; 546 | name = Release; 547 | }; 548 | /* End XCBuildConfiguration section */ 549 | 550 | /* Begin XCConfigurationList section */ 551 | 401EB0961E8104920025009D /* Build configuration list for PBXProject "QQImagesPicker" */ = { 552 | isa = XCConfigurationList; 553 | buildConfigurations = ( 554 | 401EB0B01E8104920025009D /* Debug */, 555 | 401EB0B11E8104920025009D /* Release */, 556 | ); 557 | defaultConfigurationIsVisible = 0; 558 | defaultConfigurationName = Release; 559 | }; 560 | 401EB0B21E8104920025009D /* Build configuration list for PBXNativeTarget "QQImagesPicker" */ = { 561 | isa = XCConfigurationList; 562 | buildConfigurations = ( 563 | 401EB0B31E8104920025009D /* Debug */, 564 | 401EB0B41E8104920025009D /* Release */, 565 | ); 566 | defaultConfigurationIsVisible = 0; 567 | defaultConfigurationName = Release; 568 | }; 569 | /* End XCConfigurationList section */ 570 | }; 571 | rootObject = 401EB0931E8104920025009D /* Project object */; 572 | } 573 | -------------------------------------------------------------------------------- /QQImagesPicker.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /QQImagesPicker.xcodeproj/project.xcworkspace/xcuserdata/best.xcuserdatad/UserInterfaceState.xcuserstate: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jesusLove/QQImagePicker/fac7d819a4966a54f9000c6942fd6da04e94ec8e/QQImagesPicker.xcodeproj/project.xcworkspace/xcuserdata/best.xcuserdatad/UserInterfaceState.xcuserstate -------------------------------------------------------------------------------- /QQImagesPicker.xcodeproj/xcuserdata/best.xcuserdatad/xcschemes/QQImagesPicker.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 | -------------------------------------------------------------------------------- /QQImagesPicker.xcodeproj/xcuserdata/best.xcuserdatad/xcschemes/xcschememanagement.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | SchemeUserState 6 | 7 | QQImagesPicker.xcscheme 8 | 9 | orderHint 10 | 0 11 | 12 | 13 | SuppressBuildableAutocreation 14 | 15 | 401EB09A1E8104920025009D 16 | 17 | primary 18 | 19 | 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /QQImagesPicker.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /QQImagesPicker.xcworkspace/xcuserdata/best.xcuserdatad/UserInterfaceState.xcuserstate: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jesusLove/QQImagePicker/fac7d819a4966a54f9000c6942fd6da04e94ec8e/QQImagesPicker.xcworkspace/xcuserdata/best.xcuserdatad/UserInterfaceState.xcuserstate -------------------------------------------------------------------------------- /QQImagesPicker/AppDelegate.h: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.h 3 | // QQImagesPicker 4 | // 5 | // Created by best-admin on 2017/3/21. 6 | // Copyright © 2017年 baisiChina. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface AppDelegate : UIResponder 12 | 13 | @property (strong, nonatomic) UIWindow *window; 14 | 15 | 16 | @end 17 | 18 | -------------------------------------------------------------------------------- /QQImagesPicker/AppDelegate.m: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.m 3 | // QQImagesPicker 4 | // 5 | // Created by best-admin on 2017/3/21. 6 | // Copyright © 2017年 baisiChina. All rights reserved. 7 | // 8 | 9 | #import "AppDelegate.h" 10 | #import "ViewController.h" 11 | @interface AppDelegate () 12 | 13 | @end 14 | 15 | @implementation AppDelegate 16 | 17 | 18 | - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { 19 | // Override point for customization after application launch. 20 | self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds]; 21 | ViewController *vc = [[ViewController alloc] init]; 22 | UINavigationController *nav = [[UINavigationController alloc] initWithRootViewController:vc]; 23 | self.window.rootViewController = nav; 24 | [self.window makeKeyAndVisible]; 25 | return YES; 26 | } 27 | 28 | 29 | - (void)applicationWillResignActive:(UIApplication *)application { 30 | // 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. 31 | // Use this method to pause ongoing tasks, disable timers, and invalidate graphics rendering callbacks. Games should use this method to pause the game. 32 | } 33 | 34 | 35 | - (void)applicationDidEnterBackground:(UIApplication *)application { 36 | // 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. 37 | // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. 38 | } 39 | 40 | 41 | - (void)applicationWillEnterForeground:(UIApplication *)application { 42 | // 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. 43 | } 44 | 45 | 46 | - (void)applicationDidBecomeActive:(UIApplication *)application { 47 | // 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. 48 | } 49 | 50 | 51 | - (void)applicationWillTerminate:(UIApplication *)application { 52 | // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. 53 | } 54 | 55 | 56 | @end 57 | -------------------------------------------------------------------------------- /QQImagesPicker/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "iphone", 5 | "size" : "20x20", 6 | "scale" : "2x" 7 | }, 8 | { 9 | "idiom" : "iphone", 10 | "size" : "20x20", 11 | "scale" : "3x" 12 | }, 13 | { 14 | "idiom" : "iphone", 15 | "size" : "29x29", 16 | "scale" : "2x" 17 | }, 18 | { 19 | "idiom" : "iphone", 20 | "size" : "29x29", 21 | "scale" : "3x" 22 | }, 23 | { 24 | "idiom" : "iphone", 25 | "size" : "40x40", 26 | "scale" : "2x" 27 | }, 28 | { 29 | "idiom" : "iphone", 30 | "size" : "40x40", 31 | "scale" : "3x" 32 | }, 33 | { 34 | "idiom" : "iphone", 35 | "size" : "60x60", 36 | "scale" : "2x" 37 | }, 38 | { 39 | "idiom" : "iphone", 40 | "size" : "60x60", 41 | "scale" : "3x" 42 | }, 43 | { 44 | "idiom" : "ipad", 45 | "size" : "20x20", 46 | "scale" : "1x" 47 | }, 48 | { 49 | "idiom" : "ipad", 50 | "size" : "20x20", 51 | "scale" : "2x" 52 | }, 53 | { 54 | "idiom" : "ipad", 55 | "size" : "29x29", 56 | "scale" : "1x" 57 | }, 58 | { 59 | "idiom" : "ipad", 60 | "size" : "29x29", 61 | "scale" : "2x" 62 | }, 63 | { 64 | "idiom" : "ipad", 65 | "size" : "40x40", 66 | "scale" : "1x" 67 | }, 68 | { 69 | "idiom" : "ipad", 70 | "size" : "40x40", 71 | "scale" : "2x" 72 | }, 73 | { 74 | "idiom" : "ipad", 75 | "size" : "76x76", 76 | "scale" : "1x" 77 | }, 78 | { 79 | "idiom" : "ipad", 80 | "size" : "76x76", 81 | "scale" : "2x" 82 | }, 83 | { 84 | "idiom" : "ipad", 85 | "size" : "83.5x83.5", 86 | "scale" : "2x" 87 | } 88 | ], 89 | "info" : { 90 | "version" : 1, 91 | "author" : "xcode" 92 | } 93 | } -------------------------------------------------------------------------------- /QQImagesPicker/Assets.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "version" : 1, 4 | "author" : "xcode" 5 | } 6 | } -------------------------------------------------------------------------------- /QQImagesPicker/Assets.xcassets/compose_photo_close.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "filename" : "compose_photo_close@2x.png", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /QQImagesPicker/Assets.xcassets/compose_photo_close.imageset/compose_photo_close@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jesusLove/QQImagePicker/fac7d819a4966a54f9000c6942fd6da04e94ec8e/QQImagesPicker/Assets.xcassets/compose_photo_close.imageset/compose_photo_close@2x.png -------------------------------------------------------------------------------- /QQImagesPicker/Assets.xcassets/compose_pic_add.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "filename" : "compose_pic_add@2x.png", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "filename" : "compose_pic_add@3x.png", 15 | "scale" : "3x" 16 | } 17 | ], 18 | "info" : { 19 | "version" : 1, 20 | "author" : "xcode" 21 | } 22 | } -------------------------------------------------------------------------------- /QQImagesPicker/Assets.xcassets/compose_pic_add.imageset/compose_pic_add@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jesusLove/QQImagePicker/fac7d819a4966a54f9000c6942fd6da04e94ec8e/QQImagesPicker/Assets.xcassets/compose_pic_add.imageset/compose_pic_add@2x.png -------------------------------------------------------------------------------- /QQImagesPicker/Assets.xcassets/compose_pic_add.imageset/compose_pic_add@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jesusLove/QQImagePicker/fac7d819a4966a54f9000c6942fd6da04e94ec8e/QQImagesPicker/Assets.xcassets/compose_pic_add.imageset/compose_pic_add@3x.png -------------------------------------------------------------------------------- /QQImagesPicker/Base.lproj/LaunchScreen.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /QQImagesPicker/Base.lproj/Main.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /QQImagesPicker/ImagePicker/Assets/ImagesPicker.xcassets/compose_close.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "scale" : "2x", 10 | "filename" : "close.png" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /QQImagesPicker/ImagePicker/Assets/ImagesPicker.xcassets/compose_close.imageset/close.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jesusLove/QQImagePicker/fac7d819a4966a54f9000c6942fd6da04e94ec8e/QQImagesPicker/ImagePicker/Assets/ImagesPicker.xcassets/compose_close.imageset/close.png -------------------------------------------------------------------------------- /QQImagesPicker/ImagePicker/Assets/ImagesPicker.xcassets/images/assets_placeholder_picture.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "scale" : "2x", 10 | "filename" : "assets_placeholder_picture@2x.png" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /QQImagesPicker/ImagePicker/Assets/ImagesPicker.xcassets/images/assets_placeholder_picture.imageset/assets_placeholder_picture@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jesusLove/QQImagePicker/fac7d819a4966a54f9000c6942fd6da04e94ec8e/QQImagesPicker/ImagePicker/Assets/ImagesPicker.xcassets/images/assets_placeholder_picture.imageset/assets_placeholder_picture@2x.png -------------------------------------------------------------------------------- /QQImagesPicker/ImagePicker/Assets/ImagesPicker.xcassets/images/camera_edit_cut_cancel.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "scale" : "2x", 10 | "filename" : "camera_edit_cut_cancel@2x.png" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /QQImagesPicker/ImagePicker/Assets/ImagesPicker.xcassets/images/camera_edit_cut_cancel.imageset/camera_edit_cut_cancel@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jesusLove/QQImagePicker/fac7d819a4966a54f9000c6942fd6da04e94ec8e/QQImagesPicker/ImagePicker/Assets/ImagesPicker.xcassets/images/camera_edit_cut_cancel.imageset/camera_edit_cut_cancel@2x.png -------------------------------------------------------------------------------- /QQImagesPicker/ImagePicker/Assets/ImagesPicker.xcassets/images/camera_edit_cut_cancel_highlighted.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "scale" : "2x", 10 | "filename" : "camera_edit_cut_cancel_highlighted@2x.png" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /QQImagesPicker/ImagePicker/Assets/ImagesPicker.xcassets/images/camera_edit_cut_cancel_highlighted.imageset/camera_edit_cut_cancel_highlighted@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jesusLove/QQImagePicker/fac7d819a4966a54f9000c6942fd6da04e94ec8e/QQImagesPicker/ImagePicker/Assets/ImagesPicker.xcassets/images/camera_edit_cut_cancel_highlighted.imageset/camera_edit_cut_cancel_highlighted@2x.png -------------------------------------------------------------------------------- /QQImagesPicker/ImagePicker/Assets/ImagesPicker.xcassets/images/compose_photo_original.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "scale" : "2x", 10 | "filename" : "compose_photo_original@2x.png" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x", 15 | "filename" : "compose_photo_original@3x.png" 16 | } 17 | ], 18 | "info" : { 19 | "version" : 1, 20 | "author" : "xcode" 21 | } 22 | } -------------------------------------------------------------------------------- /QQImagesPicker/ImagePicker/Assets/ImagesPicker.xcassets/images/compose_photo_original.imageset/compose_photo_original@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jesusLove/QQImagePicker/fac7d819a4966a54f9000c6942fd6da04e94ec8e/QQImagesPicker/ImagePicker/Assets/ImagesPicker.xcassets/images/compose_photo_original.imageset/compose_photo_original@2x.png -------------------------------------------------------------------------------- /QQImagesPicker/ImagePicker/Assets/ImagesPicker.xcassets/images/compose_photo_original.imageset/compose_photo_original@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jesusLove/QQImagePicker/fac7d819a4966a54f9000c6942fd6da04e94ec8e/QQImagesPicker/ImagePicker/Assets/ImagesPicker.xcassets/images/compose_photo_original.imageset/compose_photo_original@3x.png -------------------------------------------------------------------------------- /QQImagesPicker/ImagePicker/Assets/ImagesPicker.xcassets/images/compose_photo_original_highlighted.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "scale" : "2x", 10 | "filename" : "compose_photo_original_highlighted@2x.png" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x", 15 | "filename" : "compose_photo_original_highlighted@3x.png" 16 | } 17 | ], 18 | "info" : { 19 | "version" : 1, 20 | "author" : "xcode" 21 | } 22 | } -------------------------------------------------------------------------------- /QQImagesPicker/ImagePicker/Assets/ImagesPicker.xcassets/images/compose_photo_original_highlighted.imageset/compose_photo_original_highlighted@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jesusLove/QQImagePicker/fac7d819a4966a54f9000c6942fd6da04e94ec8e/QQImagesPicker/ImagePicker/Assets/ImagesPicker.xcassets/images/compose_photo_original_highlighted.imageset/compose_photo_original_highlighted@2x.png -------------------------------------------------------------------------------- /QQImagesPicker/ImagePicker/Assets/ImagesPicker.xcassets/images/compose_photo_original_highlighted.imageset/compose_photo_original_highlighted@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jesusLove/QQImagePicker/fac7d819a4966a54f9000c6942fd6da04e94ec8e/QQImagesPicker/ImagePicker/Assets/ImagesPicker.xcassets/images/compose_photo_original_highlighted.imageset/compose_photo_original_highlighted@3x.png -------------------------------------------------------------------------------- /QQImagesPicker/ImagePicker/Assets/ImagesPicker.xcassets/images/compose_photograph.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "scale" : "2x", 10 | "filename" : "compose_photograph@2x.png" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x", 15 | "filename" : "compose_photograph@3x.png" 16 | } 17 | ], 18 | "info" : { 19 | "version" : 1, 20 | "author" : "xcode" 21 | } 22 | } -------------------------------------------------------------------------------- /QQImagesPicker/ImagePicker/Assets/ImagesPicker.xcassets/images/compose_photograph.imageset/compose_photograph@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jesusLove/QQImagePicker/fac7d819a4966a54f9000c6942fd6da04e94ec8e/QQImagesPicker/ImagePicker/Assets/ImagesPicker.xcassets/images/compose_photograph.imageset/compose_photograph@2x.png -------------------------------------------------------------------------------- /QQImagesPicker/ImagePicker/Assets/ImagesPicker.xcassets/images/compose_photograph.imageset/compose_photograph@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jesusLove/QQImagePicker/fac7d819a4966a54f9000c6942fd6da04e94ec8e/QQImagesPicker/ImagePicker/Assets/ImagesPicker.xcassets/images/compose_photograph.imageset/compose_photograph@3x.png -------------------------------------------------------------------------------- /QQImagesPicker/ImagePicker/Assets/ImagesPicker.xcassets/images/compose_photograph_background.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "scale" : "2x", 10 | "filename" : "compose_photograph_background@2x.png" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /QQImagesPicker/ImagePicker/Assets/ImagesPicker.xcassets/images/compose_photograph_background.imageset/compose_photograph_background@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jesusLove/QQImagePicker/fac7d819a4966a54f9000c6942fd6da04e94ec8e/QQImagesPicker/ImagePicker/Assets/ImagesPicker.xcassets/images/compose_photograph_background.imageset/compose_photograph_background@2x.png -------------------------------------------------------------------------------- /QQImagesPicker/ImagePicker/Assets/ImagesPicker.xcassets/images/compose_photograph_highlighted.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "scale" : "2x", 10 | "filename" : "compose_photograph_highlighted@2x.png" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x", 15 | "filename" : "compose_photograph_highlighted@3x.png" 16 | } 17 | ], 18 | "info" : { 19 | "version" : 1, 20 | "author" : "xcode" 21 | } 22 | } -------------------------------------------------------------------------------- /QQImagesPicker/ImagePicker/Assets/ImagesPicker.xcassets/images/compose_photograph_highlighted.imageset/compose_photograph_highlighted@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jesusLove/QQImagePicker/fac7d819a4966a54f9000c6942fd6da04e94ec8e/QQImagesPicker/ImagePicker/Assets/ImagesPicker.xcassets/images/compose_photograph_highlighted.imageset/compose_photograph_highlighted@2x.png -------------------------------------------------------------------------------- /QQImagesPicker/ImagePicker/Assets/ImagesPicker.xcassets/images/compose_photograph_highlighted.imageset/compose_photograph_highlighted@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jesusLove/QQImagePicker/fac7d819a4966a54f9000c6942fd6da04e94ec8e/QQImagesPicker/ImagePicker/Assets/ImagesPicker.xcassets/images/compose_photograph_highlighted.imageset/compose_photograph_highlighted@3x.png -------------------------------------------------------------------------------- /QQImagesPicker/ImagePicker/Assets/ImagesPicker.xcassets/images/navigationbar_arrow_down.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "scale" : "2x", 10 | "filename" : "navigationbar_arrow_down@2x.png" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /QQImagesPicker/ImagePicker/Assets/ImagesPicker.xcassets/images/navigationbar_arrow_down.imageset/navigationbar_arrow_down@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jesusLove/QQImagePicker/fac7d819a4966a54f9000c6942fd6da04e94ec8e/QQImagesPicker/ImagePicker/Assets/ImagesPicker.xcassets/images/navigationbar_arrow_down.imageset/navigationbar_arrow_down@2x.png -------------------------------------------------------------------------------- /QQImagesPicker/ImagePicker/Assets/ImagesPicker.xcassets/images/navigationbar_arrow_up.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "scale" : "2x", 10 | "filename" : "navigationbar_arrow_up@2x.png" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /QQImagesPicker/ImagePicker/Assets/ImagesPicker.xcassets/images/navigationbar_arrow_up.imageset/navigationbar_arrow_up@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jesusLove/QQImagePicker/fac7d819a4966a54f9000c6942fd6da04e94ec8e/QQImagesPicker/ImagePicker/Assets/ImagesPicker.xcassets/images/navigationbar_arrow_up.imageset/navigationbar_arrow_up@2x.png -------------------------------------------------------------------------------- /QQImagesPicker/ImagePicker/Assets/ImagesPicker.xcassets/images/navigationbar_title_highlighted.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "scale" : "2x", 10 | "filename" : "navigationbar_title_highlighted@2x.png" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /QQImagesPicker/ImagePicker/Assets/ImagesPicker.xcassets/images/navigationbar_title_highlighted.imageset/navigationbar_title_highlighted@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jesusLove/QQImagePicker/fac7d819a4966a54f9000c6942fd6da04e94ec8e/QQImagesPicker/ImagePicker/Assets/ImagesPicker.xcassets/images/navigationbar_title_highlighted.imageset/navigationbar_title_highlighted@2x.png -------------------------------------------------------------------------------- /QQImagesPicker/ImagePicker/Assets/ImagesPicker.xcassets/images/photo_check_default.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "scale" : "2x", 10 | "filename" : "photo_check_default@2x.png" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x", 15 | "filename" : "photo_check_default@3x.png" 16 | } 17 | ], 18 | "info" : { 19 | "version" : 1, 20 | "author" : "xcode" 21 | } 22 | } -------------------------------------------------------------------------------- /QQImagesPicker/ImagePicker/Assets/ImagesPicker.xcassets/images/photo_check_default.imageset/photo_check_default@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jesusLove/QQImagePicker/fac7d819a4966a54f9000c6942fd6da04e94ec8e/QQImagesPicker/ImagePicker/Assets/ImagesPicker.xcassets/images/photo_check_default.imageset/photo_check_default@2x.png -------------------------------------------------------------------------------- /QQImagesPicker/ImagePicker/Assets/ImagesPicker.xcassets/images/photo_check_default.imageset/photo_check_default@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jesusLove/QQImagePicker/fac7d819a4966a54f9000c6942fd6da04e94ec8e/QQImagesPicker/ImagePicker/Assets/ImagesPicker.xcassets/images/photo_check_default.imageset/photo_check_default@3x.png -------------------------------------------------------------------------------- /QQImagesPicker/ImagePicker/Assets/ImagesPicker.xcassets/images/photo_check_selected.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "scale" : "2x", 10 | "filename" : "photo_check_selected@2x.png" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x", 15 | "filename" : "photo_check_selected@3x.png" 16 | } 17 | ], 18 | "info" : { 19 | "version" : 1, 20 | "author" : "xcode" 21 | } 22 | } -------------------------------------------------------------------------------- /QQImagesPicker/ImagePicker/Assets/ImagesPicker.xcassets/images/photo_check_selected.imageset/photo_check_selected@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jesusLove/QQImagePicker/fac7d819a4966a54f9000c6942fd6da04e94ec8e/QQImagesPicker/ImagePicker/Assets/ImagesPicker.xcassets/images/photo_check_selected.imageset/photo_check_selected@2x.png -------------------------------------------------------------------------------- /QQImagesPicker/ImagePicker/Assets/ImagesPicker.xcassets/images/photo_check_selected.imageset/photo_check_selected@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jesusLove/QQImagePicker/fac7d819a4966a54f9000c6942fd6da04e94ec8e/QQImagesPicker/ImagePicker/Assets/ImagesPicker.xcassets/images/photo_check_selected.imageset/photo_check_selected@3x.png -------------------------------------------------------------------------------- /QQImagesPicker/ImagePicker/Assets/ImagesPicker.xcassets/images/picker_alert_sigh.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "scale" : "2x", 10 | "filename" : "picker_alert_sigh@2x.png" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /QQImagesPicker/ImagePicker/Assets/ImagesPicker.xcassets/images/picker_alert_sigh.imageset/picker_alert_sigh@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jesusLove/QQImagePicker/fac7d819a4966a54f9000c6942fd6da04e94ec8e/QQImagesPicker/ImagePicker/Assets/ImagesPicker.xcassets/images/picker_alert_sigh.imageset/picker_alert_sigh@2x.png -------------------------------------------------------------------------------- /QQImagesPicker/ImagePicker/Assets/ImagesPicker.xcassets/images/picker_button_orange.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "scale" : "2x", 10 | "filename" : "picker_button_orange@2x.png" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /QQImagesPicker/ImagePicker/Assets/ImagesPicker.xcassets/images/picker_button_orange.imageset/picker_button_orange@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jesusLove/QQImagePicker/fac7d819a4966a54f9000c6942fd6da04e94ec8e/QQImagesPicker/ImagePicker/Assets/ImagesPicker.xcassets/images/picker_button_orange.imageset/picker_button_orange@2x.png -------------------------------------------------------------------------------- /QQImagesPicker/ImagePicker/Assets/ImagesPicker.xcassets/images/picker_button_orange_highlighted.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "scale" : "2x", 10 | "filename" : "picker_button_orange_highlighted@2x.png" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /QQImagesPicker/ImagePicker/Assets/ImagesPicker.xcassets/images/picker_button_orange_highlighted.imageset/picker_button_orange_highlighted@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jesusLove/QQImagePicker/fac7d819a4966a54f9000c6942fd6da04e94ec8e/QQImagesPicker/ImagePicker/Assets/ImagesPicker.xcassets/images/picker_button_orange_highlighted.imageset/picker_button_orange_highlighted@2x.png -------------------------------------------------------------------------------- /QQImagesPicker/ImagePicker/Assets/ImagesPicker.xcassets/images/picker_image_placeholder.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "scale" : "2x", 10 | "filename" : "picker_image_placeholder@2x.png" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /QQImagesPicker/ImagePicker/Assets/ImagesPicker.xcassets/images/picker_image_placeholder.imageset/picker_image_placeholder@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jesusLove/QQImagePicker/fac7d819a4966a54f9000c6942fd6da04e94ec8e/QQImagesPicker/ImagePicker/Assets/ImagesPicker.xcassets/images/picker_image_placeholder.imageset/picker_image_placeholder@2x.png -------------------------------------------------------------------------------- /QQImagesPicker/ImagePicker/Assets/ImagesPicker.xcassets/images/picker_photo_filter_checked.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "scale" : "2x", 10 | "filename" : "picker_photo_filter_checked@2x.png" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /QQImagesPicker/ImagePicker/Assets/ImagesPicker.xcassets/images/picker_photo_filter_checked.imageset/picker_photo_filter_checked@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jesusLove/QQImagePicker/fac7d819a4966a54f9000c6942fd6da04e94ec8e/QQImagesPicker/ImagePicker/Assets/ImagesPicker.xcassets/images/picker_photo_filter_checked.imageset/picker_photo_filter_checked@2x.png -------------------------------------------------------------------------------- /QQImagesPicker/ImagePicker/Assets/en.lproj/JKImagePickerController.strings: -------------------------------------------------------------------------------- 1 | /* 2 | JKImagePickerController.strings 3 | JKImagePicker 4 | 5 | Created by Jecky on 15/1/9. 6 | Copyright (c) 2015年 Jecky. All rights reserved. 7 | */ 8 | 9 | "title" = "Select Album"; 10 | 11 | "format_photo" = "%ld Photo"; 12 | "format_photos" = "%ld Photos"; 13 | "format_video" = "%ld Video"; 14 | "format_videos" = "%ld Videos"; 15 | "format_photo_and_video" = "%ld Photo, %ld Video"; 16 | "format_photos_and_video" = "%ld Photos, %ld Video"; 17 | "format_photo_and_videos" = "%ld Photo, %ld Videos"; 18 | "format_photos_and_videos" = "%ld Photos, %ld Videos"; -------------------------------------------------------------------------------- /QQImagesPicker/ImagePicker/Assets/zh-Hans.lproj/JKImagePickerController.strings: -------------------------------------------------------------------------------- 1 | /* 2 | JKImagePickerController.strings 3 | JKImagePicker 4 | 5 | Created by Jecky on 15/1/9. 6 | Copyright (c) 2015年 Jecky. All rights reserved. 7 | */ 8 | 9 | "title" = "选择相册"; 10 | 11 | "format_photo" = "%ld 张照片"; 12 | "format_photos" = "%ld 张照片"; 13 | "format_video" = "%ld 个视频"; 14 | "format_videos" = "%ld 个视频"; 15 | "format_photo_and_video" = "%ld 张照片、%ld 个视频"; 16 | "format_photos_and_video" = "%ld 张照片、%ld 个视频"; 17 | "format_photo_and_videos" = "%ld 张照片、%ld 个视频"; 18 | "format_photos_and_videos" = "%ld 张照片、%ld 个视频"; -------------------------------------------------------------------------------- /QQImagesPicker/ImagePicker/Classes/JKAssets.h: -------------------------------------------------------------------------------- 1 | // 2 | // JKAssets.h 3 | // JKImagePicker 4 | // 5 | // Created by Jecky on 15/1/13. 6 | // Copyright (c) 2015年 Jecky. All rights reserved. 7 | // 8 | 9 | #import 10 | #import 11 | #import 12 | 13 | @interface JKAssets : NSObject 14 | 15 | @property (nonatomic, strong) NSString *groupPropertyID; 16 | @property (nonatomic, strong) NSURL *groupPropertyURL; 17 | @property (nonatomic, strong) NSURL *assetPropertyURL; 18 | @property (nonatomic, strong) UIImage *photo; 19 | 20 | @end 21 | -------------------------------------------------------------------------------- /QQImagesPicker/ImagePicker/Classes/JKAssets.m: -------------------------------------------------------------------------------- 1 | // 2 | // JKAssets.m 3 | // JKImagePicker 4 | // 5 | // Created by Jecky on 15/1/13. 6 | // Copyright (c) 2015年 Jecky. All rights reserved. 7 | // 8 | 9 | #import "JKAssets.h" 10 | 11 | NSString *const kJKPickerGroupPropertyID = @"kJKPickerGroupPropertyID"; 12 | NSString *const kJKPickerGroupPropertyURL = @"kJKPickerGroupPropertyURL"; 13 | NSString *const kJKPickerAssetPropertyURL = @"kJKPickerAssetPropertyURL"; 14 | 15 | @implementation JKAssets 16 | 17 | #pragma mark - NSCoding 18 | -(id)initWithCoder:(NSCoder *)aDecoder 19 | { 20 | if(self = [super init]) 21 | { 22 | self.groupPropertyID = [aDecoder decodeObjectForKey:kJKPickerGroupPropertyID]; 23 | self.groupPropertyURL = [aDecoder decodeObjectForKey:kJKPickerGroupPropertyURL]; 24 | self.assetPropertyURL = [aDecoder decodeObjectForKey:kJKPickerAssetPropertyURL]; 25 | } 26 | return self; 27 | } 28 | 29 | -(void)encodeWithCoder:(NSCoder *)aCoder 30 | { 31 | [aCoder encodeObject:_groupPropertyID forKey:kJKPickerGroupPropertyID]; 32 | [aCoder encodeObject:_groupPropertyURL forKey:kJKPickerGroupPropertyURL]; 33 | [aCoder encodeObject:_assetPropertyURL forKey:kJKPickerAssetPropertyURL]; 34 | } 35 | 36 | 37 | @end 38 | -------------------------------------------------------------------------------- /QQImagesPicker/ImagePicker/Classes/JKAssetsCollectionFooterView.h: -------------------------------------------------------------------------------- 1 | // 2 | // JKAssetsCollectionFooterView.h 3 | // JKImagePicker 4 | // 5 | // Created by Jecky on 15/1/12. 6 | // Copyright (c) 2015年 Jecky. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface JKAssetsCollectionFooterView : UICollectionReusableView 12 | 13 | @property (nonatomic, strong) UILabel *textLabel; 14 | 15 | @end 16 | -------------------------------------------------------------------------------- /QQImagesPicker/ImagePicker/Classes/JKAssetsCollectionFooterView.m: -------------------------------------------------------------------------------- 1 | // 2 | // JKAssetsCollectionFooterView.m 3 | // JKImagePicker 4 | // 5 | // Created by Jecky on 15/1/12. 6 | // Copyright (c) 2015年 Jecky. All rights reserved. 7 | // 8 | 9 | #import "JKAssetsCollectionFooterView.h" 10 | 11 | @implementation JKAssetsCollectionFooterView 12 | 13 | - (instancetype)initWithFrame:(CGRect)frame 14 | { 15 | self = [super initWithFrame:frame]; 16 | 17 | if (self) { 18 | // Create a label 19 | [self textLabel]; 20 | } 21 | 22 | return self; 23 | } 24 | 25 | - (void)layoutSubviews 26 | { 27 | [super layoutSubviews]; 28 | // Layout text label 29 | } 30 | 31 | - (UILabel *)textLabel{ 32 | if (!_textLabel) { 33 | _textLabel = [[UILabel alloc] initWithFrame:CGRectMake(0,(self.bounds.size.height - 21.0) / 2.0,self.bounds.size.width,21.0)]; 34 | _textLabel.backgroundColor = [UIColor clearColor]; 35 | _textLabel.font = [UIFont systemFontOfSize:17]; 36 | _textLabel.textColor = [UIColor blackColor]; 37 | _textLabel.textAlignment = NSTextAlignmentCenter; 38 | [self addSubview:_textLabel]; 39 | } 40 | return _textLabel; 41 | } 42 | 43 | 44 | @end 45 | -------------------------------------------------------------------------------- /QQImagesPicker/ImagePicker/Classes/JKAssetsGroupCell.h: -------------------------------------------------------------------------------- 1 | // 2 | // JKAssetsGroupCell.h 3 | // JKImagePicker 4 | // 5 | // Created by Jecky on 15/1/11. 6 | // Copyright (c) 2015年 Jecky. All rights reserved. 7 | // 8 | 9 | #import 10 | #import 11 | 12 | @interface JKAssetsGroupCell : UITableViewCell 13 | 14 | @property (nonatomic, strong) ALAssetsGroup *assetsGroup; 15 | @property (nonatomic, assign) BOOL isSelected; 16 | 17 | @end 18 | -------------------------------------------------------------------------------- /QQImagesPicker/ImagePicker/Classes/JKAssetsGroupCell.m: -------------------------------------------------------------------------------- 1 | // 2 | // JKAssetsGroupCell.m 3 | // JKImagePicker 4 | // 5 | // Created by Jecky on 15/1/11. 6 | // Copyright (c) 2015年 Jecky. All rights reserved. 7 | // 8 | 9 | #import "JKAssetsGroupCell.h" 10 | #import "JKUtil.h" 11 | #import "UIView+JKPicker.h" 12 | #import "JKAssetsThumbnailView.h" 13 | 14 | @interface JKAssetsGroupCell() 15 | 16 | @property (nonatomic, strong) JKAssetsThumbnailView *thumbnailView; 17 | @property (nonatomic, strong) UILabel *assetsNameLabel; 18 | @property (nonatomic, strong) UILabel *assetsCountLabel; 19 | @property (nonatomic, strong) UIImageView *checkImageView; 20 | 21 | @end 22 | 23 | @implementation JKAssetsGroupCell 24 | 25 | - (instancetype)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier 26 | { 27 | self = [super initWithStyle:style reuseIdentifier:reuseIdentifier]; 28 | 29 | if (self) { 30 | // Cell settings 31 | self.accessoryType = UITableViewCellAccessoryNone; 32 | [self thumbnailView]; 33 | } 34 | 35 | return self; 36 | } 37 | 38 | 39 | - (void)setSelected:(BOOL)selected animated:(BOOL)animated { 40 | [super setSelected:selected animated:animated]; 41 | 42 | // Configure the view for the selected state 43 | } 44 | 45 | //common_image_loading 46 | #pragma makr - setter 47 | - (void)setAssetsGroup:(ALAssetsGroup *)assetsGroup{ 48 | if (_assetsGroup != assetsGroup) { 49 | _assetsGroup = assetsGroup; 50 | 51 | // Update thumbnail view 52 | self.thumbnailView.assetsGroup = _assetsGroup; 53 | 54 | // Update label 55 | self.assetsNameLabel.text = [_assetsGroup valueForProperty:ALAssetsGroupPropertyName]; 56 | [self.assetsNameLabel sizeToFit]; 57 | self.assetsNameLabel.left = self.thumbnailView.right + 18; 58 | self.assetsNameLabel.bottom = self.thumbnailView.centerY-2; 59 | 60 | self.assetsCountLabel.text = [NSString stringWithFormat:@"%ld", (long)[_assetsGroup numberOfAssets]]; 61 | [self.assetsCountLabel sizeToFit]; 62 | self.assetsCountLabel.left = self.assetsNameLabel.left; 63 | self.assetsCountLabel.top = self.assetsNameLabel.bottom+4; 64 | 65 | } 66 | } 67 | 68 | - (void)setIsSelected:(BOOL)isSelected{ 69 | _isSelected = isSelected; 70 | 71 | self.checkImageView.hidden = !isSelected; 72 | } 73 | 74 | #pragma makr - getter 75 | - (JKAssetsThumbnailView *)thumbnailView{ 76 | if (!_thumbnailView) { 77 | _thumbnailView = [[JKAssetsThumbnailView alloc] initWithFrame:CGRectMake(8, 4, 70, 74)]; 78 | _thumbnailView.backgroundColor = [UIColor clearColor]; 79 | _thumbnailView.autoresizingMask = UIViewAutoresizingFlexibleRightMargin | UIViewAutoresizingFlexibleBottomMargin; 80 | [self.contentView addSubview:_thumbnailView]; 81 | } 82 | return _thumbnailView; 83 | } 84 | 85 | - (UIImageView *)checkImageView{ 86 | if (!_checkImageView) { 87 | _checkImageView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"picker_photo_filter_checked"]]; 88 | _checkImageView.backgroundColor = [UIColor clearColor]; 89 | _checkImageView.right = self.thumbnailView.width-3; 90 | _checkImageView.bottom = self.thumbnailView.height-3; 91 | [self.thumbnailView addSubview:_checkImageView]; 92 | } 93 | return _checkImageView; 94 | } 95 | 96 | - (UILabel *)assetsNameLabel{ 97 | if (!_assetsNameLabel) { 98 | _assetsNameLabel = [[UILabel alloc] init]; 99 | _assetsNameLabel.backgroundColor = [UIColor clearColor]; 100 | _assetsNameLabel.textColor = [UIColor blackColor]; 101 | _assetsNameLabel.font = [UIFont systemFontOfSize:17.0f]; 102 | [self.contentView addSubview:_assetsNameLabel]; 103 | } 104 | return _assetsNameLabel; 105 | } 106 | 107 | - (UILabel *)assetsCountLabel{ 108 | if (!_assetsCountLabel) { 109 | _assetsCountLabel = [[UILabel alloc] init]; 110 | _assetsCountLabel.backgroundColor = [UIColor clearColor]; 111 | _assetsCountLabel.textColor = [UIColor blackColor]; 112 | _assetsCountLabel.font = [UIFont systemFontOfSize:12.0f]; 113 | [self.contentView addSubview:_assetsCountLabel]; 114 | } 115 | return _assetsCountLabel; 116 | } 117 | @end 118 | -------------------------------------------------------------------------------- /QQImagesPicker/ImagePicker/Classes/JKAssetsGroupsView.h: -------------------------------------------------------------------------------- 1 | // 2 | // JKAssetsGroupsView.h 3 | // JKImagePicker 4 | // 5 | // Created by Jecky on 15/1/11. 6 | // Copyright (c) 2015年 Jecky. All rights reserved. 7 | // 8 | 9 | #import 10 | #import 11 | #import "JKAssets.h" 12 | 13 | @class JKAssetsGroupsView; 14 | 15 | @protocol JKAssetsGroupsViewDelegate 16 | @optional 17 | - (void)assetsGroupsViewDidCancel:(JKAssetsGroupsView *)groupsView; 18 | - (void)assetsGroupsView:(JKAssetsGroupsView *)groupsView didSelectAssetsGroup:(ALAssetsGroup *)assGroup; 19 | 20 | @end 21 | 22 | @interface JKAssetsGroupsView : UIView 23 | 24 | @property (nonatomic, weak) id delegate; 25 | @property (nonatomic, assign) NSInteger indexAssetsGroup; 26 | @property (nonatomic, strong) NSArray *assetsGroups; 27 | 28 | @property (nonatomic, strong) NSMutableDictionary *selectedAssetCount; 29 | 30 | - (void)removeAssetSelected:(JKAssets *)asset; 31 | - (void)addAssetSelected:(JKAssets *)asset; 32 | 33 | @end 34 | -------------------------------------------------------------------------------- /QQImagesPicker/ImagePicker/Classes/JKAssetsGroupsView.m: -------------------------------------------------------------------------------- 1 | // 2 | // JKAssetsGroupsView.m 3 | // JKImagePicker 4 | // 5 | // Created by Jecky on 15/1/11. 6 | // Copyright (c) 2015年 Jecky. All rights reserved. 7 | // 8 | 9 | #import "JKAssetsGroupsView.h" 10 | #import "JKAssetsGroupCell.h" 11 | #import "UIView+JKPicker.h" 12 | 13 | @interface JKAssetsGroupsView() 14 | 15 | @property (nonatomic, strong) UITableView *tableView; 16 | @property (nonatomic, strong) NSIndexPath *selectedIndexPath; 17 | @property (nonatomic, strong) UIButton *touchButton; 18 | 19 | @end 20 | 21 | static CGFloat kHeightAssetsGroupCell = 86.0; 22 | 23 | @implementation JKAssetsGroupsView 24 | 25 | - (id)initWithFrame:(CGRect)frame 26 | { 27 | self = [super initWithFrame:frame]; 28 | if (self) { 29 | self.backgroundColor = [UIColor clearColor]; 30 | 31 | [self tableView]; 32 | 33 | } 34 | return self; 35 | } 36 | 37 | - (void)cancelAssetsGroupSelect 38 | { 39 | if ([_delegate respondsToSelector:@selector(assetsGroupsViewDidCancel:)]) { 40 | [_delegate assetsGroupsViewDidCancel:self]; 41 | } 42 | } 43 | 44 | 45 | #pragma mark - UITableViewDataSource 46 | - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section 47 | { 48 | return self.assetsGroups.count; 49 | } 50 | 51 | - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath 52 | { 53 | static NSString *AssetsGroupCell = @"AssetsGroupCell"; 54 | JKAssetsGroupCell *cell = (JKAssetsGroupCell *)[tableView dequeueReusableCellWithIdentifier:AssetsGroupCell]; 55 | if (cell == nil) { 56 | cell = [[JKAssetsGroupCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:AssetsGroupCell]; 57 | } 58 | 59 | ALAssetsGroup *assetsGroup = self.assetsGroups[indexPath.row]; 60 | cell.assetsGroup = assetsGroup; 61 | cell.isSelected = [self selectAssetsGroup:assetsGroup]; 62 | if (_selectedIndexPath.row == indexPath.row) { 63 | cell.selectionStyle = UITableViewCellSelectionStyleBlue; 64 | } else { 65 | cell.selectionStyle = UITableViewCellSelectionStyleNone; 66 | } 67 | return cell; 68 | } 69 | 70 | 71 | #pragma mark - UITableViewDelegate 72 | - (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath 73 | { 74 | return kHeightAssetsGroupCell; 75 | } 76 | 77 | - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath 78 | { 79 | [tableView deselectRowAtIndexPath:indexPath animated:YES]; 80 | 81 | _selectedIndexPath = indexPath; 82 | 83 | [self.tableView reloadData]; 84 | 85 | ALAssetsGroup *assetsGroup = self.assetsGroups[indexPath.row]; 86 | if ([_delegate respondsToSelector:@selector(assetsGroupsView:didSelectAssetsGroup:)]) { 87 | [_delegate assetsGroupsView:self didSelectAssetsGroup:assetsGroup]; 88 | } 89 | 90 | } 91 | 92 | - (BOOL)selectAssetsGroup:(ALAssetsGroup *)assetsGroup 93 | { 94 | NSString *groupID = [assetsGroup valueForProperty:ALAssetsGroupPropertyPersistentID]; 95 | NSInteger count = [[self.selectedAssetCount objectForKey:groupID] integerValue]; 96 | return count>0; 97 | } 98 | 99 | - (void)removeAssetSelected:(JKAssets *)asset 100 | { 101 | NSInteger count = [[self.selectedAssetCount objectForKey:asset.groupPropertyID] integerValue]; 102 | if (count<=1) { 103 | [self.selectedAssetCount removeObjectForKey:asset.groupPropertyID]; 104 | }else{ 105 | [self.selectedAssetCount setObject:[NSNumber numberWithInteger:count-1] 106 | forKey:asset.groupPropertyID]; 107 | } 108 | 109 | [self.tableView reloadData]; 110 | } 111 | 112 | - (void)addAssetSelected:(JKAssets *)asset 113 | { 114 | NSInteger count = [[self.selectedAssetCount objectForKey:asset.groupPropertyID] integerValue]; 115 | [self.selectedAssetCount setObject:[NSNumber numberWithInteger:count+1] 116 | forKey:asset.groupPropertyID]; 117 | 118 | [self.tableView reloadData]; 119 | 120 | } 121 | 122 | #pragma mark - setter 123 | - (void)setSelectedAssetCount:(NSMutableDictionary *)selectedAssetCount{ 124 | if (_selectedAssetCount != selectedAssetCount) { 125 | _selectedAssetCount = selectedAssetCount; 126 | 127 | [self.tableView reloadData]; 128 | } 129 | } 130 | 131 | - (void)setAssetsGroups:(NSArray *)assetsGroups{ 132 | if (_assetsGroups != assetsGroups) { 133 | _assetsGroups = assetsGroups; 134 | 135 | NSInteger rowCount = 0; 136 | if ([_assetsGroups count]>4) { 137 | rowCount = 4; 138 | }else{ 139 | rowCount = [_assetsGroups count]; 140 | } 141 | 142 | _selectedIndexPath = [NSIndexPath indexPathForRow:0 inSection:0]; 143 | self.tableView.height = rowCount*kHeightAssetsGroupCell; 144 | self.touchButton.top = self.tableView.bottom; 145 | self.touchButton.height = self.height - self.tableView.bottom; 146 | [self.tableView reloadData]; 147 | } 148 | } 149 | 150 | #pragma mark - getter 151 | - (UITableView *)tableView{ 152 | if (!_tableView) { 153 | _tableView = [[UITableView alloc] initWithFrame:CGRectMake(0, 0, self.width, 4*kHeightAssetsGroupCell) style:UITableViewStylePlain]; 154 | _tableView.delegate = self; 155 | _tableView.dataSource = self; 156 | _tableView.showsHorizontalScrollIndicator = NO; 157 | _tableView.showsVerticalScrollIndicator = NO; 158 | [self addSubview:_tableView]; 159 | } 160 | return _tableView; 161 | } 162 | 163 | - (UIButton *)touchButton{ 164 | if (!_touchButton) { 165 | _touchButton = [UIButton buttonWithType:UIButtonTypeCustom]; 166 | _touchButton.frame = CGRectMake(0, self.tableView.bottom, self.width, self.height-self.tableView.bottom); 167 | [_touchButton addTarget:self action:@selector(cancelAssetsGroupSelect) forControlEvents:UIControlEventTouchUpInside]; 168 | [self addSubview:_touchButton]; 169 | } 170 | return _touchButton; 171 | } 172 | 173 | @end 174 | -------------------------------------------------------------------------------- /QQImagesPicker/ImagePicker/Classes/JKAssetsThumbnailView.h: -------------------------------------------------------------------------------- 1 | // 2 | // JKAssetsThumbnailView.h 3 | // JKImagePicker 4 | // 5 | // Created by Jecky on 15/1/11. 6 | // Copyright (c) 2015年 Jecky. All rights reserved. 7 | // 8 | 9 | #import 10 | #import 11 | 12 | @interface JKAssetsThumbnailView : UIView 13 | 14 | @property (nonatomic, strong) ALAssetsGroup *assetsGroup; 15 | 16 | @end 17 | -------------------------------------------------------------------------------- /QQImagesPicker/ImagePicker/Classes/JKAssetsThumbnailView.m: -------------------------------------------------------------------------------- 1 | // 2 | // JKAssetsThumbnailView.m 3 | // JKImagePicker 4 | // 5 | // Created by Jecky on 15/1/11. 6 | // Copyright (c) 2015年 Jecky. All rights reserved. 7 | // 8 | 9 | #import "JKAssetsThumbnailView.h" 10 | #import "JKUtil.h" 11 | 12 | @interface JKAssetsThumbnailView () 13 | 14 | @property (nonatomic, strong) NSArray *thumbnailImages; 15 | @property (nonatomic, strong) UIImage *blankImage; 16 | 17 | @end 18 | 19 | @implementation JKAssetsThumbnailView 20 | 21 | - (instancetype)initWithFrame:(CGRect)frame 22 | { 23 | self = [super initWithFrame:frame]; 24 | 25 | if (self) { 26 | self.backgroundColor = [UIColor clearColor]; 27 | } 28 | 29 | return self; 30 | } 31 | 32 | - (CGSize)sizeThatFits:(CGSize)size 33 | { 34 | return CGSizeMake(70.0, 74.0); 35 | } 36 | 37 | - (void)drawRect:(CGRect)rect 38 | { 39 | [super drawRect:rect]; 40 | 41 | CGContextRef context = UIGraphicsGetCurrentContext(); 42 | CGContextSetRGBFillColor(context, 1.0, 1.0, 1.0, 1.0); 43 | 44 | 45 | if (self.thumbnailImages.count == 3) { 46 | UIImage *thumbnailImage = self.thumbnailImages[2]; 47 | 48 | CGRect thumbnailImageRect = CGRectMake(4.0, 0, 62.0, 62.0); 49 | CGContextFillRect(context, thumbnailImageRect); 50 | [thumbnailImage drawInRect:CGRectInset(thumbnailImageRect, 0.5, 0.5)]; 51 | } 52 | if (self.thumbnailImages.count >= 2) { 53 | UIImage *thumbnailImage = self.thumbnailImages[1]; 54 | 55 | CGRect thumbnailImageRect = CGRectMake(2.0, 2.0, 66.0, 66.0); 56 | CGContextFillRect(context, thumbnailImageRect); 57 | [thumbnailImage drawInRect:CGRectInset(thumbnailImageRect, 0.5, 0.5)]; 58 | } 59 | if (self.thumbnailImages.count >= 1) { 60 | UIImage *thumbnailImage = self.thumbnailImages[0]; 61 | 62 | CGRect thumbnailImageRect = CGRectMake(0, 4.0, 70.0, 70.0); 63 | CGContextFillRect(context, thumbnailImageRect); 64 | [thumbnailImage drawInRect:CGRectInset(thumbnailImageRect, 0.5, 0.5)]; 65 | } 66 | } 67 | 68 | 69 | #pragma mark - setter/getter 70 | - (void)setAssetsGroup:(ALAssetsGroup *)assetsGroup 71 | { 72 | if (_assetsGroup != assetsGroup) { 73 | _assetsGroup = assetsGroup; 74 | 75 | // Extract three thumbnail images 76 | NSIndexSet *indexes = [NSIndexSet indexSetWithIndexesInRange:NSMakeRange(0, MIN(3, assetsGroup.numberOfAssets))]; 77 | NSMutableArray *thumbnailImages = [NSMutableArray array]; 78 | [assetsGroup enumerateAssetsAtIndexes:indexes 79 | options:0 80 | usingBlock:^(ALAsset *result, NSUInteger index, BOOL *stop) { 81 | if (result) { 82 | CGImageRef thumbnailImageRef = [result thumbnail]; 83 | if (thumbnailImageRef) { 84 | [thumbnailImages addObject:[UIImage imageWithCGImage:thumbnailImageRef]]; 85 | } else { 86 | [thumbnailImages addObject:[self blankImage]]; 87 | } 88 | } 89 | }]; 90 | 91 | if ([thumbnailImages count]>0) { 92 | self.thumbnailImages = thumbnailImages; 93 | }else{ 94 | [thumbnailImages addObject:self.blankImage]; 95 | [thumbnailImages addObject:self.blankImage]; 96 | [thumbnailImages addObject:self.blankImage]; 97 | self.thumbnailImages = thumbnailImages; 98 | } 99 | [self setNeedsDisplay]; 100 | } 101 | } 102 | 103 | - (UIImage *)blankImage 104 | { 105 | if (_blankImage == nil) { 106 | _blankImage = [UIImage imageNamed:@"assets_placeholder_picture"]; 107 | } 108 | return _blankImage; 109 | } 110 | 111 | 112 | @end 113 | -------------------------------------------------------------------------------- /QQImagesPicker/ImagePicker/Classes/JKAssetsViewCell.h: -------------------------------------------------------------------------------- 1 | // 2 | // JKAssetsViewCell.h 3 | // JKImagePicker 4 | // 5 | // Created by Jecky on 15/1/12. 6 | // Copyright (c) 2015年 Jecky. All rights reserved. 7 | // 8 | 9 | #import 10 | #import 11 | 12 | @class JKAssetsViewCell; 13 | 14 | @protocol JKAssetsViewCellDelegate 15 | @optional 16 | - (void)startPhotoAssetsViewCell:(JKAssetsViewCell *)assetsCell; 17 | - (void)didSelectItemAssetsViewCell:(JKAssetsViewCell *)assetsCell; 18 | - (void)didDeselectItemAssetsViewCell:(JKAssetsViewCell *)assetsCell; 19 | 20 | @end 21 | 22 | @interface JKAssetsViewCell : UICollectionViewCell 23 | 24 | @property (nonatomic, weak) id delegate; 25 | @property (nonatomic, strong) ALAsset *asset; 26 | @property (nonatomic, assign) BOOL isSelected; 27 | @property (nonatomic, strong) UIImage *img; 28 | 29 | 30 | @end 31 | -------------------------------------------------------------------------------- /QQImagesPicker/ImagePicker/Classes/JKAssetsViewCell.m: -------------------------------------------------------------------------------- 1 | // 2 | // JKAssetsViewCell.m 3 | // JKImagePicker 4 | // 5 | // Created by Jecky on 15/1/12. 6 | // Copyright (c) 2015年 Jecky. All rights reserved. 7 | // 8 | 9 | #import "JKAssetsViewCell.h" 10 | #import "JKUtil.h" 11 | #import "UIView+JKPicker.h" 12 | 13 | @interface JKAssetsViewCell() 14 | 15 | @property (nonatomic, strong) UIImageView *imageView; 16 | @property (nonatomic, strong) UIButton *photoButton; 17 | @property (nonatomic, strong) UIButton *checkButton; 18 | 19 | 20 | @end 21 | 22 | @implementation JKAssetsViewCell 23 | 24 | - (instancetype)initWithFrame:(CGRect)frame 25 | { 26 | self = [super initWithFrame:frame]; 27 | 28 | if (self) { 29 | // Create a image view 30 | self.backgroundColor = [UIColor clearColor]; 31 | self.autoresizesSubviews = YES; 32 | [self imageView]; 33 | self.checkButton.right = self.imageView.width; 34 | } 35 | 36 | return self; 37 | } 38 | 39 | #pragma mark - setter/getter 40 | - (void)setAsset:(ALAsset *)asset 41 | { 42 | if (asset == nil) { 43 | _asset = asset; 44 | self.photoButton.hidden = NO; 45 | self.imageView.hidden = YES; 46 | return; 47 | } 48 | 49 | self.imageView.hidden = NO; 50 | self.photoButton.hidden = YES; 51 | if (_asset != asset) { 52 | _asset = asset; 53 | // Update view 54 | CGImageRef thumbnailImageRef = [asset thumbnail]; 55 | 56 | if (thumbnailImageRef) { 57 | self.imageView.image = [UIImage imageWithCGImage:thumbnailImageRef]; 58 | self.img = [UIImage imageWithCGImage:thumbnailImageRef]; 59 | } else { 60 | self.imageView.image = [UIImage imageNamed:@"assets_placeholder_picture"]; 61 | } 62 | } 63 | 64 | } 65 | 66 | - (void)setIsSelected:(BOOL)isSelected{ 67 | _isSelected = isSelected; 68 | 69 | self.checkButton.selected = isSelected; 70 | } 71 | 72 | - (UIImageView *)imageView{ 73 | if (!_imageView) { 74 | _imageView = [[UIImageView alloc] initWithFrame:self.contentView.bounds]; 75 | _imageView.backgroundColor = [UIColor clearColor]; 76 | _imageView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight; 77 | _imageView.userInteractionEnabled = YES; 78 | [self.contentView addSubview:_imageView]; 79 | } 80 | return _imageView; 81 | } 82 | 83 | - (UIButton *)checkButton{ 84 | if (!_checkButton) { 85 | _checkButton = [UIButton buttonWithType:UIButtonTypeCustom]; 86 | UIImage *img = [UIImage imageNamed:@"photo_check_default"]; 87 | UIImage *imgH = [UIImage imageNamed:@"photo_check_selected"]; 88 | _checkButton.frame = CGRectMake(0, 0, img.size.width, img.size.height); 89 | [_checkButton setBackgroundImage:img forState:UIControlStateNormal]; 90 | [_checkButton setBackgroundImage:imgH forState:UIControlStateSelected]; 91 | [_checkButton addTarget:self action:@selector(photoDidChecked) forControlEvents:UIControlEventTouchUpInside]; 92 | _checkButton.exclusiveTouch = YES; 93 | [self.imageView addSubview:_checkButton]; 94 | } 95 | return _checkButton; 96 | } 97 | 98 | - (UIButton *)photoButton{ 99 | if (!_photoButton) { 100 | _photoButton = [UIButton buttonWithType:UIButtonTypeCustom]; 101 | _photoButton.frame = self.contentView.bounds; 102 | UIImage *bgImg = [UIImage imageNamed:@"compose_photograph_background"]; 103 | [_photoButton setBackgroundImage:bgImg forState:UIControlStateNormal]; 104 | [_photoButton setBackgroundImage:bgImg forState:UIControlStateNormal]; 105 | 106 | UIImage *img = [UIImage imageNamed:@"compose_photograph"]; 107 | UIImage *imgH = [UIImage imageNamed:@"compose_photograph_highlighted"]; 108 | [_photoButton setImage:img forState:UIControlStateNormal]; 109 | [_photoButton setImage:imgH forState:UIControlStateHighlighted]; 110 | [_photoButton addTarget:self action:@selector(photo) forControlEvents:UIControlEventTouchUpInside]; 111 | _photoButton.exclusiveTouch = YES; 112 | 113 | [self.contentView addSubview:_photoButton]; 114 | 115 | } 116 | return _photoButton; 117 | } 118 | 119 | - (void)photo 120 | { 121 | if ([_delegate respondsToSelector:@selector(startPhotoAssetsViewCell:)]) { 122 | [_delegate startPhotoAssetsViewCell:self]; 123 | } 124 | } 125 | 126 | - (void)photoDidChecked 127 | { 128 | if (self.checkButton.selected) { 129 | if ([_delegate respondsToSelector:@selector(didDeselectItemAssetsViewCell:)]) { 130 | [_delegate didDeselectItemAssetsViewCell:self]; 131 | } 132 | }else{ 133 | if ([_delegate respondsToSelector:@selector(didSelectItemAssetsViewCell:)]) { 134 | [_delegate didSelectItemAssetsViewCell:self]; 135 | } 136 | } 137 | } 138 | 139 | @end 140 | -------------------------------------------------------------------------------- /QQImagesPicker/ImagePicker/Classes/JKImagePickerController.h: -------------------------------------------------------------------------------- 1 | // 2 | // JKImagePickerController.h 3 | // JKImagePicker 4 | // 5 | // Created by Jecky on 15/1/9. 6 | // Copyright (c) 2015年 Jecky. All rights reserved. 7 | // 8 | 9 | #import 10 | #import 11 | #import "JKAssets.h" 12 | 13 | typedef NS_ENUM(NSUInteger, JKImagePickerControllerFilterType) { 14 | JKImagePickerControllerFilterTypeNone, 15 | JKImagePickerControllerFilterTypePhotos, 16 | JKImagePickerControllerFilterTypeVideos 17 | }; 18 | 19 | UIKIT_EXTERN ALAssetsFilter * ALAssetsFilterFromJKImagePickerControllerFilterType(JKImagePickerControllerFilterType type); 20 | 21 | @class JKImagePickerController; 22 | 23 | @protocol JKImagePickerControllerDelegate 24 | 25 | @optional 26 | - (void)imagePickerController:(JKImagePickerController *)imagePicker didSelectAsset:(JKAssets *)asset isSource:(BOOL)source; 27 | - (void)imagePickerController:(JKImagePickerController *)imagePicker didSelectAssets:(NSArray *)assets isSource:(BOOL)source; 28 | - (void)imagePickerControllerDidCancel:(JKImagePickerController *)imagePicker; 29 | 30 | @end 31 | 32 | @interface JKImagePickerController : UIViewController 33 | 34 | @property (nonatomic, weak) id delegate; 35 | @property (nonatomic, assign) JKImagePickerControllerFilterType filterType; 36 | @property (nonatomic, assign) BOOL showsCancelButton; 37 | @property (nonatomic, assign) BOOL allowsMultipleSelection; 38 | @property (nonatomic, assign) NSUInteger minimumNumberOfSelection; 39 | @property (nonatomic, assign) NSUInteger maximumNumberOfSelection; 40 | @property (nonatomic, strong) NSMutableArray *selectedAssetArray; 41 | @property (nonatomic ,strong) NSMutableArray *selectedPhotos; 42 | 43 | @end 44 | -------------------------------------------------------------------------------- /QQImagesPicker/ImagePicker/Classes/JKImagePickerController.m: -------------------------------------------------------------------------------- 1 | 2 | 3 | // 4 | // JKImagePickerController.m 5 | // JKImagePicker 6 | // 7 | // Created by Jecky on 15/1/9. 8 | // Copyright (c) 2015年 Jecky. All rights reserved. 9 | // 10 | 11 | #import "JKImagePickerController.h" 12 | #import "JKUtil.h" 13 | #import "JKAssetsGroupsView.h" 14 | #import "UIView+JKPicker.h" 15 | #import "JKAssetsViewCell.h" 16 | #import "JKAssetsCollectionFooterView.h" 17 | #import "JKPromptView.h" 18 | #import "JKPhotoBrowser.h" 19 | #import "PhotoAlbumManager.h" 20 | 21 | ALAssetsFilter * ALAssetsFilterFromJKImagePickerControllerFilterType(JKImagePickerControllerFilterType type) { 22 | switch (type) { 23 | case JKImagePickerControllerFilterTypeNone: 24 | return [ALAssetsFilter allAssets]; 25 | break; 26 | 27 | case JKImagePickerControllerFilterTypePhotos: 28 | return [ALAssetsFilter allPhotos]; 29 | break; 30 | 31 | case JKImagePickerControllerFilterTypeVideos: 32 | return [ALAssetsFilter allVideos]; 33 | break; 34 | } 35 | } 36 | 37 | 38 | @interface JKImagePickerController () 39 | 40 | @property (nonatomic, strong) ALAssetsLibrary *assetsLibrary; 41 | @property (nonatomic, strong) NSArray *groupTypes; 42 | 43 | @property (nonatomic, assign) BOOL showsAssetsGroupSelection; 44 | 45 | @property (nonatomic, strong) UILabel *titleLabel; 46 | @property (nonatomic, strong) UIButton *titleButton; 47 | @property (nonatomic, strong) UIButton *arrowImageView; 48 | 49 | @property (nonatomic, strong) UIButton *touchButton; 50 | @property (nonatomic, strong) UIView *overlayView; 51 | @property (nonatomic, strong) JKAssetsGroupsView *assetsGroupsView; 52 | 53 | 54 | @property (nonatomic, strong) ALAssetsGroup *selectAssetsGroup; 55 | @property (nonatomic, strong) NSMutableArray *assetsArray; 56 | @property (nonatomic, assign) NSUInteger numberOfAssets; 57 | @property (nonatomic, assign) NSUInteger numberOfPhotos; 58 | @property (nonatomic, assign) NSUInteger numberOfVideos; 59 | 60 | @property (nonatomic, strong) UIToolbar *toolbar; 61 | @property (nonatomic, strong) UIButton *selectButton; 62 | @property (nonatomic, strong) UIButton *finishButton; 63 | @property (nonatomic, strong) UILabel *finishLabel; 64 | 65 | @property (nonatomic, strong) UICollectionView *collectionView; 66 | 67 | @end 68 | 69 | @implementation JKImagePickerController 70 | 71 | - (id)init 72 | { 73 | self = [super init]; 74 | if (self) { 75 | self.filterType = JKImagePickerControllerFilterTypeNone; 76 | } 77 | return self; 78 | } 79 | 80 | - (void)viewDidLoad { 81 | [super viewDidLoad]; 82 | // Do any additional setup after loading the view. 83 | self.view.backgroundColor = [UIColor whiteColor]; 84 | [self setUpProperties]; 85 | 86 | if ([self respondsToSelector:@selector(edgesForExtendedLayout)]) { 87 | self.edgesForExtendedLayout = UIRectEdgeNone; 88 | } 89 | 90 | [self collectionView]; 91 | [self toolbar]; 92 | [self loadAssetsGroups]; 93 | } 94 | 95 | - (void)viewWillAppear:(BOOL)animated{ 96 | [super viewWillAppear:animated]; 97 | 98 | } 99 | 100 | - (void)viewDidAppear:(BOOL)animated{ 101 | [super viewDidAppear:animated]; 102 | } 103 | 104 | - (void)setUpProperties 105 | { 106 | // Property settings 107 | self.groupTypes = @[@(ALAssetsGroupLibrary), 108 | @(ALAssetsGroupSavedPhotos), 109 | @(ALAssetsGroupPhotoStream), 110 | @(ALAssetsGroupAlbum)]; 111 | 112 | self.navigationItem.titleView = self.titleButton; 113 | 114 | UIButton *preBtn = [UIButton buttonWithType:UIButtonTypeCustom]; 115 | preBtn.frame = CGRectMake(0, 0, 50, 30); 116 | [preBtn setTitle:@"预览" forState:UIControlStateNormal]; 117 | [preBtn setTitleColor:[UIColor orangeColor] forState:UIControlStateNormal]; 118 | [preBtn setTitleColor:[JKUtil getColor:@"828689"] forState:UIControlStateHighlighted]; 119 | [preBtn setTitleColor:[JKUtil getColor:@"828689"] forState:UIControlStateDisabled]; 120 | [preBtn addTarget:self action:@selector(previewPhotoesSelected) forControlEvents:UIControlEventTouchUpInside]; 121 | UIBarButtonItem *preItem = [[UIBarButtonItem alloc] initWithCustomView:preBtn]; 122 | [self.navigationItem setRightBarButtonItem:preItem animated:NO]; 123 | self.navigationItem.rightBarButtonItem.enabled = NO; 124 | } 125 | 126 | - (void)cancelEventDidTouched 127 | { 128 | if ([_delegate respondsToSelector:@selector(imagePickerControllerDidCancel:)]) { 129 | [_delegate imagePickerControllerDidCancel:self]; 130 | } 131 | } 132 | 133 | - (void)assetsGroupDidSelected 134 | { 135 | self.showsAssetsGroupSelection = YES; 136 | 137 | if (self.showsAssetsGroupSelection) { 138 | [self showAssetsGroupView]; 139 | } 140 | } 141 | 142 | - (void)selectOriginImage 143 | { 144 | _selectButton.selected = !_selectButton.selected; 145 | 146 | } 147 | 148 | - (void)assetsGroupsDidDeselected 149 | { 150 | self.showsAssetsGroupSelection = NO; 151 | [self hideAssetsGroupView]; 152 | } 153 | 154 | - (void)showAssetsGroupView 155 | { 156 | [[UIApplication sharedApplication].keyWindow addSubview:self.touchButton]; 157 | 158 | self.overlayView.alpha = 0.0f; 159 | [UIView animateWithDuration:0.3f 160 | animations:^{ 161 | self.assetsGroupsView.top = 0; 162 | self.overlayView.alpha = 0.85f; 163 | }completion:^(BOOL finished) { 164 | 165 | }]; 166 | } 167 | 168 | - (void)hideAssetsGroupView 169 | { 170 | [UIView animateWithDuration:0.3f 171 | animations:^{ 172 | self.assetsGroupsView.top = -self.assetsGroupsView.height; 173 | self.overlayView.alpha = 0.0f; 174 | }completion:^(BOOL finished) { 175 | [_touchButton removeFromSuperview]; 176 | _touchButton = nil; 177 | 178 | [_overlayView removeFromSuperview]; 179 | _overlayView = nil; 180 | }]; 181 | 182 | } 183 | 184 | - (void)previewPhotoesSelected 185 | { 186 | [self passSelectedAssets]; 187 | } 188 | 189 | - (void)browerPhotoes:(NSArray *)array page:(NSInteger)page 190 | { 191 | JKPhotoBrowser *photoBorwser = [[JKPhotoBrowser alloc] initWithFrame:[UIScreen mainScreen].bounds]; 192 | photoBorwser.delegate = self; 193 | photoBorwser.pickerController = self; 194 | photoBorwser.currentPage = page; 195 | photoBorwser.assetsArray = [NSMutableArray arrayWithArray:array]; 196 | [photoBorwser show:YES]; 197 | } 198 | 199 | #pragma mark - Managing Assets 200 | - (void)passSelectedAssets 201 | { 202 | // Load assets from URLs 203 | __block NSMutableArray *assets = [NSMutableArray array]; 204 | 205 | for (JKAssets *jka in self.selectedAssetArray) { 206 | __weak typeof(self) weakSelf = self; 207 | [self.assetsLibrary assetForURL:jka.assetPropertyURL 208 | resultBlock:^(ALAsset *asset) { 209 | // Add asset 210 | [assets addObject:asset]; 211 | // Check if the loading finished 212 | if (assets.count == weakSelf.selectedAssetArray.count) { 213 | [weakSelf browerPhotoes:assets page:0]; 214 | } 215 | } failureBlock:^(NSError *error) { 216 | 217 | }]; 218 | } 219 | } 220 | 221 | 222 | - (void)loadAssetsGroups 223 | { 224 | // Load assets groups 225 | __weak typeof(self) weakSelf = self; 226 | [self loadAssetsGroupsWithTypes:self.groupTypes 227 | completion:^(NSArray *assetsGroups) { 228 | if ([assetsGroups count]>0) { 229 | weakSelf.titleButton.enabled = YES; 230 | weakSelf.selectAssetsGroup = [assetsGroups objectAtIndex:0]; 231 | 232 | weakSelf.assetsGroupsView.assetsGroups = assetsGroups; 233 | 234 | NSMutableDictionary *dic = [NSMutableDictionary dictionaryWithCapacity:0]; 235 | for (JKAssets *asset in weakSelf.selectedAssetArray) { 236 | if (asset.groupPropertyID) { 237 | NSInteger count = [[dic objectForKey:asset.groupPropertyID] integerValue]; 238 | [dic setObject:[NSNumber numberWithInteger:count+1] forKey:asset.groupPropertyID]; 239 | } 240 | } 241 | weakSelf.assetsGroupsView.selectedAssetCount = dic; 242 | [weakSelf resetFinishFrame]; 243 | 244 | }else{ 245 | weakSelf.titleButton.enabled = NO; 246 | } 247 | }]; 248 | 249 | // Validation 250 | } 251 | 252 | - (void)setSelectAssetsGroup:(ALAssetsGroup *)selectAssetsGroup{ 253 | if (_selectAssetsGroup != selectAssetsGroup) { 254 | _selectAssetsGroup = selectAssetsGroup; 255 | 256 | NSString *assetsName = [selectAssetsGroup valueForProperty:ALAssetsGroupPropertyName]; 257 | self.titleLabel.text = assetsName; 258 | [self.titleLabel sizeToFit]; 259 | 260 | CGFloat width = CGRectGetWidth(self.titleLabel.frame)/2+2+CGRectGetWidth(self.arrowImageView.frame)+15; 261 | self.titleButton.width = width*2; 262 | 263 | self.titleLabel.centerY = self.titleButton.height/2; 264 | self.titleLabel.centerX = self.titleButton.width/2; 265 | 266 | self.arrowImageView.left = self.titleLabel.right + 5; 267 | self.arrowImageView.centerY = self.titleLabel.centerY; 268 | 269 | [self loadAllAssetsForGroups]; 270 | } 271 | } 272 | 273 | - (void)loadAllAssetsForGroups 274 | { 275 | [self.selectAssetsGroup setAssetsFilter:ALAssetsFilterFromJKImagePickerControllerFilterType(self.filterType)]; 276 | 277 | // Load assets 278 | NSMutableArray *assets = [NSMutableArray array]; 279 | __block NSUInteger numberOfAssets = 0; 280 | __block NSUInteger numberOfPhotos = 0; 281 | __block NSUInteger numberOfVideos = 0; 282 | 283 | [self.selectAssetsGroup enumerateAssetsUsingBlock:^(ALAsset *result, NSUInteger index, BOOL *stop) { 284 | if (result) { 285 | numberOfAssets++; 286 | NSString *type = [result valueForProperty:ALAssetPropertyType]; 287 | if ([type isEqualToString:ALAssetTypePhoto]){ 288 | numberOfPhotos++; 289 | }else if ([type isEqualToString:ALAssetTypeVideo]){ 290 | numberOfVideos++; 291 | } 292 | [assets addObject:result]; 293 | } 294 | }]; 295 | 296 | self.assetsArray = assets; 297 | self.numberOfAssets = numberOfAssets; 298 | self.numberOfPhotos = numberOfPhotos; 299 | self.numberOfVideos = numberOfVideos; 300 | 301 | // Update view 302 | [self.collectionView reloadData]; 303 | } 304 | 305 | - (void)loadAssetsGroupsWithTypes:(NSArray *)types completion:(void (^)(NSArray *assetsGroups))completion 306 | { 307 | __block NSMutableArray *assetsGroups = [NSMutableArray array]; 308 | __block NSUInteger numberOfFinishedTypes = 0; 309 | 310 | for (NSNumber *type in types) { 311 | __weak typeof(self) weakSelf = self; 312 | [self.assetsLibrary enumerateGroupsWithTypes:[type unsignedIntegerValue] 313 | usingBlock:^(ALAssetsGroup *assetsGroup, BOOL *stop) { 314 | if (assetsGroup) { 315 | // Filter the assets group 316 | [assetsGroup setAssetsFilter:ALAssetsFilterFromJKImagePickerControllerFilterType(weakSelf.filterType)]; 317 | 318 | // Add assets group 319 | if (assetsGroup.numberOfAssets > 0) { 320 | // Add assets group 321 | [assetsGroups addObject:assetsGroup]; 322 | } 323 | } else { 324 | numberOfFinishedTypes++; 325 | } 326 | 327 | // Check if the loading finished 328 | if (numberOfFinishedTypes == types.count) { 329 | // Sort assets groups 330 | NSArray *sortedAssetsGroups = [self sortAssetsGroups:(NSArray *)assetsGroups typesOrder:types]; 331 | 332 | // Call completion block 333 | if (completion) { 334 | completion(sortedAssetsGroups); 335 | } 336 | } 337 | } failureBlock:^(NSError *error) { 338 | 339 | }]; 340 | } 341 | } 342 | 343 | - (NSArray *)sortAssetsGroups:(NSArray *)assetsGroups typesOrder:(NSArray *)typesOrder 344 | { 345 | NSMutableArray *sortedAssetsGroups = [NSMutableArray array]; 346 | 347 | for (ALAssetsGroup *assetsGroup in assetsGroups) { 348 | if (sortedAssetsGroups.count == 0) { 349 | [sortedAssetsGroups addObject:assetsGroup]; 350 | continue; 351 | } 352 | 353 | ALAssetsGroupType assetsGroupType = [[assetsGroup valueForProperty:ALAssetsGroupPropertyType] unsignedIntegerValue]; 354 | NSUInteger indexOfAssetsGroupType = [typesOrder indexOfObject:@(assetsGroupType)]; 355 | 356 | for (NSInteger i = 0; i <= sortedAssetsGroups.count; i++) { 357 | if (i == sortedAssetsGroups.count) { 358 | [sortedAssetsGroups addObject:assetsGroup]; 359 | break; 360 | } 361 | 362 | ALAssetsGroup *sortedAssetsGroup = sortedAssetsGroups[i]; 363 | ALAssetsGroupType sortedAssetsGroupType = [[sortedAssetsGroup valueForProperty:ALAssetsGroupPropertyType] unsignedIntegerValue]; 364 | NSUInteger indexOfSortedAssetsGroupType = [typesOrder indexOfObject:@(sortedAssetsGroupType)]; 365 | 366 | if (indexOfAssetsGroupType < indexOfSortedAssetsGroupType) { 367 | [sortedAssetsGroups insertObject:assetsGroup atIndex:i]; 368 | break; 369 | } 370 | } 371 | } 372 | 373 | return sortedAssetsGroups; 374 | } 375 | 376 | - (BOOL)validateNumberOfSelections:(NSUInteger)numberOfSelections 377 | { 378 | NSUInteger minimumNumberOfSelection = MAX(1, self.minimumNumberOfSelection); 379 | BOOL qualifiesMinimumNumberOfSelection = (numberOfSelections >= minimumNumberOfSelection); 380 | 381 | BOOL qualifiesMaximumNumberOfSelection = YES; 382 | if (minimumNumberOfSelection <= self.maximumNumberOfSelection) { 383 | qualifiesMaximumNumberOfSelection = (numberOfSelections <= self.maximumNumberOfSelection); 384 | } 385 | 386 | return (qualifiesMinimumNumberOfSelection && qualifiesMaximumNumberOfSelection); 387 | } 388 | 389 | - (BOOL)validateMaximumNumberOfSelections:(NSUInteger)numberOfSelections 390 | { 391 | NSUInteger minimumNumberOfSelection = MAX(1, self.minimumNumberOfSelection); 392 | 393 | if (minimumNumberOfSelection <= self.maximumNumberOfSelection) { 394 | return (numberOfSelections <= self.maximumNumberOfSelection); 395 | } 396 | 397 | return YES; 398 | } 399 | 400 | #pragma mark - JKAssetsGroupsViewDelegate 401 | - (void)assetsGroupsViewDidCancel:(JKAssetsGroupsView *)groupsView 402 | { 403 | [self assetsGroupsDidDeselected]; 404 | } 405 | 406 | - (void)assetsGroupsView:(JKAssetsGroupsView *)groupsView didSelectAssetsGroup:(ALAssetsGroup *)assGroup 407 | { 408 | [self assetsGroupsDidDeselected]; 409 | self.selectAssetsGroup = assGroup; 410 | } 411 | 412 | #pragma mark - setter 413 | - (void)setShowsAssetsGroupSelection:(BOOL)showsAssetsGroupSelection{ 414 | _showsAssetsGroupSelection = showsAssetsGroupSelection; 415 | 416 | self.arrowImageView.selected = _showsAssetsGroupSelection; 417 | 418 | } 419 | - (void)setShowsCancelButton:(BOOL)showsCancelButton{ 420 | _showsCancelButton = showsCancelButton; 421 | 422 | // Show/hide cancel button 423 | if (showsCancelButton) { 424 | UIButton *cancelBtn = [UIButton buttonWithType:UIButtonTypeCustom]; 425 | cancelBtn.frame = CGRectMake(0, 0, 50, 30); 426 | [cancelBtn setTitle:@"取消" forState:UIControlStateNormal]; 427 | [cancelBtn setTitleEdgeInsets:UIEdgeInsetsMake(0, 0, 0, 0)]; 428 | [cancelBtn setTitleColor:[UIColor orangeColor] forState:UIControlStateNormal]; 429 | [cancelBtn setTitleColor:[JKUtil getColor:@"828689"] forState:UIControlStateHighlighted]; 430 | [cancelBtn addTarget:self action:@selector(cancelEventDidTouched) forControlEvents:UIControlEventTouchUpInside]; 431 | UIBarButtonItem *cancelItem = [[UIBarButtonItem alloc] initWithCustomView:cancelBtn]; 432 | [self.navigationItem setLeftBarButtonItem:cancelItem animated:NO]; 433 | } else { 434 | [self.navigationItem setLeftBarButtonItem:nil animated:NO]; 435 | } 436 | } 437 | 438 | 439 | - (void)finishPhotoDidSelected 440 | { 441 | if ([_delegate respondsToSelector:@selector(imagePickerController:didSelectAssets:isSource:)]) { 442 | [_delegate imagePickerController:self 443 | didSelectAssets:self.selectedAssetArray 444 | isSource:_selectButton.selected]; 445 | } 446 | } 447 | 448 | static NSString *kJKImagePickerCellIdentifier = @"kJKImagePickerCellIdentifier"; 449 | static NSString *kJKAssetsFooterViewIdentifier = @"kJKAssetsFooterViewIdentifier"; 450 | 451 | #pragma mark - UICollectionViewDataSource 452 | - (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section 453 | { 454 | return [self.assetsArray count]+1; 455 | } 456 | 457 | - (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath 458 | { 459 | JKAssetsViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:kJKImagePickerCellIdentifier forIndexPath:indexPath]; 460 | 461 | cell.delegate = self; 462 | if ([indexPath row]<=0) { 463 | cell.asset = nil; 464 | }else{ 465 | ALAsset *asset = self.assetsArray[indexPath.row-1]; 466 | cell.asset = asset; 467 | NSURL *assetURL = [asset valueForProperty:ALAssetPropertyAssetURL]; 468 | cell.isSelected = [self assetIsSelected:assetURL]; 469 | } 470 | 471 | return cell; 472 | } 473 | 474 | - (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout referenceSizeForFooterInSection:(NSInteger)section 475 | { 476 | return CGSizeMake(collectionView.bounds.size.width, 46.0); 477 | } 478 | 479 | - (UICollectionReusableView *)collectionView:(UICollectionView *)collectionView viewForSupplementaryElementOfKind:(NSString *)kind atIndexPath:(NSIndexPath *)indexPath 480 | { 481 | if (kind == UICollectionElementKindSectionFooter) { 482 | JKAssetsCollectionFooterView *footerView = [collectionView dequeueReusableSupplementaryViewOfKind:UICollectionElementKindSectionFooter 483 | withReuseIdentifier:kJKAssetsFooterViewIdentifier 484 | forIndexPath:indexPath]; 485 | 486 | switch (self.filterType) { 487 | case JKImagePickerControllerFilterTypeNone:{ 488 | NSString *format; 489 | if (self.numberOfPhotos == 1) { 490 | if (self.numberOfVideos == 1) { 491 | format = @"format_photo_and_video"; 492 | } else { 493 | format = @"format_photo_and_videos"; 494 | } 495 | } else if (self.numberOfVideos == 1) { 496 | format = @"format_photos_and_video"; 497 | } else { 498 | format = @"format_photos_and_videos"; 499 | } 500 | footerView.textLabel.text = [NSString stringWithFormat:NSLocalizedStringFromTable(format, 501 | @"JKImagePickerController", 502 | nil), 503 | self.numberOfPhotos, 504 | self.numberOfVideos 505 | ]; 506 | break; 507 | } 508 | 509 | case JKImagePickerControllerFilterTypePhotos:{ 510 | NSString *format = (self.numberOfPhotos == 1) ? @"format_photo" : @"format_photos"; 511 | footerView.textLabel.text = [NSString stringWithFormat:NSLocalizedStringFromTable(format, 512 | @"JKImagePickerController", 513 | nil), 514 | self.numberOfPhotos 515 | ]; 516 | break; 517 | } 518 | 519 | case JKImagePickerControllerFilterTypeVideos:{ 520 | NSString *format = (self.numberOfVideos == 1) ? @"format_video" : @"format_videos"; 521 | footerView.textLabel.text = [NSString stringWithFormat:NSLocalizedStringFromTable(format, 522 | @"JKImagePickerController", 523 | nil), 524 | self.numberOfVideos 525 | ]; 526 | break; 527 | } 528 | } 529 | 530 | return footerView; 531 | } 532 | 533 | return nil; 534 | } 535 | 536 | #define kSizeThumbnailCollectionView ([UIScreen mainScreen].bounds.size.width-10)/4 537 | 538 | #pragma mark - UICollectionViewDelegateFlowLayout 539 | - (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath 540 | { 541 | return CGSizeMake(kSizeThumbnailCollectionView, kSizeThumbnailCollectionView); 542 | } 543 | 544 | - (UIEdgeInsets)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout insetForSectionAtIndex:(NSInteger)section 545 | { 546 | return UIEdgeInsetsMake(2, 2, 2, 2); 547 | } 548 | 549 | - (void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath 550 | { 551 | [self browerPhotoes:self.assetsArray page:[indexPath row]-1]; 552 | } 553 | 554 | #pragma mark - getter 555 | - (void)photoBrowser:(JKPhotoBrowser *)photoBrowser didSelectAtIndex:(NSInteger)index 556 | { 557 | ALAsset *asset = self.assetsArray[index]; 558 | NSURL *assetURL = [asset valueForProperty:ALAssetPropertyAssetURL]; 559 | // CGImageRef thumbnailImageRef = [asset thumbnail]; 560 | //CGImageRef realmimage = [asset defaultRepresentation]; 561 | UIImage *image; 562 | // if (thumbnailImageRef) { 563 | // image = [UIImage imageWithCGImage:thumbnailImageRef]; 564 | if (assetURL){ 565 | image = [UIImage imageWithCGImage:[[asset defaultRepresentation] fullScreenImage]]; 566 | } else { 567 | image = [UIImage imageNamed:@"assets_placeholder_picture"]; 568 | } 569 | 570 | 571 | [self addAssetsObject:assetURL realImg:image]; 572 | [self resetFinishFrame]; 573 | [self.collectionView reloadData]; 574 | } 575 | 576 | - (void)photoBrowser:(JKPhotoBrowser *)photoBrowser didDeselectAtIndex:(NSInteger)index 577 | { 578 | ALAsset *asset = self.assetsArray[index]; 579 | NSURL *assetURL = [asset valueForProperty:ALAssetPropertyAssetURL]; 580 | [self removeAssetsObject:assetURL]; 581 | [self resetFinishFrame]; 582 | [self.collectionView reloadData]; 583 | } 584 | 585 | #pragma mark- UIImagePickerViewController 586 | - (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info{ 587 | UIImage *image = [info objectForKey:UIImagePickerControllerOriginalImage]; 588 | __weak typeof(self) weakSelf = self; 589 | 590 | NSString *assetsName = [self.selectAssetsGroup valueForProperty:ALAssetsGroupPropertyName]; 591 | 592 | [[PhotoAlbumManager sharedManager] saveImage:image 593 | toAlbum:assetsName 594 | completionBlock:^(ALAsset *asset, NSError *error) { 595 | if (error == nil && asset) { 596 | NSURL *assetURL = [asset valueForProperty:ALAssetPropertyAssetURL]; 597 | [self addAssetsObject:assetURL realImg:image]; 598 | [weakSelf finishPhotoDidSelected]; 599 | } 600 | }]; 601 | 602 | [picker dismissViewControllerAnimated:NO completion:^{}]; 603 | 604 | 605 | } 606 | 607 | #pragma mark - JKAssetsViewCellDelegate 608 | - (void)startPhotoAssetsViewCell:(JKAssetsViewCell *)assetsCell 609 | { 610 | if (self.selectedAssetArray.count>=self.maximumNumberOfSelection) { 611 | NSString *str = [NSString stringWithFormat:@"最多选择%lu张照片",self.maximumNumberOfSelection]; 612 | [JKPromptView showWithImageName:@"picker_alert_sigh" message:str]; 613 | return; 614 | } 615 | 616 | 617 | if([UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypeCamera]) { 618 | 619 | dispatch_async(dispatch_get_main_queue(), ^{ 620 | UIImagePickerController *pickerController = [[UIImagePickerController alloc]init]; 621 | 622 | pickerController.allowsEditing = NO; 623 | pickerController.delegate = self; 624 | pickerController.sourceType = UIImagePickerControllerSourceTypeCamera; 625 | 626 | [self presentViewController:pickerController animated:YES completion:^{ 627 | 628 | }]; 629 | }); 630 | 631 | } 632 | 633 | 634 | 635 | } 636 | 637 | - (void)didSelectItemAssetsViewCell:(JKAssetsViewCell *)assetsCell 638 | { 639 | if (self.selectedAssetArray.count>=self.maximumNumberOfSelection) { 640 | NSString *str = [NSString stringWithFormat:@"最多选择%lu张照片",self.maximumNumberOfSelection]; 641 | [JKPromptView showWithImageName:@"picker_alert_sigh" message:str]; 642 | } 643 | 644 | BOOL validate = [self validateMaximumNumberOfSelections:(self.selectedAssetArray.count + 1)]; 645 | if (validate) { 646 | // Add asset URL 647 | NSURL *assetURL = [assetsCell.asset valueForProperty:ALAssetPropertyAssetURL]; 648 | UIImage *img = assetsCell.img; 649 | [self addAssetsObject:assetURL realImg:img]; 650 | [self resetFinishFrame]; 651 | assetsCell.isSelected = YES; 652 | } 653 | 654 | } 655 | 656 | - (void)didDeselectItemAssetsViewCell:(JKAssetsViewCell *)assetsCell 657 | { 658 | NSURL *assetURL = [assetsCell.asset valueForProperty:ALAssetPropertyAssetURL]; 659 | [self removeAssetsObject:assetURL]; 660 | [self resetFinishFrame]; 661 | assetsCell.isSelected = NO; 662 | 663 | 664 | } 665 | 666 | - (void)removeAssetsObject:(NSURL *)assetURL 667 | { 668 | for (JKAssets *asset in self.selectedAssetArray) { 669 | if ([assetURL isEqual:asset.assetPropertyURL]) { 670 | [self.assetsGroupsView removeAssetSelected:asset]; 671 | [self.selectedAssetArray removeObject:asset]; 672 | break; 673 | } 674 | } 675 | } 676 | 677 | - (void)addAssetsObject:(NSURL *)assetURL realImg:(UIImage *)img 678 | { 679 | NSURL *groupURL = [self.selectAssetsGroup valueForProperty:ALAssetsGroupPropertyURL]; 680 | NSString *groupID = [self.selectAssetsGroup valueForProperty:ALAssetsGroupPropertyPersistentID]; 681 | JKAssets *asset = [[JKAssets alloc] init]; 682 | asset.groupPropertyID = groupID; 683 | asset.groupPropertyURL = groupURL; 684 | asset.assetPropertyURL = assetURL; 685 | ALAssetsLibrary *lib = [[ALAssetsLibrary alloc] init]; 686 | 687 | [lib assetForURL:assetURL resultBlock:^(ALAsset *myasset){ 688 | if (myasset) { 689 | asset.photo = [UIImage imageWithCGImage:[[myasset defaultRepresentation] fullScreenImage]]; 690 | } 691 | }failureBlock:^(NSError *error){ 692 | 693 | }]; 694 | 695 | [self.selectedAssetArray addObject:asset]; 696 | [self.assetsGroupsView addAssetSelected:asset]; 697 | } 698 | 699 | 700 | 701 | 702 | - (BOOL)assetIsSelected:(NSURL *)assetURL 703 | { 704 | for (JKAssets *asset in self.selectedAssetArray) { 705 | if ([assetURL isEqual:asset.assetPropertyURL]) { 706 | return YES; 707 | } 708 | } 709 | return NO; 710 | } 711 | 712 | - (void)resetFinishFrame 713 | { 714 | self.finishButton.hidden = (self.selectedAssetArray.count<=0); 715 | self.finishLabel.text = [NSString stringWithFormat:@"下一步(%ld)",self.selectedAssetArray.count]; 716 | [self.finishLabel sizeToFit]; 717 | 718 | self.finishButton.width = _finishLabel.width+10; 719 | self.finishButton.right = self.view.width - 10; 720 | self.finishLabel.centerX = self.finishButton.width/2; 721 | self.finishLabel.centerY = self.finishButton.height/2; 722 | 723 | self.navigationItem.rightBarButtonItem.enabled = (self.selectedAssetArray.count>0); 724 | 725 | } 726 | 727 | #pragma mark - getter/setter 728 | - (NSMutableArray *)selectedAssetArray{ 729 | if (!_selectedAssetArray) { 730 | _selectedAssetArray = [NSMutableArray arrayWithCapacity:0]; 731 | } 732 | return _selectedAssetArray; 733 | } 734 | 735 | - (ALAssetsLibrary *)assetsLibrary{ 736 | if (!_assetsLibrary) { 737 | _assetsLibrary = [[ALAssetsLibrary alloc] init]; 738 | } 739 | return _assetsLibrary; 740 | } 741 | 742 | - (UIButton *)titleButton{ 743 | if (!_titleButton) { 744 | _titleButton = [UIButton buttonWithType:UIButtonTypeCustom]; 745 | _titleButton.frame = CGRectMake(0, 0, 120, 30); 746 | UIImage *img =[UIImage imageNamed:@"navigationbar_title_highlighted"]; 747 | [_titleButton setBackgroundImage:nil forState:UIControlStateNormal]; 748 | [_titleButton setBackgroundImage:[JKUtil stretchImage:img capInsets:UIEdgeInsetsMake(5, 2, 5, 2) resizingMode:UIImageResizingModeStretch] forState:UIControlStateHighlighted]; 749 | [_titleButton addTarget:self action:@selector(assetsGroupDidSelected) forControlEvents:UIControlEventTouchUpInside]; 750 | } 751 | return _titleButton; 752 | } 753 | 754 | - (UIButton *)arrowImageView{ 755 | if (!_arrowImageView) { 756 | UIImage *img = [UIImage imageNamed:@"navigationbar_arrow_down"]; 757 | UIImage *imgSelect = [UIImage imageNamed:@"navigationbar_arrow_up"]; 758 | _arrowImageView = [UIButton buttonWithType:UIButtonTypeCustom]; 759 | _arrowImageView.frame = CGRectMake(0, 0, img.size.width, img.size.height); 760 | [_arrowImageView setBackgroundImage:img forState:UIControlStateNormal]; 761 | [_arrowImageView setBackgroundImage:imgSelect forState:UIControlStateSelected]; 762 | [self.titleButton addSubview:_arrowImageView]; 763 | } 764 | return _arrowImageView; 765 | } 766 | 767 | - (UILabel *)titleLabel{ 768 | if (!_titleLabel) { 769 | _titleLabel = [[UILabel alloc] init]; 770 | _titleLabel.backgroundColor = [UIColor clearColor]; 771 | _titleLabel.textColor = [UIColor blackColor]; 772 | _titleLabel.font = [UIFont systemFontOfSize:16]; 773 | [self.titleButton addSubview:_titleLabel]; 774 | } 775 | return _titleLabel; 776 | } 777 | 778 | - (JKAssetsGroupsView *)assetsGroupsView{ 779 | if (!_assetsGroupsView) { 780 | _assetsGroupsView = [[JKAssetsGroupsView alloc] initWithFrame:CGRectMake(0, -self.view.height, self.view.width, self.view.height)]; 781 | _assetsGroupsView.delegate = self; 782 | _assetsGroupsView.autoresizingMask = UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleWidth; 783 | [self.view addSubview:_assetsGroupsView]; 784 | } 785 | return _assetsGroupsView; 786 | } 787 | 788 | - (UIView *)overlayView{ 789 | if (!_overlayView) { 790 | _overlayView = [[UIView alloc] initWithFrame:self.view.bounds]; 791 | _overlayView.backgroundColor = [UIColor colorWithWhite:0 alpha:0.85f]; 792 | [self.view insertSubview:_overlayView belowSubview:self.assetsGroupsView]; 793 | } 794 | return _overlayView; 795 | } 796 | 797 | - (UIButton *)touchButton{ 798 | if (!_touchButton) { 799 | _touchButton = [UIButton buttonWithType:UIButtonTypeCustom]; 800 | _touchButton.frame = CGRectMake(0, 0, self.view.width, 64); 801 | [_touchButton addTarget:self action:@selector(assetsGroupsDidDeselected) forControlEvents:UIControlEventTouchUpInside]; 802 | } 803 | return _touchButton; 804 | } 805 | 806 | - (UIToolbar *)toolbar{ 807 | if (!_toolbar) { 808 | _toolbar = [[UIToolbar alloc] initWithFrame:CGRectMake(0, self.view.height-44-64, self.view.width, 44)]; 809 | _toolbar.tintColor = [JKUtil getColor:@"f5f7fa"]; 810 | if ([_toolbar respondsToSelector:@selector(barTintColor)]) { 811 | _toolbar.barTintColor = [JKUtil getColor:@"f5f7fa"]; 812 | } 813 | _toolbar.translucent = YES; 814 | _toolbar.userInteractionEnabled = YES; 815 | 816 | UIImage *img = [UIImage imageNamed:@"compose_photo_original"]; 817 | UIImage *imgSelect = [UIImage imageNamed:@"compose_photo_original_highlighted"]; 818 | _selectButton = [UIButton buttonWithType:UIButtonTypeCustom]; 819 | _selectButton.frame = CGRectMake(10, floor((44-img.size.height)/2), img.size.width, img.size.height); 820 | [_selectButton setBackgroundImage:img forState:UIControlStateNormal]; 821 | [_selectButton setBackgroundImage:imgSelect forState:UIControlStateSelected]; 822 | [_selectButton addTarget:self action:@selector(selectOriginImage) forControlEvents:UIControlEventTouchUpInside]; 823 | [_toolbar addSubview:_selectButton]; 824 | 825 | UILabel *label = [[UILabel alloc] init]; 826 | label.backgroundColor = [UIColor clearColor]; 827 | label.textColor = [JKUtil getColor:@"828689"]; 828 | label.font = [UIFont systemFontOfSize:11]; 829 | label.text = @"原图"; 830 | [label sizeToFit]; 831 | label.centerY = _selectButton.height/2; 832 | label.right = _selectButton.width - 14; 833 | [_selectButton addSubview:label]; 834 | 835 | _finishLabel = [[UILabel alloc] init]; 836 | _finishLabel.backgroundColor = [UIColor clearColor]; 837 | _finishLabel.textColor = [UIColor whiteColor]; 838 | _finishLabel.font = [UIFont systemFontOfSize:14]; 839 | _finishLabel.text = @"下一步(9)"; 840 | [_finishLabel sizeToFit]; 841 | 842 | _finishButton = [UIButton buttonWithType:UIButtonTypeCustom]; 843 | _finishButton.frame = CGRectMake(0, 0, _finishLabel.width+10, _selectButton.height); 844 | [_finishButton setBackgroundImage:[JKUtil stretchImage:[UIImage imageNamed:@"picker_button_orange"] capInsets:UIEdgeInsetsMake(5, 5, 5, 5) resizingMode:UIImageResizingModeStretch] forState:UIControlStateNormal]; 845 | [_finishButton setBackgroundImage:[JKUtil stretchImage:[UIImage imageNamed:@"picker_button_orange_highlighted"] capInsets:UIEdgeInsetsMake(5, 5, 5, 5) resizingMode:UIImageResizingModeStretch] forState:UIControlStateHighlighted]; 846 | _finishButton.right = self.view.width-10; 847 | _finishButton.centerY = _selectButton.centerY; 848 | _finishButton.hidden = YES; 849 | [_finishButton addTarget:self action:@selector(finishPhotoDidSelected) forControlEvents:UIControlEventTouchUpInside]; 850 | [_toolbar addSubview:_finishButton]; 851 | 852 | _finishLabel.centerY = _finishButton.height/2; 853 | _finishLabel.centerX = _finishButton.width/2; 854 | [_finishButton addSubview:_finishLabel]; 855 | 856 | [self.view addSubview:_toolbar]; 857 | } 858 | return _toolbar; 859 | } 860 | 861 | - (UICollectionView *)collectionView{ 862 | if (!_collectionView) { 863 | UICollectionViewFlowLayout *layout = [[UICollectionViewFlowLayout alloc] init]; 864 | layout.minimumLineSpacing = 2.0; 865 | layout.minimumInteritemSpacing = 2.0; 866 | layout.scrollDirection = UICollectionViewScrollDirectionVertical; 867 | 868 | _collectionView = [[UICollectionView alloc] initWithFrame:CGRectMake(0, 0, self.view.width, [UIScreen mainScreen].bounds.size.height-64-44) collectionViewLayout:layout]; 869 | _collectionView.backgroundColor = [UIColor clearColor]; 870 | [_collectionView registerClass:[JKAssetsViewCell class] forCellWithReuseIdentifier:kJKImagePickerCellIdentifier]; 871 | [_collectionView registerClass:[JKAssetsCollectionFooterView class] 872 | forSupplementaryViewOfKind:UICollectionElementKindSectionFooter 873 | withReuseIdentifier:kJKAssetsFooterViewIdentifier]; 874 | _collectionView.delegate = self; 875 | _collectionView.dataSource = self; 876 | _collectionView.showsHorizontalScrollIndicator = NO; 877 | _collectionView.showsVerticalScrollIndicator = NO; 878 | [self.view addSubview:_collectionView]; 879 | 880 | } 881 | return _collectionView; 882 | } 883 | 884 | @end 885 | -------------------------------------------------------------------------------- /QQImagesPicker/ImagePicker/Classes/JKPhotoBrowser.h: -------------------------------------------------------------------------------- 1 | // 2 | // JKPhotoBrowser.h 3 | // JKPhotoBrowser 4 | // 5 | // Created by Jecky on 14/12/29. 6 | // Copyright (c) 2014年 Jecky. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "JKImagePickerController.h" 11 | 12 | @class JKPhotoBrowser; 13 | 14 | @protocol JKPhotoBrowserDelegate 15 | @optional 16 | - (void)photoBrowser:(JKPhotoBrowser *)photoBrowser didSelectAtIndex:(NSInteger)index; 17 | - (void)photoBrowser:(JKPhotoBrowser *)photoBrowser didDeselectAtIndex:(NSInteger)index; 18 | 19 | @end 20 | 21 | @interface JKPhotoBrowser : UIView 22 | 23 | @property (nonatomic, weak) JKImagePickerController *pickerController; 24 | @property (nonatomic, weak) id delegate; 25 | 26 | @property (nonatomic, strong) NSMutableArray *assetsArray; 27 | 28 | @property (nonatomic, assign) NSInteger currentPage; 29 | 30 | 31 | - (void)show:(BOOL)animated; 32 | - (void)hide:(BOOL)animated; 33 | 34 | @end 35 | -------------------------------------------------------------------------------- /QQImagesPicker/ImagePicker/Classes/JKPhotoBrowser.m: -------------------------------------------------------------------------------- 1 | // 2 | // JKPhotoBrowser.m 3 | // JKPhotoBrowser 4 | // 5 | // Created by Jecky on 14/12/29. 6 | // Copyright (c) 2014年 Jecky. All rights reserved. 7 | // 8 | 9 | #import "JKPhotoBrowser.h" 10 | #import "JKPhotoBrowserCell.h" 11 | #import "UIView+JKPicker.h" 12 | #import "JKUtil.h" 13 | #import "JKPromptView.h" 14 | 15 | @interface JKPhotoBrowser() 16 | 17 | @property (nonatomic, strong) UICollectionView *collectionView; 18 | @property (nonatomic, strong) UIView *topView; 19 | 20 | @property (nonatomic, strong) UILabel *numberLabel; 21 | @property (nonatomic, strong) UIButton *checkButton; 22 | 23 | @end 24 | 25 | static NSString *kJKPhotoBrowserCellIdentifier = @"kJKPhotoBrowserCellIdentifier"; 26 | 27 | @implementation JKPhotoBrowser 28 | 29 | - (id)initWithFrame:(CGRect)frame 30 | { 31 | self = [super initWithFrame:frame]; 32 | if (self) { 33 | self.backgroundColor = [JKUtil getColor:@"282828"]; 34 | self.autoresizesSubviews = YES; 35 | [self collectionView]; 36 | [self topView]; 37 | } 38 | return self; 39 | } 40 | 41 | - (void)closePhotoBrower 42 | { 43 | [self hide:YES]; 44 | } 45 | 46 | 47 | - (void)photoDidChecked 48 | { 49 | if (!self.checkButton.selected&&self.pickerController.selectedAssetArray.count>=self.pickerController.maximumNumberOfSelection) { 50 | NSString *str = [NSString stringWithFormat:@"最多选择%lu张照片",self.pickerController.maximumNumberOfSelection]; 51 | [JKPromptView showWithImageName:@"picker_alert_sigh" message:str]; 52 | return; 53 | } 54 | 55 | if (self.checkButton.selected) { 56 | if ([_delegate respondsToSelector:@selector(photoBrowser:didDeselectAtIndex:)]) { 57 | [_delegate photoBrowser:self didDeselectAtIndex:self.currentPage]; 58 | } 59 | }else{ 60 | if ([_delegate respondsToSelector:@selector(photoBrowser:didSelectAtIndex:)]) { 61 | [_delegate photoBrowser:self didSelectAtIndex:self.currentPage]; 62 | } 63 | } 64 | 65 | self.checkButton.selected = !self.checkButton.selected; 66 | } 67 | 68 | - (void)show:(BOOL)animated 69 | { 70 | if (animated){ 71 | self.top = [UIScreen mainScreen].bounds.size.height; 72 | [[UIApplication sharedApplication].keyWindow addSubview:self]; 73 | [UIView animateWithDuration:0.3f 74 | animations:^{ 75 | self.top = 0; 76 | } 77 | completion:^(BOOL finished) { 78 | }]; 79 | 80 | }else{ 81 | [[UIApplication sharedApplication].keyWindow addSubview:self]; 82 | } 83 | } 84 | 85 | - (void)hide:(BOOL)animated 86 | { 87 | if (animated){ 88 | [UIView animateWithDuration:0.3f 89 | animations:^{ 90 | self.top = [UIScreen mainScreen].bounds.size.height; 91 | } 92 | completion:^(BOOL finished) { 93 | [self removeFromSuperview]; 94 | }]; 95 | } 96 | else{ 97 | [self removeFromSuperview]; 98 | } 99 | 100 | } 101 | 102 | #pragma mark - UICollectionViewDataSource 103 | - (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section 104 | { 105 | return [self.assetsArray count]; 106 | } 107 | 108 | - (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath 109 | { 110 | JKPhotoBrowserCell *cell = (JKPhotoBrowserCell *)[collectionView dequeueReusableCellWithReuseIdentifier:kJKPhotoBrowserCellIdentifier forIndexPath:indexPath]; 111 | 112 | cell.asset = [self.assetsArray objectAtIndex:indexPath.row]; 113 | return cell; 114 | 115 | } 116 | 117 | #pragma mark - UICollectionViewDelegateFlowLayout 118 | - (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath 119 | { 120 | return CGSizeMake(self.bounds.size.width+20, self.bounds.size.height); 121 | } 122 | 123 | 124 | #pragma mark - UICollectionViewDelegate 125 | - (void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath 126 | { 127 | 128 | } 129 | - (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView 130 | { 131 | CGFloat offsetX = scrollView.contentOffset.x; 132 | float itemWidth = CGRectGetWidth(self.collectionView.frame); 133 | if (offsetX >= 0){ 134 | int page = offsetX / itemWidth; 135 | [self didScrollToPage:page]; 136 | } 137 | } 138 | 139 | - (void)didScrollToPage:(int)page 140 | { 141 | _currentPage = page; 142 | [self updateStatus]; 143 | } 144 | 145 | - (BOOL)assetIsSelected:(NSURL *)assetURL 146 | { 147 | for (JKAssets *asset in self.pickerController.selectedAssetArray) { 148 | if ([assetURL isEqual:asset.assetPropertyURL]) { 149 | return YES; 150 | } 151 | } 152 | return NO; 153 | } 154 | 155 | 156 | - (void)reloadPhotoeData 157 | { 158 | [self.collectionView setContentOffset:CGPointMake(_currentPage*CGRectGetWidth(self.collectionView.frame), 0) animated:NO]; 159 | [self updateStatus]; 160 | [self.collectionView reloadData]; 161 | } 162 | 163 | 164 | - (void)updateStatus 165 | { 166 | self.numberLabel.text = [NSString stringWithFormat:@"%lu/%lu",(long)(_currentPage+1),(unsigned long)[self.assetsArray count]]; 167 | self.numberLabel.text = [NSString stringWithFormat:@"%lu/%lu",(long)(_currentPage+1),(unsigned long)[self.assetsArray count]]; 168 | 169 | ALAsset *asset = [self.assetsArray objectAtIndex:_currentPage]; 170 | NSURL *assetURL = [asset valueForProperty:ALAssetPropertyAssetURL]; 171 | self.checkButton.selected = [self assetIsSelected:assetURL]; 172 | } 173 | 174 | #pragma mark - setter 175 | - (void)setAssetsArray:(NSMutableArray *)assetsArray{ 176 | if (_assetsArray != assetsArray) { 177 | _assetsArray = assetsArray; 178 | 179 | [self reloadPhotoeData]; 180 | } 181 | } 182 | 183 | #pragma mark - getter 184 | - (UICollectionView *)collectionView{ 185 | if (!_collectionView) { 186 | UICollectionViewFlowLayout *layout = [[UICollectionViewFlowLayout alloc] init]; 187 | layout.minimumLineSpacing = 0.0; 188 | layout.minimumInteritemSpacing = 0.0; 189 | layout.scrollDirection = UICollectionViewScrollDirectionHorizontal; 190 | 191 | _collectionView = [[UICollectionView alloc] initWithFrame:CGRectMake(-10, 0, self.bounds.size.width+20, self.bounds.size.height) collectionViewLayout:layout]; 192 | _collectionView.backgroundColor = [UIColor clearColor]; 193 | [_collectionView registerClass:[JKPhotoBrowserCell class] forCellWithReuseIdentifier:kJKPhotoBrowserCellIdentifier]; 194 | _collectionView.delegate = self; 195 | _collectionView.dataSource = self; 196 | _collectionView.pagingEnabled = YES; 197 | _collectionView.showsHorizontalScrollIndicator = NO; 198 | _collectionView.showsVerticalScrollIndicator = NO; 199 | [self addSubview:_collectionView]; 200 | 201 | } 202 | return _collectionView; 203 | } 204 | 205 | - (UILabel *)numberLabel{ 206 | if (!_numberLabel) { 207 | _numberLabel = [[UILabel alloc] initWithFrame:CGRectMake(floor((CGRectGetWidth(self.frame)-100)/2), 32, 100, 20)]; 208 | _numberLabel.backgroundColor = [UIColor clearColor]; 209 | _numberLabel.textColor = [UIColor whiteColor]; 210 | _numberLabel.textAlignment = NSTextAlignmentCenter; 211 | _numberLabel.font = [UIFont systemFontOfSize:17.0f]; 212 | _numberLabel.text = @"0/0"; 213 | } 214 | return _numberLabel; 215 | } 216 | 217 | - (UIView *)topView{ 218 | if (!_topView) { 219 | _topView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, CGRectGetWidth(self.frame), 64)]; 220 | _topView.backgroundColor = [UIColor colorWithWhite:0.0 alpha:0.8]; 221 | [_topView addSubview:self.numberLabel]; 222 | 223 | UIImage *img = [UIImage imageNamed:@"camera_edit_cut_cancel"]; 224 | UIImage *imgHigh = [UIImage imageNamed:@"camera_edit_cut_cancel_highlighted"]; 225 | UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom]; 226 | button.frame = CGRectMake(10, 20+floor((44-img.size.height)/2), img.size.width, img.size.height); 227 | [button setBackgroundImage:img forState:UIControlStateNormal]; 228 | [button setBackgroundImage:imgHigh forState:UIControlStateHighlighted]; 229 | [button addTarget:self action:@selector(closePhotoBrower) forControlEvents:UIControlEventTouchUpInside]; 230 | [_topView addSubview:button]; 231 | 232 | _checkButton = [UIButton buttonWithType:UIButtonTypeCustom]; 233 | UIImage *img1 = [UIImage imageNamed:@"photo_check_default"]; 234 | UIImage *imgH = [UIImage imageNamed:@"photo_check_selected"]; 235 | _checkButton.frame = CGRectMake(0, 0, img1.size.width, img1.size.height); 236 | [_checkButton setBackgroundImage:img1 forState:UIControlStateNormal]; 237 | [_checkButton setBackgroundImage:imgH forState:UIControlStateSelected]; 238 | [_checkButton addTarget:self action:@selector(photoDidChecked) forControlEvents:UIControlEventTouchUpInside]; 239 | _checkButton.exclusiveTouch = YES; 240 | _checkButton.right = self.width-10; 241 | _checkButton.centerY = button.centerY; 242 | [_topView addSubview:_checkButton]; 243 | 244 | [self addSubview:_topView]; 245 | } 246 | return _topView; 247 | } 248 | 249 | @end 250 | -------------------------------------------------------------------------------- /QQImagesPicker/ImagePicker/Classes/JKPhotoBrowserCell.h: -------------------------------------------------------------------------------- 1 | // 2 | // JKPhotoBrowserCell.h 3 | // JKPhotoBrowser 4 | // 5 | // Created by Jecky on 14/12/29. 6 | // Copyright (c) 2014年 Jecky. All rights reserved. 7 | // 8 | 9 | #import 10 | #import 11 | 12 | 13 | @interface JKPhotoBrowserCell : UICollectionViewCell 14 | 15 | @property (nonatomic, strong) UIImage *image; 16 | @property (nonatomic, strong) ALAsset *asset; 17 | 18 | @end 19 | -------------------------------------------------------------------------------- /QQImagesPicker/ImagePicker/Classes/JKPhotoBrowserCell.m: -------------------------------------------------------------------------------- 1 | // 2 | // JKPhotoBrowserCell.m 3 | // JKPhotoBrowser 4 | // 5 | // Created by Jecky on 14/12/29. 6 | // Copyright (c) 2014年 Jecky. All rights reserved. 7 | // 8 | 9 | #import "JKPhotoBrowserCell.h" 10 | #import "UIView+JKPicker.h" 11 | 12 | @interface JKPhotoBrowserCell() 13 | 14 | @property (nonatomic, strong) UIScrollView *scrollView; 15 | @property (nonatomic, strong) UIImageView *imageView; 16 | 17 | @end 18 | 19 | @implementation JKPhotoBrowserCell 20 | 21 | - (instancetype)initWithFrame:(CGRect)frame 22 | { 23 | self = [super initWithFrame:frame]; 24 | 25 | if (self) { 26 | // Create a image view 27 | self.backgroundColor = [UIColor clearColor]; 28 | 29 | [self scrollView]; 30 | [self imageView]; 31 | 32 | self.autoresizesSubviews = YES; 33 | } 34 | 35 | return self; 36 | } 37 | 38 | - (void)prepareForReuse{ 39 | [super prepareForReuse]; 40 | 41 | [self.scrollView setZoomScale:1.0]; 42 | 43 | } 44 | 45 | #pragma mark- setter 46 | - (void)setAsset:(ALAsset *)asset{ 47 | if (_asset != asset) { 48 | _asset = asset; 49 | 50 | self.image = [UIImage imageWithCGImage:[[asset defaultRepresentation] fullScreenImage]]; 51 | } 52 | } 53 | 54 | - (void)setImage:(UIImage *)image{ 55 | if (image != _image) { 56 | _image = image; 57 | 58 | CGSize maxSize = self.scrollView.size; 59 | CGFloat widthRatio = maxSize.width/image.size.width; 60 | CGFloat heightRatio = maxSize.height/image.size.height; 61 | CGFloat initialZoom = (widthRatio > heightRatio) ? heightRatio : widthRatio; 62 | 63 | if (initialZoom > 1) { 64 | initialZoom = 1; 65 | } 66 | 67 | CGRect r = self.scrollView.frame; 68 | r.size.width = image.size.width * initialZoom; 69 | r.size.height = image.size.height * initialZoom; 70 | self.imageView.frame = r; 71 | self.imageView.center = CGPointMake(self.scrollView.width/2, self.scrollView.height/2); 72 | self.imageView.image = image; 73 | 74 | [self.scrollView setMinimumZoomScale:initialZoom]; 75 | [self.scrollView setMaximumZoomScale:5]; 76 | [self.scrollView setZoomScale:1.0]; 77 | } 78 | } 79 | 80 | #pragma mark- scroll 81 | - (void)scrollViewDidZoom:(UIScrollView *)scrollView 82 | { 83 | CGFloat offsetX = (scrollView.bounds.size.width > scrollView.contentSize.width)? 84 | (scrollView.bounds.size.width - scrollView.contentSize.width) * 0.5 : 0.0; 85 | 86 | CGFloat offsetY = (scrollView.bounds.size.height > scrollView.contentSize.height)? 87 | (scrollView.bounds.size.height - scrollView.contentSize.height) * 0.5 : 0.0; 88 | 89 | self.imageView.center = CGPointMake(scrollView.contentSize.width * 0.5 + offsetX, 90 | scrollView.contentSize.height * 0.5 + offsetY); 91 | } 92 | 93 | - (UIView *)viewForZoomingInScrollView:(UIScrollView *)scrollView 94 | { 95 | return self.imageView; 96 | } 97 | 98 | #pragma mark- getter 99 | - (UIScrollView *)scrollView 100 | { 101 | if (!_scrollView) { 102 | _scrollView = [[UIScrollView alloc] initWithFrame:CGRectMake(10, 0, self.frame.size.width-20, self.frame.size.height)]; 103 | _scrollView.delegate = self; 104 | _scrollView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleWidth; 105 | _scrollView.showsHorizontalScrollIndicator = NO; 106 | _scrollView.showsVerticalScrollIndicator = NO; 107 | [self addSubview:_scrollView]; 108 | } 109 | return _scrollView; 110 | } 111 | 112 | - (UIImageView *)imageView 113 | { 114 | if (!_imageView) { 115 | _imageView = [[UIImageView alloc] initWithFrame:CGRectZero]; 116 | _imageView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleWidth; 117 | [self.scrollView addSubview:_imageView]; 118 | } 119 | 120 | return _imageView; 121 | } 122 | 123 | @end 124 | -------------------------------------------------------------------------------- /QQImagesPicker/ImagePicker/Classes/JKPromptView.h: -------------------------------------------------------------------------------- 1 | // 2 | // JKPromptView.h 3 | // JKImagePicker 4 | // 5 | // Created by Jecky on 15/1/12. 6 | // Copyright (c) 2015年 Jecky. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface JKPromptView : UIWindow 12 | 13 | + (void)showWithImageName:(NSString*)imageName message:(NSString *)string; 14 | 15 | @end 16 | -------------------------------------------------------------------------------- /QQImagesPicker/ImagePicker/Classes/JKPromptView.m: -------------------------------------------------------------------------------- 1 | // 2 | // JKPromptView.m 3 | // JKImagePicker 4 | // 5 | // Created by Jecky on 15/1/12. 6 | // Copyright (c) 2015年 Jecky. All rights reserved. 7 | // 8 | 9 | #import "JKPromptView.h" 10 | #import "UIView+JKPicker.h" 11 | 12 | static JKPromptView *instancePrompt; 13 | 14 | @implementation JKPromptView 15 | 16 | - (instancetype)initWithImageName:(NSString*)imageName message:(NSString *)string 17 | { 18 | self = [super init]; 19 | if (self) { 20 | self.hidden = NO; 21 | self.alpha = 1.0f; 22 | self.windowLevel = UIWindowLevelStatusBar + 1.0f; 23 | 24 | self.backgroundColor = [UIColor colorWithRed:0x17/255.0f green:0x17/255.0 blue:0x17/255.0 alpha:0.9]; 25 | self.layer.masksToBounds = YES; 26 | self.layer.cornerRadius = 4; 27 | 28 | UIImage *img = [UIImage imageNamed:imageName]; 29 | UIImageView *imageView = [[UIImageView alloc] initWithImage:img]; 30 | imageView.backgroundColor = [UIColor clearColor]; 31 | [self addSubview:imageView]; 32 | 33 | UILabel *label = [[UILabel alloc] init]; 34 | label.font = [UIFont systemFontOfSize:14]; 35 | label.backgroundColor = [UIColor clearColor]; 36 | label.textColor = [UIColor whiteColor]; 37 | label.textAlignment = NSTextAlignmentCenter; 38 | label.numberOfLines = 0; 39 | label.text = string; 40 | [label sizeToFit]; 41 | [self addSubview:label]; 42 | 43 | if (imageView.width 10 | #import 11 | 12 | @interface JKUtil : NSObject 13 | 14 | + (UIImage*)loadImageFromBundle:(NSString*)relativePath; 15 | + (UIImage *)stretchImage:(UIImage *)image 16 | capInsets:(UIEdgeInsets)capInsets 17 | resizingMode:(UIImageResizingMode)resizingMode; 18 | 19 | + (UIColor *)getColor:(NSString *)hexColor; 20 | 21 | @end 22 | -------------------------------------------------------------------------------- /QQImagesPicker/ImagePicker/Classes/JKUtil.m: -------------------------------------------------------------------------------- 1 | // 2 | // JKUtil.m 3 | // JKImagePicker 4 | // 5 | // Created by Jecky on 15/1/10. 6 | // Copyright (c) 2015年 Jecky. All rights reserved. 7 | // 8 | 9 | #import "JKUtil.h" 10 | 11 | @implementation JKUtil 12 | 13 | + (UIImage*)loadImageFromBundle:(NSString*)relativePath { 14 | NSString *path = [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:relativePath]; 15 | return [UIImage imageWithContentsOfFile:path]; 16 | } 17 | 18 | + (UIImage *)stretchImage:(UIImage *)image 19 | capInsets:(UIEdgeInsets)capInsets 20 | resizingMode:(UIImageResizingMode)resizingMode 21 | { 22 | UIImage *resultImage = nil; 23 | double systemVersion = [[UIDevice currentDevice].systemVersion doubleValue]; 24 | if (systemVersion <5.0) { 25 | resultImage = [image stretchableImageWithLeftCapWidth:capInsets.left topCapHeight:capInsets.right]; 26 | }else if (systemVersion<6.0){ 27 | resultImage = [image resizableImageWithCapInsets:capInsets]; 28 | }else{ 29 | resultImage = [image resizableImageWithCapInsets:capInsets resizingMode:resizingMode]; 30 | } 31 | return resultImage; 32 | } 33 | 34 | + (UIColor *)getColor:(NSString *)hexColor 35 | { 36 | unsigned int redInt_, greenInt_, blueInt_; 37 | NSRange rangeNSRange_; 38 | rangeNSRange_.length = 2; // 范围长度为2 39 | 40 | // 取红色的值 41 | rangeNSRange_.location = 0; 42 | [[NSScanner scannerWithString:[hexColor substringWithRange:rangeNSRange_]] scanHexInt:&redInt_]; 43 | 44 | // 取绿色的值 45 | rangeNSRange_.location = 2; 46 | [[NSScanner scannerWithString:[hexColor substringWithRange:rangeNSRange_]] scanHexInt:&greenInt_]; 47 | 48 | // 取蓝色的值 49 | rangeNSRange_.location = 4; 50 | [[NSScanner scannerWithString:[hexColor substringWithRange:rangeNSRange_]] scanHexInt:&blueInt_]; 51 | 52 | return [UIColor colorWithRed:(float)(redInt_/255.0f) green:(float)(greenInt_/255.0f) blue:(float)(blueInt_/255.0f) alpha:1.0f]; 53 | 54 | } 55 | 56 | @end 57 | -------------------------------------------------------------------------------- /QQImagesPicker/ImagePicker/Classes/PhotoAlbumManager.h: -------------------------------------------------------------------------------- 1 | // 2 | // PhotoAlbumManager.h 3 | // JKImagePicker 4 | // 5 | // Created by Jecky on 15/1/16. 6 | // Copyright (c) 2015年 Jecky. All rights reserved. 7 | // 8 | 9 | #import 10 | #import 11 | #import 12 | 13 | typedef void(^SaveImageCompletion)(ALAsset *asset, NSError* error); 14 | 15 | @interface PhotoAlbumManager : NSObject 16 | 17 | + (PhotoAlbumManager *)sharedManager; 18 | 19 | -(void)saveImage:(UIImage*)image toAlbum:(NSString*)albumName completionBlock:(SaveImageCompletion)completionBlock; 20 | -(void)addAssetURL:(NSURL*)assetURL toAlbum:(NSString*)albumName completionBlock:(SaveImageCompletion)completionBlock; 21 | @end 22 | -------------------------------------------------------------------------------- /QQImagesPicker/ImagePicker/Classes/PhotoAlbumManager.m: -------------------------------------------------------------------------------- 1 | // 2 | // PhotoAlbumManager.m 3 | // JKImagePicker 4 | // 5 | // Created by Jecky on 15/1/16. 6 | // Copyright (c) 2015年 Jecky. All rights reserved. 7 | // 8 | 9 | #import "PhotoAlbumManager.h" 10 | 11 | #import "PhotoAlbumManager.h" 12 | 13 | @interface PhotoAlbumManager() 14 | 15 | @property (nonatomic, strong) ALAssetsLibrary *assetsLibrary; 16 | @end 17 | 18 | @implementation PhotoAlbumManager 19 | 20 | + (PhotoAlbumManager *)sharedManager; 21 | { 22 | static PhotoAlbumManager *photoAlbumManager = nil; 23 | static dispatch_once_t onceToken; 24 | dispatch_once(&onceToken, ^{ 25 | photoAlbumManager = [[PhotoAlbumManager alloc] init]; 26 | }); 27 | 28 | return photoAlbumManager; 29 | } 30 | 31 | - (id)init 32 | { 33 | self = [super init]; 34 | if (self) { 35 | 36 | } 37 | return self; 38 | } 39 | 40 | -(void)saveImage:(UIImage*)image toAlbum:(NSString*)albumName completionBlock:(SaveImageCompletion)completionBlock 41 | { 42 | __weak PhotoAlbumManager *weakSelf = self; 43 | [self.assetsLibrary writeImageToSavedPhotosAlbum:image.CGImage 44 | orientation:(ALAssetOrientation)image.imageOrientation 45 | completionBlock:^(NSURL *assetURL, NSError *error) { 46 | //error handling 47 | if (error!=nil) { 48 | completionBlock(nil, error); 49 | return; 50 | } 51 | //add the asset to the custom photo album 52 | PhotoAlbumManager *strongSelf = weakSelf; 53 | [strongSelf addAssetURL:assetURL 54 | toAlbum:albumName 55 | completionBlock:completionBlock]; 56 | 57 | }]; 58 | 59 | } 60 | 61 | -(void)addAssetURL:(NSURL*)assetURL toAlbum:(NSString*)albumName completionBlock:(SaveImageCompletion)completionBlock 62 | { 63 | __weak PhotoAlbumManager *weakSelf = self; 64 | __block BOOL albumWasFound = NO; 65 | 66 | [self.assetsLibrary enumerateGroupsWithTypes:ALAssetsGroupAll 67 | usingBlock:^(ALAssetsGroup *group, BOOL *stop) { 68 | PhotoAlbumManager *strongSelf = weakSelf; 69 | //compare the names of the albums 70 | if ([albumName compare: [group valueForProperty:ALAssetsGroupPropertyName]]==NSOrderedSame) { 71 | 72 | //target album is found 73 | albumWasFound = YES; 74 | 75 | //get a hold of the photo's asset instance 76 | [strongSelf.assetsLibrary assetForURL: assetURL 77 | resultBlock:^(ALAsset *asset) { 78 | //add photo to the target album 79 | [group addAsset: asset]; 80 | //run the completion block 81 | completionBlock(asset,nil); 82 | 83 | } failureBlock:^(NSError *error) { 84 | completionBlock(nil,error); 85 | }]; 86 | 87 | //album was found, bail out of the method 88 | *stop = YES; 89 | return; 90 | } 91 | 92 | if (group==nil && albumWasFound==NO) { 93 | //photo albums are over, target album does not exist, thus create it 94 | //create new assets album 95 | 96 | __weak ALAssetsLibrary *weakLibray = strongSelf.assetsLibrary; 97 | 98 | [strongSelf.assetsLibrary addAssetsGroupAlbumWithName:albumName 99 | resultBlock:^(ALAssetsGroup *group) { 100 | //get the photo's instance 101 | [weakLibray assetForURL:assetURL 102 | resultBlock:^(ALAsset *asset) { 103 | //add photo to the newly created album 104 | [group addAsset: asset]; 105 | 106 | //call the completion block 107 | completionBlock(asset,nil); 108 | } failureBlock:^(NSError *error) { 109 | completionBlock(nil,error); 110 | }]; 111 | 112 | } failureBlock:^(NSError *error) { 113 | completionBlock(nil,error); 114 | }]; 115 | 116 | //should be the last iteration anyway, but just in case 117 | *stop = YES; 118 | return; 119 | } 120 | 121 | } failureBlock:^(NSError *error) { 122 | completionBlock(nil,error); 123 | 124 | }]; 125 | } 126 | 127 | #pragma mark - getter 128 | - (ALAssetsLibrary *)assetsLibrary{ 129 | if (!_assetsLibrary) { 130 | _assetsLibrary = [[ALAssetsLibrary alloc] init]; 131 | } 132 | return _assetsLibrary; 133 | } 134 | 135 | @end 136 | -------------------------------------------------------------------------------- /QQImagesPicker/ImagePicker/Classes/UIView+JKPicker.h: -------------------------------------------------------------------------------- 1 | // 2 | // UIView+JKPicker.h 3 | // JKImagePicker 4 | // 5 | // Created by Jecky on 15/1/11. 6 | // Copyright (c) 2015年 Jecky. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface UIView (JKPicker) 12 | 13 | @property (nonatomic) CGFloat left; 14 | @property (nonatomic) CGFloat top; 15 | @property (nonatomic) CGFloat right; 16 | @property (nonatomic) CGFloat bottom; 17 | @property (nonatomic) CGFloat width; 18 | @property (nonatomic) CGFloat height; 19 | 20 | @property (nonatomic) CGFloat centerX; 21 | @property (nonatomic) CGFloat centerY; 22 | 23 | @property (nonatomic) CGPoint origin; 24 | @property (nonatomic) CGSize size; 25 | 26 | @end 27 | -------------------------------------------------------------------------------- /QQImagesPicker/ImagePicker/Classes/UIView+JKPicker.m: -------------------------------------------------------------------------------- 1 | // 2 | // UIView+JKPicker.m 3 | // JKImagePicker 4 | // 5 | // Created by Jecky on 15/1/11. 6 | // Copyright (c) 2015年 Jecky. All rights reserved. 7 | // 8 | 9 | #import "UIView+JKPicker.h" 10 | 11 | @implementation UIView (JKPicker) 12 | 13 | - (CGFloat)left { 14 | return self.frame.origin.x; 15 | } 16 | 17 | - (void)setLeft:(CGFloat)x { 18 | CGRect frame = self.frame; 19 | frame.origin.x = x; 20 | self.frame = frame; 21 | } 22 | 23 | - (CGFloat)top { 24 | return self.frame.origin.y; 25 | } 26 | 27 | - (void)setTop:(CGFloat)y { 28 | CGRect frame = self.frame; 29 | frame.origin.y = y; 30 | self.frame = frame; 31 | } 32 | 33 | - (CGFloat)right { 34 | return self.frame.origin.x + self.frame.size.width; 35 | } 36 | 37 | - (void)setRight:(CGFloat)right { 38 | CGRect frame = self.frame; 39 | frame.origin.x = right - frame.size.width; 40 | self.frame = frame; 41 | } 42 | 43 | - (CGFloat)bottom { 44 | return self.frame.origin.y + self.frame.size.height; 45 | } 46 | 47 | - (void)setBottom:(CGFloat)bottom { 48 | CGRect frame = self.frame; 49 | frame.origin.y = bottom - frame.size.height; 50 | self.frame = frame; 51 | } 52 | 53 | - (CGFloat)centerX { 54 | return self.center.x; 55 | } 56 | 57 | - (void)setCenterX:(CGFloat)centerX { 58 | self.center = CGPointMake(centerX, self.center.y); 59 | } 60 | 61 | - (CGFloat)centerY { 62 | return self.center.y; 63 | } 64 | 65 | - (void)setCenterY:(CGFloat)centerY { 66 | self.center = CGPointMake(self.center.x, centerY); 67 | } 68 | 69 | - (CGFloat)width { 70 | return self.frame.size.width; 71 | } 72 | 73 | - (void)setWidth:(CGFloat)width { 74 | CGRect frame = self.frame; 75 | frame.size.width = width; 76 | self.frame = frame; 77 | } 78 | 79 | - (CGFloat)height { 80 | return self.frame.size.height; 81 | } 82 | 83 | - (void)setHeight:(CGFloat)height { 84 | CGRect frame = self.frame; 85 | frame.size.height = height; 86 | self.frame = frame; 87 | } 88 | 89 | - (CGPoint)origin { 90 | return self.frame.origin; 91 | } 92 | 93 | - (void)setOrigin:(CGPoint)origin { 94 | CGRect frame = self.frame; 95 | frame.origin = origin; 96 | self.frame = frame; 97 | } 98 | 99 | - (CGSize)size { 100 | return self.frame.size; 101 | } 102 | 103 | - (void)setSize:(CGSize)size { 104 | CGRect frame = self.frame; 105 | frame.size = size; 106 | self.frame = frame; 107 | } 108 | 109 | @end 110 | 111 | -------------------------------------------------------------------------------- /QQImagesPicker/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 | APPL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleVersion 20 | 1 21 | LSRequiresIPhoneOS 22 | 23 | NSAppleMusicUsageDescription 24 | App需要您的同意,才能访问媒体资料库 25 | NSBluetoothPeripheralUsageDescription 26 | App需要您的同意,才能访问蓝牙 27 | NSCalendarsUsageDescription 28 | App需要您的同意,才能访问日历 29 | NSCameraUsageDescription 30 | App需要您的同意,才能访问相机 31 | NSHealthShareUsageDescription 32 | App需要您的同意,才能访问健康分享 33 | NSHealthUpdateUsageDescription 34 | App需要您的同意,才能访问健康更新 35 | NSLocationAlwaysUsageDescription 36 | App需要您的同意,才能始终访问位置 37 | NSLocationUsageDescription 38 | App需要您的同意,才能访问位置 39 | NSLocationWhenInUseUsageDescription 40 | App需要您的同意,才能在使用期间访问位置 41 | NSMicrophoneUsageDescription 42 | App需要您的同意,才能访问麦克风 43 | NSMotionUsageDescription 44 | App需要您的同意,才能访问运动与健身 45 | NSPhotoLibraryUsageDescription 46 | App需要您的同意,才能访问相册 47 | NSRemindersUsageDescription 48 | App需要您的同意,才能访问提醒事项 49 | UILaunchStoryboardName 50 | LaunchScreen 51 | UIRequiredDeviceCapabilities 52 | 53 | armv7 54 | 55 | UISupportedInterfaceOrientations 56 | 57 | UIInterfaceOrientationPortrait 58 | 59 | UISupportedInterfaceOrientations~ipad 60 | 61 | UIInterfaceOrientationPortrait 62 | UIInterfaceOrientationPortraitUpsideDown 63 | UIInterfaceOrientationLandscapeLeft 64 | UIInterfaceOrientationLandscapeRight 65 | 66 | 67 | 68 | -------------------------------------------------------------------------------- /QQImagesPicker/QQCompose/QQComposeAddPhotoViewCell.h: -------------------------------------------------------------------------------- 1 | // 2 | // QQComposeAddPhotoViewCell.h 3 | // 访问相册和相机 4 | // 5 | // Created by lqq on 16/4/14. 6 | // Copyright © 2016年 LQQ. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface QQComposeAddPhotoViewCell : UICollectionViewCell 12 | @property (nonatomic, strong) UIButton *addButton; 13 | @end 14 | -------------------------------------------------------------------------------- /QQImagesPicker/QQCompose/QQComposeAddPhotoViewCell.m: -------------------------------------------------------------------------------- 1 | // 2 | // QQComposeAddPhotoViewCell.m 3 | // 访问相册和相机 4 | // 5 | // Created by lqq on 16/4/14. 6 | // Copyright © 2016年 LQQ. All rights reserved. 7 | // 8 | 9 | #import "QQComposeAddPhotoViewCell.h" 10 | 11 | @implementation QQComposeAddPhotoViewCell 12 | 13 | - (instancetype)initWithFrame:(CGRect)frame 14 | { 15 | self = [super initWithFrame:frame]; 16 | if (self) { 17 | UIImage *img = [UIImage imageNamed:@"compose_pic_add"]; 18 | UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom]; 19 | button.frame = CGRectMake(0, 0, frame.size.width, frame.size.height); 20 | [button setBackgroundImage:img forState:UIControlStateNormal]; 21 | self.addButton = button; 22 | [self addSubview:button]; 23 | } 24 | return self; 25 | } 26 | @end 27 | -------------------------------------------------------------------------------- /QQImagesPicker/QQCompose/QQComposePhotoViewCell.h: -------------------------------------------------------------------------------- 1 | // 2 | // QQComposePhotoViewCell.h 3 | // 访问相册和相机 4 | // 5 | // Created by lqq on 16/4/13. 6 | // Copyright © 2016年 LQQ. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "JKAssets.h" 11 | @interface QQComposePhotoViewCell : UICollectionViewCell 12 | 13 | @property (nonatomic, strong) JKAssets *asset; 14 | @property (nonatomic, weak) UIButton *deletePhotoButton; 15 | @property (nonatomic, strong) NSIndexPath *indexpath; 16 | @property (nonatomic, strong) UIImageView *imageView; 17 | @end 18 | -------------------------------------------------------------------------------- /QQImagesPicker/QQCompose/QQComposePhotoViewCell.m: -------------------------------------------------------------------------------- 1 | // 2 | // QQComposePhotoViewCell.m 3 | // 访问相册和相机 4 | // 5 | // Created by lqq on 16/4/13. 6 | // Copyright © 2016年 LQQ. All rights reserved. 7 | // 8 | 9 | #import "QQComposePhotoViewCell.h" 10 | #import 11 | @implementation QQComposePhotoViewCell 12 | 13 | - (instancetype)initWithFrame:(CGRect)frame 14 | { 15 | self = [super initWithFrame:frame]; 16 | if (self) { 17 | self.backgroundColor = [UIColor clearColor]; 18 | [self imageView]; 19 | } 20 | return self; 21 | } 22 | 23 | 24 | - (void)setAsset:(JKAssets *)asset { 25 | if (_asset != asset) { 26 | _asset = asset; 27 | self.imageView.image = asset.photo; 28 | } 29 | } 30 | - (UIImageView *)imageView { 31 | if (!_imageView) { 32 | _imageView = [[UIImageView alloc] initWithFrame:self.contentView.bounds]; 33 | _imageView.backgroundColor = [UIColor clearColor]; 34 | _imageView.clipsToBounds = YES; 35 | _imageView.autoresizingMask = UIViewAutoresizingFlexibleWidth |UIViewAutoresizingFlexibleHeight; 36 | _imageView.layer.cornerRadius = 6.0f; 37 | _imageView.layer.borderColor = [UIColor clearColor].CGColor; 38 | _imageView.layer.borderWidth = 0.5; 39 | UIButton *buttonClose = [UIButton buttonWithType:UIButtonTypeCustom]; 40 | UIImageView *imgCloseButton = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, 25, 25)]; 41 | imgCloseButton.image = [UIImage imageNamed:@"compose_photo_close.png"]; 42 | [buttonClose addSubview:imgCloseButton]; 43 | buttonClose.frame = CGRectMake(_imageView.frame.origin.x + self.contentView.frame.size.width - 25, 0, 25, 25); 44 | self.deletePhotoButton = buttonClose; 45 | [self.contentView addSubview:_imageView]; 46 | [self.contentView addSubview:buttonClose]; 47 | } 48 | return _imageView; 49 | } 50 | @end 51 | -------------------------------------------------------------------------------- /QQImagesPicker/QQCompose/QQComposePhotosView.h: -------------------------------------------------------------------------------- 1 | // 2 | // QQComposePhotosView.h 3 | // 访问相册和相机 4 | // 5 | // Created by lqq on 16/4/13. 6 | // Copyright © 2016年 LQQ. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | 12 | 13 | @protocol QQComposePhotosViewDelegate 14 | /** 15 | * 响应添加照片按键 16 | */ 17 | - (void)addButtonClicked; 18 | 19 | @end 20 | @interface QQComposePhotosView : UIView 21 | @property (nonatomic, strong) id delegate; 22 | 23 | /** 24 | * 保存相册或相机返回的数据 25 | */ 26 | @property (nonatomic, strong) NSMutableArray *assetsArray; 27 | /** 28 | * 添加照片按键 29 | */ 30 | @property (nonatomic, strong) UIButton *addButton; 31 | /** 32 | * 用于显示九宫格 33 | */ 34 | @property (nonatomic, strong) UICollectionView *collectionView; 35 | @end 36 | -------------------------------------------------------------------------------- /QQImagesPicker/QQCompose/QQComposePhotosView.m: -------------------------------------------------------------------------------- 1 | // 2 | // QQComposePhotosView.m 3 | // 访问相册和相机 4 | // 5 | // Created by lqq on 16/4/13. 6 | // Copyright © 2016年 LQQ. All rights reserved. 7 | // 8 | 9 | #import "QQComposePhotosView.h" 10 | #import "JKImagePickerController.h" 11 | #import 12 | #import "QQComposePhotoViewCell.h" 13 | #import "QQComposeAddPhotoViewCell.h" 14 | @interface QQComposePhotosView () 15 | 16 | @end 17 | @implementation QQComposePhotosView 18 | 19 | static NSString *kPhotoCellIdentifier = @"kPhotoCellIdentifier"; 20 | static NSString *kAddPhotoCellIdentifier = @"kAddPhotoCellIdentifier"; 21 | 22 | - (instancetype)initWithFrame:(CGRect)frame 23 | { 24 | self = [super initWithFrame:frame]; 25 | if (self) { 26 | UICollectionViewFlowLayout *layout = [[UICollectionViewFlowLayout alloc] init]; 27 | layout.minimumLineSpacing = 5.0; 28 | layout.minimumInteritemSpacing = 5.0; 29 | _collectionView = [[UICollectionView alloc] initWithFrame:CGRectMake(15, 5, frame.size.width - 30, frame.size.height - 10) collectionViewLayout:layout]; 30 | _collectionView.backgroundColor = [UIColor clearColor]; 31 | _collectionView.delegate = self; 32 | _collectionView.dataSource = self; 33 | _collectionView.showsHorizontalScrollIndicator = NO; 34 | _collectionView.showsVerticalScrollIndicator = NO; 35 | [_collectionView registerClass:[QQComposePhotoViewCell class] forCellWithReuseIdentifier:kPhotoCellIdentifier]; 36 | [_collectionView registerClass:[QQComposeAddPhotoViewCell class] forCellWithReuseIdentifier:kAddPhotoCellIdentifier]; 37 | [self addSubview:_collectionView]; 38 | 39 | //添加长按手势 40 | UILongPressGestureRecognizer *longGesture = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:@selector(handleLongGesture:)]; 41 | [_collectionView addGestureRecognizer:longGesture]; 42 | } 43 | return self; 44 | } 45 | 46 | - (void)runInMainQueue:(void (^)())queue { 47 | dispatch_async(dispatch_get_main_queue(), queue); 48 | } 49 | - (void)runInGlobalQueue:(void(^)())queue { 50 | dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), queue); 51 | } 52 | 53 | - (BOOL)endEditing:(BOOL)force { 54 | [super endEditing:false]; 55 | [_collectionView endEditing:YES]; 56 | return YES; 57 | } 58 | 59 | #pragma mark - UICollectionViewDelegateFlowLayout 60 | // 设置Item的size 61 | - (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath { 62 | CGFloat width = ([UIScreen mainScreen].bounds.size.width - 30 - 15) / 3; 63 | return CGSizeMake(width, width); 64 | } 65 | #pragma mark - UICollectionViewDataSource 66 | - (NSInteger)numberOfSectionsInCollectionView:(UICollectionView *)collectionView { 67 | return 1; 68 | } 69 | - (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section { 70 | if (self.assetsArray.count == 9) { 71 | return 9; 72 | } else { 73 | return self.assetsArray.count + 1; 74 | } 75 | } 76 | - (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath { 77 | 78 | if (self.assetsArray.count != 0 && indexPath.row < self.assetsArray.count) { 79 | QQComposePhotoViewCell *cell = (QQComposePhotoViewCell *)[collectionView dequeueReusableCellWithReuseIdentifier:kPhotoCellIdentifier forIndexPath:indexPath]; 80 | cell.asset = self.assetsArray[indexPath.row]; 81 | cell.deletePhotoButton.tag = indexPath.row; 82 | cell.indexpath = indexPath; 83 | [cell.deletePhotoButton addTarget:self action:@selector(deleteView:) forControlEvents:UIControlEventTouchUpInside]; 84 | return cell; 85 | } 86 | QQComposeAddPhotoViewCell *cell = (QQComposeAddPhotoViewCell *)[collectionView dequeueReusableCellWithReuseIdentifier:kAddPhotoCellIdentifier forIndexPath:indexPath]; 87 | self.addButton = cell.addButton; 88 | [self.addButton addTarget:self action:@selector(addButtonAction) forControlEvents:UIControlEventTouchUpInside]; 89 | return cell; 90 | } 91 | - (BOOL)collectionView:(UICollectionView *)collectionView canMoveItemAtIndexPath:(NSIndexPath *)indexPath { 92 | return YES; 93 | } 94 | - (void)collectionView:(UICollectionView *)collectionView moveItemAtIndexPath:(NSIndexPath *)sourceIndexPath toIndexPath:(NSIndexPath *)destinationIndexPath { 95 | //取得item数据 96 | id objc = [self.assetsArray objectAtIndex:sourceIndexPath.item]; 97 | //从资源数组中移除 98 | [self.assetsArray removeObject:objc]; 99 | //将数据插入到目标位置 100 | [self.assetsArray insertObject:objc atIndex:destinationIndexPath.item]; 101 | } 102 | /** 103 | * 长按图片可以调整顺序 104 | */ 105 | - (void)handleLongGesture:(UILongPressGestureRecognizer *)sender { 106 | switch (sender.state) { 107 | case UIGestureRecognizerStateBegan: { 108 | //判断手势落点是否在路径上 109 | NSIndexPath *indexPath = [self.collectionView indexPathForItemAtPoint:[sender locationInView:self.collectionView]]; 110 | id objc = [self.collectionView cellForItemAtIndexPath:indexPath]; 111 | 112 | //当时添加的cell时不可以移动 113 | if (indexPath == nil || [objc isKindOfClass: [QQComposeAddPhotoViewCell class]]) { 114 | break; 115 | } 116 | //在路径上则开始移动该路径上的cell 117 | [self.collectionView beginInteractiveMovementForItemAtIndexPath:indexPath]; 118 | 119 | break; 120 | } 121 | case UIGestureRecognizerStateChanged: { 122 | //移动过程中随时更新cell位置 123 | NSIndexPath *indexPath = [self.collectionView indexPathForItemAtPoint:[sender locationInView:self.collectionView]]; 124 | id objc = [self.collectionView cellForItemAtIndexPath:indexPath]; 125 | if (indexPath == nil || [objc isKindOfClass: [QQComposeAddPhotoViewCell class]]) { 126 | break; 127 | } 128 | [self.collectionView updateInteractiveMovementTargetPosition:[sender locationInView:self.collectionView]]; 129 | break; 130 | } 131 | case UIGestureRecognizerStateEnded: { 132 | //移动结束后关闭cell移动 133 | [self.collectionView endInteractiveMovement]; 134 | break; 135 | } 136 | default: 137 | [self.collectionView cancelInteractiveMovement]; 138 | break; 139 | } 140 | } 141 | - (void)addButtonAction { 142 | if ([self.delegate respondsToSelector:@selector(addButtonClicked)]) { 143 | [self.delegate addButtonClicked]; 144 | } 145 | } 146 | - (void)deleteView:(id)sender { 147 | NSInteger deletedPhoto = ((UIButton *)sender).tag; 148 | [self.assetsArray removeObjectAtIndex:deletedPhoto]; 149 | [self.collectionView reloadData]; 150 | } 151 | @end 152 | -------------------------------------------------------------------------------- /QQImagesPicker/QQNUploadManager/QQQNSystemService.h: -------------------------------------------------------------------------------- 1 | // 2 | // QQQNSystemService.h 3 | // 上传图片 4 | // 5 | // Created by lqq on 16/4/14. 6 | // Copyright © 2016年 LQQ. All rights reserved. 7 | // 8 | 9 | #import 10 | #import 11 | #import 12 | @interface QQQNSystemService : NSObject 13 | @property (nonatomic, strong) NSString *token;//需要的token 14 | @property (nonatomic, strong) NSString *domain; 15 | /** 16 | * 上传单张图片 17 | * 18 | * @param image 需要上传的图片 19 | * @param progress 上传进度block 20 | * @param token 上传凭证 21 | * @param domain 上传的服务器地址 22 | * @param success 成功block 返回URL地址 23 | * @param failure 失败block 24 | */ 25 | + (void)qq_uploadImage:(UIImage *)image 26 | token:(NSString *)token 27 | domain:(NSString *)domain 28 | progress:(QNUpProgressHandler)progress 29 | success:(void (^)(NSString *url))success 30 | failure:(void(^)())failure; 31 | 32 | /** 33 | * 上传多张图片, 按队列依次上传 34 | * 35 | * @param imageArray 图片数组 36 | * @param token 上传凭证 37 | * @param domain 上传的服务器地址 38 | * @param progress 进度 39 | * @param success 成功返回 图片地址 40 | * @param failure 失败回调 41 | */ 42 | + (void)qq_uploadImages:(NSArray *)imageArray 43 | token:(NSString *)token 44 | domain:(NSString *)domain 45 | progress:(void (^)(CGFloat progress))progress 46 | success:(void (^)(NSArray *array))success 47 | failure:(void(^)())failure; 48 | /** 49 | * 将图片压缩为指定的比例 50 | * 51 | * @param image 需要处理的图片 52 | * @param size 图片大小 53 | * 54 | * @return image 55 | */ 56 | 57 | + (UIImage *)qq_originImage:(UIImage *)image 58 | scaleToSize:(CGSize)size; 59 | 60 | 61 | 62 | 63 | @end 64 | -------------------------------------------------------------------------------- /QQImagesPicker/QQNUploadManager/QQQNSystemService.m: -------------------------------------------------------------------------------- 1 | // 2 | // QQQNSystemService.m 3 | // 上传图片 4 | // 5 | // Created by lqq on 16/4/14. 6 | // Copyright © 2016年 LQQ. All rights reserved. 7 | // 8 | 9 | #import "QQQNSystemService.h" 10 | #import "QQQNUploadHelper.h" 11 | #import 12 | #import 13 | @interface QQQNSystemService () 14 | 15 | @end 16 | @implementation QQQNSystemService 17 | //token 和 domain 使用属性列表存 18 | 19 | + (QNUploadManager *) shareManager { 20 | static QNUploadManager *upManager; 21 | static dispatch_once_t onceToken; 22 | dispatch_once(&onceToken, ^{ 23 | upManager = [[QNUploadManager alloc] init]; 24 | }); 25 | return upManager; 26 | } 27 | 28 | +(void)qq_uploadImage:(UIImage *)image 29 | token:(NSString *)token 30 | domain:(NSString *)domain 31 | progress:(QNUpProgressHandler)progress 32 | success:(void (^)(NSString *))success 33 | failure:(void (^)())failure { 34 | UIImage *sizeImage = [QQQNSystemService qq_originImage:image scaleToSize:CGSizeMake(800, 900)]; 35 | NSData *data = UIImageJPEGRepresentation(sizeImage, 0.3); 36 | if (!data) { 37 | if (failure) { 38 | failure(); 39 | } 40 | return; 41 | } 42 | //只生成一次 43 | QNUploadManager *upManager = [[self class] shareManager]; 44 | //显示上传的百分比 45 | QNUploadOption *uploadOption = [[QNUploadOption alloc] initWithMime:nil progressHandler:^(NSString *key, float percent) { 46 | NSLog(@"percent == %.2f", percent); 47 | 48 | } params:nil checkCrc:NO cancellationSignal:nil]; 49 | 50 | [upManager putData:data key:nil token:token complete:^(QNResponseInfo *info, NSString *key, NSDictionary *resp) { 51 | 52 | 53 | if (info.statusCode == 200 && resp) { 54 | NSString *url = [NSString stringWithFormat:@"%@/%@", domain, resp[@"key"]]; 55 | NSLog(@"url === %@", url); 56 | if (success) { 57 | success(url); 58 | } 59 | } else { 60 | if (failure) { 61 | failure(); 62 | } 63 | } 64 | 65 | } option:uploadOption]; 66 | 67 | 68 | } 69 | 70 | + (void)qq_uploadImages:(NSArray *)imageArray token:(NSString *)token domain:(NSString *)domain progress:(void (^)(CGFloat))progress success:(void (^)(NSArray *))success failure:(void (^)())failure { 71 | if (0 == imageArray.count) { 72 | return; 73 | } 74 | NSMutableArray *array = [NSMutableArray array]; 75 | 76 | __block float totalProgress = 0.0f; 77 | __block float partProgress = 1.0f / [imageArray count]; 78 | __block NSUInteger currentIndex = 0; 79 | 80 | 81 | QQQNUploadHelper *uploadHelper = [QQQNUploadHelper sharedInstance]; 82 | __weak typeof(uploadHelper) weakHelper = uploadHelper; 83 | 84 | uploadHelper.singleFailureBlock = ^() { 85 | failure(); 86 | return ; 87 | }; 88 | 89 | uploadHelper.singleSuccessBlock = ^(NSString *url) { 90 | [array addObject:url]; 91 | totalProgress += partProgress; 92 | progress(totalProgress); 93 | 94 | currentIndex ++; 95 | NSLog(@"currentIndex == %ld", currentIndex); 96 | if (array.count == imageArray.count) { 97 | success([array copy]); 98 | return ; 99 | } else { 100 | [QQQNSystemService qq_uploadImage:imageArray[currentIndex] token:token domain:domain progress:nil success:weakHelper.singleSuccessBlock failure:weakHelper.singleFailureBlock]; 101 | } 102 | }; 103 | [QQQNSystemService qq_uploadImage:imageArray[0] token:token domain:domain progress:nil success:weakHelper.singleSuccessBlock failure:weakHelper.singleFailureBlock]; 104 | 105 | } 106 | //压缩上传图片的大小比例 107 | +(UIImage*)qq_originImage:(UIImage *)image scaleToSize:(CGSize)size{ 108 | UIGraphicsBeginImageContext(size); //size 为CGSize类型,即你所需要的图片尺寸 109 | 110 | [image drawInRect:CGRectMake(0, 0, size.width, size.height)]; 111 | 112 | UIImage* scaledImage = UIGraphicsGetImageFromCurrentImageContext(); 113 | 114 | UIGraphicsEndImageContext(); 115 | 116 | return scaledImage; //返回的就是已经改变的图片 117 | } 118 | @end 119 | 120 | -------------------------------------------------------------------------------- /QQImagesPicker/QQNUploadManager/QQQNUploadHelper.h: -------------------------------------------------------------------------------- 1 | // 2 | // QQQNUploadHelper.h 3 | // 4 | // 5 | // Created by lqq on 16/4/14. 6 | // 7 | // 8 | 9 | #import 10 | 11 | @interface QQQNUploadHelper : NSObject 12 | /** 13 | * 成功回调 14 | */ 15 | @property (nonatomic, copy) void (^singleSuccessBlock)(NSString *); 16 | /** 17 | * 失败回调 18 | */ 19 | @property (nonatomic, copy) void (^singleFailureBlock)(); 20 | + (instancetype)sharedInstance; 21 | @end 22 | -------------------------------------------------------------------------------- /QQImagesPicker/QQNUploadManager/QQQNUploadHelper.m: -------------------------------------------------------------------------------- 1 | // 2 | // QQQNUploadHelper.m 3 | // 4 | // 5 | // Created by lqq on 16/4/14. 6 | // 7 | // 8 | 9 | #import "QQQNUploadHelper.h" 10 | static QQQNUploadHelper *_sharedInstance; 11 | 12 | @implementation QQQNUploadHelper 13 | 14 | 15 | + (instancetype)sharedInstance { 16 | static dispatch_once_t onceToken; 17 | dispatch_once(&onceToken, ^{ 18 | _sharedInstance = [[QQQNUploadHelper alloc] init]; 19 | 20 | }); 21 | return _sharedInstance; 22 | } 23 | 24 | + (id)allocWithZone:(struct _NSZone *)zone { 25 | static dispatch_once_t onceToken; 26 | dispatch_once(&onceToken, ^{ 27 | _sharedInstance = [super allocWithZone:zone]; 28 | }); 29 | return _sharedInstance; 30 | } 31 | + (id)copyWithZone:(NSZone *)zone { 32 | return _sharedInstance; 33 | } 34 | @end 35 | -------------------------------------------------------------------------------- /QQImagesPicker/UIView+Extension.h: -------------------------------------------------------------------------------- 1 | // 2 | // UIView+Extension.h 3 | // 01-黑酷 4 | // 5 | // Created by apple on 14-6-27. 6 | // Copyright (c) 2014年 heima. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface UIView (Extension) 12 | @property (nonatomic, assign) CGFloat x; 13 | @property (nonatomic, assign) CGFloat y; 14 | @property (nonatomic, assign) CGFloat width; 15 | @property (nonatomic, assign) CGFloat height; 16 | @property (nonatomic, assign) CGSize size; 17 | @property (nonatomic, assign) CGFloat centerX; 18 | @property (nonatomic, assign) CGFloat centerY; 19 | 20 | @end 21 | -------------------------------------------------------------------------------- /QQImagesPicker/UIView+Extension.m: -------------------------------------------------------------------------------- 1 | // 2 | // UIView+Extension.m 3 | // 01-黑酷 4 | // 5 | // Created by apple on 14-6-27. 6 | // Copyright (c) 2014年 heima. All rights reserved. 7 | // 8 | 9 | #import "UIView+Extension.h" 10 | 11 | @implementation UIView (Extension) 12 | 13 | - (void)setX:(CGFloat)x 14 | { 15 | CGRect frame = self.frame; 16 | frame.origin.x = x; 17 | self.frame = frame; 18 | } 19 | 20 | - (CGFloat)x 21 | { 22 | return self.frame.origin.x; 23 | } 24 | 25 | - (void)setY:(CGFloat)y 26 | { 27 | CGRect frame = self.frame; 28 | frame.origin.y = y; 29 | self.frame = frame; 30 | } 31 | 32 | - (CGFloat)y 33 | { 34 | return self.frame.origin.y; 35 | } 36 | 37 | - (void)setWidth:(CGFloat)width 38 | { 39 | CGRect frame = self.frame; 40 | frame.size.width = width; 41 | self.frame = frame; 42 | } 43 | 44 | - (CGFloat)width 45 | { 46 | return self.frame.size.width; 47 | } 48 | 49 | - (void)setHeight:(CGFloat)height 50 | { 51 | CGRect frame = self.frame; 52 | frame.size.height = height; 53 | self.frame = frame; 54 | } 55 | 56 | - (void)setCenterX:(CGFloat)centerX 57 | { 58 | CGPoint center = self.center; 59 | center.x = centerX; 60 | self.center = center; 61 | } 62 | 63 | - (CGFloat)centerX 64 | { 65 | return self.center.x; 66 | } 67 | - (void)setCenterY:(CGFloat)centerY 68 | { 69 | CGPoint center = self.center; 70 | center.y = centerY; 71 | self.center = center; 72 | } 73 | 74 | - (CGFloat)centerY 75 | { 76 | return self.center.y; 77 | } 78 | 79 | - (CGFloat)height 80 | { 81 | return self.frame.size.height; 82 | } 83 | 84 | - (void)setSize:(CGSize)size 85 | { 86 | // self.width = size.width; 87 | // self.height = size.height; 88 | CGRect frame = self.frame; 89 | frame.size = size; 90 | self.frame = frame; 91 | } 92 | 93 | - (CGSize)size 94 | { 95 | return self.frame.size; 96 | } 97 | 98 | @end 99 | -------------------------------------------------------------------------------- /QQImagesPicker/ViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.h 3 | // QQImagesPicker 4 | // 5 | // Created by best-admin on 2017/3/21. 6 | // Copyright © 2017年 baisiChina. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface ViewController : UIViewController 12 | 13 | @end 14 | 15 | -------------------------------------------------------------------------------- /QQImagesPicker/ViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.m 3 | // QQImagesPicker 4 | // 5 | // Created by best-admin on 2017/3/21. 6 | // Copyright © 2017年 baisiChina. All rights reserved. 7 | // 8 | 9 | #import "ViewController.h" 10 | #import "JKImagePickerController.h" 11 | #import "QQComposePhotosView.h" 12 | #import "UIView+Extension.h" 13 | #import "QQQNSystemService.h" 14 | #import 15 | #import 16 | 17 | @interface ViewController () 18 | @property (nonatomic, strong) QQComposePhotosView *photosView; 19 | //@property (nonatomic, strong) NSMutableArray *images; 20 | @property (nonatomic, strong) NSString *domain; 21 | @property (nonatomic, strong) NSString *token; 22 | @end 23 | 24 | @implementation ViewController 25 | 26 | - (void)viewDidLoad { 27 | [super viewDidLoad]; 28 | self.title = @"长按调整图片位置"; 29 | self.view.backgroundColor = [UIColor whiteColor]; 30 | 31 | // Do any additional setup after loading the view, typically from a nib. 32 | self.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc] initWithTitle:@"上传" style:UIBarButtonItemStyleDone target:self action:@selector(updateImages)]; 33 | 34 | [self setUpPhotosView]; 35 | 36 | //这个是从后台获取的 域名和上传凭证 37 | //注意上传凭证最好生成时间片段的,不用每上传一个文件重新请求 38 | //***********************这里申请域名和上传凭证****************************// 39 | self.domain = @""; 40 | self.token = @""; 41 | //***************************************************// 42 | } 43 | /** 44 | * 图片显示View 45 | */ 46 | - (void)setUpPhotosView { 47 | self.photosView = [[QQComposePhotosView alloc] initWithFrame:CGRectMake(0, 0, [UIScreen mainScreen].bounds.size.width, 510)]; 48 | self.photosView.delegate = self; 49 | self.photosView.addButton.hidden = NO; 50 | [self.view addSubview:self.photosView]; 51 | } 52 | 53 | #pragma mark - JKImagePickerControllerDelegate 54 | 55 | - (void)addButtonClicked { 56 | JKImagePickerController *imagePicker = [[JKImagePickerController alloc] init]; 57 | imagePicker.delegate = self; 58 | imagePicker.showsCancelButton = YES; 59 | imagePicker.minimumNumberOfSelection = 1; 60 | imagePicker.maximumNumberOfSelection = 9; 61 | imagePicker.selectedAssetArray = self.photosView.assetsArray; 62 | 63 | 64 | UINavigationController *navigationController = [[UINavigationController alloc] initWithRootViewController:imagePicker]; 65 | [self presentViewController:navigationController animated:YES completion:nil]; 66 | } 67 | 68 | 69 | 70 | #pragma mark - JKImagePickerControllerDelegate 71 | - (void)imagePickerController:(JKImagePickerController *)imagePicker didSelectAsset:(JKAssets *)asset isSource:(BOOL)source { 72 | 73 | [imagePicker dismissViewControllerAnimated:YES completion:nil]; 74 | 75 | } 76 | 77 | - (void)imagePickerController:(JKImagePickerController *)imagePicker didSelectAssets:(NSArray *)assets isSource:(BOOL)source { 78 | 79 | self.photosView.assetsArray = [NSMutableArray arrayWithArray:assets]; 80 | 81 | [imagePicker dismissViewControllerAnimated:YES completion:^{ 82 | if (self.photosView.assetsArray.count > 0) { 83 | self.photosView.addButton.hidden = NO; 84 | } 85 | [self.photosView.collectionView reloadData]; 86 | }]; 87 | } 88 | - (void)imagePickerControllerDidCancel:(JKImagePickerController *)imagePicker { 89 | 90 | [imagePicker dismissViewControllerAnimated:YES completion:nil]; 91 | 92 | } 93 | 94 | 95 | 96 | 97 | 98 | - (void)updateImages { 99 | NSMutableArray *upImages = [NSMutableArray array]; 100 | for (JKAssets *asset in self.photosView.assetsArray) { 101 | [upImages addObject:asset.photo]; 102 | } 103 | NSLog(@"%@", upImages); 104 | //这里上传的图片应该是九宫格中还剩的图片 105 | [QQQNSystemService qq_uploadImages:upImages token:self.token domain:self.domain progress:^(CGFloat progress) { 106 | NSLog(@"上传图片的进度 == %lf", progress); 107 | } success:^(NSArray *array) { 108 | NSLog(@"图片地址 : %@", array); 109 | } failure:^{ 110 | NSLog(@"上传失败"); 111 | }]; 112 | } 113 | - (void)didReceiveMemoryWarning { 114 | [super didReceiveMemoryWarning]; 115 | // Dispose of any resources that can be recreated. 116 | } 117 | 118 | @end 119 | 120 | -------------------------------------------------------------------------------- /QQImagesPicker/main.m: -------------------------------------------------------------------------------- 1 | // 2 | // main.m 3 | // QQImagesPicker 4 | // 5 | // Created by best-admin on 2017/3/21. 6 | // Copyright © 2017年 baisiChina. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "AppDelegate.h" 11 | 12 | int main(int argc, char * argv[]) { 13 | @autoreleasepool { 14 | return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # QQImagePicker 2 | 3 | * 访问系统相册和相机,批量选择相册中文件 4 | * 九宫格展现选中图片,可以调整九宫格图片的顺序 5 | * 上传图片到七牛云存储, 封装批量上传. 6 | 7 | # 说明 8 | 9 | 下载源码,执行 10 | 11 | ``` 12 | pod install 13 | 14 | ``` 15 | 16 | # SDK支持 17 | 18 | 七牛SDK版本: SDK v7.1 AFNetworking 3.x。 19 | 20 | 官方文档:[七牛开发者中心](https://developer.qiniu.com/kodo/sdk/objc) 21 | --------------------------------------------------------------------------------