├── .gitignore ├── LICENSE ├── QBImagePickerControllerDemo ├── QBImagePickerControllerDemo.xcodeproj │ ├── project.pbxproj │ ├── project.xcworkspace │ │ ├── contents.xcworkspacedata │ │ ├── xcshareddata │ │ │ └── QBImagePickerControllerDemo.xccheckout │ │ └── xcuserdata │ │ │ ├── LeexMuller.xcuserdatad │ │ │ └── UserInterfaceState.xcuserstate │ │ │ └── hmg.xcuserdatad │ │ │ └── UserInterfaceState.xcuserstate │ └── xcuserdata │ │ ├── LeexMuller.xcuserdatad │ │ ├── xcdebugger │ │ │ └── Breakpoints_v2.xcbkptlist │ │ └── xcschemes │ │ │ ├── QBImagePickerControllerDemo.xcscheme │ │ │ └── xcschememanagement.plist │ │ └── hmg.xcuserdatad │ │ ├── xcdebugger │ │ └── Breakpoints_v2.xcbkptlist │ │ └── xcschemes │ │ ├── QBImagePickerControllerDemo.xcscheme │ │ └── xcschememanagement.plist ├── QBImagePickerControllerDemo │ ├── AppDelegate.h │ ├── AppDelegate.m │ ├── Default-568h@2x.png │ ├── Default.png │ ├── Default@2x.png │ ├── Images.xcassets │ │ ├── AppIcon.appiconset │ │ │ └── Contents.json │ │ └── LaunchImage.launchimage │ │ │ ├── Contents.json │ │ │ ├── Default-568h@2x.png │ │ │ └── Default@2x.png │ ├── QBImagePickerController │ │ ├── QBAssetCollectionViewController.h │ │ ├── QBAssetCollectionViewController.m │ │ ├── QBAssetCollectionViewControllerDelegate.h │ │ ├── QBImageEditerViewController.h │ │ ├── QBImageEditerViewController.m │ │ ├── QBImageEditerViewControllerDelegate.h │ │ ├── QBImagePickerAssetCell.h │ │ ├── QBImagePickerAssetCell.m │ │ ├── QBImagePickerAssetCellDelegate.h │ │ ├── QBImagePickerAssetView.h │ │ ├── QBImagePickerAssetView.m │ │ ├── QBImagePickerAssetViewDelegate.h │ │ ├── QBImagePickerController.bundle │ │ │ ├── minus.png │ │ │ ├── minus@2x.png │ │ │ ├── overlay.png │ │ │ ├── overlay@2x.png │ │ │ ├── plus.png │ │ │ ├── plus@2x.png │ │ │ ├── video.png │ │ │ └── video@2x.png │ │ ├── QBImagePickerController.h │ │ ├── QBImagePickerController.m │ │ ├── QBImagePickerFooterView.h │ │ ├── QBImagePickerFooterView.m │ │ ├── QBImagePickerGroupCell.h │ │ ├── QBImagePickerGroupCell.m │ │ ├── QBImagePickerVideoInfoView.h │ │ └── QBImagePickerVideoInfoView.m │ ├── QBImagePickerControllerDemo-Info.plist │ ├── QBImagePickerControllerDemo-Prefix.pch │ ├── ViewController.h │ ├── ViewController.m │ ├── en.lproj │ │ └── InfoPlist.strings │ └── main.m └── QBImagePickerControllerDemoTests │ ├── QBImagePickerControllerDemoTests-Info.plist │ ├── QBImagePickerControllerDemoTests.m │ └── en.lproj │ └── InfoPlist.strings └── README.md /.gitignore: -------------------------------------------------------------------------------- 1 | # CocoaPods 2 | # 3 | # We recommend against adding the Pods directory to your .gitignore. However 4 | # you should judge for yourself, the pros and cons are mentioned at: 5 | # http://guides.cocoapods.org/using/using-cocoapods.html#should-i-ignore-the-pods-directory-in-source-control? 6 | # 7 | # Pods/ 8 | 9 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2014 Harris 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /QBImagePickerControllerDemo/QBImagePickerControllerDemo.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 46; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 9E13F2BD19AACFE100A9A836 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9E13F2BC19AACFE100A9A836 /* Foundation.framework */; }; 11 | 9E13F2BF19AACFE100A9A836 /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9E13F2BE19AACFE100A9A836 /* CoreGraphics.framework */; }; 12 | 9E13F2C119AACFE100A9A836 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9E13F2C019AACFE100A9A836 /* UIKit.framework */; }; 13 | 9E13F2C719AACFE100A9A836 /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 9E13F2C519AACFE100A9A836 /* InfoPlist.strings */; }; 14 | 9E13F2C919AACFE100A9A836 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 9E13F2C819AACFE100A9A836 /* main.m */; }; 15 | 9E13F2CD19AACFE100A9A836 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 9E13F2CC19AACFE100A9A836 /* AppDelegate.m */; }; 16 | 9E13F2D319AACFE100A9A836 /* ViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 9E13F2D219AACFE100A9A836 /* ViewController.m */; }; 17 | 9E13F2D519AACFE100A9A836 /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 9E13F2D419AACFE100A9A836 /* Images.xcassets */; }; 18 | 9E13F2DC19AACFE100A9A836 /* XCTest.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9E13F2DB19AACFE100A9A836 /* XCTest.framework */; }; 19 | 9E13F2DD19AACFE100A9A836 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9E13F2BC19AACFE100A9A836 /* Foundation.framework */; }; 20 | 9E13F2DE19AACFE100A9A836 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9E13F2C019AACFE100A9A836 /* UIKit.framework */; }; 21 | 9E13F2E619AACFE100A9A836 /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 9E13F2E419AACFE100A9A836 /* InfoPlist.strings */; }; 22 | 9E13F2E819AACFE100A9A836 /* QBImagePickerControllerDemoTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 9E13F2E719AACFE100A9A836 /* QBImagePickerControllerDemoTests.m */; }; 23 | 9E3F5BF219AAE09200854C73 /* Default.png in Resources */ = {isa = PBXBuildFile; fileRef = 9E3F5BEF19AAE09200854C73 /* Default.png */; }; 24 | 9E3F5BF319AAE09200854C73 /* Default-568h@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 9E3F5BF019AAE09200854C73 /* Default-568h@2x.png */; }; 25 | 9E3F5BF419AAE09200854C73 /* Default@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 9E3F5BF119AAE09200854C73 /* Default@2x.png */; }; 26 | 9E50DCA919C17C5000088FB2 /* QBImageEditerViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 9E50DCA819C17C5000088FB2 /* QBImageEditerViewController.m */; }; 27 | 9E6B53A519AAD6400028915A /* QBAssetCollectionViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 9E6B539419AAD6400028915A /* QBAssetCollectionViewController.m */; }; 28 | 9E6B53A619AAD6400028915A /* QBImagePickerAssetCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 9E6B539719AAD6400028915A /* QBImagePickerAssetCell.m */; }; 29 | 9E6B53A719AAD6400028915A /* QBImagePickerAssetView.m in Sources */ = {isa = PBXBuildFile; fileRef = 9E6B539A19AAD6400028915A /* QBImagePickerAssetView.m */; }; 30 | 9E6B53A819AAD6400028915A /* QBImagePickerController.bundle in Resources */ = {isa = PBXBuildFile; fileRef = 9E6B539C19AAD6400028915A /* QBImagePickerController.bundle */; }; 31 | 9E6B53A919AAD6400028915A /* QBImagePickerController.m in Sources */ = {isa = PBXBuildFile; fileRef = 9E6B539E19AAD6400028915A /* QBImagePickerController.m */; }; 32 | 9E6B53AA19AAD6400028915A /* QBImagePickerFooterView.m in Sources */ = {isa = PBXBuildFile; fileRef = 9E6B53A019AAD6400028915A /* QBImagePickerFooterView.m */; }; 33 | 9E6B53AB19AAD6400028915A /* QBImagePickerGroupCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 9E6B53A219AAD6400028915A /* QBImagePickerGroupCell.m */; }; 34 | 9E6B53AC19AAD6400028915A /* QBImagePickerVideoInfoView.m in Sources */ = {isa = PBXBuildFile; fileRef = 9E6B53A419AAD6400028915A /* QBImagePickerVideoInfoView.m */; }; 35 | /* End PBXBuildFile section */ 36 | 37 | /* Begin PBXContainerItemProxy section */ 38 | 9E13F2DF19AACFE100A9A836 /* PBXContainerItemProxy */ = { 39 | isa = PBXContainerItemProxy; 40 | containerPortal = 9E13F2B119AACFE100A9A836 /* Project object */; 41 | proxyType = 1; 42 | remoteGlobalIDString = 9E13F2B819AACFE100A9A836; 43 | remoteInfo = QBImagePickerControllerDemo; 44 | }; 45 | /* End PBXContainerItemProxy section */ 46 | 47 | /* Begin PBXFileReference section */ 48 | 9E13F2B919AACFE100A9A836 /* QBImagePickerControllerDemo.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = QBImagePickerControllerDemo.app; sourceTree = BUILT_PRODUCTS_DIR; }; 49 | 9E13F2BC19AACFE100A9A836 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; }; 50 | 9E13F2BE19AACFE100A9A836 /* CoreGraphics.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreGraphics.framework; path = System/Library/Frameworks/CoreGraphics.framework; sourceTree = SDKROOT; }; 51 | 9E13F2C019AACFE100A9A836 /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; }; 52 | 9E13F2C419AACFE100A9A836 /* QBImagePickerControllerDemo-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "QBImagePickerControllerDemo-Info.plist"; sourceTree = ""; }; 53 | 9E13F2C619AACFE100A9A836 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/InfoPlist.strings; sourceTree = ""; }; 54 | 9E13F2C819AACFE100A9A836 /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; 55 | 9E13F2CA19AACFE100A9A836 /* QBImagePickerControllerDemo-Prefix.pch */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "QBImagePickerControllerDemo-Prefix.pch"; sourceTree = ""; }; 56 | 9E13F2CB19AACFE100A9A836 /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; 57 | 9E13F2CC19AACFE100A9A836 /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; 58 | 9E13F2D119AACFE100A9A836 /* ViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ViewController.h; sourceTree = ""; }; 59 | 9E13F2D219AACFE100A9A836 /* ViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ViewController.m; sourceTree = ""; }; 60 | 9E13F2D419AACFE100A9A836 /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Images.xcassets; sourceTree = ""; }; 61 | 9E13F2DA19AACFE100A9A836 /* QBImagePickerControllerDemoTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = QBImagePickerControllerDemoTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; 62 | 9E13F2DB19AACFE100A9A836 /* XCTest.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = XCTest.framework; path = Library/Frameworks/XCTest.framework; sourceTree = DEVELOPER_DIR; }; 63 | 9E13F2E319AACFE100A9A836 /* QBImagePickerControllerDemoTests-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "QBImagePickerControllerDemoTests-Info.plist"; sourceTree = ""; }; 64 | 9E13F2E519AACFE100A9A836 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/InfoPlist.strings; sourceTree = ""; }; 65 | 9E13F2E719AACFE100A9A836 /* QBImagePickerControllerDemoTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = QBImagePickerControllerDemoTests.m; sourceTree = ""; }; 66 | 9E3F5BEF19AAE09200854C73 /* Default.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = Default.png; sourceTree = ""; }; 67 | 9E3F5BF019AAE09200854C73 /* Default-568h@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Default-568h@2x.png"; sourceTree = ""; }; 68 | 9E3F5BF119AAE09200854C73 /* Default@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Default@2x.png"; sourceTree = ""; }; 69 | 9E50DCA719C17C5000088FB2 /* QBImageEditerViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = QBImageEditerViewController.h; sourceTree = ""; }; 70 | 9E50DCA819C17C5000088FB2 /* QBImageEditerViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = QBImageEditerViewController.m; sourceTree = ""; }; 71 | 9E50DCAA19C1834300088FB2 /* QBImageEditerViewControllerDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = QBImageEditerViewControllerDelegate.h; sourceTree = ""; }; 72 | 9E6B539319AAD6400028915A /* QBAssetCollectionViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = QBAssetCollectionViewController.h; sourceTree = ""; }; 73 | 9E6B539419AAD6400028915A /* QBAssetCollectionViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = QBAssetCollectionViewController.m; sourceTree = ""; }; 74 | 9E6B539519AAD6400028915A /* QBAssetCollectionViewControllerDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = QBAssetCollectionViewControllerDelegate.h; sourceTree = ""; }; 75 | 9E6B539619AAD6400028915A /* QBImagePickerAssetCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = QBImagePickerAssetCell.h; sourceTree = ""; }; 76 | 9E6B539719AAD6400028915A /* QBImagePickerAssetCell.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = QBImagePickerAssetCell.m; sourceTree = ""; }; 77 | 9E6B539819AAD6400028915A /* QBImagePickerAssetCellDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = QBImagePickerAssetCellDelegate.h; sourceTree = ""; }; 78 | 9E6B539919AAD6400028915A /* QBImagePickerAssetView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = QBImagePickerAssetView.h; sourceTree = ""; }; 79 | 9E6B539A19AAD6400028915A /* QBImagePickerAssetView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = QBImagePickerAssetView.m; sourceTree = ""; }; 80 | 9E6B539B19AAD6400028915A /* QBImagePickerAssetViewDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = QBImagePickerAssetViewDelegate.h; sourceTree = ""; }; 81 | 9E6B539C19AAD6400028915A /* QBImagePickerController.bundle */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.plug-in"; path = QBImagePickerController.bundle; sourceTree = ""; }; 82 | 9E6B539D19AAD6400028915A /* QBImagePickerController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = QBImagePickerController.h; sourceTree = ""; }; 83 | 9E6B539E19AAD6400028915A /* QBImagePickerController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = QBImagePickerController.m; sourceTree = ""; }; 84 | 9E6B539F19AAD6400028915A /* QBImagePickerFooterView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = QBImagePickerFooterView.h; sourceTree = ""; }; 85 | 9E6B53A019AAD6400028915A /* QBImagePickerFooterView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = QBImagePickerFooterView.m; sourceTree = ""; }; 86 | 9E6B53A119AAD6400028915A /* QBImagePickerGroupCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = QBImagePickerGroupCell.h; sourceTree = ""; }; 87 | 9E6B53A219AAD6400028915A /* QBImagePickerGroupCell.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = QBImagePickerGroupCell.m; sourceTree = ""; }; 88 | 9E6B53A319AAD6400028915A /* QBImagePickerVideoInfoView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = QBImagePickerVideoInfoView.h; sourceTree = ""; }; 89 | 9E6B53A419AAD6400028915A /* QBImagePickerVideoInfoView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = QBImagePickerVideoInfoView.m; sourceTree = ""; }; 90 | /* End PBXFileReference section */ 91 | 92 | /* Begin PBXFrameworksBuildPhase section */ 93 | 9E13F2B619AACFE100A9A836 /* Frameworks */ = { 94 | isa = PBXFrameworksBuildPhase; 95 | buildActionMask = 2147483647; 96 | files = ( 97 | 9E13F2BF19AACFE100A9A836 /* CoreGraphics.framework in Frameworks */, 98 | 9E13F2C119AACFE100A9A836 /* UIKit.framework in Frameworks */, 99 | 9E13F2BD19AACFE100A9A836 /* Foundation.framework in Frameworks */, 100 | ); 101 | runOnlyForDeploymentPostprocessing = 0; 102 | }; 103 | 9E13F2D719AACFE100A9A836 /* Frameworks */ = { 104 | isa = PBXFrameworksBuildPhase; 105 | buildActionMask = 2147483647; 106 | files = ( 107 | 9E13F2DC19AACFE100A9A836 /* XCTest.framework in Frameworks */, 108 | 9E13F2DE19AACFE100A9A836 /* UIKit.framework in Frameworks */, 109 | 9E13F2DD19AACFE100A9A836 /* Foundation.framework in Frameworks */, 110 | ); 111 | runOnlyForDeploymentPostprocessing = 0; 112 | }; 113 | /* End PBXFrameworksBuildPhase section */ 114 | 115 | /* Begin PBXGroup section */ 116 | 9E13F2B019AACFE100A9A836 = { 117 | isa = PBXGroup; 118 | children = ( 119 | 9E13F2C219AACFE100A9A836 /* QBImagePickerControllerDemo */, 120 | 9E13F2E119AACFE100A9A836 /* QBImagePickerControllerDemoTests */, 121 | 9E13F2BB19AACFE100A9A836 /* Frameworks */, 122 | 9E13F2BA19AACFE100A9A836 /* Products */, 123 | ); 124 | sourceTree = ""; 125 | }; 126 | 9E13F2BA19AACFE100A9A836 /* Products */ = { 127 | isa = PBXGroup; 128 | children = ( 129 | 9E13F2B919AACFE100A9A836 /* QBImagePickerControllerDemo.app */, 130 | 9E13F2DA19AACFE100A9A836 /* QBImagePickerControllerDemoTests.xctest */, 131 | ); 132 | name = Products; 133 | sourceTree = ""; 134 | }; 135 | 9E13F2BB19AACFE100A9A836 /* Frameworks */ = { 136 | isa = PBXGroup; 137 | children = ( 138 | 9E13F2BC19AACFE100A9A836 /* Foundation.framework */, 139 | 9E13F2BE19AACFE100A9A836 /* CoreGraphics.framework */, 140 | 9E13F2C019AACFE100A9A836 /* UIKit.framework */, 141 | 9E13F2DB19AACFE100A9A836 /* XCTest.framework */, 142 | ); 143 | name = Frameworks; 144 | sourceTree = ""; 145 | }; 146 | 9E13F2C219AACFE100A9A836 /* QBImagePickerControllerDemo */ = { 147 | isa = PBXGroup; 148 | children = ( 149 | 9E13F2CB19AACFE100A9A836 /* AppDelegate.h */, 150 | 9E13F2CC19AACFE100A9A836 /* AppDelegate.m */, 151 | 9E13F2D119AACFE100A9A836 /* ViewController.h */, 152 | 9E13F2D219AACFE100A9A836 /* ViewController.m */, 153 | 9E6B539219AAD6390028915A /* QBImagePickerController */, 154 | 9E13F2D419AACFE100A9A836 /* Images.xcassets */, 155 | 9E13F2C319AACFE100A9A836 /* Supporting Files */, 156 | ); 157 | path = QBImagePickerControllerDemo; 158 | sourceTree = ""; 159 | }; 160 | 9E13F2C319AACFE100A9A836 /* Supporting Files */ = { 161 | isa = PBXGroup; 162 | children = ( 163 | 9E13F2C419AACFE100A9A836 /* QBImagePickerControllerDemo-Info.plist */, 164 | 9E13F2C519AACFE100A9A836 /* InfoPlist.strings */, 165 | 9E13F2C819AACFE100A9A836 /* main.m */, 166 | 9E13F2CA19AACFE100A9A836 /* QBImagePickerControllerDemo-Prefix.pch */, 167 | 9E3F5BEF19AAE09200854C73 /* Default.png */, 168 | 9E3F5BF019AAE09200854C73 /* Default-568h@2x.png */, 169 | 9E3F5BF119AAE09200854C73 /* Default@2x.png */, 170 | ); 171 | name = "Supporting Files"; 172 | sourceTree = ""; 173 | }; 174 | 9E13F2E119AACFE100A9A836 /* QBImagePickerControllerDemoTests */ = { 175 | isa = PBXGroup; 176 | children = ( 177 | 9E13F2E719AACFE100A9A836 /* QBImagePickerControllerDemoTests.m */, 178 | 9E13F2E219AACFE100A9A836 /* Supporting Files */, 179 | ); 180 | path = QBImagePickerControllerDemoTests; 181 | sourceTree = ""; 182 | }; 183 | 9E13F2E219AACFE100A9A836 /* Supporting Files */ = { 184 | isa = PBXGroup; 185 | children = ( 186 | 9E13F2E319AACFE100A9A836 /* QBImagePickerControllerDemoTests-Info.plist */, 187 | 9E13F2E419AACFE100A9A836 /* InfoPlist.strings */, 188 | ); 189 | name = "Supporting Files"; 190 | sourceTree = ""; 191 | }; 192 | 9E6B539219AAD6390028915A /* QBImagePickerController */ = { 193 | isa = PBXGroup; 194 | children = ( 195 | 9E6B539319AAD6400028915A /* QBAssetCollectionViewController.h */, 196 | 9E6B539419AAD6400028915A /* QBAssetCollectionViewController.m */, 197 | 9E6B539519AAD6400028915A /* QBAssetCollectionViewControllerDelegate.h */, 198 | 9E6B539619AAD6400028915A /* QBImagePickerAssetCell.h */, 199 | 9E6B539719AAD6400028915A /* QBImagePickerAssetCell.m */, 200 | 9E6B539819AAD6400028915A /* QBImagePickerAssetCellDelegate.h */, 201 | 9E6B539919AAD6400028915A /* QBImagePickerAssetView.h */, 202 | 9E6B539A19AAD6400028915A /* QBImagePickerAssetView.m */, 203 | 9E6B539B19AAD6400028915A /* QBImagePickerAssetViewDelegate.h */, 204 | 9E6B539C19AAD6400028915A /* QBImagePickerController.bundle */, 205 | 9E6B539D19AAD6400028915A /* QBImagePickerController.h */, 206 | 9E6B539E19AAD6400028915A /* QBImagePickerController.m */, 207 | 9E6B539F19AAD6400028915A /* QBImagePickerFooterView.h */, 208 | 9E6B53A019AAD6400028915A /* QBImagePickerFooterView.m */, 209 | 9E6B53A119AAD6400028915A /* QBImagePickerGroupCell.h */, 210 | 9E6B53A219AAD6400028915A /* QBImagePickerGroupCell.m */, 211 | 9E6B53A319AAD6400028915A /* QBImagePickerVideoInfoView.h */, 212 | 9E6B53A419AAD6400028915A /* QBImagePickerVideoInfoView.m */, 213 | 9E50DCA719C17C5000088FB2 /* QBImageEditerViewController.h */, 214 | 9E50DCA819C17C5000088FB2 /* QBImageEditerViewController.m */, 215 | 9E50DCAA19C1834300088FB2 /* QBImageEditerViewControllerDelegate.h */, 216 | ); 217 | path = QBImagePickerController; 218 | sourceTree = ""; 219 | }; 220 | /* End PBXGroup section */ 221 | 222 | /* Begin PBXNativeTarget section */ 223 | 9E13F2B819AACFE100A9A836 /* QBImagePickerControllerDemo */ = { 224 | isa = PBXNativeTarget; 225 | buildConfigurationList = 9E13F2EB19AACFE100A9A836 /* Build configuration list for PBXNativeTarget "QBImagePickerControllerDemo" */; 226 | buildPhases = ( 227 | 9E13F2B519AACFE100A9A836 /* Sources */, 228 | 9E13F2B619AACFE100A9A836 /* Frameworks */, 229 | 9E13F2B719AACFE100A9A836 /* Resources */, 230 | ); 231 | buildRules = ( 232 | ); 233 | dependencies = ( 234 | ); 235 | name = QBImagePickerControllerDemo; 236 | productName = QBImagePickerControllerDemo; 237 | productReference = 9E13F2B919AACFE100A9A836 /* QBImagePickerControllerDemo.app */; 238 | productType = "com.apple.product-type.application"; 239 | }; 240 | 9E13F2D919AACFE100A9A836 /* QBImagePickerControllerDemoTests */ = { 241 | isa = PBXNativeTarget; 242 | buildConfigurationList = 9E13F2EE19AACFE100A9A836 /* Build configuration list for PBXNativeTarget "QBImagePickerControllerDemoTests" */; 243 | buildPhases = ( 244 | 9E13F2D619AACFE100A9A836 /* Sources */, 245 | 9E13F2D719AACFE100A9A836 /* Frameworks */, 246 | 9E13F2D819AACFE100A9A836 /* Resources */, 247 | ); 248 | buildRules = ( 249 | ); 250 | dependencies = ( 251 | 9E13F2E019AACFE100A9A836 /* PBXTargetDependency */, 252 | ); 253 | name = QBImagePickerControllerDemoTests; 254 | productName = QBImagePickerControllerDemoTests; 255 | productReference = 9E13F2DA19AACFE100A9A836 /* QBImagePickerControllerDemoTests.xctest */; 256 | productType = "com.apple.product-type.bundle.unit-test"; 257 | }; 258 | /* End PBXNativeTarget section */ 259 | 260 | /* Begin PBXProject section */ 261 | 9E13F2B119AACFE100A9A836 /* Project object */ = { 262 | isa = PBXProject; 263 | attributes = { 264 | LastUpgradeCheck = 0730; 265 | ORGANIZATIONNAME = "Cao JianRong"; 266 | TargetAttributes = { 267 | 9E13F2D919AACFE100A9A836 = { 268 | TestTargetID = 9E13F2B819AACFE100A9A836; 269 | }; 270 | }; 271 | }; 272 | buildConfigurationList = 9E13F2B419AACFE100A9A836 /* Build configuration list for PBXProject "QBImagePickerControllerDemo" */; 273 | compatibilityVersion = "Xcode 3.2"; 274 | developmentRegion = English; 275 | hasScannedForEncodings = 0; 276 | knownRegions = ( 277 | en, 278 | Base, 279 | ); 280 | mainGroup = 9E13F2B019AACFE100A9A836; 281 | productRefGroup = 9E13F2BA19AACFE100A9A836 /* Products */; 282 | projectDirPath = ""; 283 | projectRoot = ""; 284 | targets = ( 285 | 9E13F2B819AACFE100A9A836 /* QBImagePickerControllerDemo */, 286 | 9E13F2D919AACFE100A9A836 /* QBImagePickerControllerDemoTests */, 287 | ); 288 | }; 289 | /* End PBXProject section */ 290 | 291 | /* Begin PBXResourcesBuildPhase section */ 292 | 9E13F2B719AACFE100A9A836 /* Resources */ = { 293 | isa = PBXResourcesBuildPhase; 294 | buildActionMask = 2147483647; 295 | files = ( 296 | 9E3F5BF419AAE09200854C73 /* Default@2x.png in Resources */, 297 | 9E6B53A819AAD6400028915A /* QBImagePickerController.bundle in Resources */, 298 | 9E13F2D519AACFE100A9A836 /* Images.xcassets in Resources */, 299 | 9E13F2C719AACFE100A9A836 /* InfoPlist.strings in Resources */, 300 | 9E3F5BF319AAE09200854C73 /* Default-568h@2x.png in Resources */, 301 | 9E3F5BF219AAE09200854C73 /* Default.png in Resources */, 302 | ); 303 | runOnlyForDeploymentPostprocessing = 0; 304 | }; 305 | 9E13F2D819AACFE100A9A836 /* Resources */ = { 306 | isa = PBXResourcesBuildPhase; 307 | buildActionMask = 2147483647; 308 | files = ( 309 | 9E13F2E619AACFE100A9A836 /* InfoPlist.strings in Resources */, 310 | ); 311 | runOnlyForDeploymentPostprocessing = 0; 312 | }; 313 | /* End PBXResourcesBuildPhase section */ 314 | 315 | /* Begin PBXSourcesBuildPhase section */ 316 | 9E13F2B519AACFE100A9A836 /* Sources */ = { 317 | isa = PBXSourcesBuildPhase; 318 | buildActionMask = 2147483647; 319 | files = ( 320 | 9E13F2D319AACFE100A9A836 /* ViewController.m in Sources */, 321 | 9E6B53A919AAD6400028915A /* QBImagePickerController.m in Sources */, 322 | 9E6B53AA19AAD6400028915A /* QBImagePickerFooterView.m in Sources */, 323 | 9E13F2CD19AACFE100A9A836 /* AppDelegate.m in Sources */, 324 | 9E6B53A719AAD6400028915A /* QBImagePickerAssetView.m in Sources */, 325 | 9E6B53AC19AAD6400028915A /* QBImagePickerVideoInfoView.m in Sources */, 326 | 9E6B53A619AAD6400028915A /* QBImagePickerAssetCell.m in Sources */, 327 | 9E50DCA919C17C5000088FB2 /* QBImageEditerViewController.m in Sources */, 328 | 9E6B53AB19AAD6400028915A /* QBImagePickerGroupCell.m in Sources */, 329 | 9E6B53A519AAD6400028915A /* QBAssetCollectionViewController.m in Sources */, 330 | 9E13F2C919AACFE100A9A836 /* main.m in Sources */, 331 | ); 332 | runOnlyForDeploymentPostprocessing = 0; 333 | }; 334 | 9E13F2D619AACFE100A9A836 /* Sources */ = { 335 | isa = PBXSourcesBuildPhase; 336 | buildActionMask = 2147483647; 337 | files = ( 338 | 9E13F2E819AACFE100A9A836 /* QBImagePickerControllerDemoTests.m in Sources */, 339 | ); 340 | runOnlyForDeploymentPostprocessing = 0; 341 | }; 342 | /* End PBXSourcesBuildPhase section */ 343 | 344 | /* Begin PBXTargetDependency section */ 345 | 9E13F2E019AACFE100A9A836 /* PBXTargetDependency */ = { 346 | isa = PBXTargetDependency; 347 | target = 9E13F2B819AACFE100A9A836 /* QBImagePickerControllerDemo */; 348 | targetProxy = 9E13F2DF19AACFE100A9A836 /* PBXContainerItemProxy */; 349 | }; 350 | /* End PBXTargetDependency section */ 351 | 352 | /* Begin PBXVariantGroup section */ 353 | 9E13F2C519AACFE100A9A836 /* InfoPlist.strings */ = { 354 | isa = PBXVariantGroup; 355 | children = ( 356 | 9E13F2C619AACFE100A9A836 /* en */, 357 | ); 358 | name = InfoPlist.strings; 359 | sourceTree = ""; 360 | }; 361 | 9E13F2E419AACFE100A9A836 /* InfoPlist.strings */ = { 362 | isa = PBXVariantGroup; 363 | children = ( 364 | 9E13F2E519AACFE100A9A836 /* en */, 365 | ); 366 | name = InfoPlist.strings; 367 | sourceTree = ""; 368 | }; 369 | /* End PBXVariantGroup section */ 370 | 371 | /* Begin XCBuildConfiguration section */ 372 | 9E13F2E919AACFE100A9A836 /* Debug */ = { 373 | isa = XCBuildConfiguration; 374 | buildSettings = { 375 | ALWAYS_SEARCH_USER_PATHS = NO; 376 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 377 | CLANG_CXX_LIBRARY = "libc++"; 378 | CLANG_ENABLE_MODULES = YES; 379 | CLANG_ENABLE_OBJC_ARC = YES; 380 | CLANG_WARN_BOOL_CONVERSION = YES; 381 | CLANG_WARN_CONSTANT_CONVERSION = YES; 382 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 383 | CLANG_WARN_EMPTY_BODY = YES; 384 | CLANG_WARN_ENUM_CONVERSION = YES; 385 | CLANG_WARN_INT_CONVERSION = YES; 386 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 387 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 388 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 389 | COPY_PHASE_STRIP = NO; 390 | ENABLE_TESTABILITY = YES; 391 | GCC_C_LANGUAGE_STANDARD = gnu99; 392 | GCC_DYNAMIC_NO_PIC = NO; 393 | GCC_OPTIMIZATION_LEVEL = 0; 394 | GCC_PREPROCESSOR_DEFINITIONS = ( 395 | "DEBUG=1", 396 | "$(inherited)", 397 | ); 398 | GCC_SYMBOLS_PRIVATE_EXTERN = NO; 399 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 400 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 401 | GCC_WARN_UNDECLARED_SELECTOR = YES; 402 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 403 | GCC_WARN_UNUSED_FUNCTION = YES; 404 | GCC_WARN_UNUSED_VARIABLE = YES; 405 | IPHONEOS_DEPLOYMENT_TARGET = 7.1; 406 | ONLY_ACTIVE_ARCH = YES; 407 | SDKROOT = iphoneos; 408 | }; 409 | name = Debug; 410 | }; 411 | 9E13F2EA19AACFE100A9A836 /* Release */ = { 412 | isa = XCBuildConfiguration; 413 | buildSettings = { 414 | ALWAYS_SEARCH_USER_PATHS = NO; 415 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 416 | CLANG_CXX_LIBRARY = "libc++"; 417 | CLANG_ENABLE_MODULES = YES; 418 | CLANG_ENABLE_OBJC_ARC = YES; 419 | CLANG_WARN_BOOL_CONVERSION = YES; 420 | CLANG_WARN_CONSTANT_CONVERSION = YES; 421 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 422 | CLANG_WARN_EMPTY_BODY = YES; 423 | CLANG_WARN_ENUM_CONVERSION = YES; 424 | CLANG_WARN_INT_CONVERSION = YES; 425 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 426 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 427 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 428 | COPY_PHASE_STRIP = YES; 429 | ENABLE_NS_ASSERTIONS = NO; 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 = 7.1; 438 | SDKROOT = iphoneos; 439 | VALIDATE_PRODUCT = YES; 440 | }; 441 | name = Release; 442 | }; 443 | 9E13F2EC19AACFE100A9A836 /* Debug */ = { 444 | isa = XCBuildConfiguration; 445 | buildSettings = { 446 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 447 | ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage; 448 | CLANG_ENABLE_OBJC_ARC = NO; 449 | GCC_PRECOMPILE_PREFIX_HEADER = YES; 450 | GCC_PREFIX_HEADER = "QBImagePickerControllerDemo/QBImagePickerControllerDemo-Prefix.pch"; 451 | INFOPLIST_FILE = "QBImagePickerControllerDemo/QBImagePickerControllerDemo-Info.plist"; 452 | IPHONEOS_DEPLOYMENT_TARGET = 8.0; 453 | PRODUCT_BUNDLE_IDENTIFIER = "com.jsmcc.${PRODUCT_NAME:rfc1034identifier}"; 454 | PRODUCT_NAME = "$(TARGET_NAME)"; 455 | WRAPPER_EXTENSION = app; 456 | }; 457 | name = Debug; 458 | }; 459 | 9E13F2ED19AACFE100A9A836 /* Release */ = { 460 | isa = XCBuildConfiguration; 461 | buildSettings = { 462 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 463 | ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage; 464 | CLANG_ENABLE_OBJC_ARC = NO; 465 | GCC_PRECOMPILE_PREFIX_HEADER = YES; 466 | GCC_PREFIX_HEADER = "QBImagePickerControllerDemo/QBImagePickerControllerDemo-Prefix.pch"; 467 | INFOPLIST_FILE = "QBImagePickerControllerDemo/QBImagePickerControllerDemo-Info.plist"; 468 | IPHONEOS_DEPLOYMENT_TARGET = 8.0; 469 | PRODUCT_BUNDLE_IDENTIFIER = "com.jsmcc.${PRODUCT_NAME:rfc1034identifier}"; 470 | PRODUCT_NAME = "$(TARGET_NAME)"; 471 | WRAPPER_EXTENSION = app; 472 | }; 473 | name = Release; 474 | }; 475 | 9E13F2EF19AACFE100A9A836 /* Debug */ = { 476 | isa = XCBuildConfiguration; 477 | buildSettings = { 478 | BUNDLE_LOADER = "$(BUILT_PRODUCTS_DIR)/QBImagePickerControllerDemo.app/QBImagePickerControllerDemo"; 479 | FRAMEWORK_SEARCH_PATHS = ( 480 | "$(SDKROOT)/Developer/Library/Frameworks", 481 | "$(inherited)", 482 | "$(DEVELOPER_FRAMEWORKS_DIR)", 483 | ); 484 | GCC_PRECOMPILE_PREFIX_HEADER = YES; 485 | GCC_PREFIX_HEADER = "QBImagePickerControllerDemo/QBImagePickerControllerDemo-Prefix.pch"; 486 | GCC_PREPROCESSOR_DEFINITIONS = ( 487 | "DEBUG=1", 488 | "$(inherited)", 489 | ); 490 | INFOPLIST_FILE = "QBImagePickerControllerDemoTests/QBImagePickerControllerDemoTests-Info.plist"; 491 | PRODUCT_BUNDLE_IDENTIFIER = "com.jsmcc.${PRODUCT_NAME:rfc1034identifier}"; 492 | PRODUCT_NAME = "$(TARGET_NAME)"; 493 | TEST_HOST = "$(BUNDLE_LOADER)"; 494 | WRAPPER_EXTENSION = xctest; 495 | }; 496 | name = Debug; 497 | }; 498 | 9E13F2F019AACFE100A9A836 /* Release */ = { 499 | isa = XCBuildConfiguration; 500 | buildSettings = { 501 | BUNDLE_LOADER = "$(BUILT_PRODUCTS_DIR)/QBImagePickerControllerDemo.app/QBImagePickerControllerDemo"; 502 | FRAMEWORK_SEARCH_PATHS = ( 503 | "$(SDKROOT)/Developer/Library/Frameworks", 504 | "$(inherited)", 505 | "$(DEVELOPER_FRAMEWORKS_DIR)", 506 | ); 507 | GCC_PRECOMPILE_PREFIX_HEADER = YES; 508 | GCC_PREFIX_HEADER = "QBImagePickerControllerDemo/QBImagePickerControllerDemo-Prefix.pch"; 509 | INFOPLIST_FILE = "QBImagePickerControllerDemoTests/QBImagePickerControllerDemoTests-Info.plist"; 510 | PRODUCT_BUNDLE_IDENTIFIER = "com.jsmcc.${PRODUCT_NAME:rfc1034identifier}"; 511 | PRODUCT_NAME = "$(TARGET_NAME)"; 512 | TEST_HOST = "$(BUNDLE_LOADER)"; 513 | WRAPPER_EXTENSION = xctest; 514 | }; 515 | name = Release; 516 | }; 517 | /* End XCBuildConfiguration section */ 518 | 519 | /* Begin XCConfigurationList section */ 520 | 9E13F2B419AACFE100A9A836 /* Build configuration list for PBXProject "QBImagePickerControllerDemo" */ = { 521 | isa = XCConfigurationList; 522 | buildConfigurations = ( 523 | 9E13F2E919AACFE100A9A836 /* Debug */, 524 | 9E13F2EA19AACFE100A9A836 /* Release */, 525 | ); 526 | defaultConfigurationIsVisible = 0; 527 | defaultConfigurationName = Release; 528 | }; 529 | 9E13F2EB19AACFE100A9A836 /* Build configuration list for PBXNativeTarget "QBImagePickerControllerDemo" */ = { 530 | isa = XCConfigurationList; 531 | buildConfigurations = ( 532 | 9E13F2EC19AACFE100A9A836 /* Debug */, 533 | 9E13F2ED19AACFE100A9A836 /* Release */, 534 | ); 535 | defaultConfigurationIsVisible = 0; 536 | defaultConfigurationName = Release; 537 | }; 538 | 9E13F2EE19AACFE100A9A836 /* Build configuration list for PBXNativeTarget "QBImagePickerControllerDemoTests" */ = { 539 | isa = XCConfigurationList; 540 | buildConfigurations = ( 541 | 9E13F2EF19AACFE100A9A836 /* Debug */, 542 | 9E13F2F019AACFE100A9A836 /* Release */, 543 | ); 544 | defaultConfigurationIsVisible = 0; 545 | defaultConfigurationName = Release; 546 | }; 547 | /* End XCConfigurationList section */ 548 | }; 549 | rootObject = 9E13F2B119AACFE100A9A836 /* Project object */; 550 | } 551 | -------------------------------------------------------------------------------- /QBImagePickerControllerDemo/QBImagePickerControllerDemo.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /QBImagePickerControllerDemo/QBImagePickerControllerDemo.xcodeproj/project.xcworkspace/xcshareddata/QBImagePickerControllerDemo.xccheckout: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDESourceControlProjectFavoriteDictionaryKey 6 | 7 | IDESourceControlProjectIdentifier 8 | 1EA2600F-F5C1-4959-A98B-493817C70F29 9 | IDESourceControlProjectName 10 | QBImagePickerControllerDemo 11 | IDESourceControlProjectOriginsDictionary 12 | 13 | B08C4942-0EBA-401F-B842-6548864161D3 14 | https://github.com/HarrisLee/QBImagePickerController.git 15 | 16 | IDESourceControlProjectPath 17 | QBImagePickerControllerDemo/QBImagePickerControllerDemo.xcodeproj/project.xcworkspace 18 | IDESourceControlProjectRelativeInstallPathDictionary 19 | 20 | B08C4942-0EBA-401F-B842-6548864161D3 21 | ../../.. 22 | 23 | IDESourceControlProjectURL 24 | https://github.com/HarrisLee/QBImagePickerController.git 25 | IDESourceControlProjectVersion 26 | 110 27 | IDESourceControlProjectWCCIdentifier 28 | B08C4942-0EBA-401F-B842-6548864161D3 29 | IDESourceControlProjectWCConfigurations 30 | 31 | 32 | IDESourceControlRepositoryExtensionIdentifierKey 33 | public.vcs.git 34 | IDESourceControlWCCIdentifierKey 35 | B08C4942-0EBA-401F-B842-6548864161D3 36 | IDESourceControlWCCName 37 | QBImagePickerController 38 | 39 | 40 | 41 | 42 | -------------------------------------------------------------------------------- /QBImagePickerControllerDemo/QBImagePickerControllerDemo.xcodeproj/project.xcworkspace/xcuserdata/LeexMuller.xcuserdatad/UserInterfaceState.xcuserstate: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JentCastttttt/QBImagePickerController/5e0ff3c2dc992b3edf0f145c0709af06c1109a02/QBImagePickerControllerDemo/QBImagePickerControllerDemo.xcodeproj/project.xcworkspace/xcuserdata/LeexMuller.xcuserdatad/UserInterfaceState.xcuserstate -------------------------------------------------------------------------------- /QBImagePickerControllerDemo/QBImagePickerControllerDemo.xcodeproj/project.xcworkspace/xcuserdata/hmg.xcuserdatad/UserInterfaceState.xcuserstate: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JentCastttttt/QBImagePickerController/5e0ff3c2dc992b3edf0f145c0709af06c1109a02/QBImagePickerControllerDemo/QBImagePickerControllerDemo.xcodeproj/project.xcworkspace/xcuserdata/hmg.xcuserdatad/UserInterfaceState.xcuserstate -------------------------------------------------------------------------------- /QBImagePickerControllerDemo/QBImagePickerControllerDemo.xcodeproj/xcuserdata/LeexMuller.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 8 | 20 | 21 | 22 | 24 | 36 | 37 | 38 | 39 | 40 | -------------------------------------------------------------------------------- /QBImagePickerControllerDemo/QBImagePickerControllerDemo.xcodeproj/xcuserdata/LeexMuller.xcuserdatad/xcschemes/QBImagePickerControllerDemo.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 | -------------------------------------------------------------------------------- /QBImagePickerControllerDemo/QBImagePickerControllerDemo.xcodeproj/xcuserdata/LeexMuller.xcuserdatad/xcschemes/xcschememanagement.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | SchemeUserState 6 | 7 | QBImagePickerControllerDemo.xcscheme 8 | 9 | orderHint 10 | 0 11 | 12 | 13 | SuppressBuildableAutocreation 14 | 15 | 9E13F2B819AACFE100A9A836 16 | 17 | primary 18 | 19 | 20 | 9E13F2D919AACFE100A9A836 21 | 22 | primary 23 | 24 | 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /QBImagePickerControllerDemo/QBImagePickerControllerDemo.xcodeproj/xcuserdata/hmg.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 8 | 20 | 21 | 22 | 24 | 36 | 37 | 38 | 39 | 40 | -------------------------------------------------------------------------------- /QBImagePickerControllerDemo/QBImagePickerControllerDemo.xcodeproj/xcuserdata/hmg.xcuserdatad/xcschemes/QBImagePickerControllerDemo.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 33 | 39 | 40 | 41 | 42 | 43 | 49 | 50 | 51 | 52 | 61 | 62 | 68 | 69 | 70 | 71 | 72 | 73 | 79 | 80 | 86 | 87 | 88 | 89 | 91 | 92 | 95 | 96 | 97 | -------------------------------------------------------------------------------- /QBImagePickerControllerDemo/QBImagePickerControllerDemo.xcodeproj/xcuserdata/hmg.xcuserdatad/xcschemes/xcschememanagement.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | SchemeUserState 6 | 7 | QBImagePickerControllerDemo.xcscheme 8 | 9 | orderHint 10 | 0 11 | 12 | 13 | SuppressBuildableAutocreation 14 | 15 | 9E13F2B819AACFE100A9A836 16 | 17 | primary 18 | 19 | 20 | 9E13F2D919AACFE100A9A836 21 | 22 | primary 23 | 24 | 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /QBImagePickerControllerDemo/QBImagePickerControllerDemo/AppDelegate.h: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.h 3 | // QBImagePickerControllerDemo 4 | // 5 | // Created by Cao JianRong on 14-8-25. 6 | // Copyright (c) 2014年 Cao JianRong. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface AppDelegate : UIResponder 12 | { 13 | UINavigationController *rootNaviController; 14 | } 15 | 16 | @property (strong, nonatomic) UIWindow *window; 17 | 18 | @property (strong, nonatomic) UINavigationController *rootNaviController; 19 | 20 | @end 21 | -------------------------------------------------------------------------------- /QBImagePickerControllerDemo/QBImagePickerControllerDemo/AppDelegate.m: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.m 3 | // QBImagePickerControllerDemo 4 | // 5 | // Created by Cao JianRong on 14-8-25. 6 | // Copyright (c) 2014年 Cao JianRong. All rights reserved. 7 | // 8 | 9 | #import "AppDelegate.h" 10 | #import "ViewController.h" 11 | 12 | @implementation AppDelegate 13 | @synthesize rootNaviController; 14 | 15 | 16 | - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions 17 | { 18 | // Override point for customization after application launch. 19 | [[UIApplication sharedApplication] setStatusBarStyle:UIStatusBarStyleLightContent animated:NO]; 20 | [[UIApplication sharedApplication] setStatusBarHidden:NO]; 21 | 22 | ViewController *viewController = [[ViewController alloc] init]; 23 | viewController.title = @"首页"; 24 | UINavigationController *navi = [[UINavigationController alloc] initWithRootViewController:viewController]; 25 | [viewController release]; 26 | //Navigation Title Color and FontStyle 27 | NSDictionary *dict = [NSDictionary dictionaryWithObjectsAndKeys:[UIFont fontWithName:@"STHeitiK-Medium" size:20],NSFontAttributeName,[UIColor whiteColor],NSForegroundColorAttributeName,nil]; 28 | navi.navigationBar.titleTextAttributes = dict; 29 | //origination from (0,20,width,height) not (0,0,width,height) 30 | navi.navigationBar.translucent = NO; 31 | //navigation background Color 32 | navi.navigationBar.barTintColor = [UIColor colorWithRed:158/255.0 green:207/255.0 blue:240/255.0 alpha:0.5]; 33 | //navigation letf or right nafigationItem Color 34 | navi.navigationBar.tintColor = [UIColor whiteColor]; 35 | self.rootNaviController = navi; 36 | 37 | self.window = [[[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]] autorelease]; 38 | self.window.rootViewController = navi; 39 | [navi release]; 40 | [self.window makeKeyAndVisible]; 41 | 42 | return YES; 43 | } 44 | 45 | - (void)applicationWillResignActive:(UIApplication *)application 46 | { 47 | // 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. 48 | // 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. 49 | } 50 | 51 | - (void)applicationDidEnterBackground:(UIApplication *)application 52 | { 53 | // 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. 54 | // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. 55 | } 56 | 57 | - (void)applicationWillEnterForeground:(UIApplication *)application 58 | { 59 | // 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. 60 | } 61 | 62 | - (void)applicationDidBecomeActive:(UIApplication *)application 63 | { 64 | // 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. 65 | } 66 | 67 | - (void)applicationWillTerminate:(UIApplication *)application 68 | { 69 | // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. 70 | } 71 | 72 | -(void) dealloc 73 | { 74 | [rootNaviController release]; 75 | [super dealloc]; 76 | } 77 | 78 | @end 79 | -------------------------------------------------------------------------------- /QBImagePickerControllerDemo/QBImagePickerControllerDemo/Default-568h@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JentCastttttt/QBImagePickerController/5e0ff3c2dc992b3edf0f145c0709af06c1109a02/QBImagePickerControllerDemo/QBImagePickerControllerDemo/Default-568h@2x.png -------------------------------------------------------------------------------- /QBImagePickerControllerDemo/QBImagePickerControllerDemo/Default.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JentCastttttt/QBImagePickerController/5e0ff3c2dc992b3edf0f145c0709af06c1109a02/QBImagePickerControllerDemo/QBImagePickerControllerDemo/Default.png -------------------------------------------------------------------------------- /QBImagePickerControllerDemo/QBImagePickerControllerDemo/Default@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JentCastttttt/QBImagePickerController/5e0ff3c2dc992b3edf0f145c0709af06c1109a02/QBImagePickerControllerDemo/QBImagePickerControllerDemo/Default@2x.png -------------------------------------------------------------------------------- /QBImagePickerControllerDemo/QBImagePickerControllerDemo/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" : "40x40", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "iphone", 15 | "size" : "60x60", 16 | "scale" : "2x" 17 | } 18 | ], 19 | "info" : { 20 | "version" : 1, 21 | "author" : "xcode" 22 | } 23 | } -------------------------------------------------------------------------------- /QBImagePickerControllerDemo/QBImagePickerControllerDemo/Images.xcassets/LaunchImage.launchimage/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "orientation" : "portrait", 5 | "idiom" : "iphone", 6 | "extent" : "full-screen", 7 | "minimum-system-version" : "7.0", 8 | "filename" : "Default@2x.png", 9 | "scale" : "2x" 10 | }, 11 | { 12 | "extent" : "full-screen", 13 | "idiom" : "iphone", 14 | "subtype" : "retina4", 15 | "filename" : "Default-568h@2x.png", 16 | "minimum-system-version" : "7.0", 17 | "orientation" : "portrait", 18 | "scale" : "2x" 19 | } 20 | ], 21 | "info" : { 22 | "version" : 1, 23 | "author" : "xcode" 24 | } 25 | } -------------------------------------------------------------------------------- /QBImagePickerControllerDemo/QBImagePickerControllerDemo/Images.xcassets/LaunchImage.launchimage/Default-568h@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JentCastttttt/QBImagePickerController/5e0ff3c2dc992b3edf0f145c0709af06c1109a02/QBImagePickerControllerDemo/QBImagePickerControllerDemo/Images.xcassets/LaunchImage.launchimage/Default-568h@2x.png -------------------------------------------------------------------------------- /QBImagePickerControllerDemo/QBImagePickerControllerDemo/Images.xcassets/LaunchImage.launchimage/Default@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JentCastttttt/QBImagePickerController/5e0ff3c2dc992b3edf0f145c0709af06c1109a02/QBImagePickerControllerDemo/QBImagePickerControllerDemo/Images.xcassets/LaunchImage.launchimage/Default@2x.png -------------------------------------------------------------------------------- /QBImagePickerControllerDemo/QBImagePickerControllerDemo/QBImagePickerController/QBAssetCollectionViewController.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2013 Katsuma Tanaka 3 | 4 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 5 | 6 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 7 | 8 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 9 | */ 10 | 11 | #import 12 | #import 13 | #import 14 | 15 | // Delegate 16 | #import "QBAssetCollectionViewControllerDelegate.h" 17 | #import "QBImagePickerAssetCellDelegate.h" 18 | #import "QBImageEditerViewControllerDelegate.h" 19 | 20 | // Controllers 21 | #import "QBImagePickerController.h" 22 | 23 | @interface QBAssetCollectionViewController : UIViewController 24 | 25 | @property (nonatomic, assign) id delegate; 26 | @property (nonatomic, retain) ALAssetsGroup *assetsGroup; 27 | 28 | @property (nonatomic, assign) CGSize imageSize; 29 | @property (nonatomic, assign) QBImagePickerFilterType filterType; 30 | @property (nonatomic, assign) BOOL showsCancelButton; 31 | @property (nonatomic, assign) BOOL fullScreenLayoutEnabled; 32 | @property (nonatomic, assign) BOOL showsHeaderButton; 33 | @property (nonatomic, assign) BOOL showsFooterDescription; 34 | 35 | @property (nonatomic, assign) BOOL allowsMultipleSelection; 36 | @property (nonatomic, assign) BOOL allowsEdit; 37 | 38 | @property (nonatomic, assign) BOOL limitsMinimumNumberOfSelection; 39 | @property (nonatomic, assign) BOOL limitsMaximumNumberOfSelection; 40 | @property (nonatomic, assign) NSUInteger minimumNumberOfSelection; 41 | @property (nonatomic, assign) NSUInteger maximumNumberOfSelection; 42 | 43 | @end 44 | -------------------------------------------------------------------------------- /QBImagePickerControllerDemo/QBImagePickerControllerDemo/QBImagePickerController/QBAssetCollectionViewController.m: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2013 Katsuma Tanaka 3 | 4 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 5 | 6 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 7 | 8 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 9 | */ 10 | 11 | #import "QBAssetCollectionViewController.h" 12 | 13 | // Views 14 | #import "QBImagePickerAssetCell.h" 15 | #import "QBImagePickerFooterView.h" 16 | #import "QBImageEditerViewController.h" 17 | 18 | @interface QBAssetCollectionViewController () 19 | 20 | @property (nonatomic, retain) NSMutableArray *assets; 21 | @property (nonatomic, retain) NSMutableOrderedSet *selectedAssets; 22 | @property (nonatomic, retain) UITableView *tableView; 23 | @property (nonatomic, retain) UIBarButtonItem *doneButton; 24 | 25 | - (void)reloadData; 26 | - (void)updateRightBarButtonItem; 27 | - (void)updateDoneButton; 28 | - (void)done; 29 | - (void)cancel; 30 | 31 | @end 32 | 33 | @implementation QBAssetCollectionViewController 34 | 35 | - (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil 36 | { 37 | self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil]; 38 | 39 | if(self) { 40 | /* Initialization */ 41 | self.assets = [NSMutableArray array]; 42 | self.selectedAssets = [NSMutableOrderedSet orderedSet]; 43 | 44 | self.imageSize = CGSizeMake(75, 75); 45 | 46 | // Table View 47 | UITableView *tableView = [[UITableView alloc] initWithFrame:self.view.bounds style:UITableViewStylePlain]; 48 | tableView.dataSource = self; 49 | tableView.delegate = self; 50 | tableView.separatorStyle = UITableViewCellSeparatorStyleNone; 51 | tableView.allowsSelection = YES; 52 | tableView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight; 53 | 54 | [self.view addSubview:tableView]; 55 | self.tableView = tableView; 56 | [tableView release]; 57 | } 58 | 59 | return self; 60 | } 61 | 62 | - (void)viewWillAppear:(BOOL)animated 63 | { 64 | [super viewWillAppear:animated]; 65 | 66 | // Reload 67 | [self reloadData]; 68 | // if (!isIOS7) { 69 | // if(self.fullScreenLayoutEnabled) { 70 | // // Set bar styles 71 | // self.navigationController.navigationBar.barStyle = UIBarStyleBlack; 72 | // self.navigationController.navigationBar.translucent = YES; 73 | // //取消无效代码 74 | //// [[UIApplication sharedApplication] setStatusBarStyle:UIStatusBarStyleBlackTranslucent animated:NO]; 75 | // 76 | // CGFloat top = 0; 77 | // if(![[UIApplication sharedApplication] isStatusBarHidden]) top = top + 20; 78 | // if(!self.navigationController.navigationBarHidden) top = top + 44; 79 | // self.tableView.contentInset = UIEdgeInsetsMake(top, 0, 0, 0); 80 | // self.tableView.scrollIndicatorInsets = UIEdgeInsetsMake(top, 0, 0, 0); 81 | // 82 | // //取消无效代码 83 | //// [self setWantsFullScreenLayout:YES]; 84 | // } 85 | // } 86 | NSLog(@"调转到什么位置===%f",self.tableView.contentSize.height); 87 | // Scroll to bottom 88 | // if (!isIOS7) { 89 | // [self.tableView setContentOffset:CGPointMake(0, self.tableView.contentSize.height) animated:NO]; 90 | // } 91 | } 92 | 93 | - (void)viewDidAppear:(BOOL)animated 94 | { 95 | [super viewDidAppear:animated]; 96 | 97 | // Flash scroll indicators 98 | [self.tableView flashScrollIndicators]; 99 | } 100 | 101 | - (void)setShowsCancelButton:(BOOL)showsCancelButton 102 | { 103 | _showsCancelButton = showsCancelButton; 104 | 105 | [self updateRightBarButtonItem]; 106 | } 107 | 108 | - (void)setAllowsMultipleSelection:(BOOL)allowsMultipleSelection 109 | { 110 | _allowsMultipleSelection = allowsMultipleSelection; 111 | 112 | [self updateRightBarButtonItem]; 113 | } 114 | 115 | - (void)dealloc 116 | { 117 | [_assetsGroup release]; 118 | 119 | [_assets release]; 120 | [_selectedAssets release]; 121 | 122 | [_tableView release]; 123 | [_doneButton release]; 124 | 125 | [super dealloc]; 126 | } 127 | 128 | 129 | #pragma mark - Instance Methods 130 | 131 | - (void)reloadData 132 | { 133 | // Reload assets 134 | [self.assetsGroup enumerateAssetsUsingBlock:^(ALAsset *result, NSUInteger index, BOOL *stop) { 135 | if(result) { 136 | [self.assets addObject:result]; 137 | } 138 | }]; 139 | 140 | [self.tableView reloadData]; 141 | 142 | // Set footer view 143 | if(self.showsFooterDescription) { 144 | [self.assetsGroup setAssetsFilter:[ALAssetsFilter allPhotos]]; 145 | NSUInteger numberOfPhotos = self.assetsGroup.numberOfAssets; 146 | 147 | [self.assetsGroup setAssetsFilter:[ALAssetsFilter allVideos]]; 148 | NSUInteger numberOfVideos = self.assetsGroup.numberOfAssets; 149 | 150 | switch(self.filterType) { 151 | case QBImagePickerFilterTypeAllAssets: 152 | [self.assetsGroup setAssetsFilter:[ALAssetsFilter allAssets]]; 153 | break; 154 | case QBImagePickerFilterTypeAllPhotos: 155 | [self.assetsGroup setAssetsFilter:[ALAssetsFilter allPhotos]]; 156 | break; 157 | case QBImagePickerFilterTypeAllVideos: 158 | [self.assetsGroup setAssetsFilter:[ALAssetsFilter allVideos]]; 159 | break; 160 | } 161 | 162 | QBImagePickerFooterView *footerView = [[QBImagePickerFooterView alloc] initWithFrame:CGRectMake(0, 0, self.view.bounds.size.width, 48)]; 163 | 164 | if(self.filterType == QBImagePickerFilterTypeAllAssets) { 165 | footerView.titleLabel.text = [self.delegate assetCollectionViewController:self descriptionForNumberOfPhotos:numberOfPhotos numberOfVideos:numberOfVideos]; 166 | } else if(self.filterType == QBImagePickerFilterTypeAllPhotos) { 167 | footerView.titleLabel.text = [self.delegate assetCollectionViewController:self descriptionForNumberOfPhotos:numberOfPhotos]; 168 | } else if(self.filterType == QBImagePickerFilterTypeAllVideos) { 169 | footerView.titleLabel.text = [self.delegate assetCollectionViewController:self descriptionForNumberOfVideos:numberOfVideos]; 170 | } 171 | 172 | self.tableView.tableFooterView = footerView; 173 | [footerView release]; 174 | } else { 175 | QBImagePickerFooterView *footerView = [[QBImagePickerFooterView alloc] initWithFrame:CGRectMake(0, 0, self.view.bounds.size.width, 4)]; 176 | 177 | self.tableView.tableFooterView = footerView; 178 | [self.tableView.tableFooterView setBackgroundColor:[UIColor purpleColor]]; 179 | [footerView release]; 180 | } 181 | } 182 | 183 | - (void)updateRightBarButtonItem 184 | { 185 | if(self.allowsMultipleSelection) { 186 | // Set done button 187 | UIBarButtonItem *doneButton = [[UIBarButtonItem alloc] initWithTitle:@"确认" style:UIBarButtonItemStyleDone target:self action:@selector(done)];//[[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemDone target:self action:@selector(done)]; 188 | doneButton.enabled = NO; 189 | 190 | [self.navigationItem setRightBarButtonItem:doneButton animated:NO]; 191 | self.doneButton = doneButton; 192 | [doneButton release]; 193 | } else if(self.showsCancelButton) { 194 | // Set cancel button 195 | UIBarButtonItem *cancelButton = [[UIBarButtonItem alloc] initWithTitle:@"取消" style:UIBarButtonItemStyleDone target:self action:@selector(cancel)];//[[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemCancel target:self action:@selector(cancel)]; 196 | 197 | [self.navigationItem setRightBarButtonItem:cancelButton animated:NO]; 198 | [cancelButton release]; 199 | } else { 200 | [self.navigationItem setRightBarButtonItem:nil animated:NO]; 201 | } 202 | } 203 | 204 | - (void)updateDoneButton 205 | { 206 | if(self.limitsMinimumNumberOfSelection) { 207 | self.doneButton.enabled = (self.selectedAssets.count >= self.minimumNumberOfSelection); 208 | } else { 209 | self.doneButton.enabled = (self.selectedAssets.count > 0); 210 | } 211 | } 212 | 213 | - (void)done 214 | { 215 | [self.delegate assetCollectionViewController:self didFinishPickingAssets:self.selectedAssets.array]; 216 | } 217 | 218 | - (void)cancel 219 | { 220 | [self.delegate assetCollectionViewControllerDidCancel:self]; 221 | } 222 | 223 | 224 | #pragma mark - UITableViewDataSource 225 | 226 | - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView 227 | { 228 | return 3; 229 | } 230 | 231 | - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section 232 | { 233 | NSInteger numberOfRowsInSection = 0; 234 | 235 | switch(section) { 236 | case 0: case 1: 237 | { 238 | if(self.allowsMultipleSelection && !self.limitsMaximumNumberOfSelection && self.showsHeaderButton) { 239 | numberOfRowsInSection = 1; 240 | } 241 | } 242 | break; 243 | case 2: 244 | { 245 | NSInteger numberOfAssetsInRow = self.view.bounds.size.width / self.imageSize.width; 246 | numberOfRowsInSection = self.assets.count / numberOfAssetsInRow; 247 | if((self.assets.count - numberOfRowsInSection * numberOfAssetsInRow) > 0) numberOfRowsInSection++; 248 | } 249 | break; 250 | } 251 | 252 | return numberOfRowsInSection; 253 | } 254 | 255 | - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath 256 | { 257 | UITableViewCell *cell = nil; 258 | 259 | switch(indexPath.section) { 260 | case 0: 261 | { 262 | NSString *cellIdentifier = @"HeaderCell"; 263 | cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier]; 264 | 265 | if(cell == nil) { 266 | cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellIdentifier] autorelease]; 267 | cell.selectionStyle = UITableViewCellSelectionStyleBlue; 268 | } 269 | 270 | if(self.selectedAssets.count == self.assets.count) { 271 | cell.textLabel.text = [self.delegate descriptionForDeselectingAllAssets:self]; 272 | 273 | // Set accessory view 274 | UIImageView *accessoryView = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, 23, 23)]; 275 | accessoryView.image = [UIImage imageNamed:@"QBImagePickerController.bundle/minus.png"]; 276 | 277 | accessoryView.layer.shadowColor = [[UIColor colorWithWhite:0 alpha:1.0] CGColor]; 278 | accessoryView.layer.shadowOpacity = 0.70; 279 | accessoryView.layer.shadowOffset = CGSizeMake(0, 1.4); 280 | accessoryView.layer.shadowRadius = 2; 281 | 282 | cell.accessoryView = accessoryView; 283 | [accessoryView release]; 284 | } else { 285 | cell.textLabel.text = [self.delegate descriptionForSelectingAllAssets:self]; 286 | 287 | // Set accessory view 288 | UIImageView *accessoryView = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, 23, 23)]; 289 | accessoryView.image = [UIImage imageNamed:@"QBImagePickerController.bundle/plus.png"]; 290 | 291 | accessoryView.layer.shadowColor = [[UIColor colorWithWhite:0 alpha:1.0] CGColor]; 292 | accessoryView.layer.shadowOpacity = 0.70; 293 | accessoryView.layer.shadowOffset = CGSizeMake(0, 1.4); 294 | accessoryView.layer.shadowRadius = 2; 295 | 296 | cell.accessoryView = accessoryView; 297 | [accessoryView release]; 298 | } 299 | } 300 | break; 301 | case 1: 302 | { 303 | NSString *cellIdentifier = @"SeparatorCell"; 304 | cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier]; 305 | 306 | if(cell == nil) { 307 | cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellIdentifier] autorelease]; 308 | cell.selectionStyle = UITableViewCellSelectionStyleNone; 309 | 310 | // Set background view 311 | UIView *backgroundView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, self.view.bounds.size.width, 1)]; 312 | backgroundView.backgroundColor = [UIColor colorWithWhite:0.878 alpha:1.0]; 313 | 314 | cell.backgroundView = backgroundView; 315 | [backgroundView release]; 316 | } 317 | } 318 | break; 319 | case 2: 320 | { 321 | NSString *cellIdentifier = @"AssetCell"; 322 | cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier]; 323 | 324 | if(cell == nil) { 325 | NSInteger numberOfAssetsInRow = self.view.bounds.size.width / self.imageSize.width; 326 | CGFloat margin = round((self.view.bounds.size.width - self.imageSize.width * numberOfAssetsInRow) / (numberOfAssetsInRow + 1)); 327 | 328 | cell = [[[QBImagePickerAssetCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellIdentifier imageSize:self.imageSize numberOfAssets:numberOfAssetsInRow margin:margin] autorelease]; 329 | cell.selectionStyle = UITableViewCellSelectionStyleNone; 330 | [(QBImagePickerAssetCell *)cell setDelegate:self]; 331 | [(QBImagePickerAssetCell *)cell setAllowsMultipleSelection:self.allowsMultipleSelection]; 332 | } 333 | 334 | // Set assets 335 | NSInteger numberOfAssetsInRow = self.view.bounds.size.width / self.imageSize.width; 336 | NSInteger offset = numberOfAssetsInRow * indexPath.row; 337 | NSInteger numberOfAssetsToSet = (offset + numberOfAssetsInRow > self.assets.count) ? (self.assets.count - offset) : numberOfAssetsInRow; 338 | 339 | NSMutableArray *assets = [NSMutableArray array]; 340 | for(NSUInteger i = 0; i < numberOfAssetsToSet; i++) { 341 | ALAsset *asset = [self.assets objectAtIndex:(offset + i)]; 342 | 343 | [assets addObject:asset]; 344 | } 345 | 346 | [(QBImagePickerAssetCell *)cell setAssets:assets]; 347 | 348 | // Set selection states 349 | for(NSUInteger i = 0; i < numberOfAssetsToSet; i++) { 350 | ALAsset *asset = [self.assets objectAtIndex:(offset + i)]; 351 | 352 | if([self.selectedAssets containsObject:asset]) { 353 | [(QBImagePickerAssetCell *)cell selectAssetAtIndex:i]; 354 | } else { 355 | [(QBImagePickerAssetCell *)cell deselectAssetAtIndex:i]; 356 | } 357 | } 358 | } 359 | break; 360 | } 361 | 362 | return cell; 363 | } 364 | 365 | 366 | #pragma mark - UITableViewDelegate 367 | 368 | - (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath 369 | { 370 | CGFloat heightForRow = 0; 371 | 372 | switch(indexPath.section) { 373 | case 0: 374 | { 375 | heightForRow = 44; 376 | } 377 | break; 378 | case 1: 379 | { 380 | heightForRow = 1; 381 | } 382 | break; 383 | case 2: 384 | { 385 | NSInteger numberOfAssetsInRow = self.view.bounds.size.width / self.imageSize.width; 386 | CGFloat margin = round((self.view.bounds.size.width - self.imageSize.width * numberOfAssetsInRow) / (numberOfAssetsInRow + 1)); 387 | heightForRow = margin + self.imageSize.height; 388 | } 389 | break; 390 | } 391 | 392 | return heightForRow; 393 | } 394 | 395 | - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath 396 | { 397 | if(indexPath.section == 0 && indexPath.row == 0) { 398 | if(self.selectedAssets.count == self.assets.count) { 399 | // Deselect all assets 400 | [self.selectedAssets removeAllObjects]; 401 | } else { 402 | // Select all assets 403 | [self.selectedAssets addObjectsFromArray:self.assets]; 404 | } 405 | 406 | // Set done button state 407 | [self updateDoneButton]; 408 | 409 | // Update assets 410 | [tableView reloadSections:[NSIndexSet indexSetWithIndex:2] withRowAnimation:UITableViewRowAnimationNone]; 411 | 412 | // Update header text 413 | [tableView reloadSections:[NSIndexSet indexSetWithIndex:0] withRowAnimation:UITableViewRowAnimationFade]; 414 | 415 | // Cancel table view selection 416 | [tableView deselectRowAtIndexPath:indexPath animated:YES]; 417 | } 418 | } 419 | 420 | #pragma mark - QBImageEidterViewControllerDelegate 421 | - (void)editerViewController:(QBImageEditerViewController *)assetCollectionViewController didFinishPickingAsset:(ALAsset *)asset 422 | { 423 | [self.delegate assetCollectionViewController:self didFinishPickingAsset:asset]; 424 | } 425 | 426 | #pragma mark - QBImagePickerAssetCellDelegate 427 | 428 | - (BOOL)assetCell:(QBImagePickerAssetCell *)assetCell canSelectAssetAtIndex:(NSUInteger)index 429 | { 430 | BOOL canSelect = YES; 431 | 432 | if(self.allowsMultipleSelection && self.limitsMaximumNumberOfSelection) { 433 | canSelect = (self.selectedAssets.count < self.maximumNumberOfSelection); 434 | } 435 | 436 | return canSelect; 437 | } 438 | 439 | - (void)assetCell:(QBImagePickerAssetCell *)assetCell didChangeAssetSelectionState:(BOOL)selected atIndex:(NSUInteger)index 440 | { 441 | NSIndexPath *indexPath = [self.tableView indexPathForCell:assetCell]; 442 | 443 | NSInteger numberOfAssetsInRow = self.view.bounds.size.width / self.imageSize.width; 444 | NSInteger assetIndex = indexPath.row * numberOfAssetsInRow + index; 445 | ALAsset *asset = [self.assets objectAtIndex:assetIndex]; 446 | 447 | if(self.allowsMultipleSelection) { 448 | if(selected) { 449 | [self.selectedAssets addObject:asset]; 450 | } else { 451 | [self.selectedAssets removeObject:asset]; 452 | } 453 | 454 | // Set done button state 455 | [self updateDoneButton]; 456 | NSLog(@"已经选择了%d",self.selectedAssets.count); 457 | // Update header text 458 | // if((selected && self.selectedAssets.count == self.assets.count)||(!selected && self.selectedAssets.count == self.assets.count - 1)) { 459 | // [self.tableView reloadRowsAtIndexPaths:[NSArray arrayWithObject:[NSIndexPath indexPathForRow:0 inSection:0]] withRowAnimation:UITableViewRowAnimationFade]; 460 | // } 461 | } else { 462 | //如果需要对选中的图片进行处理。 可以在此处操作 463 | // if (self.allowsEdit) { 464 | // QBImageEditerViewController *editer = [[QBImageEditerViewController alloc] init]; 465 | // editer.delegate = self; 466 | // editer.title = @"裁剪图片"; 467 | // editer.asset = asset; 468 | // [self.navigationController pushViewController:editer animated:YES]; 469 | // [editer release]; 470 | // } else { 471 | [self.delegate assetCollectionViewController:self didFinishPickingAsset:asset]; 472 | // } 473 | } 474 | } 475 | 476 | @end 477 | -------------------------------------------------------------------------------- /QBImagePickerControllerDemo/QBImagePickerControllerDemo/QBImagePickerController/QBAssetCollectionViewControllerDelegate.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2013 Katsuma Tanaka 3 | 4 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 5 | 6 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 7 | 8 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 9 | */ 10 | 11 | @class QBAssetCollectionViewController; 12 | 13 | @protocol QBAssetCollectionViewControllerDelegate 14 | 15 | @required 16 | - (void)assetCollectionViewController:(QBAssetCollectionViewController *)assetCollectionViewController didFinishPickingAsset:(ALAsset *)asset; 17 | - (void)assetCollectionViewController:(QBAssetCollectionViewController *)assetCollectionViewController didFinishPickingAssets:(NSArray *)assets; 18 | - (void)assetCollectionViewControllerDidCancel:(QBAssetCollectionViewController *)assetCollectionViewController; 19 | - (NSString *)descriptionForSelectingAllAssets:(QBAssetCollectionViewController *)assetCollectionViewController; 20 | - (NSString *)descriptionForDeselectingAllAssets:(QBAssetCollectionViewController *)assetCollectionViewController; 21 | - (NSString *)assetCollectionViewController:(QBAssetCollectionViewController *)assetCollectionViewController descriptionForNumberOfPhotos:(NSUInteger)numberOfPhotos; 22 | - (NSString *)assetCollectionViewController:(QBAssetCollectionViewController *)assetCollectionViewController descriptionForNumberOfVideos:(NSUInteger)numberOfVideos; 23 | - (NSString *)assetCollectionViewController:(QBAssetCollectionViewController *)assetCollectionViewController descriptionForNumberOfPhotos:(NSUInteger)numberOfPhotos numberOfVideos:(NSUInteger)numberOfVideos; 24 | 25 | @end 26 | -------------------------------------------------------------------------------- /QBImagePickerControllerDemo/QBImagePickerControllerDemo/QBImagePickerController/QBImageEditerViewController.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2013 Katsuma Tanaka 3 | 4 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 5 | 6 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 7 | 8 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 9 | */ 10 | 11 | #import 12 | #import 13 | 14 | // Controllers 15 | #import "QBAssetCollectionViewController.h" 16 | 17 | @interface QBImageEditerViewController : UIViewController 18 | 19 | @property (nonatomic, assign) id delegate; 20 | 21 | @property (nonatomic,retain) ALAsset *asset; 22 | 23 | @end 24 | -------------------------------------------------------------------------------- /QBImagePickerControllerDemo/QBImagePickerControllerDemo/QBImagePickerController/QBImageEditerViewController.m: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2013 Katsuma Tanaka 3 | 4 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 5 | 6 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 7 | 8 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 9 | */ 10 | 11 | #import "QBImageEditerViewController.h" 12 | 13 | @implementation QBImageEditerViewController 14 | 15 | - (void)viewWillAppear:(BOOL)animated 16 | { 17 | [self.navigationController.navigationBar setHidden:YES]; 18 | [[UIApplication sharedApplication] setStatusBarHidden:YES withAnimation:UIStatusBarAnimationNone]; 19 | } 20 | 21 | - (void)viewWillDisappear:(BOOL)animated 22 | { 23 | [self.navigationController.navigationBar setHidden:NO]; 24 | [[UIApplication sharedApplication] setStatusBarHidden:NO withAnimation:UIStatusBarAnimationNone]; 25 | } 26 | 27 | - (void)viewDidLoad 28 | { 29 | UIScrollView *scroller = [[UIScrollView alloc] initWithFrame:CGRectMake(0, 0, [UIScreen mainScreen].bounds.size.width, [UIScreen mainScreen].bounds.size.height)]; 30 | [self.view addSubview:scroller]; 31 | [scroller release]; 32 | 33 | UIImageView *imgView = [[UIImageView alloc] initWithFrame:self.view.frame]; 34 | [imgView setBackgroundColor:[UIColor greenColor]]; 35 | imgView.userInteractionEnabled = NO; 36 | CGImageRef imgRef = [[self.asset defaultRepresentation] fullScreenImage]; 37 | [imgView setImage:[UIImage imageWithCGImage:imgRef]]; 38 | [scroller addSubview:imgView]; 39 | [imgView release]; 40 | 41 | } 42 | 43 | - (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event 44 | { 45 | [self.delegate editerViewController:self didFinishPickingAsset:self.asset]; 46 | } 47 | 48 | -(void) dealloc 49 | { 50 | [_asset release]; 51 | [super dealloc]; 52 | } 53 | 54 | @end 55 | -------------------------------------------------------------------------------- /QBImagePickerControllerDemo/QBImagePickerControllerDemo/QBImagePickerController/QBImageEditerViewControllerDelegate.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2013 Katsuma Tanaka 3 | 4 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 5 | 6 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 7 | 8 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 9 | */ 10 | 11 | @class QBImageEditerViewController; 12 | 13 | @protocol QBImageEditerViewControllerDelegate 14 | 15 | @required 16 | - (void)editerViewController:(QBImageEditerViewController *)assetCollectionViewController didFinishPickingAsset:(ALAsset *)asset; 17 | 18 | @end 19 | 20 | -------------------------------------------------------------------------------- /QBImagePickerControllerDemo/QBImagePickerControllerDemo/QBImagePickerController/QBImagePickerAssetCell.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2013 Katsuma Tanaka 3 | 4 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 5 | 6 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 7 | 8 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 9 | */ 10 | 11 | #import 12 | #import 13 | 14 | // Delegate 15 | #import "QBImagePickerAssetCellDelegate.h" 16 | #import "QBImagePickerAssetViewDelegate.h" 17 | 18 | @interface QBImagePickerAssetCell : UITableViewCell 19 | 20 | @property (nonatomic, assign) id delegate; 21 | @property (nonatomic, copy) NSArray *assets; 22 | @property (nonatomic, assign) CGSize imageSize; 23 | @property (nonatomic, assign) NSUInteger numberOfAssets; 24 | @property (nonatomic, assign) CGFloat margin; 25 | @property (nonatomic, assign) BOOL allowsMultipleSelection; 26 | @property (nonatomic, assign) BOOL allowsEdit; 27 | 28 | - (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier imageSize:(CGSize)imageSize numberOfAssets:(NSUInteger)numberOfAssets margin:(CGFloat)margin; 29 | 30 | - (void)selectAssetAtIndex:(NSUInteger)index; 31 | - (void)deselectAssetAtIndex:(NSUInteger)index; 32 | - (void)selectAllAssets; 33 | - (void)deselectAllAssets; 34 | 35 | @end 36 | -------------------------------------------------------------------------------- /QBImagePickerControllerDemo/QBImagePickerControllerDemo/QBImagePickerController/QBImagePickerAssetCell.m: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2013 Katsuma Tanaka 3 | 4 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 5 | 6 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 7 | 8 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 9 | */ 10 | 11 | #import "QBImagePickerAssetCell.h" 12 | 13 | // Views 14 | #import "QBImagePickerAssetView.h" 15 | 16 | @interface QBImagePickerAssetCell () 17 | 18 | - (void)addAssetViews; 19 | 20 | @end 21 | 22 | @implementation QBImagePickerAssetCell 23 | 24 | - (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier imageSize:(CGSize)imageSize numberOfAssets:(NSUInteger)numberOfAssets margin:(CGFloat)margin 25 | { 26 | self = [super initWithStyle:style reuseIdentifier:reuseIdentifier]; 27 | 28 | if(self) { 29 | self.imageSize = imageSize; 30 | self.numberOfAssets = numberOfAssets; 31 | self.margin = margin; 32 | 33 | [self addAssetViews]; 34 | } 35 | 36 | return self; 37 | } 38 | 39 | - (void)setAssets:(NSArray *)assets 40 | { 41 | [_assets release]; 42 | _assets = [assets retain]; 43 | 44 | // Set assets 45 | for(NSUInteger i = 0; i < self.numberOfAssets; i++) { 46 | QBImagePickerAssetView *assetView = (QBImagePickerAssetView *)[self.contentView viewWithTag:(1 + i)]; 47 | 48 | if(i < self.assets.count) { 49 | assetView.hidden = NO; 50 | 51 | assetView.asset = [self.assets objectAtIndex:i]; 52 | } else { 53 | assetView.hidden = YES; 54 | } 55 | } 56 | } 57 | 58 | - (void)setAllowsMultipleSelection:(BOOL)allowsMultipleSelection 59 | { 60 | if (allowsMultipleSelection) { 61 | _allowsEdit = NO; 62 | } 63 | _allowsMultipleSelection = allowsMultipleSelection; 64 | 65 | // Set property 66 | for(UIView *subview in self.contentView.subviews) { 67 | if([subview isMemberOfClass:[QBImagePickerAssetView class]]) { 68 | [(QBImagePickerAssetView *)subview setAllowsMultipleSelection:self.allowsMultipleSelection]; 69 | } 70 | } 71 | } 72 | 73 | - (void)setAllowsEdit:(BOOL)allowsEdit 74 | { 75 | if (allowsEdit) { 76 | _allowsMultipleSelection = NO; 77 | } 78 | _allowsEdit = allowsEdit; 79 | } 80 | 81 | - (void)dealloc 82 | { 83 | [_assets release]; 84 | 85 | [super dealloc]; 86 | } 87 | 88 | 89 | #pragma mark - Instance Methods 90 | 91 | - (void)addAssetViews 92 | { 93 | // Remove all asset views 94 | for(UIView *subview in self.contentView.subviews) { 95 | if([subview isMemberOfClass:[QBImagePickerAssetView class]]) { 96 | [subview removeFromSuperview]; 97 | } 98 | } 99 | 100 | // Add asset views 101 | for(NSUInteger i = 0; i < self.numberOfAssets; i++) { 102 | // Calculate frame 103 | CGFloat offset = (self.margin + self.imageSize.width) * i; 104 | CGRect assetViewFrame = CGRectMake(offset + self.margin, self.margin, self.imageSize.width, self.imageSize.height); 105 | 106 | // Add asset view 107 | QBImagePickerAssetView *assetView = [[QBImagePickerAssetView alloc] initWithFrame:assetViewFrame]; 108 | assetView.delegate = self; 109 | assetView.tag = 1 + i; 110 | assetView.autoresizingMask = UIViewAutoresizingNone; 111 | 112 | [self.contentView addSubview:assetView]; 113 | [assetView release]; 114 | } 115 | } 116 | 117 | - (void)selectAssetAtIndex:(NSUInteger)index 118 | { 119 | QBImagePickerAssetView *assetView = (QBImagePickerAssetView *)[self.contentView viewWithTag:(index + 1)]; 120 | assetView.selected = YES; 121 | } 122 | 123 | - (void)deselectAssetAtIndex:(NSUInteger)index 124 | { 125 | QBImagePickerAssetView *assetView = (QBImagePickerAssetView *)[self.contentView viewWithTag:(index + 1)]; 126 | assetView.selected = NO; 127 | } 128 | 129 | - (void)selectAllAssets 130 | { 131 | for(UIView *subview in self.contentView.subviews) { 132 | if([subview isMemberOfClass:[QBImagePickerAssetView class]]) { 133 | if(![(QBImagePickerAssetView *)subview isHidden]) { 134 | [(QBImagePickerAssetView *)subview setSelected:YES]; 135 | } 136 | } 137 | } 138 | } 139 | 140 | - (void)deselectAllAssets 141 | { 142 | for(UIView *subview in self.contentView.subviews) { 143 | if([subview isMemberOfClass:[QBImagePickerAssetView class]]) { 144 | if(![(QBImagePickerAssetView *)subview isHidden]) { 145 | [(QBImagePickerAssetView *)subview setSelected:NO]; 146 | } 147 | } 148 | } 149 | } 150 | 151 | 152 | #pragma mark - QBImagePickerAssetViewDelegate 153 | 154 | - (BOOL)assetViewCanBeSelected:(QBImagePickerAssetView *)assetView 155 | { 156 | return [self.delegate assetCell:self canSelectAssetAtIndex:(assetView.tag - 1)]; 157 | } 158 | 159 | - (void)assetView:(QBImagePickerAssetView *)assetView didChangeSelectionState:(BOOL)selected 160 | { 161 | [self.delegate assetCell:self didChangeAssetSelectionState:selected atIndex:(assetView.tag - 1)]; 162 | } 163 | 164 | @end 165 | -------------------------------------------------------------------------------- /QBImagePickerControllerDemo/QBImagePickerControllerDemo/QBImagePickerController/QBImagePickerAssetCellDelegate.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2013 Katsuma Tanaka 3 | 4 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 5 | 6 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 7 | 8 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 9 | */ 10 | 11 | @class QBImagePickerAssetCell; 12 | 13 | @protocol QBImagePickerAssetCellDelegate 14 | 15 | @required 16 | - (BOOL)assetCell:(QBImagePickerAssetCell *)assetCell canSelectAssetAtIndex:(NSUInteger)index; 17 | - (void)assetCell:(QBImagePickerAssetCell *)assetCell didChangeAssetSelectionState:(BOOL)selected atIndex:(NSUInteger)index; 18 | 19 | @end 20 | -------------------------------------------------------------------------------- /QBImagePickerControllerDemo/QBImagePickerControllerDemo/QBImagePickerController/QBImagePickerAssetView.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2013 Katsuma Tanaka 3 | 4 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 5 | 6 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 7 | 8 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 9 | */ 10 | 11 | #import 12 | #import 13 | 14 | // Delegate 15 | #import "QBImagePickerAssetViewDelegate.h" 16 | 17 | @interface QBImagePickerAssetView : UIView 18 | 19 | @property (nonatomic, assign) id delegate; 20 | @property (nonatomic, retain) ALAsset *asset; 21 | @property (nonatomic, assign) BOOL selected; 22 | @property (nonatomic, assign) BOOL allowsMultipleSelection; 23 | 24 | @end 25 | -------------------------------------------------------------------------------- /QBImagePickerControllerDemo/QBImagePickerControllerDemo/QBImagePickerController/QBImagePickerAssetView.m: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2013 Katsuma Tanaka 3 | 4 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 5 | 6 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 7 | 8 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 9 | */ 10 | 11 | #import "QBImagePickerAssetView.h" 12 | 13 | // Views 14 | #import "QBImagePickerVideoInfoView.h" 15 | 16 | @interface QBImagePickerAssetView () 17 | 18 | @property (nonatomic, retain) UIImageView *imageView; 19 | @property (nonatomic, retain) QBImagePickerVideoInfoView *videoInfoView; 20 | @property (nonatomic, retain) UIImageView *overlayImageView; 21 | 22 | - (UIImage *)thumbnail; 23 | - (UIImage *)tintedThumbnail; 24 | 25 | @end 26 | 27 | @implementation QBImagePickerAssetView 28 | 29 | - (id)initWithFrame:(CGRect)frame 30 | { 31 | self = [super initWithFrame:frame]; 32 | 33 | if(self) { 34 | /* Initialization */ 35 | // Image View 36 | UIImageView *imageView = [[UIImageView alloc] initWithFrame:self.bounds]; 37 | imageView.contentMode = UIViewContentModeScaleAspectFill; 38 | imageView.clipsToBounds = YES; 39 | imageView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight; 40 | 41 | [self addSubview:imageView]; 42 | self.imageView = imageView; 43 | [imageView release]; 44 | 45 | // Video Info View 46 | QBImagePickerVideoInfoView *videoInfoView = [[QBImagePickerVideoInfoView alloc] initWithFrame:CGRectMake(0, self.bounds.size.height - 17, self.bounds.size.width, 17)]; 47 | videoInfoView.hidden = YES; 48 | videoInfoView.autoresizingMask = UIViewAutoresizingFlexibleTopMargin | UIViewAutoresizingFlexibleWidth; 49 | 50 | [self addSubview:videoInfoView]; 51 | self.videoInfoView = videoInfoView; 52 | [videoInfoView release]; 53 | 54 | // Overlay Image View 55 | UIImageView *overlayImageView = [[UIImageView alloc] initWithFrame:self.bounds]; 56 | overlayImageView.contentMode = UIViewContentModeScaleAspectFill; 57 | overlayImageView.clipsToBounds = YES; 58 | overlayImageView.image = [UIImage imageNamed:@"QBImagePickerController.bundle/overlay.png"]; 59 | overlayImageView.hidden = YES; 60 | overlayImageView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight; 61 | 62 | [self addSubview:overlayImageView]; 63 | self.overlayImageView = overlayImageView; 64 | [overlayImageView release]; 65 | } 66 | 67 | return self; 68 | } 69 | 70 | - (void)setAsset:(ALAsset *)asset 71 | { 72 | [_asset release]; 73 | _asset = [asset retain]; 74 | 75 | // Set thumbnail image 76 | self.imageView.image = [self thumbnail]; 77 | 78 | if([self.asset valueForProperty:ALAssetPropertyType] == ALAssetTypeVideo) { 79 | double duration = [[asset valueForProperty:ALAssetPropertyDuration] doubleValue]; 80 | 81 | self.videoInfoView.hidden = NO; 82 | self.videoInfoView.duration = round(duration); 83 | } else { 84 | self.videoInfoView.hidden = YES; 85 | } 86 | } 87 | 88 | - (void)setSelected:(BOOL)selected 89 | { 90 | if(self.allowsMultipleSelection) { 91 | self.overlayImageView.hidden = !selected; 92 | } 93 | } 94 | 95 | - (BOOL)selected 96 | { 97 | return !self.overlayImageView.hidden; 98 | } 99 | 100 | - (void)dealloc 101 | { 102 | [_asset release]; 103 | 104 | [_imageView release]; 105 | [_videoInfoView release]; 106 | [_overlayImageView release]; 107 | 108 | [super dealloc]; 109 | } 110 | 111 | 112 | #pragma mark - Touch Events 113 | 114 | - (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event 115 | { 116 | if([self.delegate assetViewCanBeSelected:self] && !self.allowsMultipleSelection) { 117 | self.imageView.image = [self tintedThumbnail]; 118 | } 119 | } 120 | 121 | - (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event 122 | { 123 | if([self.delegate assetViewCanBeSelected:self]) { 124 | self.selected = !self.selected; 125 | 126 | if(self.allowsMultipleSelection) { 127 | self.imageView.image = [self thumbnail]; 128 | } else { 129 | self.imageView.image = [self tintedThumbnail]; 130 | } 131 | 132 | [self.delegate assetView:self didChangeSelectionState:self.selected]; 133 | } else { 134 | if(self.allowsMultipleSelection && self.selected) { 135 | self.selected = !self.selected; 136 | self.imageView.image = [self thumbnail]; 137 | 138 | [self.delegate assetView:self didChangeSelectionState:self.selected]; 139 | } else { 140 | self.imageView.image = [self thumbnail]; 141 | } 142 | 143 | [self.delegate assetView:self didChangeSelectionState:self.selected]; 144 | } 145 | } 146 | 147 | - (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event 148 | { 149 | self.imageView.image = [self thumbnail]; 150 | } 151 | 152 | 153 | #pragma mark - Instance Methods 154 | 155 | - (UIImage *)thumbnail 156 | { 157 | return [UIImage imageWithCGImage:[self.asset thumbnail]]; 158 | } 159 | 160 | - (UIImage *)tintedThumbnail 161 | { 162 | UIImage *thumbnail = [self thumbnail]; 163 | 164 | UIGraphicsBeginImageContext(thumbnail.size); 165 | 166 | CGRect rect = CGRectMake(0, 0, thumbnail.size.width, thumbnail.size.height); 167 | [thumbnail drawInRect:rect]; 168 | 169 | [[UIColor colorWithWhite:0 alpha:0.5] set]; 170 | UIRectFillUsingBlendMode(rect, kCGBlendModeSourceAtop); 171 | 172 | UIImage *tintedThumbnail = UIGraphicsGetImageFromCurrentImageContext(); 173 | 174 | UIGraphicsEndImageContext(); 175 | 176 | return tintedThumbnail; 177 | } 178 | 179 | @end 180 | -------------------------------------------------------------------------------- /QBImagePickerControllerDemo/QBImagePickerControllerDemo/QBImagePickerController/QBImagePickerAssetViewDelegate.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2013 Katsuma Tanaka 3 | 4 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 5 | 6 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 7 | 8 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 9 | */ 10 | 11 | @class QBImagePickerAssetView; 12 | 13 | @protocol QBImagePickerAssetViewDelegate 14 | 15 | @required 16 | - (BOOL)assetViewCanBeSelected:(QBImagePickerAssetView *)assetView; 17 | - (void)assetView:(QBImagePickerAssetView *)assetView didChangeSelectionState:(BOOL)selected; 18 | 19 | @end 20 | -------------------------------------------------------------------------------- /QBImagePickerControllerDemo/QBImagePickerControllerDemo/QBImagePickerController/QBImagePickerController.bundle/minus.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JentCastttttt/QBImagePickerController/5e0ff3c2dc992b3edf0f145c0709af06c1109a02/QBImagePickerControllerDemo/QBImagePickerControllerDemo/QBImagePickerController/QBImagePickerController.bundle/minus.png -------------------------------------------------------------------------------- /QBImagePickerControllerDemo/QBImagePickerControllerDemo/QBImagePickerController/QBImagePickerController.bundle/minus@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JentCastttttt/QBImagePickerController/5e0ff3c2dc992b3edf0f145c0709af06c1109a02/QBImagePickerControllerDemo/QBImagePickerControllerDemo/QBImagePickerController/QBImagePickerController.bundle/minus@2x.png -------------------------------------------------------------------------------- /QBImagePickerControllerDemo/QBImagePickerControllerDemo/QBImagePickerController/QBImagePickerController.bundle/overlay.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JentCastttttt/QBImagePickerController/5e0ff3c2dc992b3edf0f145c0709af06c1109a02/QBImagePickerControllerDemo/QBImagePickerControllerDemo/QBImagePickerController/QBImagePickerController.bundle/overlay.png -------------------------------------------------------------------------------- /QBImagePickerControllerDemo/QBImagePickerControllerDemo/QBImagePickerController/QBImagePickerController.bundle/overlay@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JentCastttttt/QBImagePickerController/5e0ff3c2dc992b3edf0f145c0709af06c1109a02/QBImagePickerControllerDemo/QBImagePickerControllerDemo/QBImagePickerController/QBImagePickerController.bundle/overlay@2x.png -------------------------------------------------------------------------------- /QBImagePickerControllerDemo/QBImagePickerControllerDemo/QBImagePickerController/QBImagePickerController.bundle/plus.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JentCastttttt/QBImagePickerController/5e0ff3c2dc992b3edf0f145c0709af06c1109a02/QBImagePickerControllerDemo/QBImagePickerControllerDemo/QBImagePickerController/QBImagePickerController.bundle/plus.png -------------------------------------------------------------------------------- /QBImagePickerControllerDemo/QBImagePickerControllerDemo/QBImagePickerController/QBImagePickerController.bundle/plus@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JentCastttttt/QBImagePickerController/5e0ff3c2dc992b3edf0f145c0709af06c1109a02/QBImagePickerControllerDemo/QBImagePickerControllerDemo/QBImagePickerController/QBImagePickerController.bundle/plus@2x.png -------------------------------------------------------------------------------- /QBImagePickerControllerDemo/QBImagePickerControllerDemo/QBImagePickerController/QBImagePickerController.bundle/video.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JentCastttttt/QBImagePickerController/5e0ff3c2dc992b3edf0f145c0709af06c1109a02/QBImagePickerControllerDemo/QBImagePickerControllerDemo/QBImagePickerController/QBImagePickerController.bundle/video.png -------------------------------------------------------------------------------- /QBImagePickerControllerDemo/QBImagePickerControllerDemo/QBImagePickerController/QBImagePickerController.bundle/video@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JentCastttttt/QBImagePickerController/5e0ff3c2dc992b3edf0f145c0709af06c1109a02/QBImagePickerControllerDemo/QBImagePickerControllerDemo/QBImagePickerController/QBImagePickerController.bundle/video@2x.png -------------------------------------------------------------------------------- /QBImagePickerControllerDemo/QBImagePickerControllerDemo/QBImagePickerController/QBImagePickerController.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2013 Katsuma Tanaka 3 | 4 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 5 | 6 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 7 | 8 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 9 | */ 10 | 11 | #import 12 | #import 13 | 14 | // Delegate 15 | #import "QBAssetCollectionViewControllerDelegate.h" 16 | 17 | typedef enum { 18 | QBImagePickerFilterTypeAllAssets, 19 | QBImagePickerFilterTypeAllPhotos, 20 | QBImagePickerFilterTypeAllVideos 21 | } QBImagePickerFilterType; 22 | 23 | @class QBImagePickerController; 24 | 25 | @protocol QBImagePickerControllerDelegate 26 | 27 | @optional 28 | - (void)imagePickerControllerWillFinishPickingMedia:(QBImagePickerController *)imagePickerController; 29 | - (void)imagePickerController:(QBImagePickerController *)imagePickerController didFinishPickingMediaWithInfo:(id)info; 30 | - (void)imagePickerControllerDidCancel:(QBImagePickerController *)imagePickerController; 31 | - (NSString *)descriptionForSelectingAllAssets:(QBImagePickerController *)imagePickerController; 32 | - (NSString *)descriptionForDeselectingAllAssets:(QBImagePickerController *)imagePickerController; 33 | - (NSString *)imagePickerController:(QBImagePickerController *)imagePickerController descriptionForNumberOfPhotos:(NSUInteger)numberOfPhotos; 34 | - (NSString *)imagePickerController:(QBImagePickerController *)imagePickerController descriptionForNumberOfVideos:(NSUInteger)numberOfVideos; 35 | - (NSString *)imagePickerController:(QBImagePickerController *)imagePickerController descriptionForNumberOfPhotos:(NSUInteger)numberOfPhotos numberOfVideos:(NSUInteger)numberOfVideos; 36 | 37 | @end 38 | 39 | @interface QBImagePickerController : UIViewController 40 | 41 | @property (nonatomic, assign) id delegate; 42 | @property (nonatomic, assign) QBImagePickerFilterType filterType; 43 | @property (nonatomic, assign) BOOL showsCancelButton; 44 | @property (nonatomic, assign) BOOL fullScreenLayoutEnabled; 45 | 46 | @property (nonatomic, assign) BOOL allowsMultipleSelection; 47 | @property (nonatomic, assign) BOOL allowsEdit; 48 | 49 | @property (nonatomic, assign) BOOL limitsMinimumNumberOfSelection; 50 | @property (nonatomic, assign) BOOL limitsMaximumNumberOfSelection; 51 | @property (nonatomic, assign) NSUInteger minimumNumberOfSelection; 52 | @property (nonatomic, assign) NSUInteger maximumNumberOfSelection; 53 | 54 | @end 55 | -------------------------------------------------------------------------------- /QBImagePickerControllerDemo/QBImagePickerControllerDemo/QBImagePickerController/QBImagePickerController.m: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2013 Katsuma Tanaka 3 | 4 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 5 | 6 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 7 | 8 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 9 | */ 10 | 11 | #import "QBImagePickerController.h" 12 | 13 | // Views 14 | #import "QBImagePickerGroupCell.h" 15 | 16 | // Controllers 17 | #import "QBAssetCollectionViewController.h" 18 | 19 | @interface QBImagePickerController () 20 | 21 | @property (nonatomic, retain) ALAssetsLibrary *assetsLibrary; 22 | @property (nonatomic, retain) NSMutableArray *assetsGroups; 23 | 24 | @property (nonatomic, retain) UITableView *tableView; 25 | 26 | @property (nonatomic, assign) UIBarStyle previousBarStyle; 27 | @property (nonatomic, assign) BOOL previousBarTranslucent; 28 | @property (nonatomic, assign) UIStatusBarStyle previousStatusBarStyle; 29 | 30 | - (void)cancel; 31 | - (NSDictionary *)mediaInfoFromAsset:(ALAsset *)asset; 32 | 33 | @end 34 | 35 | @implementation QBImagePickerController 36 | 37 | - (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil 38 | { 39 | self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil]; 40 | 41 | if(self) { 42 | /* Check sources */ 43 | [UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypeCamera]; 44 | [UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypePhotoLibrary]; 45 | [UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypeSavedPhotosAlbum]; 46 | 47 | /* Initialization */ 48 | self.title = @"照片"; 49 | self.filterType = QBImagePickerFilterTypeAllPhotos; 50 | self.showsCancelButton = YES; 51 | self.fullScreenLayoutEnabled = YES; 52 | 53 | self.allowsMultipleSelection = NO; 54 | self.allowsEdit = NO; 55 | 56 | self.limitsMinimumNumberOfSelection = NO; 57 | self.limitsMaximumNumberOfSelection = NO; 58 | self.minimumNumberOfSelection = 0; 59 | self.maximumNumberOfSelection = 0; 60 | 61 | ALAssetsLibrary *assetsLibrary = [[ALAssetsLibrary alloc] init]; 62 | self.assetsLibrary = assetsLibrary; 63 | [assetsLibrary release]; 64 | 65 | self.assetsGroups = [NSMutableArray array]; 66 | 67 | // Table View 68 | UITableView *tableView = [[UITableView alloc] initWithFrame:self.view.bounds style:UITableViewStylePlain]; 69 | tableView.dataSource = self; 70 | tableView.delegate = self; 71 | tableView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight; 72 | 73 | [self.view addSubview:tableView]; 74 | self.tableView = tableView; 75 | [tableView release]; 76 | } 77 | 78 | return self; 79 | } 80 | 81 | - (void)viewDidLoad 82 | { 83 | [super viewDidLoad]; 84 | 85 | void (^assetsGroupsEnumerationBlock)(ALAssetsGroup *, BOOL *) = ^(ALAssetsGroup *assetsGroup, BOOL *stop) { 86 | if(assetsGroup) { 87 | switch(self.filterType) { 88 | case QBImagePickerFilterTypeAllAssets: 89 | [assetsGroup setAssetsFilter:[ALAssetsFilter allAssets]]; 90 | break; 91 | case QBImagePickerFilterTypeAllPhotos: 92 | [assetsGroup setAssetsFilter:[ALAssetsFilter allPhotos]]; 93 | break; 94 | case QBImagePickerFilterTypeAllVideos: 95 | [assetsGroup setAssetsFilter:[ALAssetsFilter allVideos]]; 96 | break; 97 | } 98 | 99 | if(assetsGroup.numberOfAssets > 0) { 100 | [self.assetsGroups addObject:assetsGroup]; 101 | [self.tableView reloadData]; 102 | } 103 | } 104 | }; 105 | 106 | void (^assetsGroupsFailureBlock)(NSError *) = ^(NSError *error) { 107 | NSLog(@"Error: %@", [error localizedDescription]); 108 | }; 109 | 110 | // Enumerate Camera Roll 111 | [self.assetsLibrary enumerateGroupsWithTypes:ALAssetsGroupSavedPhotos usingBlock:assetsGroupsEnumerationBlock failureBlock:assetsGroupsFailureBlock]; 112 | 113 | // Photo Stream 114 | [self.assetsLibrary enumerateGroupsWithTypes:ALAssetsGroupPhotoStream usingBlock:assetsGroupsEnumerationBlock failureBlock:assetsGroupsFailureBlock]; 115 | 116 | // Album 117 | [self.assetsLibrary enumerateGroupsWithTypes:ALAssetsGroupAlbum usingBlock:assetsGroupsEnumerationBlock failureBlock:assetsGroupsFailureBlock]; 118 | 119 | // Event 120 | [self.assetsLibrary enumerateGroupsWithTypes:ALAssetsGroupEvent usingBlock:assetsGroupsEnumerationBlock failureBlock:assetsGroupsFailureBlock]; 121 | 122 | // Faces 123 | [self.assetsLibrary enumerateGroupsWithTypes:ALAssetsGroupFaces usingBlock:assetsGroupsEnumerationBlock failureBlock:assetsGroupsFailureBlock]; 124 | 125 | } 126 | 127 | - (void)viewWillAppear:(BOOL)animated 128 | { 129 | [super viewWillAppear:animated]; 130 | 131 | // Full screen layout 132 | if(self.fullScreenLayoutEnabled) { 133 | NSIndexPath *indexPath = [self.tableView indexPathForSelectedRow]; 134 | 135 | if(indexPath == nil) { 136 | self.previousBarStyle = self.navigationController.navigationBar.barStyle; 137 | self.previousBarTranslucent = self.navigationController.navigationBar.translucent; 138 | self.previousStatusBarStyle = [[UIApplication sharedApplication] statusBarStyle]; 139 | 140 | self.navigationController.navigationBar.barStyle = UIBarStyleBlack; 141 | self.navigationController.navigationBar.translucent = YES; 142 | //取消无效代码 143 | // [[UIApplication sharedApplication] setStatusBarStyle:UIStatusBarStyleBlackTranslucent animated:YES]; 144 | 145 | CGFloat top = 0; 146 | if(![[UIApplication sharedApplication] isStatusBarHidden]) top = top + 20; 147 | if(!self.navigationController.navigationBarHidden) top = top + 44; 148 | self.tableView.contentInset = UIEdgeInsetsMake(top, 0, 0, 0); 149 | self.tableView.scrollIndicatorInsets = UIEdgeInsetsMake(top, 0, 0, 0); 150 | //取消无效代码 151 | // [self setWantsFullScreenLayout:YES]; 152 | } 153 | } 154 | 155 | // Cancel table view selection 156 | [self.tableView deselectRowAtIndexPath:[self.tableView indexPathForSelectedRow] animated:YES]; 157 | } 158 | 159 | - (void)viewDidAppear:(BOOL)animated 160 | { 161 | [super viewDidAppear:animated]; 162 | 163 | // Flash scroll indicators 164 | [self.tableView flashScrollIndicators]; 165 | } 166 | 167 | - (void)viewWillDisappear:(BOOL)animated 168 | { 169 | [super viewWillDisappear:animated]; 170 | 171 | // Restore bar styles 172 | self.navigationController.navigationBar.barStyle = self.previousBarStyle; 173 | self.navigationController.navigationBar.translucent = self.previousBarTranslucent; 174 | [[UIApplication sharedApplication] setStatusBarStyle:self.previousStatusBarStyle animated:YES]; 175 | } 176 | 177 | - (void)setShowsCancelButton:(BOOL)showsCancelButton 178 | { 179 | _showsCancelButton = showsCancelButton; 180 | 181 | if(self.showsCancelButton) { 182 | UIBarButtonItem *cancelButton = [[UIBarButtonItem alloc] initWithTitle:@"取消" style:UIBarButtonItemStyleDone target:self action:@selector(cancel)];//[[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemCancel target:self action:@selector(cancel)]; 183 | [self.navigationItem setRightBarButtonItem:cancelButton animated:NO]; 184 | [cancelButton release]; 185 | } else { 186 | [self.navigationItem setRightBarButtonItem:nil animated:NO]; 187 | } 188 | } 189 | 190 | - (void)dealloc 191 | { 192 | [_assetsLibrary release]; 193 | [_assetsGroups release]; 194 | 195 | [_tableView release]; 196 | 197 | [super dealloc]; 198 | } 199 | 200 | 201 | #pragma mark - Instance Methods 202 | 203 | - (void)cancel 204 | { 205 | if([self.delegate respondsToSelector:@selector(imagePickerControllerDidCancel:)]) { 206 | [self.delegate imagePickerControllerDidCancel:self]; 207 | } 208 | } 209 | 210 | - (NSDictionary *)mediaInfoFromAsset:(ALAsset *)asset 211 | { 212 | NSMutableDictionary *mediaInfo = [NSMutableDictionary dictionary]; 213 | [mediaInfo setObject:[asset valueForProperty:ALAssetPropertyType] forKey:@"UIImagePickerControllerMediaType"]; 214 | [mediaInfo setObject:[UIImage imageWithCGImage:[[asset defaultRepresentation] fullScreenImage]] forKey:@"UIImagePickerControllerOriginalImage"]; 215 | [mediaInfo setObject:[[asset valueForProperty:ALAssetPropertyURLs] valueForKey:[[[asset valueForProperty:ALAssetPropertyURLs] allKeys] objectAtIndex:0]] forKey:@"UIImagePickerControllerReferenceURL"]; 216 | 217 | return mediaInfo; 218 | } 219 | 220 | 221 | #pragma mark - UITableViewDataSource 222 | 223 | - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView 224 | { 225 | return 1; 226 | } 227 | 228 | - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section 229 | { 230 | NSLog(@"self.assetsGroups.count==%ld",self.assetsGroups.count); 231 | return self.assetsGroups.count; 232 | } 233 | 234 | - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath 235 | { 236 | static NSString *cellIdentifier = @"Cell"; 237 | QBImagePickerGroupCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier]; 238 | 239 | if(cell == nil) { 240 | cell = [[[QBImagePickerGroupCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellIdentifier] autorelease]; 241 | cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator; 242 | } 243 | 244 | ALAssetsGroup *assetsGroup = [self.assetsGroups objectAtIndex:indexPath.row]; 245 | 246 | cell.iconView.image = [UIImage imageWithCGImage:assetsGroup.posterImage]; 247 | cell.titleLabel.text = [NSString stringWithFormat:@"%@", [assetsGroup valueForProperty:ALAssetsGroupPropertyName]]; 248 | cell.countLabel.text = [NSString stringWithFormat:@"(%ld)", assetsGroup.numberOfAssets]; 249 | 250 | return cell; 251 | } 252 | 253 | 254 | #pragma mark - UITableViewDelegate 255 | 256 | - (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath 257 | { 258 | return 60.0f; 259 | } 260 | 261 | - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath 262 | { 263 | ALAssetsGroup *assetsGroup = [self.assetsGroups objectAtIndex:indexPath.row]; 264 | 265 | //是否隐藏UITableView上的HeaderView 266 | // BOOL showsHeaderButton = ([self.delegate respondsToSelector:@selector(descriptionForSelectingAllAssets:)] && [self.delegate respondsToSelector:@selector(descriptionForDeselectingAllAssets:)]); 267 | 268 | BOOL showsFooterDescription = NO; 269 | 270 | switch(self.filterType) { 271 | case QBImagePickerFilterTypeAllAssets: 272 | showsFooterDescription = ([self.delegate respondsToSelector:@selector(imagePickerController:descriptionForNumberOfPhotos:numberOfVideos:)]); 273 | break; 274 | case QBImagePickerFilterTypeAllPhotos: 275 | showsFooterDescription = ([self.delegate respondsToSelector:@selector(imagePickerController:descriptionForNumberOfPhotos:)]); 276 | break; 277 | case QBImagePickerFilterTypeAllVideos: 278 | showsFooterDescription = ([self.delegate respondsToSelector:@selector(imagePickerController:descriptionForNumberOfVideos:)]); 279 | break; 280 | } 281 | 282 | // Show assets collection view 283 | QBAssetCollectionViewController *assetCollectionViewController = [[QBAssetCollectionViewController alloc] init]; 284 | assetCollectionViewController.title = [assetsGroup valueForProperty:ALAssetsGroupPropertyName]; 285 | assetCollectionViewController.delegate = self; 286 | assetCollectionViewController.assetsGroup = assetsGroup; 287 | assetCollectionViewController.filterType = self.filterType; 288 | assetCollectionViewController.showsCancelButton = self.showsCancelButton; 289 | assetCollectionViewController.fullScreenLayoutEnabled = self.fullScreenLayoutEnabled; 290 | assetCollectionViewController.showsHeaderButton = NO; 291 | assetCollectionViewController.showsFooterDescription = showsFooterDescription; 292 | 293 | assetCollectionViewController.allowsMultipleSelection = self.allowsMultipleSelection; 294 | assetCollectionViewController.allowsEdit = self.allowsEdit; 295 | assetCollectionViewController.limitsMinimumNumberOfSelection = self.limitsMinimumNumberOfSelection; 296 | assetCollectionViewController.limitsMaximumNumberOfSelection = self.limitsMaximumNumberOfSelection; 297 | assetCollectionViewController.minimumNumberOfSelection = self.minimumNumberOfSelection; 298 | assetCollectionViewController.maximumNumberOfSelection = self.maximumNumberOfSelection; 299 | 300 | [self.navigationController pushViewController:assetCollectionViewController animated:YES]; 301 | 302 | [assetCollectionViewController release]; 303 | } 304 | 305 | #pragma mark - QBAssetCollectionViewControllerDelegate 306 | 307 | - (void)assetCollectionViewController:(QBAssetCollectionViewController *)assetCollectionViewController didFinishPickingAsset:(ALAsset *)asset 308 | { 309 | if([self.delegate respondsToSelector:@selector(imagePickerControllerWillFinishPickingMedia:)]) { 310 | [self.delegate imagePickerControllerWillFinishPickingMedia:self]; 311 | } 312 | 313 | if([self.delegate respondsToSelector:@selector(imagePickerController:didFinishPickingMediaWithInfo:)]) { 314 | [self.delegate imagePickerController:self didFinishPickingMediaWithInfo:[self mediaInfoFromAsset:asset]]; 315 | } 316 | } 317 | 318 | - (void)assetCollectionViewController:(QBAssetCollectionViewController *)assetCollectionViewController didFinishPickingAssets:(NSArray *)assets 319 | { 320 | if([self.delegate respondsToSelector:@selector(imagePickerControllerWillFinishPickingMedia:)]) { 321 | [self.delegate imagePickerControllerWillFinishPickingMedia:self]; 322 | } 323 | 324 | if([self.delegate respondsToSelector:@selector(imagePickerController:didFinishPickingMediaWithInfo:)]) { 325 | NSMutableArray *info = [NSMutableArray array]; 326 | //根据需要, 穿入ALAsset对象 或者 dic对象(包含UIImage,类型,UIImagePickerControllerReferenceURL) 327 | for(ALAsset *asset in assets) { 328 | // [info addObject:[self mediaInfoFromAsset:asset]]; 329 | [info addObject:asset]; 330 | } 331 | 332 | [self.delegate imagePickerController:self didFinishPickingMediaWithInfo:info]; 333 | } 334 | } 335 | 336 | - (void)assetCollectionViewControllerDidCancel:(QBAssetCollectionViewController *)assetCollectionViewController 337 | { 338 | if([self.delegate respondsToSelector:@selector(imagePickerControllerDidCancel:)]) { 339 | [self.delegate imagePickerControllerDidCancel:self]; 340 | } 341 | } 342 | 343 | - (NSString *)descriptionForSelectingAllAssets:(QBAssetCollectionViewController *)assetCollectionViewController 344 | { 345 | NSString *description = nil; 346 | 347 | if([self.delegate respondsToSelector:@selector(descriptionForSelectingAllAssets:)]) { 348 | description = [self.delegate descriptionForSelectingAllAssets:self]; 349 | } 350 | 351 | return description; 352 | } 353 | 354 | - (NSString *)descriptionForDeselectingAllAssets:(QBAssetCollectionViewController *)assetCollectionViewController 355 | { 356 | NSString *description = nil; 357 | 358 | if([self.delegate respondsToSelector:@selector(descriptionForDeselectingAllAssets:)]) { 359 | description = [self.delegate descriptionForDeselectingAllAssets:self]; 360 | } 361 | 362 | return description; 363 | } 364 | 365 | - (NSString *)assetCollectionViewController:(QBAssetCollectionViewController *)assetCollectionViewController descriptionForNumberOfPhotos:(NSUInteger)numberOfPhotos 366 | { 367 | NSString *description = nil; 368 | 369 | if([self.delegate respondsToSelector:@selector(imagePickerController:descriptionForNumberOfPhotos:)]) { 370 | description = [self.delegate imagePickerController:self descriptionForNumberOfPhotos:numberOfPhotos]; 371 | } 372 | 373 | return description; 374 | } 375 | 376 | - (NSString *)assetCollectionViewController:(QBAssetCollectionViewController *)assetCollectionViewController descriptionForNumberOfVideos:(NSUInteger)numberOfVideos 377 | { 378 | NSString *description = nil; 379 | 380 | if([self.delegate respondsToSelector:@selector(imagePickerController:descriptionForNumberOfVideos:)]) { 381 | description = [self.delegate imagePickerController:self descriptionForNumberOfVideos:numberOfVideos]; 382 | } 383 | 384 | return description; 385 | } 386 | 387 | - (NSString *)assetCollectionViewController:(QBAssetCollectionViewController *)assetCollectionViewController descriptionForNumberOfPhotos:(NSUInteger)numberOfPhotos numberOfVideos:(NSUInteger)numberOfVideos 388 | { 389 | NSString *description = nil; 390 | 391 | if([self.delegate respondsToSelector:@selector(imagePickerController:descriptionForNumberOfPhotos:numberOfVideos:)]) { 392 | description = [self.delegate imagePickerController:self descriptionForNumberOfPhotos:numberOfPhotos numberOfVideos:numberOfVideos]; 393 | } 394 | 395 | return description; 396 | } 397 | 398 | @end 399 | -------------------------------------------------------------------------------- /QBImagePickerControllerDemo/QBImagePickerControllerDemo/QBImagePickerController/QBImagePickerFooterView.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2013 Katsuma Tanaka 3 | 4 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 5 | 6 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 7 | 8 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 9 | */ 10 | 11 | #import 12 | 13 | @interface QBImagePickerFooterView : UIView 14 | 15 | @property (nonatomic, retain) UILabel *titleLabel; 16 | 17 | @end 18 | -------------------------------------------------------------------------------- /QBImagePickerControllerDemo/QBImagePickerControllerDemo/QBImagePickerController/QBImagePickerFooterView.m: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2013 Katsuma Tanaka 3 | 4 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 5 | 6 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 7 | 8 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 9 | */ 10 | 11 | #import "QBImagePickerFooterView.h" 12 | 13 | @implementation QBImagePickerFooterView 14 | 15 | - (id)initWithFrame:(CGRect)frame 16 | { 17 | self = [super initWithFrame:frame]; 18 | 19 | if(self) { 20 | /* Initialization */ 21 | UILabel *titleLabel = [[UILabel alloc] initWithFrame:self.bounds]; 22 | titleLabel.font = [UIFont systemFontOfSize:20]; 23 | titleLabel.textAlignment = NSTextAlignmentCenter; 24 | titleLabel.textColor = [UIColor colorWithRed:0.502 green:0.533 blue:0.58 alpha:1.0]; 25 | titleLabel.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight; 26 | 27 | [self addSubview:titleLabel]; 28 | self.titleLabel = titleLabel; 29 | [titleLabel release]; 30 | } 31 | 32 | return self; 33 | } 34 | 35 | - (void)dealloc 36 | { 37 | [_titleLabel release]; 38 | 39 | [super dealloc]; 40 | } 41 | 42 | @end 43 | -------------------------------------------------------------------------------- /QBImagePickerControllerDemo/QBImagePickerControllerDemo/QBImagePickerController/QBImagePickerGroupCell.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2013 Katsuma Tanaka 3 | 4 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 5 | 6 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 7 | 8 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 9 | */ 10 | 11 | #import 12 | 13 | @interface QBImagePickerGroupCell : UITableViewCell 14 | 15 | @property (nonatomic, retain) UIImageView *iconView; 16 | @property (nonatomic, retain) UILabel *titleLabel; 17 | @property (nonatomic, retain) UILabel *countLabel; 18 | 19 | @end 20 | -------------------------------------------------------------------------------- /QBImagePickerControllerDemo/QBImagePickerControllerDemo/QBImagePickerController/QBImagePickerGroupCell.m: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2013 Katsuma Tanaka 3 | 4 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 5 | 6 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 7 | 8 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 9 | */ 10 | 11 | #import "QBImagePickerGroupCell.h" 12 | 13 | @implementation QBImagePickerGroupCell 14 | 15 | - (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier 16 | { 17 | self = [super initWithStyle:style reuseIdentifier:reuseIdentifier]; 18 | 19 | if(self) { 20 | /* Initialization */ 21 | // Title 22 | UIImageView *icon = [[UIImageView alloc] initWithFrame:CGRectMake(10, 2.0, 56, 56)]; 23 | icon.layer.cornerRadius = icon.frame.size.height/2.0; 24 | icon.clipsToBounds = YES; 25 | [self.contentView addSubview:icon]; 26 | self.iconView = icon; 27 | [icon release]; 28 | 29 | UILabel *titleLabel = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, 0, 0)]; 30 | titleLabel.font = [UIFont boldSystemFontOfSize:17]; 31 | titleLabel.textColor = [UIColor blackColor]; 32 | titleLabel.highlightedTextColor = [UIColor whiteColor]; 33 | titleLabel.autoresizingMask = UIViewAutoresizingFlexibleRightMargin | UIViewAutoresizingFlexibleWidth; 34 | [self.contentView addSubview:titleLabel]; 35 | self.titleLabel = titleLabel; 36 | [titleLabel release]; 37 | 38 | // Count 39 | UILabel *countLabel = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, 0, 0)]; 40 | countLabel.font = [UIFont systemFontOfSize:17]; 41 | countLabel.textColor = [UIColor colorWithWhite:0.498 alpha:1.0]; 42 | countLabel.highlightedTextColor = [UIColor whiteColor]; 43 | countLabel.autoresizingMask = UIViewAutoresizingFlexibleLeftMargin; 44 | [self.contentView addSubview:countLabel]; 45 | self.countLabel = countLabel; 46 | [countLabel release]; 47 | } 48 | 49 | return self; 50 | } 51 | 52 | - (void)setSelected:(BOOL)selected animated:(BOOL)animated 53 | { 54 | [super setSelected:selected animated:animated]; 55 | 56 | self.titleLabel.highlighted = selected; 57 | self.countLabel.highlighted = selected; 58 | } 59 | 60 | - (void)layoutSubviews 61 | { 62 | [super layoutSubviews]; 63 | 64 | CGFloat height = self.contentView.bounds.size.height; 65 | CGFloat width = self.contentView.bounds.size.width - 20; 66 | 67 | NSDictionary *dicCount = [NSDictionary dictionaryWithObjectsAndKeys:self.countLabel.font,NSFontAttributeName, nil]; 68 | NSDictionary *dicTitle = [NSDictionary dictionaryWithObjectsAndKeys:self.titleLabel.font,NSFontAttributeName, nil]; 69 | 70 | CGSize countSize = [self.countLabel.text boundingRectWithSize:CGSizeMake(width - 76, 20) options:NSStringDrawingTruncatesLastVisibleLine | NSStringDrawingUsesLineFragmentOrigin | NSStringDrawingUsesFontLeading attributes:dicCount context:nil].size; 71 | CGSize titleSize = [self.titleLabel.text boundingRectWithSize:CGSizeMake(width - 76 - countSize.width, 20) options:NSStringDrawingTruncatesLastVisibleLine | NSStringDrawingUsesLineFragmentOrigin | NSStringDrawingUsesFontLeading attributes:dicTitle context:nil].size; 72 | if (titleSize.width == 0 && [self.titleLabel.text length] > 0) { 73 | titleSize = CGSizeMake(width - 76 - countSize.width, 20.0); 74 | } 75 | self.titleLabel.frame = CGRectMake(76, 0, titleSize.width, height); 76 | self.countLabel.frame = CGRectMake(titleSize.width + 78, 0, countSize.width, height); 77 | } 78 | 79 | - (void)dealloc 80 | { 81 | [_iconView release]; 82 | [_titleLabel release]; 83 | [_countLabel release]; 84 | 85 | [super dealloc]; 86 | } 87 | 88 | @end 89 | -------------------------------------------------------------------------------- /QBImagePickerControllerDemo/QBImagePickerControllerDemo/QBImagePickerController/QBImagePickerVideoInfoView.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2013 Katsuma Tanaka 3 | 4 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 5 | 6 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 7 | 8 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 9 | */ 10 | 11 | #import 12 | 13 | @interface QBImagePickerVideoInfoView : UIView 14 | 15 | @property (nonatomic, assign) CGFloat duration; 16 | 17 | @end 18 | -------------------------------------------------------------------------------- /QBImagePickerControllerDemo/QBImagePickerControllerDemo/QBImagePickerController/QBImagePickerVideoInfoView.m: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2013 Katsuma Tanaka 3 | 4 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 5 | 6 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 7 | 8 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 9 | */ 10 | 11 | #import "QBImagePickerVideoInfoView.h" 12 | 13 | @interface QBImagePickerVideoInfoView () 14 | 15 | @property (nonatomic, retain) UILabel *durationLabel; 16 | 17 | @end 18 | 19 | @implementation QBImagePickerVideoInfoView 20 | 21 | - (id)initWithFrame:(CGRect)frame 22 | { 23 | self = [super initWithFrame:frame]; 24 | 25 | if(self) { 26 | self.backgroundColor = [UIColor colorWithWhite:0 alpha:0.65]; 27 | 28 | // Image View 29 | CGRect iconImageViewFrame = CGRectMake(6, (self.bounds.size.height - 8) / 2, 14, 8); 30 | UIImageView *iconImageView = [[UIImageView alloc] initWithFrame:iconImageViewFrame]; 31 | iconImageView.image = [UIImage imageNamed:@"QBImagePickerController.bundle/video.png"]; 32 | iconImageView.autoresizingMask = UIViewAutoresizingFlexibleRightMargin; 33 | 34 | [self addSubview:iconImageView]; 35 | [iconImageView release]; 36 | 37 | // Label 38 | CGRect durationLabelFrame = CGRectMake(iconImageViewFrame.origin.x + iconImageViewFrame.size.width + 6, 0, self.bounds.size.width - (iconImageViewFrame.origin.x + iconImageViewFrame.size.width + 6) - 6, self.bounds.size.height); 39 | UILabel *durationLabel = [[UILabel alloc] initWithFrame:durationLabelFrame]; 40 | durationLabel.backgroundColor = [UIColor clearColor]; 41 | durationLabel.textAlignment = NSTextAlignmentRight; 42 | durationLabel.textColor = [UIColor whiteColor]; 43 | durationLabel.font = [UIFont boldSystemFontOfSize:12]; 44 | durationLabel.autoresizingMask = UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleWidth; 45 | 46 | [self addSubview:durationLabel]; 47 | self.durationLabel = durationLabel; 48 | [durationLabel release]; 49 | } 50 | 51 | return self; 52 | } 53 | 54 | - (void)setDuration:(CGFloat)duration 55 | { 56 | _duration = duration; 57 | 58 | // Set text 59 | if(0 <= self.duration && self.duration < 60 * 60) { 60 | NSInteger min = self.duration / 60.0; 61 | NSInteger sec = self.duration - 60 * min; 62 | 63 | self.durationLabel.text = [NSString stringWithFormat:@"%d:%02d", min, sec]; 64 | } else if(60 * 60 <= self.duration && self.duration < 60 * 60 * 60) { 65 | NSInteger hour = self.duration / (60.0 * 60.0); 66 | NSInteger min = (self.duration - (60.0 * 60.0) * hour) / 60.0; 67 | NSInteger sec = self.duration - (60.0 * 60.0) * hour - (60 * min); 68 | 69 | self.durationLabel.text = [NSString stringWithFormat:@"%d:%02d:%02d", hour, min, sec]; 70 | } 71 | } 72 | 73 | - (void)dealloc 74 | { 75 | [_durationLabel release]; 76 | 77 | [super dealloc]; 78 | } 79 | 80 | @end 81 | -------------------------------------------------------------------------------- /QBImagePickerControllerDemo/QBImagePickerControllerDemo/QBImagePickerControllerDemo-Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleDisplayName 8 | ${PRODUCT_NAME} 9 | CFBundleExecutable 10 | ${EXECUTABLE_NAME} 11 | CFBundleIdentifier 12 | $(PRODUCT_BUNDLE_IDENTIFIER) 13 | CFBundleInfoDictionaryVersion 14 | 6.0 15 | CFBundleName 16 | ${PRODUCT_NAME} 17 | CFBundlePackageType 18 | APPL 19 | CFBundleShortVersionString 20 | 1.0 21 | CFBundleSignature 22 | ???? 23 | CFBundleVersion 24 | 1.0 25 | LSRequiresIPhoneOS 26 | 27 | UIRequiredDeviceCapabilities 28 | 29 | armv7 30 | 31 | UIStatusBarHidden 32 | 33 | UISupportedInterfaceOrientations 34 | 35 | UIInterfaceOrientationPortrait 36 | UIInterfaceOrientationLandscapeLeft 37 | UIInterfaceOrientationLandscapeRight 38 | 39 | UIViewControllerBasedStatusBarAppearance 40 | 41 | NSPhotoLibraryUsageDescription 42 | 访问你的照片 43 | 44 | 45 | -------------------------------------------------------------------------------- /QBImagePickerControllerDemo/QBImagePickerControllerDemo/QBImagePickerControllerDemo-Prefix.pch: -------------------------------------------------------------------------------- 1 | // 2 | // Prefix header 3 | // 4 | // The contents of this file are implicitly included at the beginning of every source file. 5 | // 6 | 7 | #import 8 | 9 | #ifndef __IPHONE_5_0 10 | #warning "This project uses features only available in iOS SDK 5.0 and later." 11 | #endif 12 | 13 | #ifdef __OBJC__ 14 | #import 15 | #import 16 | #endif 17 | -------------------------------------------------------------------------------- /QBImagePickerControllerDemo/QBImagePickerControllerDemo/ViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.h 3 | // QBImagePickerControllerDemo 4 | // 5 | // Created by Cao JianRong on 14-8-25. 6 | // Copyright (c) 2014年 Cao JianRong. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "QBImagePickerController.h" 11 | 12 | @interface ViewController : UIViewController 13 | { 14 | 15 | } 16 | @end 17 | -------------------------------------------------------------------------------- /QBImagePickerControllerDemo/QBImagePickerControllerDemo/ViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.m 3 | // QBImagePickerControllerDemo 4 | // 5 | // Created by Cao JianRong on 14-8-25. 6 | // Copyright (c) 2014年 Cao JianRong. All rights reserved. 7 | // 8 | 9 | #import "ViewController.h" 10 | 11 | 12 | @interface ViewController () 13 | 14 | @end 15 | 16 | @implementation ViewController 17 | 18 | - (void)viewDidLoad 19 | { 20 | [super viewDidLoad]; 21 | // Do any additional setup after loading the view, typically from a nib. 22 | self.view.backgroundColor = [UIColor whiteColor]; 23 | 24 | 25 | UIImageView *img = [[UIImageView alloc] initWithFrame:CGRectMake(20, 60, 280, 100)]; 26 | [img setBackgroundColor:[UIColor brownColor]]; 27 | NSString *path = [[NSBundle mainBundle] pathForResource:@"Default@2x" ofType:@"png"]; 28 | [img setImage:[UIImage imageWithContentsOfFile:path]]; 29 | [self.view addSubview:img]; 30 | [img release]; 31 | } 32 | 33 | /** 34 | * 多选照片的代理方法。在这里进行选择,上传等一系列操作 35 | */ 36 | #pragma mark - QBImagePickerControllerDelegate 37 | 38 | - (void)imagePickerController:(QBImagePickerController *)imagePickerController didFinishPickingMediaWithInfo:(id)info 39 | { 40 | 41 | if(imagePickerController.allowsMultipleSelection) { 42 | NSArray *mediaInfoArray = (NSArray *)info; 43 | [self dismissViewControllerAnimated:YES completion:^{ 44 | 45 | }]; 46 | NSLog(@"Selected %d photos and mediaInfoArray==%@", mediaInfoArray.count,mediaInfoArray); 47 | } else { 48 | NSDictionary *mediaInfo = (NSDictionary *)info; 49 | NSLog(@"Selected: %@", mediaInfo); 50 | 51 | UIImageView *img = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, [UIScreen mainScreen].bounds.size.width, [UIScreen mainScreen].bounds.size.height - 20)]; 52 | img.clipsToBounds = YES; 53 | img.contentMode = UIViewContentModeScaleAspectFill; 54 | [img setImage:[mediaInfo objectForKey:@"UIImagePickerControllerOriginalImage"]]; 55 | [self.view addSubview:img]; 56 | [img release]; 57 | 58 | [self dismissViewControllerAnimated:YES completion:^{ 59 | 60 | }]; 61 | } 62 | } 63 | 64 | - (void)imagePickerControllerDidCancel:(QBImagePickerController *)imagePickerController 65 | { 66 | NSLog(@"取消选择"); 67 | 68 | [self dismissViewControllerAnimated:YES completion:NULL]; 69 | } 70 | 71 | - (NSString *)descriptionForSelectingAllAssets:(QBImagePickerController *)imagePickerController 72 | { 73 | return @""; 74 | } 75 | 76 | - (NSString *)descriptionForDeselectingAllAssets:(QBImagePickerController *)imagePickerController 77 | { 78 | return @""; 79 | } 80 | 81 | - (NSString *)imagePickerController:(QBImagePickerController *)imagePickerController descriptionForNumberOfPhotos:(NSUInteger)numberOfPhotos 82 | { 83 | return [NSString stringWithFormat:@"图片%d张", numberOfPhotos]; 84 | } 85 | 86 | - (NSString *)imagePickerController:(QBImagePickerController *)imagePickerController descriptionForNumberOfVideos:(NSUInteger)numberOfVideos 87 | { 88 | return [NSString stringWithFormat:@"视频%d", numberOfVideos]; 89 | } 90 | 91 | - (NSString *)imagePickerController:(QBImagePickerController *)imagePickerController descriptionForNumberOfPhotos:(NSUInteger)numberOfPhotos numberOfVideos:(NSUInteger)numberOfVideos 92 | { 93 | return [NSString stringWithFormat:@"图片%d 视频%d", numberOfPhotos, numberOfVideos]; 94 | } 95 | 96 | - (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event 97 | { 98 | QBImagePickerController *imagePickerController = [[QBImagePickerController alloc] init]; 99 | imagePickerController.delegate = self; 100 | 101 | imagePickerController.allowsMultipleSelection = NO; 102 | imagePickerController.allowsEdit = YES; 103 | 104 | UINavigationController *navi = [[UINavigationController alloc] initWithRootViewController:imagePickerController]; 105 | //Navigation Title Color and FontStyle 106 | NSDictionary *dict = [NSDictionary dictionaryWithObjectsAndKeys:[UIFont fontWithName:@"STHeitiK-Medium" size:20],NSFontAttributeName,[UIColor whiteColor],NSForegroundColorAttributeName,nil]; 107 | navi.navigationBar.titleTextAttributes = dict; 108 | //origination from (0,20,width,height) not (0,0,width,height) 109 | navi.navigationBar.translucent = NO; 110 | //navigation background Color 111 | navi.navigationBar.barTintColor = [UIColor colorWithRed:151/255.0 green:217/255.0 blue:204/255.0 alpha:0.5]; 112 | //navigation letf or right nafigationItem Color 113 | navi.navigationBar.tintColor = [UIColor whiteColor]; 114 | [self presentViewController:navi animated:YES completion:NULL]; 115 | [imagePickerController release]; 116 | [navi release]; 117 | return ; 118 | 119 | ViewController *vController = [[ViewController alloc] init]; 120 | vController.title = @"详情"; 121 | [self.navigationController pushViewController:vController animated:YES]; 122 | [vController release]; 123 | } 124 | 125 | - (void)didReceiveMemoryWarning 126 | { 127 | [super didReceiveMemoryWarning]; 128 | // Dispose of any resources that can be recreated. 129 | } 130 | 131 | @end 132 | -------------------------------------------------------------------------------- /QBImagePickerControllerDemo/QBImagePickerControllerDemo/en.lproj/InfoPlist.strings: -------------------------------------------------------------------------------- 1 | /* Localized versions of Info.plist keys */ 2 | 3 | -------------------------------------------------------------------------------- /QBImagePickerControllerDemo/QBImagePickerControllerDemo/main.m: -------------------------------------------------------------------------------- 1 | // 2 | // main.m 3 | // QBImagePickerControllerDemo 4 | // 5 | // Created by Cao JianRong on 14-8-25. 6 | // Copyright (c) 2014年 Cao JianRong. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | #import "AppDelegate.h" 12 | 13 | int main(int argc, char * argv[]) 14 | { 15 | @autoreleasepool { 16 | return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /QBImagePickerControllerDemo/QBImagePickerControllerDemoTests/QBImagePickerControllerDemoTests-Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | ${EXECUTABLE_NAME} 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundlePackageType 14 | BNDL 15 | CFBundleShortVersionString 16 | 1.0 17 | CFBundleSignature 18 | ???? 19 | CFBundleVersion 20 | 1 21 | 22 | 23 | -------------------------------------------------------------------------------- /QBImagePickerControllerDemo/QBImagePickerControllerDemoTests/QBImagePickerControllerDemoTests.m: -------------------------------------------------------------------------------- 1 | // 2 | // QBImagePickerControllerDemoTests.m 3 | // QBImagePickerControllerDemoTests 4 | // 5 | // Created by Cao JianRong on 14-8-25. 6 | // Copyright (c) 2014年 Cao JianRong. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface QBImagePickerControllerDemoTests : XCTestCase 12 | 13 | @end 14 | 15 | @implementation QBImagePickerControllerDemoTests 16 | 17 | - (void)setUp 18 | { 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 | { 25 | // Put teardown code here. This method is called after the invocation of each test method in the class. 26 | [super tearDown]; 27 | } 28 | 29 | - (void)testExample 30 | { 31 | XCTFail(@"No implementation for \"%s\"", __PRETTY_FUNCTION__); 32 | } 33 | 34 | @end 35 | -------------------------------------------------------------------------------- /QBImagePickerControllerDemo/QBImagePickerControllerDemoTests/en.lproj/InfoPlist.strings: -------------------------------------------------------------------------------- 1 | /* Localized versions of Info.plist keys */ 2 | 3 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | QBImagePickerController 2 | ======================= 3 | 4 | UIImagePickerView can accpet memory warning. So take the place of UIImagePickerViewController 5 | --------------------------------------------------------------------------------