├── PhotoPicker.xcodeproj ├── project.pbxproj ├── project.xcworkspace │ ├── contents.xcworkspacedata │ ├── xcshareddata │ │ └── PhotoPicker.xccheckout │ └── xcuserdata │ │ ├── Charlin.xcuserdatad │ │ └── UserInterfaceState.xcuserstate │ │ └── huaxi100.xcuserdatad │ │ ├── UserInterfaceState.xcuserstate │ │ └── WorkspaceSettings.xcsettings └── xcuserdata │ ├── Charlin.xcuserdatad │ └── xcschemes │ │ ├── PhotoPicker.xcscheme │ │ └── xcschememanagement.plist │ └── huaxi100.xcuserdatad │ ├── xcdebugger │ └── Breakpoints_v2.xcbkptlist │ └── xcschemes │ ├── PhotoPicker.xcscheme │ └── xcschememanagement.plist ├── PhotoPicker ├── AppDelegate.h ├── AppDelegate.m ├── Base.lproj │ ├── LaunchScreen.xib │ └── Main.storyboard ├── CorePhotoPickerVCManager │ ├── CorePhoto.h │ ├── CorePhoto.m │ ├── CorePhotoPickerVCManager.h │ ├── CorePhotoPickerVCManager.m │ ├── HMSingleton.h │ └── Library │ │ ├── UIImage+UzysExtension.h │ │ ├── UIImage+UzysExtension.m │ │ ├── UzysAppearanceConfig.h │ │ ├── UzysAppearanceConfig.m │ │ ├── UzysAssetPickerController.bundle │ │ ├── uzysAP_ico_arrow_upload_album_d@2x.png │ │ ├── uzysAP_ico_assets_video@2x.png │ │ ├── uzysAP_ico_checkMark@2x.png │ │ ├── uzysAP_ico_no_access@2x.png │ │ ├── uzysAP_ico_no_image@2x.png │ │ ├── uzysAP_ico_no_video@2x.png │ │ ├── uzysAP_ico_photo_thumb_check@2x.png │ │ ├── uzysAP_ico_photo_thumb_check@3x.png │ │ ├── uzysAP_ico_photo_thumb_uncheck@2x.png │ │ ├── uzysAP_ico_photo_thumb_uncheck@3x.png │ │ ├── uzysAP_ico_upload_camera@2x.png │ │ ├── uzysAP_ico_upload_camera@3x.png │ │ ├── uzysAP_ico_upload_done@2x.png │ │ └── uzysAP_navi_icon_close@2x.png │ │ ├── UzysAssetsPickerController.h │ │ ├── UzysAssetsPickerController.m │ │ ├── UzysAssetsPickerController.xib │ │ ├── UzysAssetsPickerController_Configuration.h │ │ ├── UzysAssetsViewCell.h │ │ ├── UzysAssetsViewCell.m │ │ ├── UzysGroupPickerView.h │ │ ├── UzysGroupPickerView.m │ │ ├── UzysGroupViewCell.h │ │ ├── UzysGroupViewCell.m │ │ ├── UzysWrapperPickerController.h │ │ └── UzysWrapperPickerController.m ├── Images.xcassets │ └── AppIcon.appiconset │ │ └── Contents.json ├── Info.plist ├── ViewController.h ├── ViewController.m ├── img │ ├── 1.png │ ├── 2.png │ └── 3.png └── main.m ├── PhotoPickerTests ├── Info.plist └── PhotoPickerTests.m └── README.md /PhotoPicker.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 46; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 89FBA9D71C1AE8C800E3EA09 /* UIImage+UzysExtension.m in Sources */ = {isa = PBXBuildFile; fileRef = 89FBA9C71C1AE8C800E3EA09 /* UIImage+UzysExtension.m */; }; 11 | 89FBA9D81C1AE8C800E3EA09 /* UzysAppearanceConfig.m in Sources */ = {isa = PBXBuildFile; fileRef = 89FBA9C91C1AE8C800E3EA09 /* UzysAppearanceConfig.m */; }; 12 | 89FBA9DA1C1AE8C800E3EA09 /* UzysAssetsPickerController.m in Sources */ = {isa = PBXBuildFile; fileRef = 89FBA9CC1C1AE8C800E3EA09 /* UzysAssetsPickerController.m */; }; 13 | 89FBA9DB1C1AE8C800E3EA09 /* UzysAssetsPickerController.xib in Resources */ = {isa = PBXBuildFile; fileRef = 89FBA9CD1C1AE8C800E3EA09 /* UzysAssetsPickerController.xib */; }; 14 | 89FBA9DC1C1AE8C800E3EA09 /* UzysAssetsViewCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 89FBA9D01C1AE8C800E3EA09 /* UzysAssetsViewCell.m */; }; 15 | 89FBA9DD1C1AE8C800E3EA09 /* UzysGroupPickerView.m in Sources */ = {isa = PBXBuildFile; fileRef = 89FBA9D21C1AE8C800E3EA09 /* UzysGroupPickerView.m */; }; 16 | 89FBA9DE1C1AE8C800E3EA09 /* UzysGroupViewCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 89FBA9D41C1AE8C800E3EA09 /* UzysGroupViewCell.m */; }; 17 | 89FBA9DF1C1AE8C800E3EA09 /* UzysWrapperPickerController.m in Sources */ = {isa = PBXBuildFile; fileRef = 89FBA9D61C1AE8C800E3EA09 /* UzysWrapperPickerController.m */; }; 18 | 89FBA9E11C1AE91A00E3EA09 /* UzysAssetPickerController.bundle in Resources */ = {isa = PBXBuildFile; fileRef = 89FBA9E01C1AE91A00E3EA09 /* UzysAssetPickerController.bundle */; }; 19 | EE597F721A9042E70037CF67 /* 1.png in Resources */ = {isa = PBXBuildFile; fileRef = EE597F6F1A9042E70037CF67 /* 1.png */; }; 20 | EE597F741A9042E70037CF67 /* 3.png in Resources */ = {isa = PBXBuildFile; fileRef = EE597F711A9042E70037CF67 /* 3.png */; }; 21 | EE597F981A90469A0037CF67 /* 2.png in Resources */ = {isa = PBXBuildFile; fileRef = EE597F971A90469A0037CF67 /* 2.png */; }; 22 | EE8227751AC15D54004049D7 /* CorePhoto.m in Sources */ = {isa = PBXBuildFile; fileRef = EE82275F1AC15D54004049D7 /* CorePhoto.m */; }; 23 | EE8227761AC15D54004049D7 /* CorePhotoPickerVCManager.m in Sources */ = {isa = PBXBuildFile; fileRef = EE8227611AC15D54004049D7 /* CorePhotoPickerVCManager.m */; }; 24 | EEC5119D1A8D96A40082C50E /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = EEC5119C1A8D96A40082C50E /* main.m */; }; 25 | EEC511A01A8D96A40082C50E /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = EEC5119F1A8D96A40082C50E /* AppDelegate.m */; }; 26 | EEC511A31A8D96A40082C50E /* ViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = EEC511A21A8D96A40082C50E /* ViewController.m */; }; 27 | EEC511A61A8D96A40082C50E /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = EEC511A41A8D96A40082C50E /* Main.storyboard */; }; 28 | EEC511A81A8D96A40082C50E /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = EEC511A71A8D96A40082C50E /* Images.xcassets */; }; 29 | EEC511AB1A8D96A40082C50E /* LaunchScreen.xib in Resources */ = {isa = PBXBuildFile; fileRef = EEC511A91A8D96A40082C50E /* LaunchScreen.xib */; }; 30 | EEC511B71A8D96A40082C50E /* PhotoPickerTests.m in Sources */ = {isa = PBXBuildFile; fileRef = EEC511B61A8D96A40082C50E /* PhotoPickerTests.m */; }; 31 | /* End PBXBuildFile section */ 32 | 33 | /* Begin PBXContainerItemProxy section */ 34 | EEC511B11A8D96A40082C50E /* PBXContainerItemProxy */ = { 35 | isa = PBXContainerItemProxy; 36 | containerPortal = EEC5118F1A8D96A40082C50E /* Project object */; 37 | proxyType = 1; 38 | remoteGlobalIDString = EEC511961A8D96A40082C50E; 39 | remoteInfo = PhotoPicker; 40 | }; 41 | /* End PBXContainerItemProxy section */ 42 | 43 | /* Begin PBXFileReference section */ 44 | 89FBA9C61C1AE8C800E3EA09 /* UIImage+UzysExtension.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "UIImage+UzysExtension.h"; sourceTree = ""; }; 45 | 89FBA9C71C1AE8C800E3EA09 /* UIImage+UzysExtension.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "UIImage+UzysExtension.m"; sourceTree = ""; }; 46 | 89FBA9C81C1AE8C800E3EA09 /* UzysAppearanceConfig.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = UzysAppearanceConfig.h; sourceTree = ""; }; 47 | 89FBA9C91C1AE8C800E3EA09 /* UzysAppearanceConfig.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = UzysAppearanceConfig.m; sourceTree = ""; }; 48 | 89FBA9CB1C1AE8C800E3EA09 /* UzysAssetsPickerController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = UzysAssetsPickerController.h; sourceTree = ""; }; 49 | 89FBA9CC1C1AE8C800E3EA09 /* UzysAssetsPickerController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = UzysAssetsPickerController.m; sourceTree = ""; }; 50 | 89FBA9CD1C1AE8C800E3EA09 /* UzysAssetsPickerController.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = UzysAssetsPickerController.xib; sourceTree = ""; }; 51 | 89FBA9CE1C1AE8C800E3EA09 /* UzysAssetsPickerController_Configuration.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = UzysAssetsPickerController_Configuration.h; sourceTree = ""; }; 52 | 89FBA9CF1C1AE8C800E3EA09 /* UzysAssetsViewCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = UzysAssetsViewCell.h; sourceTree = ""; }; 53 | 89FBA9D01C1AE8C800E3EA09 /* UzysAssetsViewCell.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = UzysAssetsViewCell.m; sourceTree = ""; }; 54 | 89FBA9D11C1AE8C800E3EA09 /* UzysGroupPickerView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = UzysGroupPickerView.h; sourceTree = ""; }; 55 | 89FBA9D21C1AE8C800E3EA09 /* UzysGroupPickerView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = UzysGroupPickerView.m; sourceTree = ""; }; 56 | 89FBA9D31C1AE8C800E3EA09 /* UzysGroupViewCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = UzysGroupViewCell.h; sourceTree = ""; }; 57 | 89FBA9D41C1AE8C800E3EA09 /* UzysGroupViewCell.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = UzysGroupViewCell.m; sourceTree = ""; }; 58 | 89FBA9D51C1AE8C800E3EA09 /* UzysWrapperPickerController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = UzysWrapperPickerController.h; sourceTree = ""; }; 59 | 89FBA9D61C1AE8C800E3EA09 /* UzysWrapperPickerController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = UzysWrapperPickerController.m; sourceTree = ""; }; 60 | 89FBA9E01C1AE91A00E3EA09 /* UzysAssetPickerController.bundle */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.plug-in"; path = UzysAssetPickerController.bundle; sourceTree = ""; }; 61 | EE597F6F1A9042E70037CF67 /* 1.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = 1.png; sourceTree = ""; }; 62 | EE597F711A9042E70037CF67 /* 3.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = 3.png; sourceTree = ""; }; 63 | EE597F971A90469A0037CF67 /* 2.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = 2.png; sourceTree = ""; }; 64 | EE82275E1AC15D54004049D7 /* CorePhoto.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CorePhoto.h; sourceTree = ""; }; 65 | EE82275F1AC15D54004049D7 /* CorePhoto.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CorePhoto.m; sourceTree = ""; }; 66 | EE8227601AC15D54004049D7 /* CorePhotoPickerVCManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CorePhotoPickerVCManager.h; sourceTree = ""; }; 67 | EE8227611AC15D54004049D7 /* CorePhotoPickerVCManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CorePhotoPickerVCManager.m; sourceTree = ""; }; 68 | EE8227621AC15D54004049D7 /* HMSingleton.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = HMSingleton.h; sourceTree = ""; }; 69 | EEC511971A8D96A40082C50E /* PhotoPicker.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = PhotoPicker.app; sourceTree = BUILT_PRODUCTS_DIR; }; 70 | EEC5119B1A8D96A40082C50E /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 71 | EEC5119C1A8D96A40082C50E /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; 72 | EEC5119E1A8D96A40082C50E /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; 73 | EEC5119F1A8D96A40082C50E /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; 74 | EEC511A11A8D96A40082C50E /* ViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ViewController.h; sourceTree = ""; }; 75 | EEC511A21A8D96A40082C50E /* ViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ViewController.m; sourceTree = ""; }; 76 | EEC511A51A8D96A40082C50E /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; 77 | EEC511A71A8D96A40082C50E /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Images.xcassets; sourceTree = ""; }; 78 | EEC511AA1A8D96A40082C50E /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/LaunchScreen.xib; sourceTree = ""; }; 79 | EEC511B01A8D96A40082C50E /* PhotoPickerTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = PhotoPickerTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; 80 | EEC511B51A8D96A40082C50E /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 81 | EEC511B61A8D96A40082C50E /* PhotoPickerTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = PhotoPickerTests.m; sourceTree = ""; }; 82 | /* End PBXFileReference section */ 83 | 84 | /* Begin PBXFrameworksBuildPhase section */ 85 | EEC511941A8D96A40082C50E /* Frameworks */ = { 86 | isa = PBXFrameworksBuildPhase; 87 | buildActionMask = 2147483647; 88 | files = ( 89 | ); 90 | runOnlyForDeploymentPostprocessing = 0; 91 | }; 92 | EEC511AD1A8D96A40082C50E /* Frameworks */ = { 93 | isa = PBXFrameworksBuildPhase; 94 | buildActionMask = 2147483647; 95 | files = ( 96 | ); 97 | runOnlyForDeploymentPostprocessing = 0; 98 | }; 99 | /* End PBXFrameworksBuildPhase section */ 100 | 101 | /* Begin PBXGroup section */ 102 | 89FBA9C51C1AE8C800E3EA09 /* Library */ = { 103 | isa = PBXGroup; 104 | children = ( 105 | 89FBA9E01C1AE91A00E3EA09 /* UzysAssetPickerController.bundle */, 106 | 89FBA9C61C1AE8C800E3EA09 /* UIImage+UzysExtension.h */, 107 | 89FBA9C71C1AE8C800E3EA09 /* UIImage+UzysExtension.m */, 108 | 89FBA9C81C1AE8C800E3EA09 /* UzysAppearanceConfig.h */, 109 | 89FBA9C91C1AE8C800E3EA09 /* UzysAppearanceConfig.m */, 110 | 89FBA9CB1C1AE8C800E3EA09 /* UzysAssetsPickerController.h */, 111 | 89FBA9CC1C1AE8C800E3EA09 /* UzysAssetsPickerController.m */, 112 | 89FBA9CD1C1AE8C800E3EA09 /* UzysAssetsPickerController.xib */, 113 | 89FBA9CE1C1AE8C800E3EA09 /* UzysAssetsPickerController_Configuration.h */, 114 | 89FBA9CF1C1AE8C800E3EA09 /* UzysAssetsViewCell.h */, 115 | 89FBA9D01C1AE8C800E3EA09 /* UzysAssetsViewCell.m */, 116 | 89FBA9D11C1AE8C800E3EA09 /* UzysGroupPickerView.h */, 117 | 89FBA9D21C1AE8C800E3EA09 /* UzysGroupPickerView.m */, 118 | 89FBA9D31C1AE8C800E3EA09 /* UzysGroupViewCell.h */, 119 | 89FBA9D41C1AE8C800E3EA09 /* UzysGroupViewCell.m */, 120 | 89FBA9D51C1AE8C800E3EA09 /* UzysWrapperPickerController.h */, 121 | 89FBA9D61C1AE8C800E3EA09 /* UzysWrapperPickerController.m */, 122 | ); 123 | path = Library; 124 | sourceTree = ""; 125 | }; 126 | EE597F6E1A9042E70037CF67 /* img */ = { 127 | isa = PBXGroup; 128 | children = ( 129 | EE597F971A90469A0037CF67 /* 2.png */, 130 | EE597F6F1A9042E70037CF67 /* 1.png */, 131 | EE597F711A9042E70037CF67 /* 3.png */, 132 | ); 133 | path = img; 134 | sourceTree = ""; 135 | }; 136 | EE82275D1AC15D54004049D7 /* CorePhotoPickerVCManager */ = { 137 | isa = PBXGroup; 138 | children = ( 139 | 89FBA9C51C1AE8C800E3EA09 /* Library */, 140 | EE82275E1AC15D54004049D7 /* CorePhoto.h */, 141 | EE82275F1AC15D54004049D7 /* CorePhoto.m */, 142 | EE8227601AC15D54004049D7 /* CorePhotoPickerVCManager.h */, 143 | EE8227611AC15D54004049D7 /* CorePhotoPickerVCManager.m */, 144 | EE8227621AC15D54004049D7 /* HMSingleton.h */, 145 | ); 146 | path = CorePhotoPickerVCManager; 147 | sourceTree = ""; 148 | }; 149 | EEC5118E1A8D96A40082C50E = { 150 | isa = PBXGroup; 151 | children = ( 152 | EEC511991A8D96A40082C50E /* PhotoPicker */, 153 | EEC511B31A8D96A40082C50E /* PhotoPickerTests */, 154 | EEC511981A8D96A40082C50E /* Products */, 155 | ); 156 | sourceTree = ""; 157 | }; 158 | EEC511981A8D96A40082C50E /* Products */ = { 159 | isa = PBXGroup; 160 | children = ( 161 | EEC511971A8D96A40082C50E /* PhotoPicker.app */, 162 | EEC511B01A8D96A40082C50E /* PhotoPickerTests.xctest */, 163 | ); 164 | name = Products; 165 | sourceTree = ""; 166 | }; 167 | EEC511991A8D96A40082C50E /* PhotoPicker */ = { 168 | isa = PBXGroup; 169 | children = ( 170 | EE82275D1AC15D54004049D7 /* CorePhotoPickerVCManager */, 171 | EEC5119E1A8D96A40082C50E /* AppDelegate.h */, 172 | EEC5119F1A8D96A40082C50E /* AppDelegate.m */, 173 | EEC511A11A8D96A40082C50E /* ViewController.h */, 174 | EEC511A21A8D96A40082C50E /* ViewController.m */, 175 | EEC511A41A8D96A40082C50E /* Main.storyboard */, 176 | EEC511A71A8D96A40082C50E /* Images.xcassets */, 177 | EEC511A91A8D96A40082C50E /* LaunchScreen.xib */, 178 | EEC5119A1A8D96A40082C50E /* Supporting Files */, 179 | ); 180 | path = PhotoPicker; 181 | sourceTree = ""; 182 | }; 183 | EEC5119A1A8D96A40082C50E /* Supporting Files */ = { 184 | isa = PBXGroup; 185 | children = ( 186 | EE597F6E1A9042E70037CF67 /* img */, 187 | EEC5119B1A8D96A40082C50E /* Info.plist */, 188 | EEC5119C1A8D96A40082C50E /* main.m */, 189 | ); 190 | name = "Supporting Files"; 191 | sourceTree = ""; 192 | }; 193 | EEC511B31A8D96A40082C50E /* PhotoPickerTests */ = { 194 | isa = PBXGroup; 195 | children = ( 196 | EEC511B61A8D96A40082C50E /* PhotoPickerTests.m */, 197 | EEC511B41A8D96A40082C50E /* Supporting Files */, 198 | ); 199 | path = PhotoPickerTests; 200 | sourceTree = ""; 201 | }; 202 | EEC511B41A8D96A40082C50E /* Supporting Files */ = { 203 | isa = PBXGroup; 204 | children = ( 205 | EEC511B51A8D96A40082C50E /* Info.plist */, 206 | ); 207 | name = "Supporting Files"; 208 | sourceTree = ""; 209 | }; 210 | /* End PBXGroup section */ 211 | 212 | /* Begin PBXNativeTarget section */ 213 | EEC511961A8D96A40082C50E /* PhotoPicker */ = { 214 | isa = PBXNativeTarget; 215 | buildConfigurationList = EEC511BA1A8D96A40082C50E /* Build configuration list for PBXNativeTarget "PhotoPicker" */; 216 | buildPhases = ( 217 | EEC511931A8D96A40082C50E /* Sources */, 218 | EEC511941A8D96A40082C50E /* Frameworks */, 219 | EEC511951A8D96A40082C50E /* Resources */, 220 | ); 221 | buildRules = ( 222 | ); 223 | dependencies = ( 224 | ); 225 | name = PhotoPicker; 226 | productName = PhotoPicker; 227 | productReference = EEC511971A8D96A40082C50E /* PhotoPicker.app */; 228 | productType = "com.apple.product-type.application"; 229 | }; 230 | EEC511AF1A8D96A40082C50E /* PhotoPickerTests */ = { 231 | isa = PBXNativeTarget; 232 | buildConfigurationList = EEC511BD1A8D96A40082C50E /* Build configuration list for PBXNativeTarget "PhotoPickerTests" */; 233 | buildPhases = ( 234 | EEC511AC1A8D96A40082C50E /* Sources */, 235 | EEC511AD1A8D96A40082C50E /* Frameworks */, 236 | EEC511AE1A8D96A40082C50E /* Resources */, 237 | ); 238 | buildRules = ( 239 | ); 240 | dependencies = ( 241 | EEC511B21A8D96A40082C50E /* PBXTargetDependency */, 242 | ); 243 | name = PhotoPickerTests; 244 | productName = PhotoPickerTests; 245 | productReference = EEC511B01A8D96A40082C50E /* PhotoPickerTests.xctest */; 246 | productType = "com.apple.product-type.bundle.unit-test"; 247 | }; 248 | /* End PBXNativeTarget section */ 249 | 250 | /* Begin PBXProject section */ 251 | EEC5118F1A8D96A40082C50E /* Project object */ = { 252 | isa = PBXProject; 253 | attributes = { 254 | LastUpgradeCheck = 0610; 255 | ORGANIZATIONNAME = muxi; 256 | TargetAttributes = { 257 | EEC511961A8D96A40082C50E = { 258 | CreatedOnToolsVersion = 6.1.1; 259 | }; 260 | EEC511AF1A8D96A40082C50E = { 261 | CreatedOnToolsVersion = 6.1.1; 262 | TestTargetID = EEC511961A8D96A40082C50E; 263 | }; 264 | }; 265 | }; 266 | buildConfigurationList = EEC511921A8D96A40082C50E /* Build configuration list for PBXProject "PhotoPicker" */; 267 | compatibilityVersion = "Xcode 3.2"; 268 | developmentRegion = English; 269 | hasScannedForEncodings = 0; 270 | knownRegions = ( 271 | en, 272 | Base, 273 | ); 274 | mainGroup = EEC5118E1A8D96A40082C50E; 275 | productRefGroup = EEC511981A8D96A40082C50E /* Products */; 276 | projectDirPath = ""; 277 | projectRoot = ""; 278 | targets = ( 279 | EEC511961A8D96A40082C50E /* PhotoPicker */, 280 | EEC511AF1A8D96A40082C50E /* PhotoPickerTests */, 281 | ); 282 | }; 283 | /* End PBXProject section */ 284 | 285 | /* Begin PBXResourcesBuildPhase section */ 286 | EEC511951A8D96A40082C50E /* Resources */ = { 287 | isa = PBXResourcesBuildPhase; 288 | buildActionMask = 2147483647; 289 | files = ( 290 | EEC511A61A8D96A40082C50E /* Main.storyboard in Resources */, 291 | EEC511AB1A8D96A40082C50E /* LaunchScreen.xib in Resources */, 292 | 89FBA9E11C1AE91A00E3EA09 /* UzysAssetPickerController.bundle in Resources */, 293 | EE597F981A90469A0037CF67 /* 2.png in Resources */, 294 | EE597F741A9042E70037CF67 /* 3.png in Resources */, 295 | EE597F721A9042E70037CF67 /* 1.png in Resources */, 296 | EEC511A81A8D96A40082C50E /* Images.xcassets in Resources */, 297 | 89FBA9DB1C1AE8C800E3EA09 /* UzysAssetsPickerController.xib in Resources */, 298 | ); 299 | runOnlyForDeploymentPostprocessing = 0; 300 | }; 301 | EEC511AE1A8D96A40082C50E /* Resources */ = { 302 | isa = PBXResourcesBuildPhase; 303 | buildActionMask = 2147483647; 304 | files = ( 305 | ); 306 | runOnlyForDeploymentPostprocessing = 0; 307 | }; 308 | /* End PBXResourcesBuildPhase section */ 309 | 310 | /* Begin PBXSourcesBuildPhase section */ 311 | EEC511931A8D96A40082C50E /* Sources */ = { 312 | isa = PBXSourcesBuildPhase; 313 | buildActionMask = 2147483647; 314 | files = ( 315 | EEC511A31A8D96A40082C50E /* ViewController.m in Sources */, 316 | 89FBA9DC1C1AE8C800E3EA09 /* UzysAssetsViewCell.m in Sources */, 317 | EE8227751AC15D54004049D7 /* CorePhoto.m in Sources */, 318 | EEC511A01A8D96A40082C50E /* AppDelegate.m in Sources */, 319 | EE8227761AC15D54004049D7 /* CorePhotoPickerVCManager.m in Sources */, 320 | 89FBA9D71C1AE8C800E3EA09 /* UIImage+UzysExtension.m in Sources */, 321 | 89FBA9DF1C1AE8C800E3EA09 /* UzysWrapperPickerController.m in Sources */, 322 | EEC5119D1A8D96A40082C50E /* main.m in Sources */, 323 | 89FBA9DD1C1AE8C800E3EA09 /* UzysGroupPickerView.m in Sources */, 324 | 89FBA9D81C1AE8C800E3EA09 /* UzysAppearanceConfig.m in Sources */, 325 | 89FBA9DE1C1AE8C800E3EA09 /* UzysGroupViewCell.m in Sources */, 326 | 89FBA9DA1C1AE8C800E3EA09 /* UzysAssetsPickerController.m in Sources */, 327 | ); 328 | runOnlyForDeploymentPostprocessing = 0; 329 | }; 330 | EEC511AC1A8D96A40082C50E /* Sources */ = { 331 | isa = PBXSourcesBuildPhase; 332 | buildActionMask = 2147483647; 333 | files = ( 334 | EEC511B71A8D96A40082C50E /* PhotoPickerTests.m in Sources */, 335 | ); 336 | runOnlyForDeploymentPostprocessing = 0; 337 | }; 338 | /* End PBXSourcesBuildPhase section */ 339 | 340 | /* Begin PBXTargetDependency section */ 341 | EEC511B21A8D96A40082C50E /* PBXTargetDependency */ = { 342 | isa = PBXTargetDependency; 343 | target = EEC511961A8D96A40082C50E /* PhotoPicker */; 344 | targetProxy = EEC511B11A8D96A40082C50E /* PBXContainerItemProxy */; 345 | }; 346 | /* End PBXTargetDependency section */ 347 | 348 | /* Begin PBXVariantGroup section */ 349 | EEC511A41A8D96A40082C50E /* Main.storyboard */ = { 350 | isa = PBXVariantGroup; 351 | children = ( 352 | EEC511A51A8D96A40082C50E /* Base */, 353 | ); 354 | name = Main.storyboard; 355 | sourceTree = ""; 356 | }; 357 | EEC511A91A8D96A40082C50E /* LaunchScreen.xib */ = { 358 | isa = PBXVariantGroup; 359 | children = ( 360 | EEC511AA1A8D96A40082C50E /* Base */, 361 | ); 362 | name = LaunchScreen.xib; 363 | sourceTree = ""; 364 | }; 365 | /* End PBXVariantGroup section */ 366 | 367 | /* Begin XCBuildConfiguration section */ 368 | EEC511B81A8D96A40082C50E /* Debug */ = { 369 | isa = XCBuildConfiguration; 370 | buildSettings = { 371 | ALWAYS_SEARCH_USER_PATHS = NO; 372 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 373 | CLANG_CXX_LIBRARY = "libc++"; 374 | CLANG_ENABLE_MODULES = YES; 375 | CLANG_ENABLE_OBJC_ARC = YES; 376 | CLANG_WARN_BOOL_CONVERSION = YES; 377 | CLANG_WARN_CONSTANT_CONVERSION = YES; 378 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 379 | CLANG_WARN_EMPTY_BODY = YES; 380 | CLANG_WARN_ENUM_CONVERSION = YES; 381 | CLANG_WARN_INT_CONVERSION = YES; 382 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 383 | CLANG_WARN_UNREACHABLE_CODE = YES; 384 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 385 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 386 | COPY_PHASE_STRIP = NO; 387 | ENABLE_STRICT_OBJC_MSGSEND = YES; 388 | GCC_C_LANGUAGE_STANDARD = gnu99; 389 | GCC_DYNAMIC_NO_PIC = NO; 390 | GCC_OPTIMIZATION_LEVEL = 0; 391 | GCC_PREPROCESSOR_DEFINITIONS = ( 392 | "DEBUG=1", 393 | "$(inherited)", 394 | ); 395 | GCC_SYMBOLS_PRIVATE_EXTERN = NO; 396 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 397 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 398 | GCC_WARN_UNDECLARED_SELECTOR = YES; 399 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 400 | GCC_WARN_UNUSED_FUNCTION = YES; 401 | GCC_WARN_UNUSED_VARIABLE = YES; 402 | IPHONEOS_DEPLOYMENT_TARGET = 8.1; 403 | MTL_ENABLE_DEBUG_INFO = YES; 404 | ONLY_ACTIVE_ARCH = YES; 405 | SDKROOT = iphoneos; 406 | }; 407 | name = Debug; 408 | }; 409 | EEC511B91A8D96A40082C50E /* Release */ = { 410 | isa = XCBuildConfiguration; 411 | buildSettings = { 412 | ALWAYS_SEARCH_USER_PATHS = NO; 413 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 414 | CLANG_CXX_LIBRARY = "libc++"; 415 | CLANG_ENABLE_MODULES = YES; 416 | CLANG_ENABLE_OBJC_ARC = YES; 417 | CLANG_WARN_BOOL_CONVERSION = YES; 418 | CLANG_WARN_CONSTANT_CONVERSION = YES; 419 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 420 | CLANG_WARN_EMPTY_BODY = YES; 421 | CLANG_WARN_ENUM_CONVERSION = YES; 422 | CLANG_WARN_INT_CONVERSION = YES; 423 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 424 | CLANG_WARN_UNREACHABLE_CODE = YES; 425 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 426 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 427 | COPY_PHASE_STRIP = YES; 428 | ENABLE_NS_ASSERTIONS = NO; 429 | ENABLE_STRICT_OBJC_MSGSEND = YES; 430 | GCC_C_LANGUAGE_STANDARD = gnu99; 431 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 432 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 433 | GCC_WARN_UNDECLARED_SELECTOR = YES; 434 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 435 | GCC_WARN_UNUSED_FUNCTION = YES; 436 | GCC_WARN_UNUSED_VARIABLE = YES; 437 | IPHONEOS_DEPLOYMENT_TARGET = 8.1; 438 | MTL_ENABLE_DEBUG_INFO = NO; 439 | SDKROOT = iphoneos; 440 | VALIDATE_PRODUCT = YES; 441 | }; 442 | name = Release; 443 | }; 444 | EEC511BB1A8D96A40082C50E /* Debug */ = { 445 | isa = XCBuildConfiguration; 446 | buildSettings = { 447 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 448 | INFOPLIST_FILE = PhotoPicker/Info.plist; 449 | IPHONEOS_DEPLOYMENT_TARGET = 6.0; 450 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 451 | PRODUCT_NAME = "$(TARGET_NAME)"; 452 | }; 453 | name = Debug; 454 | }; 455 | EEC511BC1A8D96A40082C50E /* Release */ = { 456 | isa = XCBuildConfiguration; 457 | buildSettings = { 458 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 459 | INFOPLIST_FILE = PhotoPicker/Info.plist; 460 | IPHONEOS_DEPLOYMENT_TARGET = 6.0; 461 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 462 | PRODUCT_NAME = "$(TARGET_NAME)"; 463 | }; 464 | name = Release; 465 | }; 466 | EEC511BE1A8D96A40082C50E /* Debug */ = { 467 | isa = XCBuildConfiguration; 468 | buildSettings = { 469 | BUNDLE_LOADER = "$(TEST_HOST)"; 470 | FRAMEWORK_SEARCH_PATHS = ( 471 | "$(SDKROOT)/Developer/Library/Frameworks", 472 | "$(inherited)", 473 | ); 474 | GCC_PREPROCESSOR_DEFINITIONS = ( 475 | "DEBUG=1", 476 | "$(inherited)", 477 | ); 478 | INFOPLIST_FILE = PhotoPickerTests/Info.plist; 479 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 480 | PRODUCT_NAME = "$(TARGET_NAME)"; 481 | TEST_HOST = "$(BUILT_PRODUCTS_DIR)/PhotoPicker.app/PhotoPicker"; 482 | }; 483 | name = Debug; 484 | }; 485 | EEC511BF1A8D96A40082C50E /* Release */ = { 486 | isa = XCBuildConfiguration; 487 | buildSettings = { 488 | BUNDLE_LOADER = "$(TEST_HOST)"; 489 | FRAMEWORK_SEARCH_PATHS = ( 490 | "$(SDKROOT)/Developer/Library/Frameworks", 491 | "$(inherited)", 492 | ); 493 | INFOPLIST_FILE = PhotoPickerTests/Info.plist; 494 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 495 | PRODUCT_NAME = "$(TARGET_NAME)"; 496 | TEST_HOST = "$(BUILT_PRODUCTS_DIR)/PhotoPicker.app/PhotoPicker"; 497 | }; 498 | name = Release; 499 | }; 500 | /* End XCBuildConfiguration section */ 501 | 502 | /* Begin XCConfigurationList section */ 503 | EEC511921A8D96A40082C50E /* Build configuration list for PBXProject "PhotoPicker" */ = { 504 | isa = XCConfigurationList; 505 | buildConfigurations = ( 506 | EEC511B81A8D96A40082C50E /* Debug */, 507 | EEC511B91A8D96A40082C50E /* Release */, 508 | ); 509 | defaultConfigurationIsVisible = 0; 510 | defaultConfigurationName = Release; 511 | }; 512 | EEC511BA1A8D96A40082C50E /* Build configuration list for PBXNativeTarget "PhotoPicker" */ = { 513 | isa = XCConfigurationList; 514 | buildConfigurations = ( 515 | EEC511BB1A8D96A40082C50E /* Debug */, 516 | EEC511BC1A8D96A40082C50E /* Release */, 517 | ); 518 | defaultConfigurationIsVisible = 0; 519 | defaultConfigurationName = Release; 520 | }; 521 | EEC511BD1A8D96A40082C50E /* Build configuration list for PBXNativeTarget "PhotoPickerTests" */ = { 522 | isa = XCConfigurationList; 523 | buildConfigurations = ( 524 | EEC511BE1A8D96A40082C50E /* Debug */, 525 | EEC511BF1A8D96A40082C50E /* Release */, 526 | ); 527 | defaultConfigurationIsVisible = 0; 528 | defaultConfigurationName = Release; 529 | }; 530 | /* End XCConfigurationList section */ 531 | }; 532 | rootObject = EEC5118F1A8D96A40082C50E /* Project object */; 533 | } 534 | -------------------------------------------------------------------------------- /PhotoPicker.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /PhotoPicker.xcodeproj/project.xcworkspace/xcshareddata/PhotoPicker.xccheckout: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDESourceControlProjectFavoriteDictionaryKey 6 | 7 | IDESourceControlProjectIdentifier 8 | 3ACC21CA-5B75-45C5-BA25-2113DF7DE524 9 | IDESourceControlProjectName 10 | PhotoPicker 11 | IDESourceControlProjectOriginsDictionary 12 | 13 | 8D3EF7B8757F298C765C67DFCADA834CAE0CF098 14 | https://github.com/nsdictionary/CorePhotoPickerVCManager.git 15 | 16 | IDESourceControlProjectPath 17 | PhotoPicker.xcodeproj 18 | IDESourceControlProjectRelativeInstallPathDictionary 19 | 20 | 8D3EF7B8757F298C765C67DFCADA834CAE0CF098 21 | ../.. 22 | 23 | IDESourceControlProjectURL 24 | https://github.com/nsdictionary/CorePhotoPickerVCManager.git 25 | IDESourceControlProjectVersion 26 | 111 27 | IDESourceControlProjectWCCIdentifier 28 | 8D3EF7B8757F298C765C67DFCADA834CAE0CF098 29 | IDESourceControlProjectWCConfigurations 30 | 31 | 32 | IDESourceControlRepositoryExtensionIdentifierKey 33 | public.vcs.git 34 | IDESourceControlWCCIdentifierKey 35 | 8D3EF7B8757F298C765C67DFCADA834CAE0CF098 36 | IDESourceControlWCCName 37 | PhotoPicker 38 | 39 | 40 | 41 | 42 | -------------------------------------------------------------------------------- /PhotoPicker.xcodeproj/project.xcworkspace/xcuserdata/Charlin.xcuserdatad/UserInterfaceState.xcuserstate: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CharlinFeng/CorePhotoPickerVCManager/b779b2c2ee025857c95b18345328080061b24909/PhotoPicker.xcodeproj/project.xcworkspace/xcuserdata/Charlin.xcuserdatad/UserInterfaceState.xcuserstate -------------------------------------------------------------------------------- /PhotoPicker.xcodeproj/project.xcworkspace/xcuserdata/huaxi100.xcuserdatad/UserInterfaceState.xcuserstate: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CharlinFeng/CorePhotoPickerVCManager/b779b2c2ee025857c95b18345328080061b24909/PhotoPicker.xcodeproj/project.xcworkspace/xcuserdata/huaxi100.xcuserdatad/UserInterfaceState.xcuserstate -------------------------------------------------------------------------------- /PhotoPicker.xcodeproj/project.xcworkspace/xcuserdata/huaxi100.xcuserdatad/WorkspaceSettings.xcsettings: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | HasAskedToTakeAutomaticSnapshotBeforeSignificantChanges 6 | 7 | SnapshotAutomaticallyBeforeSignificantChanges 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /PhotoPicker.xcodeproj/xcuserdata/Charlin.xcuserdatad/xcschemes/PhotoPicker.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 33 | 39 | 40 | 41 | 42 | 43 | 49 | 50 | 51 | 52 | 53 | 54 | 64 | 66 | 72 | 73 | 74 | 75 | 76 | 77 | 83 | 85 | 91 | 92 | 93 | 94 | 96 | 97 | 100 | 101 | 102 | -------------------------------------------------------------------------------- /PhotoPicker.xcodeproj/xcuserdata/Charlin.xcuserdatad/xcschemes/xcschememanagement.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | SchemeUserState 6 | 7 | PhotoPicker.xcscheme 8 | 9 | orderHint 10 | 0 11 | 12 | 13 | SuppressBuildableAutocreation 14 | 15 | EEC511961A8D96A40082C50E 16 | 17 | primary 18 | 19 | 20 | EEC511AF1A8D96A40082C50E 21 | 22 | primary 23 | 24 | 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /PhotoPicker.xcodeproj/xcuserdata/huaxi100.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | -------------------------------------------------------------------------------- /PhotoPicker.xcodeproj/xcuserdata/huaxi100.xcuserdatad/xcschemes/PhotoPicker.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 29 | 35 | 36 | 37 | 38 | 39 | 44 | 45 | 47 | 53 | 54 | 55 | 56 | 57 | 63 | 64 | 65 | 66 | 75 | 76 | 82 | 83 | 84 | 85 | 86 | 87 | 93 | 94 | 100 | 101 | 102 | 103 | 105 | 106 | 109 | 110 | 111 | -------------------------------------------------------------------------------- /PhotoPicker.xcodeproj/xcuserdata/huaxi100.xcuserdatad/xcschemes/xcschememanagement.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | SchemeUserState 6 | 7 | PhotoPicker.xcscheme 8 | 9 | orderHint 10 | 0 11 | 12 | 13 | SuppressBuildableAutocreation 14 | 15 | EEC511961A8D96A40082C50E 16 | 17 | primary 18 | 19 | 20 | EEC511AF1A8D96A40082C50E 21 | 22 | primary 23 | 24 | 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /PhotoPicker/AppDelegate.h: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.h 3 | // PhotoPicker 4 | // 5 | // Created by muxi on 15/2/13. 6 | // Copyright (c) 2015年 muxi. 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 | -------------------------------------------------------------------------------- /PhotoPicker/AppDelegate.m: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.m 3 | // PhotoPicker 4 | // 5 | // Created by muxi on 15/2/13. 6 | // Copyright (c) 2015年 muxi. All rights reserved. 7 | // 8 | 9 | #import "AppDelegate.h" 10 | 11 | @interface AppDelegate () 12 | 13 | @end 14 | 15 | @implementation AppDelegate 16 | 17 | 18 | - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { 19 | // Override point for customization after application launch. 20 | return YES; 21 | } 22 | 23 | - (void)applicationWillResignActive:(UIApplication *)application { 24 | // 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. 25 | // Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game. 26 | } 27 | 28 | - (void)applicationDidEnterBackground:(UIApplication *)application { 29 | // 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. 30 | // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. 31 | } 32 | 33 | - (void)applicationWillEnterForeground:(UIApplication *)application { 34 | // Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background. 35 | } 36 | 37 | - (void)applicationDidBecomeActive:(UIApplication *)application { 38 | // 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. 39 | } 40 | 41 | - (void)applicationWillTerminate:(UIApplication *)application { 42 | // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. 43 | } 44 | 45 | @end 46 | -------------------------------------------------------------------------------- /PhotoPicker/Base.lproj/LaunchScreen.xib: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 20 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | -------------------------------------------------------------------------------- /PhotoPicker/Base.lproj/Main.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | -------------------------------------------------------------------------------- /PhotoPicker/CorePhotoPickerVCManager/CorePhoto.h: -------------------------------------------------------------------------------- 1 | // 2 | // CorePhoto.h 3 | // PhotoPicker 4 | // 5 | // Created by muxi on 15/2/13. 6 | // Copyright (c) 2015年 muxi. All rights reserved. 7 | // 相册数据对象 8 | 9 | #import 10 | #import 11 | #import 12 | 13 | @interface CorePhoto : NSObject 14 | 15 | 16 | @property (nonatomic,copy) NSString *referenceURL; //相册的路径 17 | 18 | @property (nonatomic,strong) NSString *mediaType; //媒体类型 19 | 20 | @property (nonatomic,strong) UIImage *originalImage; //原image对象 21 | 22 | @property (nonatomic,strong) UIImage *editedImage; //编辑过的image对象 23 | 24 | 25 | 26 | /** 27 | * 快速解析出一个实例:系统框架照片选取 28 | */ 29 | +(instancetype)photoWithInfoDict:(NSDictionary *)infoDict; 30 | 31 | 32 | /** 33 | * 快速解析出一个实例:ALAsset 34 | */ 35 | +(instancetype)photoWithAsset:(ALAsset *)asset; 36 | 37 | 38 | /** 39 | * 解析ALAsset数据,并返回数组 40 | */ 41 | +(NSArray *)photosWithAssets:(NSArray *)assets; 42 | 43 | @end 44 | -------------------------------------------------------------------------------- /PhotoPicker/CorePhotoPickerVCManager/CorePhoto.m: -------------------------------------------------------------------------------- 1 | // 2 | // CorePhoto.m 3 | // PhotoPicker 4 | // 5 | // Created by muxi on 15/2/13. 6 | // Copyright (c) 2015年 muxi. All rights reserved. 7 | // 8 | 9 | #import "CorePhoto.h" 10 | 11 | 12 | @implementation CorePhoto 13 | 14 | 15 | /** 16 | * 快速解析出一个实例:系统框架照片选取 17 | */ 18 | +(instancetype)photoWithInfoDict:(NSDictionary *)infoDict{ 19 | 20 | CorePhoto *photo = [[CorePhoto alloc] init]; 21 | 22 | photo.editedImage=infoDict[UIImagePickerControllerEditedImage]; 23 | photo.mediaType=infoDict[UIImagePickerControllerMediaType]; 24 | photo.originalImage=infoDict[UIImagePickerControllerOriginalImage]; 25 | photo.referenceURL=infoDict[UIImagePickerControllerReferenceURL]; 26 | return photo; 27 | } 28 | 29 | 30 | 31 | /** 32 | * 快速解析出一个实例:ALAsset 33 | */ 34 | +(instancetype)photoWithAsset:(ALAsset *)asset{ 35 | 36 | CorePhoto *photo = [[CorePhoto alloc] init]; 37 | 38 | //获取全屏图片,考虑上传此处不获取高清图片 39 | photo.editedImage=[[UIImage alloc] initWithCGImage:asset.defaultRepresentation.fullScreenImage]; 40 | 41 | return photo; 42 | } 43 | 44 | 45 | 46 | /** 47 | * 解析ALAsset数据,并返回数组 48 | */ 49 | +(NSArray *)photosWithAssets:(NSArray *)assets{ 50 | 51 | if(assets==nil || assets.count==0) return nil; 52 | 53 | NSMutableArray *assetsM=[NSMutableArray arrayWithCapacity:assets.count]; 54 | [assets enumerateObjectsUsingBlock:^(ALAsset *asset, NSUInteger idx, BOOL *stop) { 55 | CorePhoto *photo = [self photoWithAsset:asset]; 56 | [assetsM addObject:photo]; 57 | }]; 58 | 59 | return assetsM; 60 | } 61 | 62 | @end 63 | -------------------------------------------------------------------------------- /PhotoPicker/CorePhotoPickerVCManager/CorePhotoPickerVCManager.h: -------------------------------------------------------------------------------- 1 | // 2 | // CorePhotoPickerVC.h 3 | // PhotoPicker 4 | // 5 | // Created by muxi on 15/2/13. 6 | // Copyright (c) 2015年 muxi. All rights reserved. 7 | // 照片选取控制器 8 | 9 | #import 10 | #import "CorePhoto.h" 11 | #import "HMSingleton.h" 12 | 13 | 14 | typedef void(^FinishPickingMedia)(NSArray *medias); 15 | 16 | 17 | typedef enum{ 18 | 19 | //用户拍照 20 | CorePhotoPickerVCMangerTypeCamera=0, 21 | 22 | //单张照片选取 23 | CorePhotoPickerVCMangerTypeSinglePhoto, 24 | 25 | //多张照片选取 26 | CorePhotoPickerVCMangerTypeMultiPhoto, 27 | 28 | //视频选取(暂不考虑,本框架仍可以完美支持) 29 | CorePhotoPickerVCMangerTypeVideo, 30 | 31 | }CorePhotoPickerVCMangerType; 32 | 33 | 34 | typedef enum{ 35 | 36 | //无错误,可用 37 | CorePhotoPickerUnavailableTypeNone, 38 | 39 | //相机不可用 40 | CorePhotoPickerUnavailableTypeCamera, 41 | 42 | //相册不可用 43 | CorePhotoPickerUnavailableTypePhoto, 44 | 45 | }CorePhotoPickerUnavailableType; 46 | 47 | 48 | 49 | @interface CorePhotoPickerVCManager : NSObject 50 | HMSingletonH(CorePhotoPickerVCManager) 51 | 52 | //照片选取器类型 53 | @property (nonatomic,assign) CorePhotoPickerVCMangerType pickerVCManagerType; 54 | 55 | //照片选取器不可用类型 56 | @property (nonatomic,assign) CorePhotoPickerUnavailableType unavailableType; 57 | 58 | //照片选取控制器 59 | @property (nonatomic,strong) UIViewController *imagePickerController; 60 | 61 | //选取结束block 62 | @property (nonatomic,copy) FinishPickingMedia finishPickingMedia; 63 | 64 | /** 65 | * 多选参数,单行此属性将自动忽略 66 | * 此属性=0,表示不限制 67 | */ 68 | @property (nonatomic,assign) NSInteger maxSelectedPhotoNumber; //最多可选取的照片数量 69 | 70 | 71 | 72 | 73 | @end 74 | -------------------------------------------------------------------------------- /PhotoPicker/CorePhotoPickerVCManager/CorePhotoPickerVCManager.m: -------------------------------------------------------------------------------- 1 | // 2 | // CorePhotoPickerVC.m 3 | // PhotoPicker 4 | // 5 | // Created by muxi on 15/2/13. 6 | // Copyright (c) 2015年 muxi. All rights reserved. 7 | // 8 | 9 | #import "CorePhotoPickerVCManager.h" 10 | #import "UzysAssetsPickerController.h" 11 | 12 | @interface CorePhotoPickerVCManager () 13 | 14 | //相册多选控制器 15 | @property (nonatomic,strong) UzysAssetsPickerController *multiImagePickerController; 16 | 17 | @end 18 | 19 | @implementation CorePhotoPickerVCManager 20 | HMSingletonM(CorePhotoPickerVCManager) 21 | 22 | 23 | /** 24 | * 选取器类型 25 | */ 26 | -(void)setPickerVCManagerType:(CorePhotoPickerVCMangerType)pickerVCManagerType{ 27 | 28 | //记录 29 | _pickerVCManagerType=pickerVCManagerType; 30 | 31 | //只有设置了值,才能确定照片选取器 32 | //初始化照片选取器 33 | [self pickerVCPrepareWithManagerType:pickerVCManagerType]; 34 | } 35 | 36 | 37 | /** 38 | * 初始化照片选取器 39 | */ 40 | -(void)pickerVCPrepareWithManagerType:(CorePhotoPickerVCMangerType)managerType{ 41 | 42 | //重置错误值 43 | self.unavailableType=CorePhotoPickerUnavailableTypeNone; 44 | 45 | if(CorePhotoPickerVCMangerTypeCamera==_pickerVCManagerType || CorePhotoPickerVCMangerTypeSinglePhoto==_pickerVCManagerType){ 46 | //这个是系统相册选取器 47 | //sourceType 48 | UIImagePickerControllerSourceType sourceType=[self tranformCorePhotoPickerVCMangerTypeForSourceType:managerType]; 49 | 50 | UIImagePickerController *imagePickerController=[[UIImagePickerController alloc] init]; 51 | 52 | //判断是否可用 53 | BOOL isSourceTypeAvailable = [UIImagePickerController isSourceTypeAvailable:sourceType]; 54 | 55 | if(!isSourceTypeAvailable){ 56 | //不可用,直接抛出错误 57 | self.unavailableType=[self tranformCorePhotoPickerVCMangerTypeForUnavailableType:managerType]; 58 | NSLog(@"当前设备不可用:%@",@(managerType)); 59 | return; 60 | } 61 | 62 | //错误处理完毕,配置照片选取控制器 63 | //类型 64 | imagePickerController.sourceType=sourceType; 65 | 66 | //允许编辑 67 | imagePickerController.allowsEditing=YES; 68 | 69 | //代理 70 | imagePickerController.delegate=self; 71 | 72 | //记录控制器 73 | self.imagePickerController=imagePickerController; 74 | 75 | }else if (CorePhotoPickerVCMangerTypeMultiPhoto==_pickerVCManagerType){ 76 | //这个是第三方多张照片选取器 77 | 78 | UzysAssetsPickerController *multiImagePickerController=[[UzysAssetsPickerController alloc] init]; 79 | 80 | //记录控制器 81 | self.multiImagePickerController=multiImagePickerController; 82 | 83 | //暂不支持选视频 84 | multiImagePickerController.maximumNumberOfSelectionVideo=0; 85 | 86 | //初始化最大允许选取的图片数量 87 | multiImagePickerController.maximumNumberOfSelectionPhoto=MAXFLOAT; 88 | 89 | //设置代理 90 | multiImagePickerController.delegate=self; 91 | 92 | //记录控制器 93 | self.imagePickerController=multiImagePickerController; 94 | 95 | }else{ 96 | //视频选取器,暂不支持 97 | } 98 | } 99 | 100 | 101 | 102 | 103 | 104 | 105 | -(void)setMaxSelectedPhotoNumber:(NSInteger)maxSelectedPhotoNumber{ 106 | 107 | if(maxSelectedPhotoNumber<=0) return; 108 | 109 | //记录 110 | _maxSelectedPhotoNumber=maxSelectedPhotoNumber; 111 | 112 | if(self.multiImagePickerController==nil) return; 113 | 114 | //设置 115 | self.multiImagePickerController.maximumNumberOfSelectionPhoto=maxSelectedPhotoNumber; 116 | } 117 | 118 | 119 | 120 | 121 | #pragma mark -系统自带控制器选取相册代理方法区 122 | #pragma mark 选取了照片 123 | -(void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info{ 124 | 125 | //关闭自己 126 | [picker dismissViewControllerAnimated:YES completion:^{ 127 | 128 | CorePhoto *photo=[CorePhoto photoWithInfoDict:info]; 129 | 130 | if(self.finishPickingMedia != nil) _finishPickingMedia(@[photo]); 131 | }]; 132 | } 133 | 134 | #pragma mark 点击了取消按钮 135 | -(void)imagePickerControllerDidCancel:(UIImagePickerController *)picker{ 136 | 137 | //直接取消 138 | [picker dismissViewControllerAnimated:YES completion:nil]; 139 | } 140 | 141 | 142 | #pragma mark - 多选代理方法区 143 | 144 | -(void)uzysAssetsPickerController:(UzysAssetsPickerController *)picker didFinishPickingAssets:(NSArray *)assets{ 145 | 146 | //获取相册数组 147 | NSArray *photos=[CorePhoto photosWithAssets:assets]; 148 | 149 | if(self.finishPickingMedia != nil) _finishPickingMedia(photos); 150 | } 151 | 152 | #pragma mark 超过选取上限 153 | -(void)uzysAssetsPickerControllerDidExceedMaximumNumberOfSelection:(UzysAssetsPickerController *)picker{ 154 | NSLog(@"超过选取上限"); 155 | } 156 | 157 | #pragma mark 取消 158 | -(void)uzysAssetsPickerControllerDidCancel:(UzysAssetsPickerController *)picker{ 159 | //直接取消:无需操作 160 | } 161 | 162 | 163 | 164 | /** 165 | * CorePhotoPickerVCMangerType 转 UIImagePickerControllerSourceType 166 | */ 167 | -(UIImagePickerControllerSourceType)tranformCorePhotoPickerVCMangerTypeForSourceType:(CorePhotoPickerVCMangerType)type{ 168 | 169 | if(CorePhotoPickerVCMangerTypeCamera == type) return UIImagePickerControllerSourceTypeCamera; 170 | 171 | if(CorePhotoPickerVCMangerTypeSinglePhoto == type) return UIImagePickerControllerSourceTypePhotoLibrary; 172 | 173 | return 0; 174 | } 175 | 176 | /** 177 | * CorePhotoPickerVCMangerType 转 CorePhotoPickerUnavailableType 178 | */ 179 | -(CorePhotoPickerUnavailableType)tranformCorePhotoPickerVCMangerTypeForUnavailableType:(CorePhotoPickerVCMangerType)type{ 180 | 181 | if(CorePhotoPickerVCMangerTypeCamera == type) return CorePhotoPickerUnavailableTypeCamera; 182 | 183 | if(CorePhotoPickerVCMangerTypeSinglePhoto == type) return CorePhotoPickerUnavailableTypePhoto; 184 | 185 | return 0; 186 | } 187 | 188 | @end 189 | -------------------------------------------------------------------------------- /PhotoPicker/CorePhotoPickerVCManager/HMSingleton.h: -------------------------------------------------------------------------------- 1 | // .h文件 2 | #define HMSingletonH(name) + (instancetype)shared##name; 3 | 4 | // .m文件 5 | #if __has_feature(objc_arc) 6 | 7 | #define HMSingletonM(name) \ 8 | static id _instace; \ 9 | \ 10 | + (id)allocWithZone:(struct _NSZone *)zone \ 11 | { \ 12 | static dispatch_once_t onceToken; \ 13 | dispatch_once(&onceToken, ^{ \ 14 | _instace = [super allocWithZone:zone]; \ 15 | }); \ 16 | return _instace; \ 17 | } \ 18 | \ 19 | + (instancetype)shared##name \ 20 | { \ 21 | static dispatch_once_t onceToken; \ 22 | dispatch_once(&onceToken, ^{ \ 23 | _instace = [[self alloc] init]; \ 24 | }); \ 25 | return _instace; \ 26 | } \ 27 | \ 28 | - (id)copyWithZone:(NSZone *)zone \ 29 | { \ 30 | return _instace; \ 31 | } 32 | 33 | #else 34 | 35 | #define HMSingletonM(name) \ 36 | static id _instace; \ 37 | \ 38 | + (id)allocWithZone:(struct _NSZone *)zone \ 39 | { \ 40 | static dispatch_once_t onceToken; \ 41 | dispatch_once(&onceToken, ^{ \ 42 | _instace = [super allocWithZone:zone]; \ 43 | }); \ 44 | return _instace; \ 45 | } \ 46 | \ 47 | + (instancetype)shared##name \ 48 | { \ 49 | static dispatch_once_t onceToken; \ 50 | dispatch_once(&onceToken, ^{ \ 51 | _instace = [[self alloc] init]; \ 52 | }); \ 53 | return _instace; \ 54 | } \ 55 | \ 56 | - (id)copyWithZone:(NSZone *)zone \ 57 | { \ 58 | return _instace; \ 59 | } \ 60 | \ 61 | - (oneway void)release { } \ 62 | - (id)retain { return self; } \ 63 | - (NSUInteger)retainCount { return 1;} \ 64 | - (id)autorelease { return self;} 65 | 66 | #endif -------------------------------------------------------------------------------- /PhotoPicker/CorePhotoPickerVCManager/Library/UIImage+UzysExtension.h: -------------------------------------------------------------------------------- 1 | // 2 | // UIImage+UzysExtension.h 3 | // UzysAssetsPickerController 4 | // 5 | // Created by jianpx on 8/26/14. 6 | // Copyright (c) 2014 Uzys. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface UIImage (UzysExtension) 12 | 13 | /** 14 | * First search main bundle, if find the image return it, otherwise search the UzysAssertPickerController.bundle to get the image. 15 | * 16 | * @param imageName name of the image. 17 | * 18 | * @return UIImage instance or nil 19 | */ 20 | + (UIImage *)Uzys_imageNamed:(NSString *)imageName; 21 | @end 22 | -------------------------------------------------------------------------------- /PhotoPicker/CorePhotoPickerVCManager/Library/UIImage+UzysExtension.m: -------------------------------------------------------------------------------- 1 | // 2 | // UIImage+UzysExtension.m 3 | // UzysAssetsPickerController 4 | // 5 | // Created by jianpx on 8/26/14. 6 | // Copyright (c) 2014 Uzys. All rights reserved. 7 | // 8 | 9 | #import "UIImage+UzysExtension.h" 10 | #import "UzysAssetsPickerController.h" 11 | 12 | @implementation UIImage (UzysExtension) 13 | 14 | + (UIImage *)Uzys_imageNamed:(NSString *)imageName 15 | { 16 | UIImage *image = [[self class] imageNamed:imageName]; 17 | if (image) { 18 | return image; 19 | } 20 | NSString *imagePathInControllerBundle = [NSString stringWithFormat:@"UzysAssetPickerController.bundle/%@", imageName]; 21 | image = [[self class] imageNamed:imagePathInControllerBundle]; 22 | if(image) { 23 | return image; 24 | } 25 | //for Swift podfile 26 | NSString *imagePathInBundleForClass = [NSString stringWithFormat:@"%@/UzysAssetPickerController.bundle/%@", [[NSBundle bundleForClass:[UzysAssetsPickerController class]] resourcePath], imageName ]; 27 | image = [[self class] imageNamed:imagePathInBundleForClass]; 28 | return image; 29 | } 30 | @end 31 | -------------------------------------------------------------------------------- /PhotoPicker/CorePhotoPickerVCManager/Library/UzysAppearanceConfig.h: -------------------------------------------------------------------------------- 1 | // 2 | // UzysAppearanceConfig.h 3 | // UzysAssetsPickerController 4 | // 5 | // Created by jianpx on 8/26/14. 6 | // Copyright (c) 2014 Uzys. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "UIImage+UzysExtension.h" 11 | @interface UzysAppearanceConfig : NSObject 12 | //selected photo/video checkmark 13 | @property (nonatomic, strong) NSString *assetSelectedImageName; 14 | //deselected photo/video checkmark 15 | @property (nonatomic, strong) NSString *assetDeselectedImageName; 16 | @property (nonatomic, strong) NSString *assetsGroupSelectedImageName; 17 | @property (nonatomic, strong) NSString *cameraImageName; 18 | @property (nonatomic, strong) NSString *closeImageName; 19 | @property (nonatomic, strong) UIColor *finishSelectionButtonColor; 20 | // 21 | @property (nonatomic, assign) NSInteger assetsCountInALine; 22 | @property (nonatomic, assign) CGFloat cellSpacing; 23 | 24 | + (instancetype)sharedConfig; 25 | @end 26 | -------------------------------------------------------------------------------- /PhotoPicker/CorePhotoPickerVCManager/Library/UzysAppearanceConfig.m: -------------------------------------------------------------------------------- 1 | // 2 | // UzysAppearanceConfig.m 3 | // UzysAssetsPickerController 4 | // 5 | // Created by jianpx on 8/26/14. 6 | // Copyright (c) 2014 Uzys. All rights reserved. 7 | // 8 | 9 | #import "UzysAppearanceConfig.h" 10 | 11 | @implementation UzysAppearanceConfig 12 | 13 | + (instancetype)sharedConfig 14 | { 15 | static UzysAppearanceConfig *shared = nil; 16 | static dispatch_once_t onceToken; 17 | dispatch_once(&onceToken, ^{ 18 | shared = [[self alloc] init]; 19 | }); 20 | return shared; 21 | } 22 | 23 | - (instancetype)init 24 | { 25 | self = [super init]; 26 | 27 | if (self) { 28 | self.assetsCountInALine = 4; 29 | self.cellSpacing = 1.0f; 30 | } 31 | 32 | return self; 33 | } 34 | 35 | - (NSString *)assetSelectedImageName 36 | { 37 | if (!_assetSelectedImageName) { 38 | return @"uzysAP_ico_photo_thumb_check"; 39 | } 40 | return _assetSelectedImageName; 41 | } 42 | 43 | - (NSString *)assetDeselectedImageName 44 | { 45 | if (!_assetDeselectedImageName) { 46 | return @"uzysAP_ico_photo_thumb_uncheck"; 47 | } 48 | return _assetDeselectedImageName; 49 | } 50 | 51 | - (NSString *)assetsGroupSelectedImageName 52 | { 53 | if (!_assetsGroupSelectedImageName) { 54 | return @"uzysAP_ico_checkMark"; 55 | } 56 | return _assetsGroupSelectedImageName; 57 | } 58 | 59 | - (NSString *)cameraImageName 60 | { 61 | if (!_cameraImageName) { 62 | return @"uzysAP_ico_upload_camera"; 63 | } 64 | return _cameraImageName; 65 | } 66 | 67 | - (NSString *)closeImageName 68 | { 69 | if (!_closeImageName) { 70 | return @"uzysAP_navi_icon_close"; 71 | } 72 | return _closeImageName; 73 | } 74 | 75 | - (UIColor *)finishSelectionButtonColor 76 | { 77 | if (!_finishSelectionButtonColor) { 78 | return [UIColor redColor]; 79 | } 80 | return _finishSelectionButtonColor; 81 | } 82 | 83 | @end 84 | -------------------------------------------------------------------------------- /PhotoPicker/CorePhotoPickerVCManager/Library/UzysAssetPickerController.bundle/uzysAP_ico_arrow_upload_album_d@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CharlinFeng/CorePhotoPickerVCManager/b779b2c2ee025857c95b18345328080061b24909/PhotoPicker/CorePhotoPickerVCManager/Library/UzysAssetPickerController.bundle/uzysAP_ico_arrow_upload_album_d@2x.png -------------------------------------------------------------------------------- /PhotoPicker/CorePhotoPickerVCManager/Library/UzysAssetPickerController.bundle/uzysAP_ico_assets_video@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CharlinFeng/CorePhotoPickerVCManager/b779b2c2ee025857c95b18345328080061b24909/PhotoPicker/CorePhotoPickerVCManager/Library/UzysAssetPickerController.bundle/uzysAP_ico_assets_video@2x.png -------------------------------------------------------------------------------- /PhotoPicker/CorePhotoPickerVCManager/Library/UzysAssetPickerController.bundle/uzysAP_ico_checkMark@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CharlinFeng/CorePhotoPickerVCManager/b779b2c2ee025857c95b18345328080061b24909/PhotoPicker/CorePhotoPickerVCManager/Library/UzysAssetPickerController.bundle/uzysAP_ico_checkMark@2x.png -------------------------------------------------------------------------------- /PhotoPicker/CorePhotoPickerVCManager/Library/UzysAssetPickerController.bundle/uzysAP_ico_no_access@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CharlinFeng/CorePhotoPickerVCManager/b779b2c2ee025857c95b18345328080061b24909/PhotoPicker/CorePhotoPickerVCManager/Library/UzysAssetPickerController.bundle/uzysAP_ico_no_access@2x.png -------------------------------------------------------------------------------- /PhotoPicker/CorePhotoPickerVCManager/Library/UzysAssetPickerController.bundle/uzysAP_ico_no_image@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CharlinFeng/CorePhotoPickerVCManager/b779b2c2ee025857c95b18345328080061b24909/PhotoPicker/CorePhotoPickerVCManager/Library/UzysAssetPickerController.bundle/uzysAP_ico_no_image@2x.png -------------------------------------------------------------------------------- /PhotoPicker/CorePhotoPickerVCManager/Library/UzysAssetPickerController.bundle/uzysAP_ico_no_video@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CharlinFeng/CorePhotoPickerVCManager/b779b2c2ee025857c95b18345328080061b24909/PhotoPicker/CorePhotoPickerVCManager/Library/UzysAssetPickerController.bundle/uzysAP_ico_no_video@2x.png -------------------------------------------------------------------------------- /PhotoPicker/CorePhotoPickerVCManager/Library/UzysAssetPickerController.bundle/uzysAP_ico_photo_thumb_check@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CharlinFeng/CorePhotoPickerVCManager/b779b2c2ee025857c95b18345328080061b24909/PhotoPicker/CorePhotoPickerVCManager/Library/UzysAssetPickerController.bundle/uzysAP_ico_photo_thumb_check@2x.png -------------------------------------------------------------------------------- /PhotoPicker/CorePhotoPickerVCManager/Library/UzysAssetPickerController.bundle/uzysAP_ico_photo_thumb_check@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CharlinFeng/CorePhotoPickerVCManager/b779b2c2ee025857c95b18345328080061b24909/PhotoPicker/CorePhotoPickerVCManager/Library/UzysAssetPickerController.bundle/uzysAP_ico_photo_thumb_check@3x.png -------------------------------------------------------------------------------- /PhotoPicker/CorePhotoPickerVCManager/Library/UzysAssetPickerController.bundle/uzysAP_ico_photo_thumb_uncheck@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CharlinFeng/CorePhotoPickerVCManager/b779b2c2ee025857c95b18345328080061b24909/PhotoPicker/CorePhotoPickerVCManager/Library/UzysAssetPickerController.bundle/uzysAP_ico_photo_thumb_uncheck@2x.png -------------------------------------------------------------------------------- /PhotoPicker/CorePhotoPickerVCManager/Library/UzysAssetPickerController.bundle/uzysAP_ico_photo_thumb_uncheck@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CharlinFeng/CorePhotoPickerVCManager/b779b2c2ee025857c95b18345328080061b24909/PhotoPicker/CorePhotoPickerVCManager/Library/UzysAssetPickerController.bundle/uzysAP_ico_photo_thumb_uncheck@3x.png -------------------------------------------------------------------------------- /PhotoPicker/CorePhotoPickerVCManager/Library/UzysAssetPickerController.bundle/uzysAP_ico_upload_camera@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CharlinFeng/CorePhotoPickerVCManager/b779b2c2ee025857c95b18345328080061b24909/PhotoPicker/CorePhotoPickerVCManager/Library/UzysAssetPickerController.bundle/uzysAP_ico_upload_camera@2x.png -------------------------------------------------------------------------------- /PhotoPicker/CorePhotoPickerVCManager/Library/UzysAssetPickerController.bundle/uzysAP_ico_upload_camera@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CharlinFeng/CorePhotoPickerVCManager/b779b2c2ee025857c95b18345328080061b24909/PhotoPicker/CorePhotoPickerVCManager/Library/UzysAssetPickerController.bundle/uzysAP_ico_upload_camera@3x.png -------------------------------------------------------------------------------- /PhotoPicker/CorePhotoPickerVCManager/Library/UzysAssetPickerController.bundle/uzysAP_ico_upload_done@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CharlinFeng/CorePhotoPickerVCManager/b779b2c2ee025857c95b18345328080061b24909/PhotoPicker/CorePhotoPickerVCManager/Library/UzysAssetPickerController.bundle/uzysAP_ico_upload_done@2x.png -------------------------------------------------------------------------------- /PhotoPicker/CorePhotoPickerVCManager/Library/UzysAssetPickerController.bundle/uzysAP_navi_icon_close@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CharlinFeng/CorePhotoPickerVCManager/b779b2c2ee025857c95b18345328080061b24909/PhotoPicker/CorePhotoPickerVCManager/Library/UzysAssetPickerController.bundle/uzysAP_navi_icon_close@2x.png -------------------------------------------------------------------------------- /PhotoPicker/CorePhotoPickerVCManager/Library/UzysAssetsPickerController.h: -------------------------------------------------------------------------------- 1 | // 2 | // UzysAssetsPickerController.h 3 | // UzysAssetsPickerController 4 | // 5 | // Created by Uzysjung on 2014. 2. 12.. 6 | // Copyright (c) 2014년 Uzys. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "UzysAssetsPickerController_Configuration.h" 11 | #import "UzysAppearanceConfig.h" 12 | #import 13 | 14 | @class UzysAssetsPickerController; 15 | @protocol UzysAssetsPickerControllerDelegate 16 | - (void)uzysAssetsPickerController:(UzysAssetsPickerController *)picker didFinishPickingAssets:(NSArray *)assets; 17 | @optional 18 | - (void)uzysAssetsPickerControllerDidCancel:(UzysAssetsPickerController *)picker; 19 | - (void)uzysAssetsPickerControllerDidExceedMaximumNumberOfSelection:(UzysAssetsPickerController *)picker; 20 | @end 21 | 22 | @interface UzysAssetsPickerController : UIViewController 23 | @property (nonatomic, strong) ALAssetsFilter *assetsFilter; 24 | @property (nonatomic, strong) CLLocation * location; 25 | @property (nonatomic, assign) NSInteger maximumNumberOfSelectionVideo; 26 | @property (nonatomic, assign) NSInteger maximumNumberOfSelectionPhoto; 27 | //-------------------------------------------------------------------- 28 | @property (nonatomic, assign) NSInteger maximumNumberOfSelectionMedia; 29 | 30 | @property (nonatomic, weak) id delegate; 31 | + (ALAssetsLibrary *)defaultAssetsLibrary; 32 | /** 33 | * setup the appearance, including the all the properties in UzysAppearanceConfig, check UzysAppearanceConfig.h out for details. 34 | * 35 | * @param config UzysAppearanceConfig instance. 36 | */ 37 | + (void)setUpAppearanceConfig:(UzysAppearanceConfig *)config; 38 | 39 | @end 40 | -------------------------------------------------------------------------------- /PhotoPicker/CorePhotoPickerVCManager/Library/UzysAssetsPickerController.m: -------------------------------------------------------------------------------- 1 | // 2 | // UzysAssetsPickerController.m 3 | // UzysAssetsPickerController 4 | // 5 | // Created by Uzysjung on 2014. 2. 12.. 6 | // Copyright (c) 2014년 Uzys. All rights reserved. 7 | // 8 | #import "UzysAssetsPickerController.h" 9 | #import "UzysAssetsViewCell.h" 10 | #import "UzysWrapperPickerController.h" 11 | #import "UzysGroupPickerView.h" 12 | #import 13 | 14 | @interface UzysAssetsPickerController () 15 | //View 16 | @property (weak, nonatomic) IBOutlet UIImageView *imageViewTitleArrow; 17 | @property (weak, nonatomic) IBOutlet UIButton *btnTitle; 18 | @property (weak, nonatomic) IBOutlet UIButton *btnDone; 19 | @property (weak, nonatomic) IBOutlet UIView *navigationTop; 20 | @property (weak, nonatomic) IBOutlet UIView *bottomView; 21 | @property (weak, nonatomic) IBOutlet UISegmentedControl *segmentedControl; 22 | @property (weak, nonatomic) IBOutlet UILabel *labelSelectedMedia; 23 | @property (weak, nonatomic) IBOutlet UIButton *btnCamera; 24 | @property (weak, nonatomic) IBOutlet UIButton *btnClose; 25 | 26 | @property (nonatomic, strong) UIView *noAssetView; 27 | @property (nonatomic, strong) UICollectionView *collectionView; 28 | @property (nonatomic, strong) UzysWrapperPickerController *picker; 29 | @property (nonatomic, strong) UzysGroupPickerView *groupPicker; 30 | //@property (nonatomic, strong) UzysGroupPickerViewController *groupPicker; 31 | 32 | @property (nonatomic, strong) ALAssetsGroup *assetsGroup; 33 | @property (nonatomic, strong) NSMutableArray *groups; 34 | @property (nonatomic, strong) ALAssetsLibrary *assetsLibrary; 35 | 36 | @property (nonatomic, strong) NSMutableArray *assets; 37 | @property (nonatomic, assign) NSInteger numberOfPhotos; 38 | @property (nonatomic, assign) NSInteger numberOfVideos; 39 | @property (nonatomic, assign) NSInteger maximumNumberOfSelection; 40 | @property (nonatomic, assign) NSInteger curAssetFilterType; 41 | 42 | @property (nonatomic, strong) NSMutableArray *orderedSelectedItem; 43 | 44 | - (IBAction)btnAction:(id)sender; 45 | - (IBAction)indexDidChangeForSegmentedControl:(id)sender; 46 | 47 | @end 48 | 49 | @implementation UzysAssetsPickerController 50 | 51 | @synthesize location; 52 | 53 | #pragma mark - ALAssetsLibrary 54 | 55 | + (ALAssetsLibrary *)defaultAssetsLibrary 56 | { 57 | static dispatch_once_t pred = 0; 58 | static ALAssetsLibrary *library = nil; 59 | dispatch_once(&pred,^ 60 | { 61 | library = [[ALAssetsLibrary alloc] init]; 62 | }); 63 | return library; 64 | } 65 | 66 | 67 | - (id)init 68 | { 69 | self = [super initWithNibName:@"UzysAssetsPickerController" bundle:[NSBundle bundleForClass:[UzysAssetsPickerController class]]]; 70 | if(self) 71 | { 72 | [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(assetsLibraryUpdated:) name:ALAssetsLibraryChangedNotification object:nil]; 73 | } 74 | return self; 75 | } 76 | - (void)dealloc 77 | { 78 | [[NSNotificationCenter defaultCenter] removeObserver:self name:ALAssetsLibraryChangedNotification object:nil]; 79 | self.assetsLibrary = nil; 80 | self.assetsGroup = nil; 81 | self.assets = nil; 82 | } 83 | - (void)didReceiveMemoryWarning 84 | { 85 | [super didReceiveMemoryWarning]; 86 | // Dispose of any resources that can be recreated. 87 | } 88 | - (void)viewDidLoad 89 | { 90 | [super viewDidLoad]; 91 | // Do any additional setup after loading the view from its nib. 92 | [self initVariable]; 93 | [self initImagePicker]; 94 | [self setupOneMediaTypeSelection]; 95 | 96 | __weak typeof(self) weakSelf = self; 97 | [self setupGroup:^{ 98 | [weakSelf.groupPicker.tableView selectRowAtIndexPath:[NSIndexPath indexPathForRow:0 inSection:0] animated:NO scrollPosition:UITableViewScrollPositionNone]; 99 | } withSetupAsset:YES]; 100 | [self setupLayout]; 101 | [self setupCollectionView]; 102 | [self setupGroupPickerview]; 103 | [self initNoAssetView]; 104 | 105 | } 106 | 107 | - (void)initVariable 108 | { 109 | // self.assetsFilter = [ALAssetsFilter allPhotos]; 110 | [self setAssetsFilter:[ALAssetsFilter allPhotos] type:1]; 111 | self.maximumNumberOfSelection = self.maximumNumberOfSelectionPhoto; 112 | self.view.clipsToBounds = YES; 113 | self.orderedSelectedItem = [[NSMutableArray alloc] init]; 114 | } 115 | - (void)initImagePicker 116 | { 117 | UzysWrapperPickerController *picker = [[UzysWrapperPickerController alloc] init]; 118 | // picker.modalPresentationStyle = UIModalPresentationCurrentContext; 119 | picker.delegate = self; 120 | picker.allowsEditing = NO; 121 | picker.videoQuality = UIImagePickerControllerQualityTypeHigh; 122 | if ([UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypeCamera]) 123 | { 124 | NSArray *availableMediaTypes = 125 | [UIImagePickerController availableMediaTypesForSourceType: 126 | UIImagePickerControllerSourceTypeCamera]; 127 | NSMutableArray *mediaTypes = [NSMutableArray arrayWithArray:availableMediaTypes]; 128 | 129 | if (_maximumNumberOfSelectionMedia == 0) 130 | { 131 | if (_maximumNumberOfSelectionPhoto == 0) 132 | [mediaTypes removeObject:@"public.image"]; 133 | else if (_maximumNumberOfSelectionVideo == 0) 134 | [mediaTypes removeObject:@"public.movie"]; 135 | } 136 | 137 | picker.sourceType = UIImagePickerControllerSourceTypeCamera; 138 | picker.mediaTypes = mediaTypes; 139 | } 140 | self.picker = picker; 141 | } 142 | - (void)setupLayout 143 | { 144 | UzysAppearanceConfig *appearanceConfig = [UzysAppearanceConfig sharedConfig]; 145 | [self.btnCamera setImage:[UIImage Uzys_imageNamed:appearanceConfig.cameraImageName] forState:UIControlStateNormal]; 146 | [self.btnClose setImage:[UIImage Uzys_imageNamed:appearanceConfig.closeImageName] forState:UIControlStateNormal]; 147 | self.btnDone.layer.cornerRadius = 15; 148 | self.btnDone.clipsToBounds = YES; 149 | [self.btnDone setBackgroundColor:appearanceConfig.finishSelectionButtonColor]; 150 | 151 | UIView *lineView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, [UIScreen mainScreen].bounds.size.width, 0.5)]; 152 | lineView.backgroundColor = [UIColor colorWithWhite:0 alpha:0.15f]; 153 | [self.bottomView addSubview:lineView]; 154 | } 155 | - (void)setupGroupPickerview 156 | { 157 | __weak typeof(self) weakSelf = self; 158 | self.groupPicker = [[UzysGroupPickerView alloc] initWithGroups:self.groups]; 159 | self.groupPicker.blockTouchCell = ^(NSInteger row){ 160 | [weakSelf changeGroup:row]; 161 | }; 162 | 163 | [self.view insertSubview:self.groupPicker aboveSubview:self.bottomView]; 164 | [self.view bringSubviewToFront:self.navigationTop]; 165 | [self menuArrowRotate]; 166 | 167 | } 168 | - (void)setupOneMediaTypeSelection 169 | { 170 | if(_maximumNumberOfSelectionMedia > 0) 171 | { 172 | // self.assetsFilter = [ALAssetsFilter allAssets]; 173 | [self setAssetsFilter:[ALAssetsFilter allAssets] type:0]; 174 | self.maximumNumberOfSelection = self.maximumNumberOfSelectionMedia; 175 | self.segmentedControl.hidden = YES; 176 | self.labelSelectedMedia.hidden = NO; 177 | if(_maximumNumberOfSelection > 1) 178 | self.labelSelectedMedia.text = NSLocalizedStringFromTable(@"Choose media", @"UzysAssetsPickerController", nil); 179 | else 180 | self.labelSelectedMedia.text = NSLocalizedStringFromTable(@"Choose a media", @"UzysAssetsPickerController", nil); 181 | 182 | } 183 | else 184 | { 185 | if(_maximumNumberOfSelectionPhoto == 0) 186 | { 187 | // self.assetsFilter = [ALAssetsFilter allVideos]; 188 | [self setAssetsFilter:[ALAssetsFilter allVideos] type:2]; 189 | 190 | self.maximumNumberOfSelection = self.maximumNumberOfSelectionVideo; 191 | self.segmentedControl.hidden = YES; 192 | self.labelSelectedMedia.hidden = NO; 193 | if(_maximumNumberOfSelection > 1) 194 | self.labelSelectedMedia.text = NSLocalizedStringFromTable(@"Choose videos", @"UzysAssetsPickerController", nil); 195 | else 196 | self.labelSelectedMedia.text = NSLocalizedStringFromTable(@"Choose a video", @"UzysAssetsPickerController", nil); 197 | } 198 | else if(_maximumNumberOfSelectionVideo == 0) 199 | { 200 | // self.assetsFilter = [ALAssetsFilter allPhotos]; 201 | [self setAssetsFilter:[ALAssetsFilter allPhotos] type:1]; 202 | 203 | self.segmentedControl.selectedSegmentIndex = 0; 204 | self.maximumNumberOfSelection = self.maximumNumberOfSelectionPhoto; 205 | self.segmentedControl.hidden = YES; 206 | self.labelSelectedMedia.hidden = NO; 207 | if(_maximumNumberOfSelection >1) 208 | self.labelSelectedMedia.text = NSLocalizedStringFromTable(@"Choose photos", @"UzysAssetsPickerController", nil); 209 | else 210 | self.labelSelectedMedia.text = NSLocalizedStringFromTable(@"Choose a photo", @"UzysAssetsPickerController", nil); 211 | } 212 | else 213 | { 214 | self.segmentedControl.hidden = NO; 215 | self.labelSelectedMedia.hidden = YES; 216 | } 217 | 218 | } 219 | } 220 | 221 | - (void)setupCollectionView 222 | { 223 | 224 | UICollectionViewFlowLayout *layout = [[UICollectionViewFlowLayout alloc] init]; 225 | 226 | UzysAppearanceConfig *appearanceConfig = [UzysAppearanceConfig sharedConfig]; 227 | 228 | CGFloat itemWidth = ([UIScreen mainScreen].bounds.size.width - appearanceConfig.cellSpacing * ((CGFloat)appearanceConfig.assetsCountInALine - 1.0f)) / (CGFloat)appearanceConfig.assetsCountInALine; 229 | layout.itemSize = CGSizeMake(itemWidth, itemWidth); 230 | layout.sectionInset = UIEdgeInsetsMake(1.0, 0, 0, 0); 231 | layout.minimumInteritemSpacing = 1.0; 232 | layout.minimumLineSpacing = appearanceConfig.cellSpacing; 233 | 234 | self.collectionView = [[UICollectionView alloc] initWithFrame:CGRectMake(0, 64, [UIScreen mainScreen].bounds.size.width, [UIScreen mainScreen].bounds.size.height - 64 -48) collectionViewLayout:layout]; 235 | self.collectionView.allowsMultipleSelection = YES; 236 | [self.collectionView registerClass:[UzysAssetsViewCell class] 237 | forCellWithReuseIdentifier:kAssetsViewCellIdentifier]; 238 | 239 | self.collectionView.delegate = self; 240 | self.collectionView.dataSource = self; 241 | self.collectionView.backgroundColor = [UIColor whiteColor]; 242 | self.collectionView.bounces = YES; 243 | self.collectionView.alwaysBounceVertical = YES; 244 | self.collectionView.scrollsToTop = YES; 245 | 246 | [self.view insertSubview:self.collectionView atIndex:0]; 247 | } 248 | #pragma mark - Property 249 | - (void)setAssetsFilter:(ALAssetsFilter *)assetsFilter type:(NSInteger)type 250 | { 251 | _assetsFilter = assetsFilter; 252 | _curAssetFilterType = type; 253 | } 254 | #pragma mark - public methods 255 | + (void)setUpAppearanceConfig:(UzysAppearanceConfig *)config 256 | { 257 | UzysAppearanceConfig *appearanceConfig = [UzysAppearanceConfig sharedConfig]; 258 | appearanceConfig.assetSelectedImageName = config.assetSelectedImageName; 259 | appearanceConfig.assetDeselectedImageName = config.assetDeselectedImageName; 260 | appearanceConfig.cameraImageName = config.cameraImageName; 261 | appearanceConfig.finishSelectionButtonColor = config.finishSelectionButtonColor; 262 | appearanceConfig.assetsGroupSelectedImageName = config.assetsGroupSelectedImageName; 263 | appearanceConfig.closeImageName = config.closeImageName; 264 | appearanceConfig.assetsCountInALine = config.assetsCountInALine; 265 | appearanceConfig.cellSpacing = config.cellSpacing; 266 | } 267 | 268 | - (void)changeGroup:(NSInteger)item 269 | { 270 | self.assetsGroup = self.groups[item]; 271 | [self setupAssets:nil]; 272 | [self.groupPicker.tableView selectRowAtIndexPath:[NSIndexPath indexPathForRow:item inSection:0] animated:NO scrollPosition:UITableViewScrollPositionNone]; 273 | [self.groupPicker dismiss:YES]; 274 | [self.orderedSelectedItem removeAllObjects]; 275 | [self menuArrowRotate]; 276 | } 277 | - (void)changeAssetType:(BOOL)isPhoto endBlock:(voidBlock)endBlock 278 | { 279 | if(isPhoto) 280 | { 281 | self.maximumNumberOfSelection = self.maximumNumberOfSelectionPhoto; 282 | // self.assetsFilter = [ALAssetsFilter allPhotos]; 283 | [self setAssetsFilter:[ALAssetsFilter allPhotos] type:1]; 284 | 285 | [self setupAssets:endBlock]; 286 | } 287 | else 288 | { 289 | self.maximumNumberOfSelection = self.maximumNumberOfSelectionVideo; 290 | // self.assetsFilter = [ALAssetsFilter allVideos]; 291 | [self setAssetsFilter:[ALAssetsFilter allVideos] type:2]; 292 | 293 | [self setupAssets:endBlock]; 294 | 295 | } 296 | } 297 | - (void)setupGroup:(voidBlock)endblock withSetupAsset:(BOOL)doSetupAsset 298 | { 299 | if (!self.assetsLibrary) 300 | { 301 | self.assetsLibrary = [self.class defaultAssetsLibrary]; 302 | } 303 | 304 | if (!self.groups) 305 | self.groups = [[NSMutableArray alloc] init]; 306 | else 307 | [self.groups removeAllObjects]; 308 | 309 | 310 | __weak typeof(self) weakSelf = self; 311 | 312 | ALAssetsFilter *assetsFilter = self.assetsFilter; // number of Asset 메쏘드 호출 시에 적용. 313 | 314 | ALAssetsLibraryGroupsEnumerationResultsBlock resultsBlock = ^(ALAssetsGroup *group, BOOL *stop) { 315 | __strong typeof(weakSelf) strongSelf = weakSelf; 316 | if (group) 317 | { 318 | [group setAssetsFilter:assetsFilter]; 319 | NSInteger groupType = [[group valueForProperty:ALAssetsGroupPropertyType] integerValue]; 320 | if(groupType == ALAssetsGroupSavedPhotos) 321 | { 322 | [strongSelf.groups insertObject:group atIndex:0]; 323 | if(doSetupAsset) 324 | { 325 | strongSelf.assetsGroup = group; 326 | [strongSelf setupAssets:nil]; 327 | } 328 | } 329 | else 330 | { 331 | if (group.numberOfAssets > 0) 332 | [strongSelf.groups addObject:group]; 333 | } 334 | } 335 | //traverse to the end, so reload groupPicker. 336 | else 337 | { 338 | dispatch_async(dispatch_get_main_queue(), ^{ 339 | [weakSelf.groupPicker reloadData]; 340 | NSUInteger selectedIndex = [weakSelf indexOfAssetGroup:weakSelf.assetsGroup inGroups:weakSelf.groups]; 341 | if (selectedIndex != NSNotFound) { 342 | [weakSelf.groupPicker.tableView selectRowAtIndexPath:[NSIndexPath indexPathForRow:selectedIndex inSection:0] animated:YES scrollPosition:UITableViewScrollPositionNone]; 343 | } 344 | if(endblock) 345 | endblock(); 346 | }); 347 | } 348 | }; 349 | 350 | ALAssetsLibraryAccessFailureBlock failureBlock = ^(NSError *error) { 351 | __strong typeof(weakSelf) strongSelf = weakSelf; 352 | //접근이 허락 안되었을 경우 353 | [strongSelf showNotAllowed]; 354 | strongSelf.segmentedControl.enabled = NO; 355 | strongSelf.btnDone.enabled = NO; 356 | strongSelf.btnCamera.enabled = NO; 357 | [strongSelf setTitle:NSLocalizedStringFromTable(@"Not Allowed", @"UzysAssetsPickerController",nil)]; 358 | // [self.btnTitle setTitle:NSLocalizedStringFromTable(@"Not Allowed", @"UzysAssetsPickerController",nil) forState:UIControlStateNormal]; 359 | [strongSelf.btnTitle setImage:nil forState:UIControlStateNormal]; 360 | 361 | }; 362 | 363 | [self.assetsLibrary enumerateGroupsWithTypes:ALAssetsGroupAll 364 | usingBlock:resultsBlock 365 | failureBlock:failureBlock]; 366 | } 367 | 368 | - (void)setupAssets:(voidBlock)successBlock 369 | { 370 | self.title = [self.assetsGroup valueForProperty:ALAssetsGroupPropertyName]; 371 | 372 | if (!self.assets) 373 | self.assets = [[NSMutableArray alloc] init]; 374 | else 375 | [self.assets removeAllObjects]; 376 | 377 | if(!self.assetsGroup) 378 | { 379 | self.assetsGroup = self.groups[0]; 380 | } 381 | [self.assetsGroup setAssetsFilter:self.assetsFilter]; 382 | __weak typeof(self) weakSelf = self; 383 | 384 | ALAssetsGroupEnumerationResultsBlock resultsBlock = ^(ALAsset *asset, NSUInteger index, BOOL *stop) { 385 | __strong typeof(weakSelf) strongSelf = weakSelf; 386 | if (asset) 387 | { 388 | [strongSelf.assets addObject:asset]; 389 | 390 | NSString *type = [asset valueForProperty:ALAssetPropertyType]; 391 | 392 | if ([type isEqual:ALAssetTypePhoto]) 393 | strongSelf.numberOfPhotos ++; 394 | if ([type isEqual:ALAssetTypeVideo]) 395 | strongSelf.numberOfVideos ++; 396 | } 397 | 398 | else 399 | { 400 | dispatch_async(dispatch_get_main_queue(), ^{ 401 | [self reloadData]; 402 | if(successBlock) 403 | successBlock(); 404 | 405 | }); 406 | 407 | } 408 | }; 409 | [self.assetsGroup enumerateAssetsWithOptions:NSEnumerationReverse usingBlock:resultsBlock]; 410 | } 411 | - (void)reloadData 412 | { 413 | [self.collectionView reloadData]; 414 | [self.btnDone setTitle:[NSString stringWithFormat:@"%lu",(unsigned long)self.collectionView.indexPathsForSelectedItems 415 | .count] forState:UIControlStateNormal]; 416 | [self showNoAssetsIfNeeded]; 417 | } 418 | - (void)setAssetsCountWithSelectedIndexPaths:(NSArray *)indexPaths 419 | { 420 | [self.btnDone setTitle:[NSString stringWithFormat:@"%lu",(unsigned long)indexPaths.count] forState:UIControlStateNormal]; 421 | } 422 | 423 | #pragma mark - Asset Exception View 424 | - (void)initNoAssetView 425 | { 426 | UIView *noAssetsView = [[UIView alloc] initWithFrame:self.collectionView.bounds]; 427 | 428 | CGRect rect = CGRectInset(self.collectionView.bounds, 10, 10); 429 | UILabel *title = [[UILabel alloc] initWithFrame:rect]; 430 | UILabel *message = [[UILabel alloc] initWithFrame:rect]; 431 | 432 | title.text = NSLocalizedStringFromTable(@"No Photos or Videos", @"UzysAssetsPickerController", nil); 433 | title.font = [UIFont systemFontOfSize:19.0]; 434 | title.textColor = [UIColor colorWithRed:153.0/255.0 green:153.0/255.0 blue:153.0/255.0 alpha:1]; 435 | title.textAlignment = NSTextAlignmentCenter; 436 | title.numberOfLines = 5; 437 | title.tag = kTagNoAssetViewTitleLabel; 438 | 439 | message.text = NSLocalizedStringFromTable(@"You can sync photos and videos onto your iPhone using iTunes.", @"UzysAssetsPickerController",nil); 440 | message.font = [UIFont systemFontOfSize:15.0]; 441 | message.textColor = [UIColor colorWithRed:153.0/255.0 green:153.0/255.0 blue:153.0/255.0 alpha:1]; 442 | message.textAlignment = NSTextAlignmentCenter; 443 | message.numberOfLines = 5; 444 | message.tag = kTagNoAssetViewMsgLabel; 445 | 446 | UIImageView *titleImage = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"UzysAssetPickerController.bundle/uzysAP_ico_no_image"]]; 447 | titleImage.contentMode = UIViewContentModeCenter; 448 | titleImage.tag = kTagNoAssetViewImageView; 449 | 450 | [title sizeToFit]; 451 | [message sizeToFit]; 452 | 453 | title.center = CGPointMake(noAssetsView.center.x, noAssetsView.center.y - 10 - title.frame.size.height / 2 + 40); 454 | message.center = CGPointMake(noAssetsView.center.x, noAssetsView.center.y + 10 + message.frame.size.height / 2 + 20); 455 | titleImage.center = CGPointMake(noAssetsView.center.x, noAssetsView.center.y - 10 - titleImage.frame.size.height /2); 456 | [noAssetsView addSubview:title]; 457 | [noAssetsView addSubview:message]; 458 | [noAssetsView addSubview:titleImage]; 459 | 460 | [self.collectionView addSubview:noAssetsView]; 461 | self.noAssetView = noAssetsView; 462 | self.noAssetView.hidden = YES; 463 | } 464 | 465 | - (void)showNotAllowed 466 | { 467 | self.title = nil; 468 | 469 | UIView *lockedView = [[UIView alloc] initWithFrame:self.collectionView.bounds]; 470 | UIImageView *locked = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"UzysAssetPickerController.bundle/uzysAP_ico_no_access"]]; 471 | locked.contentMode = UIViewContentModeCenter; 472 | 473 | CGRect rect = CGRectInset(self.collectionView.bounds, 8, 8); 474 | UILabel *title = [[UILabel alloc] initWithFrame:rect]; 475 | UILabel *message = [[UILabel alloc] initWithFrame:rect]; 476 | 477 | title.text = NSLocalizedStringFromTable(@"This app does not have access to your photos or videos.", @"UzysAssetsPickerController",nil); 478 | title.font = [UIFont boldSystemFontOfSize:17.0]; 479 | title.textColor = [UIColor colorWithRed:129.0/255.0 green:136.0/255.0 blue:148.0/255.0 alpha:1]; 480 | title.textAlignment = NSTextAlignmentCenter; 481 | title.numberOfLines = 5; 482 | 483 | message.text = NSLocalizedStringFromTable(@"You can enable access in Privacy Settings.", @"UzysAssetsPickerController",nil); 484 | message.font = [UIFont systemFontOfSize:14.0]; 485 | message.textColor = [UIColor colorWithRed:129.0/255.0 green:136.0/255.0 blue:148.0/255.0 alpha:1]; 486 | message.textAlignment = NSTextAlignmentCenter; 487 | message.numberOfLines = 5; 488 | 489 | [title sizeToFit]; 490 | [message sizeToFit]; 491 | 492 | locked.center = CGPointMake(lockedView.center.x, lockedView.center.y - locked.bounds.size.height /2 - 20); 493 | title.center = locked.center; 494 | message.center = locked.center; 495 | 496 | rect = title.frame; 497 | rect.origin.y = locked.frame.origin.y + locked.frame.size.height + 10; 498 | title.frame = rect; 499 | 500 | rect = message.frame; 501 | rect.origin.y = title.frame.origin.y + title.frame.size.height + 5; 502 | message.frame = rect; 503 | 504 | [lockedView addSubview:locked]; 505 | [lockedView addSubview:title]; 506 | [lockedView addSubview:message]; 507 | [self.collectionView addSubview:lockedView]; 508 | } 509 | 510 | - (void)showNoAssetsIfNeeded 511 | { 512 | __weak typeof(self) weakSelf = self; 513 | 514 | voidBlock setNoImage = ^{ 515 | UIImageView *imgView = (UIImageView *)[weakSelf.noAssetView viewWithTag:kTagNoAssetViewImageView]; 516 | imgView.contentMode = UIViewContentModeCenter; 517 | imgView.image = [UIImage imageNamed:@"UzysAssetPickerController.bundle/uzysAP_ico_no_image"]; 518 | 519 | UILabel *title = (UILabel *)[weakSelf.noAssetView viewWithTag:kTagNoAssetViewTitleLabel]; 520 | title.text = NSLocalizedStringFromTable(@"No Photos", @"UzysAssetsPickerController",nil); 521 | UILabel *msg = (UILabel *)[weakSelf.noAssetView viewWithTag:kTagNoAssetViewMsgLabel]; 522 | msg.text = NSLocalizedStringFromTable(@"You can sync photos onto your iPhone using iTunes.",@"UzysAssetsPickerController", nil); 523 | }; 524 | voidBlock setNoVideo = ^{ 525 | UIImageView *imgView = (UIImageView *)[weakSelf.noAssetView viewWithTag:kTagNoAssetViewImageView]; 526 | imgView.image = [UIImage imageNamed:@"UzysAssetPickerController.bundle/uzysAP_ico_no_video"]; 527 | DLog(@"no video"); 528 | UILabel *title = (UILabel *)[weakSelf.noAssetView viewWithTag:kTagNoAssetViewTitleLabel]; 529 | title.text = NSLocalizedStringFromTable(@"No Videos", @"UzysAssetsPickerController",nil); 530 | UILabel *msg = (UILabel *)[weakSelf.noAssetView viewWithTag:kTagNoAssetViewMsgLabel]; 531 | msg.text = NSLocalizedStringFromTable(@"You can sync videos onto your iPhone using iTunes.",@"UzysAssetsPickerController", nil); 532 | 533 | }; 534 | 535 | if(self.assets.count ==0) 536 | { 537 | self.noAssetView.hidden = NO; 538 | if(self.segmentedControl.hidden == NO) 539 | { 540 | if(self.segmentedControl.selectedSegmentIndex ==0) 541 | { 542 | setNoImage(); 543 | } 544 | else 545 | { 546 | setNoVideo(); 547 | } 548 | } 549 | else 550 | { 551 | if(self.maximumNumberOfSelectionMedia >0) 552 | { 553 | UIImageView *imgView = (UIImageView *)[self.noAssetView viewWithTag:kTagNoAssetViewImageView]; 554 | imgView.image = [UIImage imageNamed:@"UzysAssetPickerController.bundle/uzysAP_ico_no_image"]; 555 | DLog(@"no media"); 556 | UILabel *title = (UILabel *)[self.noAssetView viewWithTag:kTagNoAssetViewTitleLabel]; 557 | title.text = NSLocalizedStringFromTable(@"No Videos", @"UzysAssetsPickerController",nil); 558 | UILabel *msg = (UILabel *)[self.noAssetView viewWithTag:kTagNoAssetViewMsgLabel]; 559 | msg.text = NSLocalizedStringFromTable(@"You can sync media onto your iPhone using iTunes.",@"UzysAssetsPickerController", nil); 560 | 561 | } 562 | else if(self.maximumNumberOfSelectionPhoto == 0) 563 | { 564 | setNoVideo(); 565 | } 566 | else if(self.maximumNumberOfSelectionVideo == 0) 567 | { 568 | setNoImage(); 569 | } 570 | } 571 | } 572 | else 573 | { 574 | self.noAssetView.hidden = YES; 575 | } 576 | } 577 | 578 | 579 | #pragma mark - Collection View Data Source 580 | 581 | - (NSInteger)numberOfSectionsInCollectionView:(UICollectionView *)collectionView 582 | { 583 | return 1; 584 | } 585 | 586 | - (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section 587 | { 588 | return self.assets.count; 589 | } 590 | 591 | - (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath 592 | { 593 | static NSString *CellIdentifier = kAssetsViewCellIdentifier; 594 | 595 | UzysAssetsViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:CellIdentifier forIndexPath:indexPath]; 596 | 597 | [cell applyData:[self.assets objectAtIndex:indexPath.row]]; 598 | 599 | return cell; 600 | } 601 | 602 | #pragma mark - Collection View Delegate 603 | 604 | - (BOOL)collectionView:(UICollectionView *)collectionView shouldSelectItemAtIndexPath:(NSIndexPath *)indexPath 605 | { 606 | BOOL didExceedMaximumNumberOfSelection = [collectionView indexPathsForSelectedItems].count >= self.maximumNumberOfSelection; 607 | if (didExceedMaximumNumberOfSelection && self.delegate && [self.delegate respondsToSelector:@selector(uzysAssetsPickerControllerDidExceedMaximumNumberOfSelection:)]) { 608 | [self.delegate uzysAssetsPickerControllerDidExceedMaximumNumberOfSelection:self]; 609 | } 610 | return !didExceedMaximumNumberOfSelection; 611 | } 612 | 613 | - (void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath 614 | { 615 | ALAsset *selectedAsset = [self.assets objectAtIndex:indexPath.item]; 616 | [self.orderedSelectedItem addObject:selectedAsset]; 617 | [self setAssetsCountWithSelectedIndexPaths:collectionView.indexPathsForSelectedItems]; 618 | } 619 | 620 | - (void)collectionView:(UICollectionView *)collectionView didDeselectItemAtIndexPath:(NSIndexPath *)indexPath 621 | { 622 | ALAsset *deselectedAsset = [self.assets objectAtIndex:indexPath.item]; 623 | 624 | [self.orderedSelectedItem removeObject:deselectedAsset]; 625 | [self setAssetsCountWithSelectedIndexPaths:collectionView.indexPathsForSelectedItems]; 626 | } 627 | 628 | 629 | #pragma mark - Actions 630 | 631 | - (void)finishPickingAssets 632 | { 633 | NSMutableArray *assets = [[NSMutableArray alloc] initWithArray:self.orderedSelectedItem]; 634 | // 635 | // for (NSIndexPath *index in self.orderedSelectedItem) 636 | // { 637 | // [assets addObject:[self.assets objectAtIndex:index.item]]; 638 | // } 639 | // 640 | if([assets count]>0) 641 | { 642 | UzysAssetsPickerController *picker = (UzysAssetsPickerController *)self; 643 | 644 | if([picker.delegate respondsToSelector:@selector(uzysAssetsPickerController:didFinishPickingAssets:)]) 645 | [picker.delegate uzysAssetsPickerController:picker didFinishPickingAssets:assets]; 646 | 647 | [self dismissViewControllerAnimated:YES completion:^{ 648 | 649 | }]; 650 | } 651 | } 652 | #pragma mark - Helper methods 653 | - (NSDictionary *)queryStringToDictionaryOfNSURL:(NSURL *)url 654 | { 655 | NSArray *urlComponents = [url.query componentsSeparatedByString:@"&"]; 656 | if (urlComponents.count <= 0) 657 | { 658 | return nil; 659 | } 660 | NSMutableDictionary *queryDict = [NSMutableDictionary dictionary]; 661 | for (NSString *keyValuePair in urlComponents) 662 | { 663 | NSArray *pairComponents = [keyValuePair componentsSeparatedByString:@"="]; 664 | [queryDict setObject:pairComponents[1] forKey:pairComponents[0]]; 665 | } 666 | return [queryDict copy]; 667 | } 668 | 669 | - (NSUInteger)indexOfAssetGroup:(ALAssetsGroup *)group inGroups:(NSArray *)groups 670 | { 671 | NSString *targetGroupId = [group valueForProperty:ALAssetsGroupPropertyPersistentID]; 672 | __block NSUInteger index = NSNotFound; 673 | [groups enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) { 674 | ALAssetsGroup *g = obj; 675 | NSString *gid = [g valueForProperty:ALAssetsGroupPropertyPersistentID]; 676 | if ([gid isEqualToString:targetGroupId]) 677 | { 678 | index = idx; 679 | *stop = YES; 680 | } 681 | 682 | }]; 683 | return index; 684 | } 685 | 686 | - (NSString *)getUTCFormattedDate:(NSDate *)localDate { 687 | static NSDateFormatter *dateFormatter = nil; 688 | if (dateFormatter == nil) { 689 | dateFormatter = [[NSDateFormatter alloc] init]; 690 | [dateFormatter setDateFormat:@"yyyy:MM:dd HH:mm:ss"]; 691 | } 692 | NSString *dateString = [dateFormatter stringFromDate:localDate]; 693 | return dateString; 694 | } 695 | 696 | // Mostly from here: http://stackoverflow.com/questions/3884060/need-help-in-saving-geotag-info-with-photo-on-ios4-1 697 | - (void)addGPSLocation:(NSMutableDictionary *)metaData { 698 | 699 | if (self.location != nil) { 700 | 701 | CLLocationDegrees exifLatitude = location.coordinate.latitude; 702 | CLLocationDegrees exifLongitude = location.coordinate.longitude; 703 | 704 | NSString *latRef; 705 | NSString *lngRef; 706 | if (exifLatitude < 0.0) { 707 | exifLatitude = exifLatitude * -1.0f; 708 | latRef = @"S"; 709 | } else { 710 | latRef = @"N"; 711 | } 712 | 713 | if (exifLongitude < 0.0) { 714 | exifLongitude = exifLongitude * -1.0f; 715 | lngRef = @"W"; 716 | } else { 717 | lngRef = @"E"; 718 | } 719 | 720 | NSMutableDictionary *locDict = [[NSMutableDictionary alloc] init]; 721 | if ([metaData objectForKey:(NSString*)kCGImagePropertyGPSDictionary]) { 722 | [locDict addEntriesFromDictionary:[metaData objectForKey:(NSString*)kCGImagePropertyGPSDictionary]]; 723 | } 724 | [locDict setObject:[self getUTCFormattedDate:location.timestamp] forKey:(NSString*)kCGImagePropertyGPSTimeStamp]; 725 | [locDict setObject:latRef forKey:(NSString*)kCGImagePropertyGPSLatitudeRef]; 726 | [locDict setObject:[NSNumber numberWithFloat:exifLatitude] forKey:(NSString*)kCGImagePropertyGPSLatitude]; 727 | [locDict setObject:lngRef forKey:(NSString*)kCGImagePropertyGPSLongitudeRef]; 728 | [locDict setObject:[NSNumber numberWithFloat:exifLongitude] forKey:(NSString*)kCGImagePropertyGPSLongitude]; 729 | [locDict setObject:[NSNumber numberWithFloat:location.horizontalAccuracy] forKey:(NSString*)kCGImagePropertyGPSDOP]; 730 | [locDict setObject:[NSNumber numberWithFloat:location.altitude] forKey:(NSString*)kCGImagePropertyGPSAltitude]; 731 | 732 | [metaData setObject:locDict forKey:(NSString*)kCGImagePropertyGPSDictionary]; 733 | } 734 | } 735 | 736 | #pragma mark - Notification 737 | 738 | - (void)assetsLibraryUpdated:(NSNotification *)notification 739 | { 740 | //recheck here 741 | if(![notification.name isEqualToString:ALAssetsLibraryChangedNotification]) 742 | { 743 | return ; 744 | } 745 | __weak typeof(self) weakSelf = self; 746 | dispatch_async(dispatch_get_main_queue(), ^{ 747 | __strong typeof(self) strongSelf = weakSelf; 748 | NSDictionary* info = [notification userInfo]; 749 | NSSet *updatedAssets = [info objectForKey:ALAssetLibraryUpdatedAssetsKey]; 750 | NSSet *updatedAssetGroup = [info objectForKey:ALAssetLibraryUpdatedAssetGroupsKey]; 751 | NSSet *deletedAssetGroup = [info objectForKey:ALAssetLibraryDeletedAssetGroupsKey]; 752 | NSSet *insertedAssetGroup = [info objectForKey:ALAssetLibraryInsertedAssetGroupsKey]; 753 | DLog(@"-------------+"); 754 | DLog(@"updated assets:%@", updatedAssets); 755 | DLog(@"updated asset group:%@", updatedAssetGroup); 756 | DLog(@"deleted asset group:%@", deletedAssetGroup); 757 | DLog(@"inserted asset group:%@", insertedAssetGroup); 758 | DLog(@"-------------="); 759 | 760 | if(info == nil) 761 | { 762 | //AllClear 763 | [strongSelf setupGroup:nil withSetupAsset:YES]; 764 | return; 765 | } 766 | 767 | if(info.count == 0) 768 | { 769 | return; 770 | } 771 | 772 | if (deletedAssetGroup.count > 0 || insertedAssetGroup.count > 0 || updatedAssetGroup.count >0) 773 | { 774 | BOOL currentAssetsGroupIsInDeletedAssetGroup = NO; 775 | BOOL currentAssetsGroupIsInUpdatedAssetGroup = NO; 776 | NSString *currentAssetGroupId = [strongSelf.assetsGroup valueForProperty:ALAssetsGroupPropertyPersistentID]; 777 | //check whether user deleted a chosen assetGroup. 778 | for (NSURL *groupUrl in deletedAssetGroup) 779 | { 780 | NSDictionary *queryDictionInURL = [strongSelf queryStringToDictionaryOfNSURL:groupUrl]; 781 | if ([queryDictionInURL[@"id"] isEqualToString:currentAssetGroupId]) 782 | { 783 | currentAssetsGroupIsInDeletedAssetGroup = YES; 784 | break; 785 | } 786 | } 787 | for (NSURL *groupUrl in updatedAssetGroup) 788 | { 789 | NSDictionary *queryDictionInURL = [strongSelf queryStringToDictionaryOfNSURL:groupUrl]; 790 | if ([queryDictionInURL[@"id"] isEqualToString:currentAssetGroupId]) 791 | { 792 | currentAssetsGroupIsInUpdatedAssetGroup = YES; 793 | break; 794 | } 795 | } 796 | 797 | if (currentAssetsGroupIsInDeletedAssetGroup || [strongSelf.assetsGroup numberOfAssets]==0) 798 | { 799 | //if user really deletes a chosen assetGroup, make it self.groups[0] to be default selected. 800 | [strongSelf setupGroup:^{ 801 | [strongSelf.groupPicker reloadData]; 802 | [strongSelf.groupPicker.tableView selectRowAtIndexPath:[NSIndexPath indexPathForRow:0 inSection:0] animated:NO scrollPosition:UITableViewScrollPositionNone]; 803 | } withSetupAsset:YES]; 804 | return; 805 | } 806 | else 807 | { 808 | if(currentAssetsGroupIsInUpdatedAssetGroup) 809 | { 810 | NSMutableArray *selectedItems = [NSMutableArray array]; 811 | NSArray *selectedPath = strongSelf.collectionView.indexPathsForSelectedItems; 812 | 813 | for (NSIndexPath *idxPath in selectedPath) 814 | { 815 | [selectedItems addObject:[strongSelf.assets objectAtIndex:idxPath.row]]; 816 | } 817 | NSInteger beforeAssets = strongSelf.assets.count; 818 | [strongSelf setupAssets:^{ 819 | for (ALAsset *item in selectedItems) 820 | { 821 | BOOL isExist = false; 822 | for(ALAsset *asset in strongSelf.assets) 823 | { 824 | if([[[asset valueForProperty:ALAssetPropertyAssetURL] absoluteString] isEqualToString:[[item valueForProperty:ALAssetPropertyAssetURL] absoluteString]]) 825 | { 826 | NSUInteger idx = [strongSelf.assets indexOfObject:asset]; 827 | NSIndexPath *newPath = [NSIndexPath indexPathForRow:idx inSection:0]; 828 | [strongSelf.collectionView selectItemAtIndexPath:newPath animated:NO scrollPosition:UICollectionViewScrollPositionNone]; 829 | isExist = true; 830 | } 831 | } 832 | if(isExist ==false) 833 | { 834 | [strongSelf.orderedSelectedItem removeObject:item]; 835 | } 836 | } 837 | 838 | [strongSelf setAssetsCountWithSelectedIndexPaths:strongSelf.collectionView.indexPathsForSelectedItems]; 839 | if(strongSelf.assets.count > beforeAssets) 840 | { 841 | [strongSelf.collectionView setContentOffset:CGPointMake(0, 0) animated:NO]; 842 | } 843 | 844 | }]; 845 | [strongSelf setupGroup:^{ 846 | [strongSelf.groupPicker reloadData]; 847 | } withSetupAsset:NO]; 848 | 849 | 850 | } 851 | else 852 | { 853 | [strongSelf setupGroup:^{ 854 | [strongSelf.groupPicker reloadData]; 855 | } withSetupAsset:NO]; 856 | return; 857 | } 858 | } 859 | 860 | } 861 | 862 | 863 | }); 864 | } 865 | #pragma mark - Property 866 | - (void)setTitle:(NSString *)title 867 | { 868 | [super setTitle:title]; 869 | [self.btnTitle setTitle:title forState:UIControlStateNormal]; 870 | [self.btnTitle setImageEdgeInsets:UIEdgeInsetsMake(5, 0, 0, 0)]; 871 | [self.btnTitle setTitleEdgeInsets:UIEdgeInsetsMake(5, 0, 0, 0)]; 872 | [self.btnTitle layoutIfNeeded]; 873 | } 874 | - (void)menuArrowRotate 875 | { 876 | [UIView animateWithDuration:0.35 animations:^{ 877 | if(self.groupPicker.isOpen) 878 | { 879 | self.imageViewTitleArrow.transform = CGAffineTransformMakeRotation(M_PI); 880 | } 881 | else 882 | { 883 | self.imageViewTitleArrow.transform = CGAffineTransformIdentity; 884 | } 885 | } completion:^(BOOL finished) { 886 | }]; 887 | 888 | } 889 | #pragma mark - Control Action 890 | - (IBAction)btnAction:(id)sender { 891 | 892 | UIButton *btn = (UIButton *)sender; 893 | 894 | switch (btn.tag) { 895 | case kTagButtonCamera: 896 | { 897 | if (![UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypeCamera]) { 898 | NSString *title = NSLocalizedStringFromTable(@"Error", @"UzysAssetsPickerController", nil); 899 | NSString *message = NSLocalizedStringFromTable(@"Device has no camera", @"UzysAssetsPickerController", nil); 900 | UIAlertView *myAlertView = [[UIAlertView alloc] initWithTitle:title message:message delegate:nil cancelButtonTitle:@"OK" otherButtonTitles: nil]; 901 | [myAlertView show]; 902 | } 903 | else 904 | { 905 | __weak typeof(self) weakSelf = self; 906 | [self presentViewController:self.picker animated:YES completion:^{ 907 | __strong typeof(self) strongSelf = weakSelf; 908 | //카메라 화면으로 가면 강제로 카메라 롤로 변경. 909 | NSString *curGroupName =[[strongSelf.assetsGroup valueForProperty:ALAssetsGroupPropertyURL] absoluteString]; 910 | NSString *cameraRollName = [[strongSelf.groups[0] valueForProperty:ALAssetsGroupPropertyURL] absoluteString]; 911 | 912 | if(![curGroupName isEqualToString:cameraRollName] ) 913 | { 914 | strongSelf.assetsGroup = strongSelf.groups[0]; 915 | [strongSelf changeGroup:0]; 916 | } 917 | }]; 918 | } 919 | } 920 | break; 921 | case kTagButtonClose: 922 | { 923 | if([self.delegate respondsToSelector:@selector(uzysAssetsPickerControllerDidCancel:)]) 924 | { 925 | [self.delegate uzysAssetsPickerControllerDidCancel:self]; 926 | } 927 | [self dismissViewControllerAnimated:YES completion:^{ 928 | 929 | }]; 930 | } 931 | break; 932 | case kTagButtonGroupPicker: 933 | { 934 | [self.groupPicker toggle]; 935 | [self menuArrowRotate]; 936 | } 937 | break; 938 | case kTagButtonDone: 939 | [self finishPickingAssets]; 940 | break; 941 | default: 942 | break; 943 | } 944 | } 945 | 946 | - (IBAction)indexDidChangeForSegmentedControl:(id)sender { 947 | UISegmentedControl *segmentedControl = (UISegmentedControl *) sender; 948 | NSInteger selectedSegment = segmentedControl.selectedSegmentIndex; 949 | if(selectedSegment ==0) 950 | { 951 | [self changeAssetType:YES endBlock:nil]; 952 | } 953 | else 954 | { 955 | [self changeAssetType:NO endBlock:nil]; 956 | } 957 | } 958 | - (void)saveAssetsAction:(NSURL *)assetURL error:(NSError *)error isPhoto:(BOOL)isPhoto { 959 | if(error) 960 | return; 961 | __weak typeof(self) weakSelf = self; 962 | [self.assetsLibrary assetForURL:assetURL resultBlock:^(ALAsset *asset) { 963 | dispatch_async(dispatch_get_main_queue(), ^{ 964 | if (asset ==nil) 965 | { 966 | return ; 967 | } 968 | if(self.curAssetFilterType == 0 || (self.curAssetFilterType ==1 && isPhoto ==YES) || (self.curAssetFilterType == 2 && isPhoto ==NO)) 969 | { 970 | NSMutableArray *selectedItems = [NSMutableArray array]; 971 | NSArray *selectedPath = self.collectionView.indexPathsForSelectedItems; 972 | 973 | for (NSIndexPath *idxPath in selectedPath) 974 | { 975 | [selectedItems addObject:[self.assets objectAtIndex:idxPath.row]]; 976 | } 977 | 978 | [self.assets insertObject:asset atIndex:0]; 979 | [self reloadData]; 980 | 981 | for (ALAsset *item in selectedItems) 982 | { 983 | for(ALAsset *asset in self.assets) 984 | { 985 | if([[[asset valueForProperty:ALAssetPropertyAssetURL] absoluteString] isEqualToString:[[item valueForProperty:ALAssetPropertyAssetURL] absoluteString]]) 986 | { 987 | NSUInteger idx = [self.assets indexOfObject:asset]; 988 | NSIndexPath *newPath = [NSIndexPath indexPathForRow:idx inSection:0]; 989 | [self.collectionView selectItemAtIndexPath:newPath animated:NO scrollPosition:UICollectionViewScrollPositionNone]; 990 | } 991 | } 992 | } 993 | [self.collectionView setContentOffset:CGPointMake(0, 0) animated:NO]; 994 | 995 | if(self.maximumNumberOfSelection > self.collectionView.indexPathsForSelectedItems.count) 996 | { 997 | NSIndexPath *newPath = [NSIndexPath indexPathForRow:0 inSection:0]; 998 | [self.collectionView selectItemAtIndexPath:newPath animated:NO scrollPosition:UICollectionViewScrollPositionNone]; 999 | [self.orderedSelectedItem addObject:asset]; 1000 | } 1001 | [self setAssetsCountWithSelectedIndexPaths:self.collectionView.indexPathsForSelectedItems]; 1002 | } 1003 | 1004 | dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ 1005 | __strong typeof(weakSelf) strongSelf = weakSelf; 1006 | [[NSNotificationCenter defaultCenter] addObserver:strongSelf selector:@selector(assetsLibraryUpdated:) name:ALAssetsLibraryChangedNotification object:nil]; 1007 | }); 1008 | 1009 | 1010 | }); 1011 | 1012 | } failureBlock:^(NSError *err){ 1013 | 1014 | dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ 1015 | __strong typeof(weakSelf) strongSelf = weakSelf; 1016 | [[NSNotificationCenter defaultCenter] addObserver:strongSelf selector:@selector(assetsLibraryUpdated:) name:ALAssetsLibraryChangedNotification object:nil]; 1017 | }); 1018 | 1019 | }]; 1020 | } 1021 | 1022 | #pragma mark - UIImagerPickerDelegate 1023 | - (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info 1024 | { 1025 | __weak typeof(self) weakSelf = self; 1026 | //사진 촬영 시 1027 | if (CFStringCompare((CFStringRef) [info objectForKey:UIImagePickerControllerMediaType], kUTTypeImage, 0) == kCFCompareEqualTo) 1028 | { 1029 | if(self.segmentedControl.selectedSegmentIndex ==1 && self.segmentedControl.hidden == NO) 1030 | { 1031 | self.segmentedControl.selectedSegmentIndex = 0; 1032 | [self changeAssetType:YES endBlock:^{ 1033 | __strong typeof(weakSelf) strongSelf = weakSelf; 1034 | UIImage *image = info[UIImagePickerControllerOriginalImage]; 1035 | [[NSNotificationCenter defaultCenter] removeObserver:strongSelf name:ALAssetsLibraryChangedNotification object:nil]; 1036 | 1037 | NSMutableDictionary *metaData = [NSMutableDictionary dictionaryWithDictionary:info[UIImagePickerControllerMediaMetadata]]; 1038 | [self addGPSLocation:metaData]; 1039 | 1040 | [strongSelf.assetsLibrary writeImageToSavedPhotosAlbum:image.CGImage metadata:metaData completionBlock:^(NSURL *assetURL, NSError *error) { 1041 | dispatch_async(dispatch_get_main_queue(), ^{ 1042 | [self saveAssetsAction:assetURL error:error isPhoto:YES]; 1043 | }); 1044 | DLog(@"writeImageToSavedPhotosAlbum"); 1045 | }]; 1046 | 1047 | }]; 1048 | 1049 | } 1050 | else 1051 | { 1052 | UIImage *image = info[UIImagePickerControllerOriginalImage]; 1053 | [[NSNotificationCenter defaultCenter] removeObserver:self name:ALAssetsLibraryChangedNotification object:nil]; 1054 | 1055 | NSMutableDictionary *metaData = [NSMutableDictionary dictionaryWithDictionary:info[UIImagePickerControllerMediaMetadata]]; 1056 | [self addGPSLocation:metaData]; 1057 | 1058 | [self.assetsLibrary writeImageToSavedPhotosAlbum:image.CGImage metadata:metaData completionBlock:^(NSURL *assetURL, NSError *error) { 1059 | __strong typeof(weakSelf) strongSelf = weakSelf; 1060 | dispatch_async(dispatch_get_main_queue(), ^{ 1061 | [strongSelf saveAssetsAction:assetURL error:error isPhoto:YES]; 1062 | }); 1063 | DLog(@"writeImageToSavedPhotosAlbum"); 1064 | }]; 1065 | } 1066 | } 1067 | else //비디오 촬영시 1068 | { 1069 | if(self.segmentedControl.selectedSegmentIndex ==0 && self.segmentedControl.hidden == NO) 1070 | { 1071 | self.segmentedControl.selectedSegmentIndex = 1; 1072 | [self changeAssetType:NO endBlock:^{ 1073 | __strong typeof(weakSelf) strongSelf = weakSelf; 1074 | 1075 | [[NSNotificationCenter defaultCenter] removeObserver:strongSelf name:ALAssetsLibraryChangedNotification object:nil]; 1076 | [strongSelf.assetsLibrary writeVideoAtPathToSavedPhotosAlbum:info[UIImagePickerControllerMediaURL] completionBlock:^(NSURL *assetURL, NSError *error) { 1077 | DLog(@"assetURL %@",assetURL); 1078 | dispatch_async(dispatch_get_main_queue(), ^{ 1079 | [self saveAssetsAction:assetURL error:error isPhoto:NO]; 1080 | }); 1081 | }]; 1082 | 1083 | }]; 1084 | } 1085 | else 1086 | { 1087 | [[NSNotificationCenter defaultCenter] removeObserver:self name:ALAssetsLibraryChangedNotification object:nil]; 1088 | [self.assetsLibrary writeVideoAtPathToSavedPhotosAlbum:info[UIImagePickerControllerMediaURL] completionBlock:^(NSURL *assetURL, NSError *error) { 1089 | dispatch_async(dispatch_get_main_queue(), ^{ 1090 | [self saveAssetsAction:assetURL error:error isPhoto:NO]; 1091 | }); 1092 | 1093 | }]; 1094 | 1095 | } 1096 | } 1097 | 1098 | [picker dismissViewControllerAnimated:YES completion:^{}]; 1099 | 1100 | 1101 | } 1102 | - (void)imagePickerControllerDidCancel:(UIImagePickerController *)picker 1103 | { 1104 | [picker dismissViewControllerAnimated:YES completion:^{ 1105 | 1106 | }]; 1107 | } 1108 | 1109 | #pragma mark - UIViewController Property 1110 | 1111 | - (UIStatusBarStyle)preferredStatusBarStyle 1112 | { 1113 | return UIStatusBarStyleDefault; 1114 | } 1115 | - (UIViewController *)childViewControllerForStatusBarHidden 1116 | { 1117 | return nil; 1118 | } 1119 | - (BOOL)prefersStatusBarHidden 1120 | { 1121 | return NO; 1122 | } 1123 | -(NSUInteger)supportedInterfaceOrientations 1124 | { 1125 | return UIInterfaceOrientationMaskPortrait; 1126 | } 1127 | - (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation 1128 | { 1129 | return UIInterfaceOrientationPortrait; 1130 | } 1131 | 1132 | @end 1133 | -------------------------------------------------------------------------------- /PhotoPicker/CorePhotoPickerVCManager/Library/UzysAssetsPickerController.xib: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 43 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 123 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | 164 | 165 | 166 | 167 | 168 | 169 | 170 | 171 | 172 | 173 | 174 | 175 | 176 | 177 | -------------------------------------------------------------------------------- /PhotoPicker/CorePhotoPickerVCManager/Library/UzysAssetsPickerController_Configuration.h: -------------------------------------------------------------------------------- 1 | // 2 | // UzysAssetsPickerController_configuration.h 3 | // UzysAssetsPickerController 4 | // 5 | // Created by Uzysjung on 2014. 2. 12.. 6 | // Copyright (c) 2014년 Uzys. All rights reserved. 7 | // 8 | #import 9 | #import 10 | typedef void (^intBlock)(NSInteger); 11 | typedef void (^voidBlock)(void); 12 | 13 | #define IS_IPHONE (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPhone) // iPhone and iPod touch style UI 14 | #define IS_IOS8 ([[UIDevice currentDevice].systemVersion floatValue]>=8) 15 | #define IS_IPHONE_6_IOS8 (IS_IPHONE && IS_IOS8 &&([[UIScreen mainScreen] nativeBounds].size.height/[[UIScreen mainScreen] nativeScale]) == 667.0f) 16 | #define IS_IPHONE_6P_IOS8 (IS_IPHONE && IS_IOS8 &&([[UIScreen mainScreen] nativeBounds].size.height/[[UIScreen mainScreen] nativeScale]) == 736.0f) 17 | 18 | 19 | #define kGroupViewCellIdentifier @"groupViewCellIdentifier" 20 | #define kAssetsViewCellIdentifier @"AssetsViewCellIdentifier" 21 | #define kAssetsSupplementaryViewIdentifier @"AssetsSupplementaryViewIdentifier" 22 | #define kThumbnailLength 79.0f 23 | #define kThumbnailLength_IPHONE6 78.0f + 15.0f 24 | #define kThumbnailLength_IPHONE6P 78.0f + 24.5f 25 | 26 | #define kThumbnailSize CGSizeMake(kThumbnailLength, kThumbnailLength) 27 | #define kThumbnailSize_IPHONE6 CGSizeMake(kThumbnailLength_IPHONE6,kThumbnailLength_IPHONE6) 28 | #define kThumbnailSize_IPHONE6P CGSizeMake(kThumbnailLength_IPHONE6P ,kThumbnailLength_IPHONE6P) 29 | 30 | #define THUMBNAIL_SIZE if(IS_IPHONE) kThumbnailSize 31 | 32 | #define kTagButtonClose 101 33 | #define kTagButtonCamera 102 34 | #define kTagButtonGroupPicker 103 35 | #define kTagButtonDone 104 36 | #define kTagNoAssetViewImageView 30 37 | #define kTagNoAssetViewTitleLabel 31 38 | #define kTagNoAssetViewMsgLabel 32 39 | 40 | #define kGroupPickerViewCellLength 90 41 | 42 | 43 | 44 | #ifdef DEBUG 45 | // for debug mode 46 | #ifndef DLog 47 | #define DLog(f, ...) NSLog(f, ##__VA_ARGS__) 48 | #endif 49 | 50 | #else 51 | 52 | // for release mode 53 | #ifndef DLog 54 | #define DLog(f, ...) /* noop */ 55 | #endif 56 | 57 | #endif 58 | -------------------------------------------------------------------------------- /PhotoPicker/CorePhotoPickerVCManager/Library/UzysAssetsViewCell.h: -------------------------------------------------------------------------------- 1 | // 2 | // UzysAssetsViewCell.h 3 | // UzysAssetsPickerController 4 | // 5 | // Created by Uzysjung on 2014. 2. 12.. 6 | // Copyright (c) 2014년 Uzys. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "UzysAssetsPickerController_Configuration.h" 11 | @interface UzysAssetsViewCell : UICollectionViewCell 12 | - (void)applyData:(ALAsset *)asset; 13 | @end 14 | -------------------------------------------------------------------------------- /PhotoPicker/CorePhotoPickerVCManager/Library/UzysAssetsViewCell.m: -------------------------------------------------------------------------------- 1 | // 2 | // UzysAssetsViewCell.m 3 | // UzysAssetsPickerController 4 | // 5 | // Created by Uzysjung on 2014. 2. 12.. 6 | // Copyright (c) 2014년 Uzys. All rights reserved. 7 | // 8 | 9 | #import "UzysAssetsViewCell.h" 10 | #import "UzysAppearanceConfig.h" 11 | 12 | @interface UzysAssetsViewCell() 13 | @property (nonatomic, strong) ALAsset *asset; 14 | @property (nonatomic, strong) UIImage *image; 15 | @property (nonatomic, copy) NSString *type; 16 | @property (nonatomic, copy) NSString *title; 17 | @property (nonatomic, strong) UIImage *videoImage; 18 | @end 19 | @implementation UzysAssetsViewCell 20 | 21 | static UIFont *videoTimeFont = nil; 22 | 23 | static CGFloat videoTimeHeight; 24 | static UIImage *videoIcon; 25 | static UIColor *videoTitleColor; 26 | static UIImage *checkedIcon; 27 | static UIImage *uncheckedIcon; 28 | static UIColor *selectedColor; 29 | static CGFloat thumnailLength; 30 | + (void)initialize 31 | { 32 | UzysAppearanceConfig *appearanceConfig = [UzysAppearanceConfig sharedConfig]; 33 | 34 | videoTitleColor = [UIColor whiteColor]; 35 | videoTimeFont = [UIFont systemFontOfSize:12]; 36 | videoTimeHeight = 20.0f; 37 | videoIcon = [UIImage imageNamed:@"UzysAssetPickerController.bundle/uzysAP_ico_assets_video"]; 38 | 39 | checkedIcon = [UIImage Uzys_imageNamed:appearanceConfig.assetSelectedImageName]; 40 | uncheckedIcon = [UIImage Uzys_imageNamed:appearanceConfig.assetDeselectedImageName]; 41 | selectedColor = [UIColor colorWithWhite:1 alpha:0.3]; 42 | 43 | thumnailLength = ([UIScreen mainScreen].bounds.size.width - appearanceConfig.cellSpacing * ((CGFloat)appearanceConfig.assetsCountInALine - 1.0f)) / (CGFloat)appearanceConfig.assetsCountInALine; 44 | } 45 | 46 | 47 | - (id)initWithFrame:(CGRect)frame 48 | { 49 | self = [super initWithFrame:frame]; 50 | if (self) 51 | { 52 | // Initialization code 53 | self.opaque = YES; 54 | 55 | } 56 | return self; 57 | } 58 | - (void)applyData:(ALAsset *)asset 59 | { 60 | self.asset = asset; 61 | self.image = [UIImage imageWithCGImage:asset.thumbnail]; 62 | self.type = [asset valueForProperty:ALAssetPropertyType]; 63 | self.title = [UzysAssetsViewCell getTimeStringOfTimeInterval:[[asset valueForProperty:ALAssetPropertyDuration] doubleValue]]; 64 | } 65 | 66 | - (void)setSelected:(BOOL)selected 67 | { 68 | [super setSelected:selected]; 69 | [self setNeedsDisplay]; 70 | 71 | if(selected) 72 | { 73 | [UIView animateWithDuration:0.1 delay:0.0 options:UIViewAnimationOptionCurveEaseIn|UIViewAnimationOptionAllowUserInteraction animations:^{ 74 | self.transform = CGAffineTransformMakeScale(0.97, 0.97); 75 | } completion:^(BOOL finished) { 76 | [UIView animateWithDuration:0.1 delay:0.0 options:UIViewAnimationOptionCurveEaseOut|UIViewAnimationOptionAllowUserInteraction animations:^{ 77 | self.transform = CGAffineTransformIdentity; 78 | } completion:^(BOOL finished) { 79 | 80 | }]; 81 | }]; 82 | } 83 | else 84 | { 85 | [UIView animateWithDuration:0.1 delay:0.0 options:UIViewAnimationOptionCurveEaseIn|UIViewAnimationOptionAllowUserInteraction animations:^{ 86 | self.transform = CGAffineTransformMakeScale(1.03, 1.03); 87 | } completion:^(BOOL finished) { 88 | [UIView animateWithDuration:0.1 delay:0.0 options:UIViewAnimationOptionCurveEaseOut|UIViewAnimationOptionAllowUserInteraction animations:^{ 89 | self.transform = CGAffineTransformIdentity; 90 | } completion:^(BOOL finished) { 91 | 92 | }]; 93 | }]; 94 | 95 | } 96 | } 97 | 98 | 99 | - (void)drawRect:(CGRect)rect 100 | { 101 | // Image 102 | [self.image drawInRect:CGRectMake(-.5f, -1.0f, thumnailLength+1.5f, thumnailLength+1.0f)]; 103 | 104 | // Video title 105 | if ([self.type isEqual:ALAssetTypeVideo]) 106 | { 107 | // Create a gradient from transparent to black 108 | CGFloat colors [] = 109 | { 110 | 0.0, 0.0, 0.0, 0.0, 111 | 0.0, 0.0, 0.0, 0.8, 112 | 0.0, 0.0, 0.0, 1.0 113 | }; 114 | 115 | CGFloat locations [] = {0.0, 0.75, 1.0}; 116 | 117 | CGColorSpaceRef baseSpace = CGColorSpaceCreateDeviceRGB(); 118 | CGGradientRef gradient = CGGradientCreateWithColorComponents(baseSpace, colors, locations, 2); 119 | CGContextRef context = UIGraphicsGetCurrentContext(); 120 | 121 | CGFloat height = rect.size.height; 122 | CGPoint startPoint = CGPointMake(CGRectGetMidX(rect), height - videoTimeHeight); 123 | CGPoint endPoint = CGPointMake(CGRectGetMidX(rect), CGRectGetMaxY(rect)); 124 | 125 | CGContextDrawLinearGradient(context, gradient, startPoint, endPoint, kCGGradientDrawsBeforeStartLocation); 126 | 127 | NSDictionary *attributes = @{NSFontAttributeName:videoTimeFont,NSForegroundColorAttributeName:videoTitleColor}; 128 | CGSize titleSize = [self.title sizeWithAttributes:attributes]; 129 | [self.title drawInRect:CGRectMake(rect.size.width - (NSInteger)titleSize.width - 2 , startPoint.y + (videoTimeHeight - 12) / 2, thumnailLength, height) withAttributes:attributes]; 130 | 131 | [videoIcon drawAtPoint:CGPointMake(2, startPoint.y + (videoTimeHeight - videoIcon.size.height) / 2)]; 132 | 133 | } 134 | 135 | if (self.selected) 136 | { 137 | CGContextRef context = UIGraphicsGetCurrentContext(); 138 | CGContextSetFillColorWithColor(context, selectedColor.CGColor); 139 | CGContextFillRect(context, rect); 140 | [checkedIcon drawAtPoint:CGPointMake(CGRectGetMaxX(rect) - checkedIcon.size.width -2, CGRectGetMinY(rect)+2)]; 141 | } 142 | else 143 | { 144 | [uncheckedIcon drawAtPoint:CGPointMake(CGRectGetMaxX(rect) - uncheckedIcon.size.width -2, CGRectGetMinY(rect)+2)]; 145 | 146 | } 147 | } 148 | 149 | 150 | + (NSString *)getTimeStringOfTimeInterval:(NSTimeInterval)timeInterval 151 | { 152 | NSCalendar *calendar = [NSCalendar currentCalendar]; 153 | 154 | NSDate *dateRef = [[NSDate alloc] init]; 155 | NSDate *dateNow = [[NSDate alloc] initWithTimeInterval:timeInterval sinceDate:dateRef]; 156 | 157 | unsigned int uFlags = 158 | NSSecondCalendarUnit | NSMinuteCalendarUnit | NSHourCalendarUnit | 159 | NSDayCalendarUnit | NSMonthCalendarUnit | NSYearCalendarUnit; 160 | 161 | 162 | NSDateComponents *components = [calendar components:uFlags 163 | fromDate:dateRef 164 | toDate:dateNow 165 | options:0]; 166 | NSString *retTimeInterval; 167 | if (components.hour > 0) 168 | { 169 | retTimeInterval = [NSString stringWithFormat:@"%ld:%02ld:%02ld", (long)components.hour, (long)components.minute, (long)components.second]; 170 | } 171 | 172 | else 173 | { 174 | retTimeInterval = [NSString stringWithFormat:@"%ld:%02ld", (long)components.minute, (long)components.second]; 175 | } 176 | return retTimeInterval; 177 | } 178 | 179 | 180 | @end 181 | -------------------------------------------------------------------------------- /PhotoPicker/CorePhotoPickerVCManager/Library/UzysGroupPickerView.h: -------------------------------------------------------------------------------- 1 | // 2 | // UzysGroupPickerView.h 3 | // UzysAssetsPickerController 4 | // 5 | // Created by Uzysjung on 2014. 2. 13.. 6 | // Copyright (c) 2014년 Uzys. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "UzysAssetsPickerController_Configuration.h" 11 | @interface UzysGroupPickerView : UIView 12 | @property (nonatomic,strong) UITableView *tableView; 13 | @property (strong) NSMutableArray *groups; 14 | @property (nonatomic,strong) UITapGestureRecognizer *tapGestureRecognizer; 15 | @property (nonatomic,copy) intBlock blockTouchCell; 16 | @property (nonatomic,assign) BOOL isOpen; 17 | - (id)initWithGroups:(NSMutableArray *)groups; 18 | 19 | - (void)show; 20 | - (void)dismiss:(BOOL)animated; 21 | - (void)toggle; 22 | - (void)reloadData; 23 | @end 24 | -------------------------------------------------------------------------------- /PhotoPicker/CorePhotoPickerVCManager/Library/UzysGroupPickerView.m: -------------------------------------------------------------------------------- 1 | // 2 | // UzysGroupPickerView.m 3 | // UzysAssetsPickerController 4 | // 5 | // Created by Uzysjung on 2014. 2. 13.. 6 | // Copyright (c) 2014년 Uzys. All rights reserved. 7 | // 8 | 9 | #import "UzysGroupPickerView.h" 10 | #import "UzysGroupViewCell.h" 11 | #import "UzysAssetsPickerController_Configuration.h" 12 | 13 | #define BounceAnimationPixel 5 14 | #define NavigationHeight 64 15 | @implementation UzysGroupPickerView 16 | 17 | - (id)initWithGroups:(NSMutableArray *)groups 18 | { 19 | self = [super initWithFrame:CGRectZero]; 20 | if (self) { 21 | // Initialization code 22 | self.groups = groups; 23 | [self setupLayout]; 24 | [self setupTableView]; 25 | [self addObserver:self forKeyPath:@"groups" options:NSKeyValueObservingOptionNew|NSKeyValueObservingOptionOld context:nil]; 26 | } 27 | return self; 28 | } 29 | - (void)dealloc 30 | { 31 | [self removeObserver:self forKeyPath:@"groups"]; 32 | } 33 | 34 | - (void)setupLayout 35 | { 36 | //anchorPoint 를 잡는데 화살표 지점으로 잡아야함 37 | self.frame = CGRectMake(0, - [UIScreen mainScreen].bounds.size.height, [UIScreen mainScreen].bounds.size.width, [UIScreen mainScreen].bounds.size.height); 38 | self.layer.cornerRadius = 4; 39 | self.clipsToBounds = YES; 40 | self.backgroundColor = [UIColor whiteColor]; 41 | 42 | } 43 | - (void)setupTableView 44 | { 45 | self.tableView = [[UITableView alloc] initWithFrame:CGRectMake(0, NavigationHeight, [UIScreen mainScreen].bounds.size.width, self.bounds.size.height -NavigationHeight) style:UITableViewStylePlain]; 46 | self.tableView.autoresizingMask = UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleTopMargin; 47 | self.tableView.contentInset = UIEdgeInsetsMake(1, 0, 0, 0); 48 | self.tableView.separatorStyle = UITableViewCellSeparatorStyleNone; 49 | self.tableView.dataSource = self; 50 | self.tableView.delegate = self; 51 | self.tableView.scrollsToTop = NO; 52 | 53 | self.tableView.rowHeight = kGroupPickerViewCellLength; 54 | self.tableView.backgroundColor = [UIColor whiteColor]; 55 | [self addSubview:self.tableView]; 56 | } 57 | - (void)reloadData 58 | { 59 | [self.tableView reloadData]; 60 | } 61 | - (void)show 62 | { 63 | [UIView animateWithDuration:0.25f delay:0.f options:UIViewAnimationOptionCurveEaseInOut|UIViewAnimationOptionBeginFromCurrentState animations:^{ 64 | self.frame = CGRectMake(0, BounceAnimationPixel , [UIScreen mainScreen].bounds.size.width, [UIScreen mainScreen].bounds.size.height); 65 | } completion:^(BOOL finished) { 66 | [UIView animateWithDuration:0.15f delay:0.f options:UIViewAnimationOptionCurveEaseOut|UIViewAnimationOptionBeginFromCurrentState animations:^{ 67 | self.frame = CGRectMake(0, 0 , [UIScreen mainScreen].bounds.size.width, [UIScreen mainScreen].bounds.size.height); 68 | } completion:^(BOOL finished) { 69 | }]; 70 | }]; 71 | self.isOpen = YES; 72 | } 73 | - (void)dismiss:(BOOL)animated 74 | { 75 | if (!animated) 76 | { 77 | self.frame = CGRectMake(0, -[UIScreen mainScreen].bounds.size.height, [UIScreen mainScreen].bounds.size.width, [UIScreen mainScreen].bounds.size.height ); 78 | } 79 | else 80 | { 81 | [UIView animateWithDuration:0.3f animations:^{ 82 | self.frame = CGRectMake(0, - [UIScreen mainScreen].bounds.size.height, [UIScreen mainScreen].bounds.size.width, [UIScreen mainScreen].bounds.size.height); 83 | } completion:^(BOOL finished) { 84 | }]; 85 | } 86 | self.isOpen = NO; 87 | 88 | } 89 | - (void)toggle 90 | { 91 | if(self.frame.origin.y <0) 92 | { 93 | [self show]; 94 | } 95 | else 96 | { 97 | [self dismiss:YES]; 98 | } 99 | } 100 | #pragma mark - Table view data source 101 | 102 | - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView 103 | { 104 | return 1; 105 | } 106 | 107 | - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section 108 | { 109 | return self.groups.count; 110 | } 111 | 112 | - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath 113 | { 114 | static NSString *CellIdentifier = @"kGroupViewCellIdentifier"; 115 | 116 | UzysGroupViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier]; 117 | if (cell == nil) 118 | { 119 | cell = [[UzysGroupViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier]; 120 | } 121 | 122 | if (self.groups.count > 0) { 123 | [cell applyData:[self.groups objectAtIndex:indexPath.row]]; 124 | } 125 | 126 | return cell; 127 | } 128 | 129 | 130 | #pragma mark - Table view delegate 131 | 132 | - (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath 133 | { 134 | return kGroupPickerViewCellLength; 135 | } 136 | 137 | - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath 138 | { 139 | if(self.blockTouchCell) 140 | self.blockTouchCell(indexPath.row); 141 | } 142 | 143 | @end 144 | -------------------------------------------------------------------------------- /PhotoPicker/CorePhotoPickerVCManager/Library/UzysGroupViewCell.h: -------------------------------------------------------------------------------- 1 | // 2 | // UzysGroupViewCell.h 3 | // UzysAssetsPickerController 4 | // 5 | // Created by Uzysjung on 2014. 2. 13.. 6 | // Copyright (c) 2014년 Uzys. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "UzysAssetsPickerController_Configuration.h" 11 | @interface UzysGroupViewCell : UITableViewCell 12 | @property (nonatomic, strong) ALAssetsGroup *assetsGroup; 13 | - (void)applyData:(ALAssetsGroup *)assetsGroup; 14 | @end 15 | -------------------------------------------------------------------------------- /PhotoPicker/CorePhotoPickerVCManager/Library/UzysGroupViewCell.m: -------------------------------------------------------------------------------- 1 | // 2 | // uzysGroupViewCell.m 3 | // UzysAssetsPickerController 4 | // 5 | // Created by Uzysjung on 2014. 2. 13.. 6 | // Copyright (c) 2014년 Uzys. All rights reserved. 7 | // 8 | #import "UzysAssetsPickerController_Configuration.h" 9 | #import "UzysGroupViewCell.h" 10 | #import "UzysAppearanceConfig.h" 11 | 12 | @implementation UzysGroupViewCell 13 | 14 | - (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier 15 | { 16 | self = [super initWithStyle:style reuseIdentifier:reuseIdentifier]; 17 | if (self) { 18 | // Initialization code 19 | self.textLabel.font = [UIFont fontWithName:@"AppleSDGothicNeo-Medium" size:17]; 20 | self.detailTextLabel.font = [UIFont fontWithName:@"AppleSDGothicNeo-Medium" size:11]; 21 | UzysAppearanceConfig *appearanceConfig = [UzysAppearanceConfig sharedConfig]; 22 | self.accessoryView = [[UIImageView alloc] initWithImage:[UIImage Uzys_imageNamed:appearanceConfig.assetsGroupSelectedImageName]]; 23 | self.selectedBackgroundView = nil; 24 | self.selectionStyle = UITableViewCellSelectionStyleNone; 25 | } 26 | return self; 27 | } 28 | 29 | - (void)setSelected:(BOOL)selected animated:(BOOL)animated 30 | { 31 | [super setSelected:selected animated:animated]; 32 | 33 | // Configure the view for the selected state 34 | if(selected) 35 | { 36 | self.accessoryView.hidden = NO; 37 | } 38 | else 39 | { 40 | self.accessoryView.hidden = YES; 41 | } 42 | 43 | } 44 | 45 | 46 | - (void)applyData:(ALAssetsGroup *)assetsGroup 47 | { 48 | self.assetsGroup = assetsGroup; 49 | 50 | CGImageRef posterImage = assetsGroup.posterImage; 51 | size_t height = CGImageGetHeight(posterImage); 52 | float scale = height / kThumbnailLength; 53 | 54 | self.imageView.image = [UIImage imageWithCGImage:posterImage scale:scale orientation:UIImageOrientationUp]; 55 | self.textLabel.text = [assetsGroup valueForProperty:ALAssetsGroupPropertyName]; 56 | self.detailTextLabel.text = [NSString stringWithFormat:@"%ld", (long)[assetsGroup numberOfAssets]]; 57 | self.accessoryType = UITableViewCellAccessoryDisclosureIndicator; 58 | } 59 | @end 60 | -------------------------------------------------------------------------------- /PhotoPicker/CorePhotoPickerVCManager/Library/UzysWrapperPickerController.h: -------------------------------------------------------------------------------- 1 | // 2 | // UzysWrapperPickerController.h 3 | // IdolChat 4 | // 5 | // Created by Uzysjung on 2014. 1. 28.. 6 | // Copyright (c) 2014년 SKPlanet. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface UzysWrapperPickerController : UIImagePickerController 12 | @end 13 | -------------------------------------------------------------------------------- /PhotoPicker/CorePhotoPickerVCManager/Library/UzysWrapperPickerController.m: -------------------------------------------------------------------------------- 1 | // 2 | // UzysWrapperPickerController.m 3 | // IdolChat 4 | // 5 | // Created by Uzysjung on 2014. 1. 28.. 6 | // Copyright (c) 2014년 SKPlanet. All rights reserved. 7 | // 8 | 9 | #import "UzysWrapperPickerController.h" 10 | 11 | @interface UzysWrapperPickerController () 12 | 13 | @end 14 | 15 | @implementation UzysWrapperPickerController 16 | 17 | - (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil 18 | { 19 | self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil]; 20 | if (self) { 21 | // Custom initialization 22 | } 23 | return self; 24 | } 25 | 26 | - (void)viewDidLoad 27 | { 28 | [super viewDidLoad]; 29 | // Do any additional setup after loading the view. 30 | } 31 | 32 | - (void)didReceiveMemoryWarning 33 | { 34 | [super didReceiveMemoryWarning]; 35 | // Dispose of any resources that can be recreated. 36 | } 37 | #pragma mark - View Controller Setting /Rotation 38 | -(BOOL)shouldAutorotate 39 | { 40 | return YES; 41 | } 42 | - (UIViewController *)childViewControllerForStatusBarHidden 43 | { 44 | return nil; 45 | } 46 | - (BOOL)prefersStatusBarHidden 47 | { 48 | return YES; 49 | } 50 | - (void)dealloc 51 | { 52 | // DLog(@"UzysWrapperPicerController dealloc"); 53 | } 54 | //-(NSUInteger)supportedInterfaceOrientations 55 | //{ 56 | // return UIInterfaceOrientationMaskPortrait; 57 | //} 58 | //- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation 59 | //{ 60 | // return UIInterfaceOrientationPortrait; 61 | //} 62 | //- (UIStatusBarStyle)preferredStatusBarStyle 63 | //{ 64 | // return UIStatusBarStyleLightContent; 65 | //} 66 | 67 | @end 68 | -------------------------------------------------------------------------------- /PhotoPicker/Images.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "iphone", 5 | "size" : "29x29", 6 | "scale" : "2x" 7 | }, 8 | { 9 | "idiom" : "iphone", 10 | "size" : "29x29", 11 | "scale" : "3x" 12 | }, 13 | { 14 | "idiom" : "iphone", 15 | "size" : "40x40", 16 | "scale" : "2x" 17 | }, 18 | { 19 | "idiom" : "iphone", 20 | "size" : "40x40", 21 | "scale" : "3x" 22 | }, 23 | { 24 | "idiom" : "iphone", 25 | "size" : "60x60", 26 | "scale" : "2x" 27 | }, 28 | { 29 | "idiom" : "iphone", 30 | "size" : "60x60", 31 | "scale" : "3x" 32 | } 33 | ], 34 | "info" : { 35 | "version" : 1, 36 | "author" : "xcode" 37 | } 38 | } -------------------------------------------------------------------------------- /PhotoPicker/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | com.huaxi.$(PRODUCT_NAME:rfc1034identifier) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | APPL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | 1 23 | LSRequiresIPhoneOS 24 | 25 | UILaunchStoryboardName 26 | LaunchScreen 27 | UIMainStoryboardFile 28 | Main 29 | UIRequiredDeviceCapabilities 30 | 31 | armv7 32 | 33 | UISupportedInterfaceOrientations 34 | 35 | UIInterfaceOrientationPortrait 36 | UIInterfaceOrientationLandscapeLeft 37 | UIInterfaceOrientationLandscapeRight 38 | 39 | 40 | 41 | -------------------------------------------------------------------------------- /PhotoPicker/ViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.h 3 | // PhotoPicker 4 | // 5 | // Created by muxi on 15/2/13. 6 | // Copyright (c) 2015年 muxi. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface ViewController : UIViewController 12 | 13 | 14 | @end 15 | 16 | -------------------------------------------------------------------------------- /PhotoPicker/ViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.m 3 | // PhotoPicker 4 | // 5 | // Created by muxi on 15/2/13. 6 | // Copyright (c) 2015年 muxi. All rights reserved. 7 | // 8 | 9 | #import "ViewController.h" 10 | #import "CorePhotoPickerVCManager.h" 11 | 12 | 13 | @interface ViewController () 14 | 15 | @property (nonatomic,strong) CorePhotoPickerVCManager *manager; 16 | @property (strong, nonatomic) IBOutlet UIImageView *imageV; 17 | 18 | 19 | 20 | @end 21 | 22 | @implementation ViewController 23 | 24 | - (void)viewDidLoad { 25 | [super viewDidLoad]; 26 | 27 | } 28 | 29 | - (IBAction)btnClick:(id)sender { 30 | 31 | UIActionSheet *sheet=[[UIActionSheet alloc] initWithTitle:@"请选取" delegate:self cancelButtonTitle:@"取消" destructiveButtonTitle:@"拍摄" otherButtonTitles:@"照片库",@"照片多选", nil]; 32 | 33 | [sheet showInView:self.view]; 34 | 35 | 36 | } 37 | 38 | 39 | -(void)actionSheet:(UIActionSheet *)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex{ 40 | 41 | CorePhotoPickerVCMangerType type=0; 42 | 43 | 44 | if(buttonIndex==0) type=CorePhotoPickerVCMangerTypeCamera; 45 | 46 | if(buttonIndex==1) type=CorePhotoPickerVCMangerTypeSinglePhoto; 47 | 48 | if(buttonIndex==2) type=CorePhotoPickerVCMangerTypeMultiPhoto; 49 | 50 | CorePhotoPickerVCManager *manager=[CorePhotoPickerVCManager sharedCorePhotoPickerVCManager]; 51 | 52 | //设置类型 53 | manager.pickerVCManagerType=type; 54 | 55 | //最多可选3张 56 | manager.maxSelectedPhotoNumber=5; 57 | 58 | //错误处理 59 | if(manager.unavailableType!=CorePhotoPickerUnavailableTypeNone){ 60 | NSLog(@"设备不可用"); 61 | return; 62 | } 63 | 64 | UIViewController *pickerVC=manager.imagePickerController; 65 | 66 | //选取结束 67 | manager.finishPickingMedia=^(NSArray *medias){ 68 | 69 | [medias enumerateObjectsUsingBlock:^(CorePhoto *photo, NSUInteger idx, BOOL *stop) { 70 | NSLog(@"%@",photo.editedImage); 71 | }]; 72 | }; 73 | 74 | [self presentViewController:pickerVC animated:YES completion:nil]; 75 | 76 | 77 | } 78 | 79 | 80 | 81 | @end 82 | -------------------------------------------------------------------------------- /PhotoPicker/img/1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CharlinFeng/CorePhotoPickerVCManager/b779b2c2ee025857c95b18345328080061b24909/PhotoPicker/img/1.png -------------------------------------------------------------------------------- /PhotoPicker/img/2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CharlinFeng/CorePhotoPickerVCManager/b779b2c2ee025857c95b18345328080061b24909/PhotoPicker/img/2.png -------------------------------------------------------------------------------- /PhotoPicker/img/3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CharlinFeng/CorePhotoPickerVCManager/b779b2c2ee025857c95b18345328080061b24909/PhotoPicker/img/3.png -------------------------------------------------------------------------------- /PhotoPicker/main.m: -------------------------------------------------------------------------------- 1 | // 2 | // main.m 3 | // PhotoPicker 4 | // 5 | // Created by muxi on 15/2/13. 6 | // Copyright (c) 2015年 muxi. 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 | -------------------------------------------------------------------------------- /PhotoPickerTests/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | com.huaxi.$(PRODUCT_NAME:rfc1034identifier) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | BNDL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | 1 23 | 24 | 25 | -------------------------------------------------------------------------------- /PhotoPickerTests/PhotoPickerTests.m: -------------------------------------------------------------------------------- 1 | // 2 | // PhotoPickerTests.m 3 | // PhotoPickerTests 4 | // 5 | // Created by muxi on 15/2/13. 6 | // Copyright (c) 2015年 muxi. All rights reserved. 7 | // 8 | 9 | #import 10 | #import 11 | 12 | @interface PhotoPickerTests : XCTestCase 13 | 14 | @end 15 | 16 | @implementation PhotoPickerTests 17 | 18 | - (void)setUp { 19 | [super setUp]; 20 | // Put setup code here. This method is called before the invocation of each test method in the class. 21 | } 22 | 23 | - (void)tearDown { 24 | // Put teardown code here. This method is called after the invocation of each test method in the class. 25 | [super tearDown]; 26 | } 27 | 28 | - (void)testExample { 29 | // This is an example of a functional test case. 30 | XCTAssert(YES, @"Pass"); 31 | } 32 | 33 | - (void)testPerformanceExample { 34 | // This is an example of a performance test case. 35 | [self measureBlock:^{ 36 | // Put the code you want to measure the time of here. 37 | }]; 38 | } 39 | 40 | @end 41 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 2 | Charlin出框架的目标:简单、易用、高度封装、绝对解耦! 3 | 4 | #CorePhotoPickerVCManager 5 | ####大统一的多功能照片选取器,集成拍摄,单选,多选。 6 | 7 | 8 | 9 | ##框架特性:
10 | >1.无需代理,无需解析数据,传一个type值,block就把图片对象给你!
11 | >2.支持相册目录(后期支持视频选取)。
12 | >3.支持iPhone6/iPhone6 Plus及横竖屏。
13 | >4.支持相册直接拍摄、相册选取(单选),相册多选
14 | >5.相册多选支持最少选取张数,最多选取张数,并带有超出选取自动提示。
15 | >6.界面专业设计,界面美观。
16 | >7.支持设备不可用block回调。
17 | >8.整个使用过程你不再需要设置代理,全部使用block回调。
18 | >9.您如果需要不同的选取功能,直接在初始化的时候指定type即可
19 | 20 | ##重要定义: 21 | typedef enum{ 22 | 23 | //用户拍照 24 | CorePhotoPickerVCMangerTypeCamera=0, 25 | 26 | //单张照片选取 27 | CorePhotoPickerVCMangerTypeSinglePhoto, 28 | 29 | //多张照片选取 30 | CorePhotoPickerVCMangerTypeMultiPhoto, 31 | 32 | //视频选取(暂不考虑,本框架仍可以完美支持) 33 | CorePhotoPickerVCMangerTypeVideo, 34 | 35 | }CorePhotoPickerVCMangerType; 36 | 37 | 38 | typedef enum{ 39 | 40 | //无错误,可用 41 | CorePhotoPickerUnavailableTypeNone, 42 | 43 | //相机不可用 44 | CorePhotoPickerUnavailableTypeCamera, 45 | 46 | //相册不可用 47 | CorePhotoPickerUnavailableTypePhoto, 48 | 49 | }CorePhotoPickerUnavailableType; 50 | 51 | 52 | #使用示例: 53 | 54 | CorePhotoPickerVCManager *manager=[CorePhotoPickerVCManager sharedCorePhotoPickerVCManager]; 55 | 56 | //设置类型 57 | manager.pickerVCManagerType=type; 58 | 59 | //最多可选3张 60 | manager.maxSelectedPhotoNumber=3; 61 | 62 | //错误处理 63 | if(manager.unavailableType!=CorePhotoPickerUnavailableTypeNone){ 64 | NSLog(@"设备不可用"); 65 | return; 66 | } 67 | 68 | UIViewController *pickerVC=manager.imagePickerController; 69 | 70 | //选取结束 71 | manager.finishPickingMedia=^(NSArray *medias){ 72 | 73 | [medias enumerateObjectsUsingBlock:^(CorePhoto *photo, NSUInteger idx, BOOL *stop) { 74 | NSLog(@"%@",photo.editedImage); 75 | }]; 76 | }; 77 | 78 | [self presentViewController:pickerVC animated:YES completion:nil]; 79 | 80 | 81 | #看看效果图吧: 82 | ![image](./PhotoPicker/img/1.png) 83 | ![image](./PhotoPicker/img/2.png) 84 | ![image](./PhotoPicker/img/3.png) 85 | 86 |



87 | 88 | ----- 89 | CorePhotoPickerVCManager 大统一的多功能照片选取器,集成拍摄,单选,多选。 90 | ----- 91 | 92 |

93 | 94 | #### 版权说明 RIGHTS
95 | 作品说明:本框架由iOS开发攻城狮Charlin制作。
96 | 作品时间: 2015.01.02 23:50
97 | 更新时间: 2015.03.03 15:14

98 | 99 | #### 关于Chariln INTRODUCE
100 | 作者简介:Charlin-四川成都华西都市报旗下华西都市网络有限公司技术部iOS工程师!

101 | 102 | 103 | #### 联系方式 CONTACT
104 | Q Q:1761904945(请注明缘由)
105 | Mail:1761904945@qq.com
106 | --------------------------------------------------------------------------------