├── .DS_Store
├── ZYQAssetPickerController
├── .DS_Store
├── ZYQAssetPicker.Bundle
│ └── Images
│ │ ├── AssetsPickerChecked@2x.png
│ │ ├── AssetsPickerLocked@2x.png
│ │ ├── AssetsPickerVideo@2x.png
│ │ └── AssetsPickerChecked~iOS6@2x.png
├── ZYQAssetPickerController.h
└── ZYQAssetPickerController.m
├── ZYQAssetPickerControllerDemo
├── ZYQAssetPickerControllerDemo
│ ├── en.lproj
│ │ └── InfoPlist.strings
│ ├── zh-Hans.lproj
│ │ └── InfoPlist.strings
│ ├── Images.xcassets
│ │ ├── LaunchImage.launchimage
│ │ │ ├── Default.png
│ │ │ ├── Default-1.png
│ │ │ ├── Default-2.png
│ │ │ ├── Default-3.png
│ │ │ ├── Default-4.png
│ │ │ ├── Default-5.png
│ │ │ ├── Default-6.png
│ │ │ └── Contents.json
│ │ └── AppIcon.appiconset
│ │ │ └── Contents.json
│ ├── MainViewController.h
│ ├── AppDelegate.h
│ ├── main.m
│ ├── ZYQAssetPickerControllerDemo-Prefix.pch
│ ├── ZYQAssetPickerControllerDemo-Info.plist
│ ├── AppDelegate.m
│ └── MainViewController.m
├── .DS_Store
├── ZYQAssetPickerControllerDemoTests
│ ├── zh-Hans.lproj
│ │ └── InfoPlist.strings
│ ├── ZYQAssetPickerControllerDemoTests-Info.plist
│ ├── ZYQAssetPickerControllerDemoTests.m
│ └── en.lproj
│ │ └── InfoPlist.strings
└── ZYQAssetPickerControllerDemo.xcodeproj
│ ├── xcuserdata
│ ├── apple.xcuserdatad
│ │ ├── xcdebugger
│ │ │ └── Breakpoints_v2.xcbkptlist
│ │ └── xcschemes
│ │ │ ├── xcschememanagement.plist
│ │ │ └── ZYQAssetPickerControllerDemo.xcscheme
│ ├── zhaoyiqi.xcuserdatad
│ │ ├── xcdebugger
│ │ │ └── Breakpoints_v2.xcbkptlist
│ │ └── xcschemes
│ │ │ ├── xcschememanagement.plist
│ │ │ └── ZYQAssetPickerControllerDemo.xcscheme
│ ├── admin.xcuserdatad
│ │ └── xcschemes
│ │ │ ├── xcschememanagement.plist
│ │ │ └── ZYQAssetPickerControllerDemo.xcscheme
│ └── heroims.xcuserdatad
│ │ ├── xcschemes
│ │ ├── xcschememanagement.plist
│ │ └── ZYQAssetPickerControllerDemo.xcscheme
│ │ └── xcdebugger
│ │ └── Breakpoints_v2.xcbkptlist
│ ├── project.xcworkspace
│ ├── contents.xcworkspacedata
│ ├── xcuserdata
│ │ ├── admin.xcuserdatad
│ │ │ └── UserInterfaceState.xcuserstate
│ │ ├── apple.xcuserdatad
│ │ │ └── UserInterfaceState.xcuserstate
│ │ ├── heroims.xcuserdatad
│ │ │ ├── UserInterfaceState.xcuserstate
│ │ │ └── WorkspaceSettings.xcsettings
│ │ └── zhaoyiqi.xcuserdatad
│ │ │ └── UserInterfaceState.xcuserstate
│ └── xcshareddata
│ │ ├── IDEWorkspaceChecks.plist
│ │ └── ZYQAssetPickerControllerDemo.xccheckout
│ └── project.pbxproj
├── .gitignore
├── README.md
└── ZYQAssetPickerController.podspec
/.DS_Store:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/heroims/ZYQAssetPickerController/HEAD/.DS_Store
--------------------------------------------------------------------------------
/ZYQAssetPickerController/.DS_Store:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/heroims/ZYQAssetPickerController/HEAD/ZYQAssetPickerController/.DS_Store
--------------------------------------------------------------------------------
/ZYQAssetPickerControllerDemo/ZYQAssetPickerControllerDemo/en.lproj/InfoPlist.strings:
--------------------------------------------------------------------------------
1 | /* Localized versions of Info.plist keys */
2 |
3 |
--------------------------------------------------------------------------------
/ZYQAssetPickerControllerDemo/ZYQAssetPickerControllerDemo/zh-Hans.lproj/InfoPlist.strings:
--------------------------------------------------------------------------------
1 | /* Localized versions of Info.plist keys */
2 |
3 |
--------------------------------------------------------------------------------
/ZYQAssetPickerControllerDemo/.DS_Store:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/heroims/ZYQAssetPickerController/HEAD/ZYQAssetPickerControllerDemo/.DS_Store
--------------------------------------------------------------------------------
/ZYQAssetPickerControllerDemo/ZYQAssetPickerControllerDemoTests/zh-Hans.lproj/InfoPlist.strings:
--------------------------------------------------------------------------------
1 | /* Localized versions of Info.plist keys */
2 |
3 |
--------------------------------------------------------------------------------
/ZYQAssetPickerController/ZYQAssetPicker.Bundle/Images/AssetsPickerChecked@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/heroims/ZYQAssetPickerController/HEAD/ZYQAssetPickerController/ZYQAssetPicker.Bundle/Images/AssetsPickerChecked@2x.png
--------------------------------------------------------------------------------
/ZYQAssetPickerController/ZYQAssetPicker.Bundle/Images/AssetsPickerLocked@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/heroims/ZYQAssetPickerController/HEAD/ZYQAssetPickerController/ZYQAssetPicker.Bundle/Images/AssetsPickerLocked@2x.png
--------------------------------------------------------------------------------
/ZYQAssetPickerController/ZYQAssetPicker.Bundle/Images/AssetsPickerVideo@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/heroims/ZYQAssetPickerController/HEAD/ZYQAssetPickerController/ZYQAssetPicker.Bundle/Images/AssetsPickerVideo@2x.png
--------------------------------------------------------------------------------
/ZYQAssetPickerController/ZYQAssetPicker.Bundle/Images/AssetsPickerChecked~iOS6@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/heroims/ZYQAssetPickerController/HEAD/ZYQAssetPickerController/ZYQAssetPicker.Bundle/Images/AssetsPickerChecked~iOS6@2x.png
--------------------------------------------------------------------------------
/ZYQAssetPickerControllerDemo/ZYQAssetPickerControllerDemo.xcodeproj/xcuserdata/apple.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
--------------------------------------------------------------------------------
/ZYQAssetPickerControllerDemo/ZYQAssetPickerControllerDemo.xcodeproj/xcuserdata/zhaoyiqi.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
--------------------------------------------------------------------------------
/ZYQAssetPickerControllerDemo/ZYQAssetPickerControllerDemo/Images.xcassets/LaunchImage.launchimage/Default.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/heroims/ZYQAssetPickerController/HEAD/ZYQAssetPickerControllerDemo/ZYQAssetPickerControllerDemo/Images.xcassets/LaunchImage.launchimage/Default.png
--------------------------------------------------------------------------------
/ZYQAssetPickerControllerDemo/ZYQAssetPickerControllerDemo/Images.xcassets/LaunchImage.launchimage/Default-1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/heroims/ZYQAssetPickerController/HEAD/ZYQAssetPickerControllerDemo/ZYQAssetPickerControllerDemo/Images.xcassets/LaunchImage.launchimage/Default-1.png
--------------------------------------------------------------------------------
/ZYQAssetPickerControllerDemo/ZYQAssetPickerControllerDemo/Images.xcassets/LaunchImage.launchimage/Default-2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/heroims/ZYQAssetPickerController/HEAD/ZYQAssetPickerControllerDemo/ZYQAssetPickerControllerDemo/Images.xcassets/LaunchImage.launchimage/Default-2.png
--------------------------------------------------------------------------------
/ZYQAssetPickerControllerDemo/ZYQAssetPickerControllerDemo/Images.xcassets/LaunchImage.launchimage/Default-3.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/heroims/ZYQAssetPickerController/HEAD/ZYQAssetPickerControllerDemo/ZYQAssetPickerControllerDemo/Images.xcassets/LaunchImage.launchimage/Default-3.png
--------------------------------------------------------------------------------
/ZYQAssetPickerControllerDemo/ZYQAssetPickerControllerDemo/Images.xcassets/LaunchImage.launchimage/Default-4.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/heroims/ZYQAssetPickerController/HEAD/ZYQAssetPickerControllerDemo/ZYQAssetPickerControllerDemo/Images.xcassets/LaunchImage.launchimage/Default-4.png
--------------------------------------------------------------------------------
/ZYQAssetPickerControllerDemo/ZYQAssetPickerControllerDemo/Images.xcassets/LaunchImage.launchimage/Default-5.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/heroims/ZYQAssetPickerController/HEAD/ZYQAssetPickerControllerDemo/ZYQAssetPickerControllerDemo/Images.xcassets/LaunchImage.launchimage/Default-5.png
--------------------------------------------------------------------------------
/ZYQAssetPickerControllerDemo/ZYQAssetPickerControllerDemo/Images.xcassets/LaunchImage.launchimage/Default-6.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/heroims/ZYQAssetPickerController/HEAD/ZYQAssetPickerControllerDemo/ZYQAssetPickerControllerDemo/Images.xcassets/LaunchImage.launchimage/Default-6.png
--------------------------------------------------------------------------------
/ZYQAssetPickerControllerDemo/ZYQAssetPickerControllerDemo.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/ZYQAssetPickerControllerDemo/ZYQAssetPickerControllerDemo.xcodeproj/project.xcworkspace/xcuserdata/admin.xcuserdatad/UserInterfaceState.xcuserstate:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/heroims/ZYQAssetPickerController/HEAD/ZYQAssetPickerControllerDemo/ZYQAssetPickerControllerDemo.xcodeproj/project.xcworkspace/xcuserdata/admin.xcuserdatad/UserInterfaceState.xcuserstate
--------------------------------------------------------------------------------
/ZYQAssetPickerControllerDemo/ZYQAssetPickerControllerDemo.xcodeproj/project.xcworkspace/xcuserdata/apple.xcuserdatad/UserInterfaceState.xcuserstate:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/heroims/ZYQAssetPickerController/HEAD/ZYQAssetPickerControllerDemo/ZYQAssetPickerControllerDemo.xcodeproj/project.xcworkspace/xcuserdata/apple.xcuserdatad/UserInterfaceState.xcuserstate
--------------------------------------------------------------------------------
/ZYQAssetPickerControllerDemo/ZYQAssetPickerControllerDemo.xcodeproj/project.xcworkspace/xcuserdata/heroims.xcuserdatad/UserInterfaceState.xcuserstate:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/heroims/ZYQAssetPickerController/HEAD/ZYQAssetPickerControllerDemo/ZYQAssetPickerControllerDemo.xcodeproj/project.xcworkspace/xcuserdata/heroims.xcuserdatad/UserInterfaceState.xcuserstate
--------------------------------------------------------------------------------
/ZYQAssetPickerControllerDemo/ZYQAssetPickerControllerDemo.xcodeproj/project.xcworkspace/xcuserdata/zhaoyiqi.xcuserdatad/UserInterfaceState.xcuserstate:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/heroims/ZYQAssetPickerController/HEAD/ZYQAssetPickerControllerDemo/ZYQAssetPickerControllerDemo.xcodeproj/project.xcworkspace/xcuserdata/zhaoyiqi.xcuserdatad/UserInterfaceState.xcuserstate
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Mac OS X Finder
2 | .DS_Store
3 |
4 | # Xcode per-user config
5 | *.mode1
6 | *.mode1v3
7 | *.mode2v3
8 | *.perspective
9 | *.perspectivev3
10 | *.pbxuser
11 | xcuserdata
12 | *.xccheckout
13 |
14 | # Build products
15 | build/
16 | *.o
17 | *.LinkFileList
18 | *.hmap
19 |
20 | # Automatic backup files
21 | *~.nib/
22 | *.swp
23 | *~
24 | *.dat
25 | *.dep
26 |
--------------------------------------------------------------------------------
/ZYQAssetPickerControllerDemo/ZYQAssetPickerControllerDemo/MainViewController.h:
--------------------------------------------------------------------------------
1 | //
2 | // MainViewController.h
3 | // ZYQAssetPickerControllerDemo
4 | //
5 | // Created by Zhao Yiqi on 13-12-26.
6 | // Copyright (c) 2013年 heroims. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @interface MainViewController : UIViewController
12 |
13 | @end
14 |
--------------------------------------------------------------------------------
/ZYQAssetPickerControllerDemo/ZYQAssetPickerControllerDemo.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | IDEDidComputeMac32BitWarning
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/ZYQAssetPickerControllerDemo/ZYQAssetPickerControllerDemo/AppDelegate.h:
--------------------------------------------------------------------------------
1 | //
2 | // AppDelegate.h
3 | // ZYQAssetPickerControllerDemo
4 | //
5 | // Created by Zhao Yiqi on 13-12-25.
6 | // Copyright (c) 2013年 heroims. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | #import "MainViewController.h"
12 |
13 | @interface AppDelegate : UIResponder
14 |
15 | @property (strong, nonatomic) UIWindow *window;
16 |
17 | @end
18 |
--------------------------------------------------------------------------------
/ZYQAssetPickerControllerDemo/ZYQAssetPickerControllerDemo/main.m:
--------------------------------------------------------------------------------
1 | //
2 | // main.m
3 | // ZYQAssetPickerControllerDemo
4 | //
5 | // Created by Zhao Yiqi on 13-12-25.
6 | // Copyright (c) 2013年 heroims. 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 |
--------------------------------------------------------------------------------
/ZYQAssetPickerControllerDemo/ZYQAssetPickerControllerDemo/ZYQAssetPickerControllerDemo-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_3_0
10 | #warning "This project uses features only available in iOS SDK 3.0 and later."
11 | #endif
12 |
13 | #ifdef __OBJC__
14 | #import
15 | #import
16 | #endif
17 |
--------------------------------------------------------------------------------
/ZYQAssetPickerControllerDemo/ZYQAssetPickerControllerDemo.xcodeproj/project.xcworkspace/xcuserdata/heroims.xcuserdatad/WorkspaceSettings.xcsettings:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | HasAskedToTakeAutomaticSnapshotBeforeSignificantChanges
6 |
7 | SnapshotAutomaticallyBeforeSignificantChanges
8 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | ZYQAssetPickerController
2 | ========================
3 | [](http://i.imgur.com/Yv6RIjd.gif?1)
4 | ## Minimum Requirement
5 | iOS 6.0
6 |
7 | ## Installation
8 |
9 | ### via CocoaPods
10 | Install CocoaPods if you do not have it:-
11 | ````
12 | $ [sudo] gem install cocoapods
13 | $ pod setup
14 | ````
15 | Create Podfile:-
16 | ````
17 | $ edit Podfile
18 | platform :ios, '5.0'
19 | pod 'ZYQAssetPickerController', '~> 1.2.0'
20 | $ pod install
21 | ````
22 | Use the Xcode workspace instead of the project from now on.
23 |
--------------------------------------------------------------------------------
/ZYQAssetPickerControllerDemo/ZYQAssetPickerControllerDemo.xcodeproj/xcuserdata/admin.xcuserdatad/xcschemes/xcschememanagement.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | SchemeUserState
6 |
7 | ZYQAssetPickerControllerDemo.xcscheme
8 |
9 | orderHint
10 | 0
11 |
12 |
13 | SuppressBuildableAutocreation
14 |
15 | D8E6C4C4186B21AC0057C549
16 |
17 | primary
18 |
19 |
20 | D8E6C4DF186B21AD0057C549
21 |
22 | primary
23 |
24 |
25 |
26 |
27 |
28 |
--------------------------------------------------------------------------------
/ZYQAssetPickerControllerDemo/ZYQAssetPickerControllerDemo.xcodeproj/xcuserdata/apple.xcuserdatad/xcschemes/xcschememanagement.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | SchemeUserState
6 |
7 | ZYQAssetPickerControllerDemo.xcscheme
8 |
9 | orderHint
10 | 0
11 |
12 |
13 | SuppressBuildableAutocreation
14 |
15 | D8E6C4C4186B21AC0057C549
16 |
17 | primary
18 |
19 |
20 | D8E6C4DF186B21AD0057C549
21 |
22 | primary
23 |
24 |
25 |
26 |
27 |
28 |
--------------------------------------------------------------------------------
/ZYQAssetPickerControllerDemo/ZYQAssetPickerControllerDemo.xcodeproj/xcuserdata/heroims.xcuserdatad/xcschemes/xcschememanagement.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | SchemeUserState
6 |
7 | ZYQAssetPickerControllerDemo.xcscheme
8 |
9 | orderHint
10 | 0
11 |
12 |
13 | SuppressBuildableAutocreation
14 |
15 | D8E6C4C4186B21AC0057C549
16 |
17 | primary
18 |
19 |
20 | D8E6C4DF186B21AD0057C549
21 |
22 | primary
23 |
24 |
25 |
26 |
27 |
28 |
--------------------------------------------------------------------------------
/ZYQAssetPickerControllerDemo/ZYQAssetPickerControllerDemo.xcodeproj/xcuserdata/zhaoyiqi.xcuserdatad/xcschemes/xcschememanagement.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | SchemeUserState
6 |
7 | ZYQAssetPickerControllerDemo.xcscheme
8 |
9 | orderHint
10 | 0
11 |
12 |
13 | SuppressBuildableAutocreation
14 |
15 | D8E6C4C4186B21AC0057C549
16 |
17 | primary
18 |
19 |
20 | D8E6C4DF186B21AD0057C549
21 |
22 | primary
23 |
24 |
25 |
26 |
27 |
28 |
--------------------------------------------------------------------------------
/ZYQAssetPickerControllerDemo/ZYQAssetPickerControllerDemoTests/ZYQAssetPickerControllerDemoTests-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 |
--------------------------------------------------------------------------------
/ZYQAssetPickerController.podspec:
--------------------------------------------------------------------------------
1 | Pod::Spec.new do |s|
2 | s.name = 'ZYQAssetPickerController'
3 | s.version = '1.3.1'
4 | s.summary = 'A clone of the UIImagePickerController using the Assets Library Framework allowing for multiple asset selection'
5 | s.homepage = 'https://github.com/heroims/ZYQAssetPickerController'
6 | s.license = { :type => 'MIT', :file => 'README.md' }
7 | s.author = { 'heroims' => 'heroims@163.com' }
8 | s.source = { :git => 'https://github.com/heroims/ZYQAssetPickerController.git', :tag => "#{s.version}" }
9 | s.platform = :ios, '5.0'
10 | s.source_files = 'ZYQAssetPickerController/*.{h,m}'
11 | s.resources = 'ZYQAssetPickerController/*.Bundle'
12 | s.frameworks = ['AssetsLibrary']
13 | s.requires_arc = true
14 | end
15 |
--------------------------------------------------------------------------------
/ZYQAssetPickerControllerDemo/ZYQAssetPickerControllerDemoTests/ZYQAssetPickerControllerDemoTests.m:
--------------------------------------------------------------------------------
1 | //
2 | // ZYQAssetPickerControllerDemoTests.m
3 | // ZYQAssetPickerControllerDemoTests
4 | //
5 | // Created by Zhao Yiqi on 13-12-25.
6 | // Copyright (c) 2013年 heroims. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @interface ZYQAssetPickerControllerDemoTests : XCTestCase
12 |
13 | @end
14 |
15 | @implementation ZYQAssetPickerControllerDemoTests
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 |
--------------------------------------------------------------------------------
/ZYQAssetPickerControllerDemo/ZYQAssetPickerControllerDemoTests/en.lproj/InfoPlist.strings:
--------------------------------------------------------------------------------
1 | /* Localized versions of Info.plist keys */
2 | /* Navigation bar buttons */
3 | "取消" = "Cancel";
4 | "完成" = "Done";
5 |
6 | /* Title */
7 | "相簿" = "Photos";
8 |
9 | /* No. of selected */
10 | "已选择 %ld 张照片 " = "%ld Photo Selected";
11 | "已选择 %ld 张照片" = "%ld Photos Selected";
12 | "已选择 %ld 部视频 " = "%ld Video Selected";
13 | "已选择 %ld 部视频" = "%ld Videos Selected";
14 | "已选择 %ld 个项目" = "%ld Items Selected";
15 |
16 | /* Library Footer */
17 | "%ld 张照片" = "%ld Photos";
18 | "%ld 部视频" = "%ld Videos";
19 | "%ld 张照片, %ld 部视频" = "%ld Photos, %ld Videos";
20 |
21 | /* Message if privacy is not granted */
22 | "此应用无法使用您的照片或视频。" = "This app does not have access to your photos or videos.";
23 | "你可以在「隐私设置」中启用存取。" = "You can enable access in Privacy Settings.";
24 |
25 | /* Message if no assets */
26 | "没有照片或视频。" = "No Photos or Videos";
27 | "您可以使用 iTunes 将照片和视频\n同步到 iPhone。" = "You can sync photos and videos onto your iPhone using iTunes.";
--------------------------------------------------------------------------------
/ZYQAssetPickerControllerDemo/ZYQAssetPickerControllerDemo.xcodeproj/xcuserdata/heroims.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
8 |
14 |
15 |
16 |
18 |
30 |
31 |
32 |
33 |
34 |
--------------------------------------------------------------------------------
/ZYQAssetPickerControllerDemo/ZYQAssetPickerControllerDemo.xcodeproj/project.xcworkspace/xcshareddata/ZYQAssetPickerControllerDemo.xccheckout:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | IDESourceControlProjectFavoriteDictionaryKey
6 |
7 | IDESourceControlProjectIdentifier
8 | 89D42853-7356-475E-97E3-1E2B853226CD
9 | IDESourceControlProjectName
10 | ZYQAssetPickerControllerDemo
11 | IDESourceControlProjectOriginsDictionary
12 |
13 | 8A606363-E623-47A1-8E96-45EDC0DCD34E
14 | https://github.com/heroims/ZYQAssetPickerController.git
15 |
16 | IDESourceControlProjectPath
17 | ZYQAssetPickerControllerDemo/ZYQAssetPickerControllerDemo.xcodeproj/project.xcworkspace
18 | IDESourceControlProjectRelativeInstallPathDictionary
19 |
20 | 8A606363-E623-47A1-8E96-45EDC0DCD34E
21 | ../../..
22 |
23 | IDESourceControlProjectURL
24 | https://github.com/heroims/ZYQAssetPickerController.git
25 | IDESourceControlProjectVersion
26 | 110
27 | IDESourceControlProjectWCCIdentifier
28 | 8A606363-E623-47A1-8E96-45EDC0DCD34E
29 | IDESourceControlProjectWCConfigurations
30 |
31 |
32 | IDESourceControlRepositoryExtensionIdentifierKey
33 | public.vcs.git
34 | IDESourceControlWCCIdentifierKey
35 | 8A606363-E623-47A1-8E96-45EDC0DCD34E
36 | IDESourceControlWCCName
37 | ZYQAssetPickerController
38 |
39 |
40 |
41 |
42 |
--------------------------------------------------------------------------------
/ZYQAssetPickerControllerDemo/ZYQAssetPickerControllerDemo/ZYQAssetPickerControllerDemo-Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | en
7 | CFBundleDisplayName
8 | ${PRODUCT_NAME}
9 | CFBundleExecutable
10 | ${EXECUTABLE_NAME}
11 | CFBundleIcons
12 |
13 | CFBundleIcons~ipad
14 |
15 | CFBundleIdentifier
16 | $(PRODUCT_BUNDLE_IDENTIFIER)
17 | CFBundleInfoDictionaryVersion
18 | 6.0
19 | CFBundleName
20 | ${PRODUCT_NAME}
21 | CFBundlePackageType
22 | APPL
23 | CFBundleShortVersionString
24 | 1.0
25 | CFBundleSignature
26 | ????
27 | CFBundleVersion
28 | 1.0
29 | LSRequiresIPhoneOS
30 |
31 | NSPhotoLibraryAddUsageDescription
32 |
33 | NSPhotoLibraryUsageDescription
34 |
35 | UIRequiredDeviceCapabilities
36 |
37 | armv7
38 |
39 | UISupportedInterfaceOrientations
40 |
41 | UIInterfaceOrientationPortrait
42 | UIInterfaceOrientationLandscapeLeft
43 | UIInterfaceOrientationLandscapeRight
44 |
45 | UISupportedInterfaceOrientations~ipad
46 |
47 | UIInterfaceOrientationPortrait
48 | UIInterfaceOrientationPortraitUpsideDown
49 | UIInterfaceOrientationLandscapeLeft
50 | UIInterfaceOrientationLandscapeRight
51 |
52 |
53 |
54 |
--------------------------------------------------------------------------------
/ZYQAssetPickerControllerDemo/ZYQAssetPickerControllerDemo/Images.xcassets/AppIcon.appiconset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "iphone",
5 | "size" : "20x20",
6 | "scale" : "2x"
7 | },
8 | {
9 | "idiom" : "iphone",
10 | "size" : "20x20",
11 | "scale" : "3x"
12 | },
13 | {
14 | "idiom" : "iphone",
15 | "size" : "29x29",
16 | "scale" : "2x"
17 | },
18 | {
19 | "idiom" : "iphone",
20 | "size" : "29x29",
21 | "scale" : "3x"
22 | },
23 | {
24 | "idiom" : "iphone",
25 | "size" : "40x40",
26 | "scale" : "2x"
27 | },
28 | {
29 | "idiom" : "iphone",
30 | "size" : "40x40",
31 | "scale" : "3x"
32 | },
33 | {
34 | "idiom" : "iphone",
35 | "size" : "60x60",
36 | "scale" : "2x"
37 | },
38 | {
39 | "idiom" : "iphone",
40 | "size" : "60x60",
41 | "scale" : "3x"
42 | },
43 | {
44 | "idiom" : "ipad",
45 | "size" : "20x20",
46 | "scale" : "1x"
47 | },
48 | {
49 | "idiom" : "ipad",
50 | "size" : "20x20",
51 | "scale" : "2x"
52 | },
53 | {
54 | "idiom" : "ipad",
55 | "size" : "29x29",
56 | "scale" : "1x"
57 | },
58 | {
59 | "idiom" : "ipad",
60 | "size" : "29x29",
61 | "scale" : "2x"
62 | },
63 | {
64 | "idiom" : "ipad",
65 | "size" : "40x40",
66 | "scale" : "1x"
67 | },
68 | {
69 | "idiom" : "ipad",
70 | "size" : "40x40",
71 | "scale" : "2x"
72 | },
73 | {
74 | "idiom" : "ipad",
75 | "size" : "76x76",
76 | "scale" : "1x"
77 | },
78 | {
79 | "idiom" : "ipad",
80 | "size" : "76x76",
81 | "scale" : "2x"
82 | },
83 | {
84 | "idiom" : "ipad",
85 | "size" : "83.5x83.5",
86 | "scale" : "2x"
87 | },
88 | {
89 | "idiom" : "ios-marketing",
90 | "size" : "1024x1024",
91 | "scale" : "1x"
92 | }
93 | ],
94 | "info" : {
95 | "version" : 1,
96 | "author" : "xcode"
97 | }
98 | }
--------------------------------------------------------------------------------
/ZYQAssetPickerControllerDemo/ZYQAssetPickerControllerDemo/AppDelegate.m:
--------------------------------------------------------------------------------
1 | //
2 | // AppDelegate.m
3 | // ZYQAssetPickerControllerDemo
4 | //
5 | // Created by Zhao Yiqi on 13-12-25.
6 | // Copyright (c) 2013年 heroims. All rights reserved.
7 | //
8 |
9 | #import "AppDelegate.h"
10 |
11 | @implementation AppDelegate
12 |
13 | - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
14 | {
15 | self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
16 | // Override point for customization after application launch.
17 | self.window.backgroundColor = [UIColor whiteColor];
18 | self.window.rootViewController=[[MainViewController alloc] init];
19 | [self.window makeKeyAndVisible];
20 | return YES;
21 | }
22 |
23 | - (void)applicationWillResignActive:(UIApplication *)application
24 | {
25 | // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
26 | // Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game.
27 | }
28 |
29 | - (void)applicationDidEnterBackground:(UIApplication *)application
30 | {
31 | // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.
32 | // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
33 | }
34 |
35 | - (void)applicationWillEnterForeground:(UIApplication *)application
36 | {
37 | // 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.
38 | }
39 |
40 | - (void)applicationDidBecomeActive:(UIApplication *)application
41 | {
42 | // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
43 | }
44 |
45 | - (void)applicationWillTerminate:(UIApplication *)application
46 | {
47 | // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
48 | }
49 |
50 | @end
51 |
--------------------------------------------------------------------------------
/ZYQAssetPickerControllerDemo/ZYQAssetPickerControllerDemo.xcodeproj/xcuserdata/apple.xcuserdatad/xcschemes/ZYQAssetPickerControllerDemo.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 |
--------------------------------------------------------------------------------
/ZYQAssetPickerControllerDemo/ZYQAssetPickerControllerDemo/Images.xcassets/LaunchImage.launchimage/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "extent" : "full-screen",
5 | "idiom" : "iphone",
6 | "subtype" : "2436h",
7 | "filename" : "Default-6.png",
8 | "minimum-system-version" : "11.0",
9 | "orientation" : "portrait",
10 | "scale" : "3x"
11 | },
12 | {
13 | "extent" : "full-screen",
14 | "idiom" : "iphone",
15 | "subtype" : "736h",
16 | "filename" : "Default.png",
17 | "minimum-system-version" : "8.0",
18 | "orientation" : "portrait",
19 | "scale" : "3x"
20 | },
21 | {
22 | "orientation" : "landscape",
23 | "idiom" : "iphone",
24 | "extent" : "full-screen",
25 | "minimum-system-version" : "8.0",
26 | "subtype" : "736h",
27 | "scale" : "3x"
28 | },
29 | {
30 | "extent" : "full-screen",
31 | "idiom" : "iphone",
32 | "subtype" : "667h",
33 | "filename" : "Default-1.png",
34 | "minimum-system-version" : "8.0",
35 | "orientation" : "portrait",
36 | "scale" : "2x"
37 | },
38 | {
39 | "orientation" : "portrait",
40 | "idiom" : "iphone",
41 | "filename" : "Default-3.png",
42 | "extent" : "full-screen",
43 | "minimum-system-version" : "7.0",
44 | "scale" : "2x"
45 | },
46 | {
47 | "extent" : "full-screen",
48 | "idiom" : "iphone",
49 | "subtype" : "retina4",
50 | "filename" : "Default-2.png",
51 | "minimum-system-version" : "7.0",
52 | "orientation" : "portrait",
53 | "scale" : "2x"
54 | },
55 | {
56 | "orientation" : "portrait",
57 | "idiom" : "ipad",
58 | "extent" : "full-screen",
59 | "minimum-system-version" : "7.0",
60 | "scale" : "1x"
61 | },
62 | {
63 | "orientation" : "landscape",
64 | "idiom" : "ipad",
65 | "extent" : "full-screen",
66 | "minimum-system-version" : "7.0",
67 | "scale" : "1x"
68 | },
69 | {
70 | "orientation" : "portrait",
71 | "idiom" : "ipad",
72 | "extent" : "full-screen",
73 | "minimum-system-version" : "7.0",
74 | "scale" : "2x"
75 | },
76 | {
77 | "orientation" : "landscape",
78 | "idiom" : "ipad",
79 | "extent" : "full-screen",
80 | "minimum-system-version" : "7.0",
81 | "scale" : "2x"
82 | },
83 | {
84 | "orientation" : "portrait",
85 | "idiom" : "iphone",
86 | "extent" : "full-screen",
87 | "scale" : "1x"
88 | },
89 | {
90 | "orientation" : "portrait",
91 | "idiom" : "iphone",
92 | "filename" : "Default-4.png",
93 | "extent" : "full-screen",
94 | "scale" : "2x"
95 | },
96 | {
97 | "orientation" : "portrait",
98 | "idiom" : "iphone",
99 | "filename" : "Default-5.png",
100 | "extent" : "full-screen",
101 | "subtype" : "retina4",
102 | "scale" : "2x"
103 | },
104 | {
105 | "orientation" : "portrait",
106 | "idiom" : "ipad",
107 | "extent" : "to-status-bar",
108 | "scale" : "1x"
109 | },
110 | {
111 | "orientation" : "portrait",
112 | "idiom" : "ipad",
113 | "extent" : "full-screen",
114 | "scale" : "1x"
115 | },
116 | {
117 | "orientation" : "landscape",
118 | "idiom" : "ipad",
119 | "extent" : "to-status-bar",
120 | "scale" : "1x"
121 | },
122 | {
123 | "orientation" : "landscape",
124 | "idiom" : "ipad",
125 | "extent" : "full-screen",
126 | "scale" : "1x"
127 | },
128 | {
129 | "orientation" : "portrait",
130 | "idiom" : "ipad",
131 | "extent" : "to-status-bar",
132 | "scale" : "2x"
133 | },
134 | {
135 | "orientation" : "portrait",
136 | "idiom" : "ipad",
137 | "extent" : "full-screen",
138 | "scale" : "2x"
139 | },
140 | {
141 | "orientation" : "landscape",
142 | "idiom" : "ipad",
143 | "extent" : "to-status-bar",
144 | "scale" : "2x"
145 | },
146 | {
147 | "orientation" : "landscape",
148 | "idiom" : "ipad",
149 | "extent" : "full-screen",
150 | "scale" : "2x"
151 | }
152 | ],
153 | "info" : {
154 | "version" : 1,
155 | "author" : "xcode"
156 | }
157 | }
--------------------------------------------------------------------------------
/ZYQAssetPickerControllerDemo/ZYQAssetPickerControllerDemo.xcodeproj/xcuserdata/admin.xcuserdatad/xcschemes/ZYQAssetPickerControllerDemo.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 |
--------------------------------------------------------------------------------
/ZYQAssetPickerControllerDemo/ZYQAssetPickerControllerDemo.xcodeproj/xcuserdata/heroims.xcuserdatad/xcschemes/ZYQAssetPickerControllerDemo.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 |
--------------------------------------------------------------------------------
/ZYQAssetPickerControllerDemo/ZYQAssetPickerControllerDemo.xcodeproj/xcuserdata/zhaoyiqi.xcuserdatad/xcschemes/ZYQAssetPickerControllerDemo.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 |
--------------------------------------------------------------------------------
/ZYQAssetPickerControllerDemo/ZYQAssetPickerControllerDemo/MainViewController.m:
--------------------------------------------------------------------------------
1 | //
2 | // MainViewController.m
3 | // ZYQAssetPickerControllerDemo
4 | //
5 | // Created by Zhao Yiqi on 13-12-26.
6 | // Copyright (c) 2013年 heroims. All rights reserved.
7 | //
8 |
9 | #import "MainViewController.h"
10 | #import "ZYQAssetPickerController.h"
11 |
12 | @interface MainViewController (){
13 | UIButton *btn;
14 |
15 | UIScrollView *src;
16 |
17 | UIPageControl *pageControl;
18 | }
19 |
20 | @end
21 |
22 | @implementation MainViewController
23 |
24 | - (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
25 | {
26 | self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
27 | if (self) {
28 | // Custom initialization
29 | }
30 | return self;
31 | }
32 |
33 | - (void)viewDidLoad
34 | {
35 | [super viewDidLoad];
36 |
37 |
38 | btn=[[UIButton alloc] init];
39 | btn.frame=CGRectMake(60., self.view.frame.size.height-80, self.view.frame.size.width-120, 60);
40 | [btn setTitle:@"Open" forState:UIControlStateNormal];
41 | [btn setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];
42 | [self.view addSubview:btn];
43 | [btn addTarget:self action:@selector(btnClick:) forControlEvents:UIControlEventTouchUpInside];
44 |
45 |
46 | src=[[UIScrollView alloc] initWithFrame:CGRectMake(20, 20, self.view.frame.size.width-40, self.view.frame.size.height-120)];
47 | src.pagingEnabled=YES;
48 | src.backgroundColor=[UIColor lightGrayColor];
49 | src.delegate=self;
50 | [self.view addSubview:src];
51 |
52 | pageControl=[[UIPageControl alloc] initWithFrame:CGRectMake(src.frame.origin.x, src.frame.origin.y+src.frame.size.height-20, src.frame.size.width, 20)];
53 | [self.view addSubview:pageControl];
54 | // Do any additional setup after loading the view.
55 | }
56 |
57 | -(void)btnClick:(id)sender{
58 |
59 | ZYQAssetPickerController *picker = [[ZYQAssetPickerController alloc] init];
60 |
61 | picker.maximumNumberOfSelection = 5;
62 | picker.assetsFilter = ZYQAssetsFilterAllAssets;
63 | picker.showEmptyGroups=NO;
64 | picker.delegate=self;
65 | picker.timeDescSort = NO;
66 | picker.scrollBottom=YES;
67 | picker.selectionFilter = [NSPredicate predicateWithBlock:^BOOL(id evaluatedObject, NSDictionary *bindings) {
68 |
69 | if ([(ZYQAsset*)evaluatedObject mediaType]==ZYQAssetMediaTypeVideo) {
70 | NSTimeInterval duration = [(ZYQAsset*)evaluatedObject duration];
71 | return duration >= 5;
72 | } else {
73 | return YES;
74 | }
75 |
76 |
77 | }];
78 | picker.modalPresentationStyle=UIModalPresentationFullScreen;
79 | [self presentViewController:picker animated:YES completion:NULL];
80 |
81 | }
82 |
83 | - (void)didReceiveMemoryWarning
84 | {
85 | [super didReceiveMemoryWarning];
86 | // Dispose of any resources that can be recreated.
87 | }
88 |
89 | #pragma mark - ZYQAssetPickerController Delegate
90 | -(void)assetPickerController:(ZYQAssetPickerController *)picker didFinishPickingAssets:(NSArray *)assets{
91 | [src.subviews makeObjectsPerformSelector:@selector(removeFromSuperview)];
92 | src.contentSize=CGSizeMake(assets.count*src.frame.size.width, src.frame.size.height);
93 | pageControl.numberOfPages=assets.count;
94 | for (int i=0; i
10 | #import
11 | #import
12 |
13 | typedef enum ZYQAssetsFilter:NSInteger{
14 | ZYQAssetsFilterAllPhotos=0,
15 | ZYQAssetsFilterAllVideos,
16 | ZYQAssetsFilterAllAssets
17 | }ZYQAssetsFilter;
18 |
19 | #pragma mark - ZYQAssetsGroup
20 | typedef void (^ZYQAssetsGroupEnumerationResultsBlock)(id obj, NSUInteger index, BOOL *stop);
21 |
22 | @interface ZYQAssetsGroup : NSObject
23 |
24 | @property(nonatomic,strong)id originAssetGroup;
25 | @property(nonatomic,strong)id originFetchResult;
26 |
27 | @property(nonatomic,strong)NSString *groupName;
28 | @property(nonatomic,assign,readonly)NSInteger count;
29 | @property(nonatomic,copy)void(^getThumbnail)(UIImage *result);
30 |
31 | - (void)enumerateObjectsUsingBlock:(ZYQAssetsGroupEnumerationResultsBlock)enumerationBlock;
32 |
33 | @end
34 |
35 | #pragma mark - ZYQAsset
36 |
37 | typedef NS_ENUM(NSInteger, ZYQAssetMediaType) {
38 | ZYQAssetMediaTypeUnknown = 0,
39 | ZYQAssetMediaTypeImage = 1,
40 | ZYQAssetMediaTypeVideo = 2,
41 | ZYQAssetMediaTypeAudio = 3,
42 | };
43 |
44 | @interface ZYQAsset : NSObject
45 |
46 | @property(nonatomic,strong)id originAsset;
47 | @property(nonatomic,copy)void(^getThumbnail)(UIImage *result);
48 | @property(nonatomic,copy)void(^getFullScreenImage)(UIImage *result);
49 | @property(nonatomic,copy)void(^getOriginImage)(UIImage *result);
50 | @property(nonatomic,copy)void(^getExportSession)(AVAssetExportSession *result);
51 | @property(nonatomic,assign,readonly)NSTimeInterval duration;
52 | @property(nonatomic,assign,readonly)ZYQAssetMediaType mediaType;
53 | @property(nonatomic,retain,readonly)NSDate *modificationDate;
54 | @property(nonatomic,assign,readonly)CGSize size;
55 |
56 | -(void)setGetThumbnail:(void (^)(UIImage *))getThumbnail fromNetwokProgressHandler:(void (^)(double ,NSError * , BOOL *, NSDictionary *))progressHandler;
57 |
58 | -(void)setGetFullScreenImage:(void (^)(UIImage *))getFullScreenImage fromNetwokProgressHandler:(void (^)(double ,NSError * , BOOL *, NSDictionary *))progressHandler;
59 |
60 | -(void)setGetOriginImage:(void (^)(UIImage *))getOriginImage fromNetwokProgressHandler:(void (^)(double ,NSError * , BOOL *, NSDictionary *))progressHandler;
61 |
62 | -(void)setGetExportSession:(void (^)(AVAssetExportSession *))getExportSession exportPreset:(NSString *)exportPreset fromNetwokProgressHandler:(void (^)(double ,NSError * , BOOL *, NSDictionary *))progressHandler;
63 |
64 | @end
65 |
66 | #pragma mark - ZYQAssetPickerController
67 |
68 | @protocol ZYQAssetPickerControllerDelegate;
69 |
70 | @interface ZYQAssetPickerController : UINavigationController
71 |
72 | @property (nonatomic, weak) id delegate;
73 |
74 | @property (nonatomic, assign) ZYQAssetsFilter assetsFilter;
75 |
76 | @property (nonatomic, copy, readonly) NSArray *indexPathsForSelectedItems;
77 |
78 | @property (nonatomic, assign) NSInteger maximumNumberOfSelection;
79 | @property (nonatomic, assign) NSInteger minimumNumberOfSelection;
80 |
81 | @property (nonatomic, strong) NSPredicate *selectionFilter;
82 | /**
83 | 是否根据时间降序排列,
84 | 默认:NO
85 | NO:时间较早拍摄的的照片,展示时排列在上面
86 | YES:时间较早拍摄的的照片,展示时排列在最下面,(用户进入相册可以看到最新照片)
87 | */
88 | @property (nonatomic, assign) BOOL timeDescSort;
89 |
90 | @property (nonatomic, assign) BOOL scrollBottom;
91 |
92 | @property (nonatomic, assign) BOOL showCancelButton;
93 |
94 | @property (nonatomic, assign) BOOL showEmptyGroups;
95 |
96 | @property (nonatomic, assign) BOOL isFinishDismissViewController;
97 |
98 | @end
99 |
100 | @protocol ZYQAssetPickerControllerDelegate
101 |
102 | -(void)assetPickerController:(ZYQAssetPickerController *)picker didFinishPickingAssets:(NSArray *)assets;
103 |
104 | @optional
105 |
106 | -(void)assetPickerControllerDidCancel:(ZYQAssetPickerController *)picker;
107 |
108 | -(void)assetPickerController:(ZYQAssetPickerController *)picker didSelectAsset:(ZYQAsset*)asset;
109 |
110 | -(void)assetPickerController:(ZYQAssetPickerController *)picker didDeselectAsset:(ZYQAsset*)asset;
111 |
112 | -(void)assetPickerControllerDidMaximum:(ZYQAssetPickerController *)picker;
113 |
114 | -(void)assetPickerControllerDidMinimum:(ZYQAssetPickerController *)picker;
115 |
116 | @end
117 |
118 | #pragma mark - ZYQAssetViewController
119 |
120 | @interface ZYQAssetViewController : UITableViewController
121 |
122 | @property (nonatomic, strong) ZYQAssetsGroup *assetsGroup;
123 | @property (nonatomic, strong) NSMutableArray *indexPathsForSelectedItems;
124 |
125 | @end
126 |
127 | #pragma mark - ZYQVideoTitleView
128 |
129 | @interface ZYQVideoTitleView : UILabel
130 |
131 | @end
132 |
133 | #pragma mark - ZYQTapAssetView
134 |
135 | @protocol ZYQTapAssetViewDelegate
136 |
137 | -(void)touchSelect:(BOOL)select;
138 | -(BOOL)shouldTap:(BOOL)select;
139 |
140 | @end
141 |
142 | @interface ZYQTapAssetView : UIView
143 |
144 | @property (nonatomic, assign) BOOL selected;
145 | @property (nonatomic, assign) BOOL disabled;
146 | @property (nonatomic, weak) id delegate;
147 |
148 | @end
149 |
150 | #pragma mark - ZYQAssetView
151 |
152 | @protocol ZYQAssetViewDelegate
153 |
154 | -(BOOL)shouldSelectAsset:(ZYQAsset*)asset select:(BOOL)select;
155 | -(void)tapSelectHandle:(BOOL)select asset:(ZYQAsset*)asset;
156 |
157 | @end
158 |
159 | @interface ZYQAssetView : UIView
160 |
161 | - (void)bind:(ZYQAsset*)asset selectionFilter:(NSPredicate*)selectionFilter isSeleced:(BOOL)isSeleced;
162 |
163 | @end
164 |
165 | #pragma mark - ZYQAssetViewCell
166 |
167 | @protocol ZYQAssetViewCellDelegate;
168 |
169 | @interface ZYQAssetViewCell : UITableViewCell
170 |
171 | @property(nonatomic,weak)id delegate;
172 |
173 | - (void)bind:(NSArray *)assets selectionFilter:(NSPredicate*)selectionFilter minimumInteritemSpacing:(float)minimumInteritemSpacing minimumLineSpacing:(float)minimumLineSpacing columns:(int)columns assetViewX:(float)assetViewX;
174 |
175 | @end
176 |
177 | @protocol ZYQAssetViewCellDelegate
178 |
179 | - (BOOL)shouldSelectAsset:(ZYQAsset*)asset select:(BOOL)select;
180 | - (void)didSelectAsset:(ZYQAsset*)asset;
181 | - (void)didDeselectAsset:(ZYQAsset*)asset;
182 |
183 | @end
184 |
185 | #pragma mark - ZYQAssetGroupViewCell
186 |
187 | @interface ZYQAssetGroupViewCell : UITableViewCell
188 |
189 | - (void)bind:(ZYQAssetsGroup*)assetsGroup;
190 |
191 | @end
192 |
193 | #pragma mark - ZYQAssetGroupViewController
194 |
195 | @interface ZYQAssetGroupViewController : UITableViewController
196 |
197 | @end
198 |
199 |
--------------------------------------------------------------------------------
/ZYQAssetPickerControllerDemo/ZYQAssetPickerControllerDemo.xcodeproj/project.pbxproj:
--------------------------------------------------------------------------------
1 | // !$*UTF8*$!
2 | {
3 | archiveVersion = 1;
4 | classes = {
5 | };
6 | objectVersion = 46;
7 | objects = {
8 |
9 | /* Begin PBXBuildFile section */
10 | D8446D4F18702A3B00375761 /* ZYQAssetPicker.Bundle in Resources */ = {isa = PBXBuildFile; fileRef = D8446D4C18702A3B00375761 /* ZYQAssetPicker.Bundle */; };
11 | D8446D5018702A3B00375761 /* ZYQAssetPickerController.m in Sources */ = {isa = PBXBuildFile; fileRef = D8446D4E18702A3B00375761 /* ZYQAssetPickerController.m */; };
12 | D8C4C4201D03E1ED00137782 /* Photos.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D8C4C41F1D03E1ED00137782 /* Photos.framework */; };
13 | D8E6C4C9186B21AC0057C549 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D8E6C4C8186B21AC0057C549 /* Foundation.framework */; };
14 | D8E6C4CB186B21AC0057C549 /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D8E6C4CA186B21AC0057C549 /* CoreGraphics.framework */; };
15 | D8E6C4CD186B21AC0057C549 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D8E6C4CC186B21AC0057C549 /* UIKit.framework */; };
16 | D8E6C4D3186B21AC0057C549 /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = D8E6C4D1186B21AC0057C549 /* InfoPlist.strings */; };
17 | D8E6C4D5186B21AC0057C549 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = D8E6C4D4186B21AC0057C549 /* main.m */; };
18 | D8E6C4D9186B21AC0057C549 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = D8E6C4D8186B21AC0057C549 /* AppDelegate.m */; };
19 | D8E6C4E2186B21AD0057C549 /* XCTest.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D8E6C4E1186B21AD0057C549 /* XCTest.framework */; };
20 | D8E6C4E3186B21AD0057C549 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D8E6C4C8186B21AC0057C549 /* Foundation.framework */; };
21 | D8E6C4E4186B21AD0057C549 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D8E6C4CC186B21AC0057C549 /* UIKit.framework */; };
22 | D8E6C4EC186B21AD0057C549 /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = D8E6C4EA186B21AD0057C549 /* InfoPlist.strings */; };
23 | D8E6C4EE186B21AD0057C549 /* ZYQAssetPickerControllerDemoTests.m in Sources */ = {isa = PBXBuildFile; fileRef = D8E6C4ED186B21AD0057C549 /* ZYQAssetPickerControllerDemoTests.m */; };
24 | D8E6C500186B47410057C549 /* MainViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = D8E6C4FF186B47410057C549 /* MainViewController.m */; };
25 | D8E6C52D187013650057C549 /* AssetsLibrary.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D8E6C52C187013650057C549 /* AssetsLibrary.framework */; };
26 | D8F0F1CE1AB196FA0036D030 /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = D8F0F1CD1AB196FA0036D030 /* Images.xcassets */; };
27 | /* End PBXBuildFile section */
28 |
29 | /* Begin PBXContainerItemProxy section */
30 | D8E6C4E5186B21AD0057C549 /* PBXContainerItemProxy */ = {
31 | isa = PBXContainerItemProxy;
32 | containerPortal = D8E6C4BD186B21AC0057C549 /* Project object */;
33 | proxyType = 1;
34 | remoteGlobalIDString = D8E6C4C4186B21AC0057C549;
35 | remoteInfo = ZYQAssetPickerControllerDemo;
36 | };
37 | /* End PBXContainerItemProxy section */
38 |
39 | /* Begin PBXFileReference section */
40 | D8446D4C18702A3B00375761 /* ZYQAssetPicker.Bundle */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.plug-in"; path = ZYQAssetPicker.Bundle; sourceTree = ""; };
41 | D8446D4D18702A3B00375761 /* ZYQAssetPickerController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ZYQAssetPickerController.h; sourceTree = ""; };
42 | D8446D4E18702A3B00375761 /* ZYQAssetPickerController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ZYQAssetPickerController.m; sourceTree = ""; };
43 | D86038BA18732B460046A5F9 /* zh-Hans */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "zh-Hans"; path = "zh-Hans.lproj/InfoPlist.strings"; sourceTree = ""; };
44 | D86038BB18732B460046A5F9 /* zh-Hans */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "zh-Hans"; path = "zh-Hans.lproj/InfoPlist.strings"; sourceTree = ""; };
45 | D8C4C41F1D03E1ED00137782 /* Photos.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Photos.framework; path = System/Library/Frameworks/Photos.framework; sourceTree = SDKROOT; };
46 | D8E6C4C5186B21AC0057C549 /* ZYQAssetPickerControllerDemo.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = ZYQAssetPickerControllerDemo.app; sourceTree = BUILT_PRODUCTS_DIR; };
47 | D8E6C4C8186B21AC0057C549 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; };
48 | D8E6C4CA186B21AC0057C549 /* CoreGraphics.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreGraphics.framework; path = System/Library/Frameworks/CoreGraphics.framework; sourceTree = SDKROOT; };
49 | D8E6C4CC186B21AC0057C549 /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; };
50 | D8E6C4D0186B21AC0057C549 /* ZYQAssetPickerControllerDemo-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "ZYQAssetPickerControllerDemo-Info.plist"; sourceTree = ""; };
51 | D8E6C4D2186B21AC0057C549 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/InfoPlist.strings; sourceTree = ""; };
52 | D8E6C4D4186B21AC0057C549 /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; };
53 | D8E6C4D6186B21AC0057C549 /* ZYQAssetPickerControllerDemo-Prefix.pch */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "ZYQAssetPickerControllerDemo-Prefix.pch"; sourceTree = ""; };
54 | D8E6C4D7186B21AC0057C549 /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; };
55 | D8E6C4D8186B21AC0057C549 /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; };
56 | D8E6C4E0186B21AD0057C549 /* ZYQAssetPickerControllerDemoTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = ZYQAssetPickerControllerDemoTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
57 | D8E6C4E1186B21AD0057C549 /* XCTest.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = XCTest.framework; path = Library/Frameworks/XCTest.framework; sourceTree = DEVELOPER_DIR; };
58 | D8E6C4E9186B21AD0057C549 /* ZYQAssetPickerControllerDemoTests-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "ZYQAssetPickerControllerDemoTests-Info.plist"; sourceTree = ""; };
59 | D8E6C4EB186B21AD0057C549 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/InfoPlist.strings; sourceTree = ""; };
60 | D8E6C4ED186B21AD0057C549 /* ZYQAssetPickerControllerDemoTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ZYQAssetPickerControllerDemoTests.m; sourceTree = ""; };
61 | D8E6C4FE186B47410057C549 /* MainViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MainViewController.h; sourceTree = ""; };
62 | D8E6C4FF186B47410057C549 /* MainViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MainViewController.m; sourceTree = ""; };
63 | D8E6C52C187013650057C549 /* AssetsLibrary.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AssetsLibrary.framework; path = System/Library/Frameworks/AssetsLibrary.framework; sourceTree = SDKROOT; };
64 | D8F0F1CD1AB196FA0036D030 /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Images.xcassets; sourceTree = ""; };
65 | /* End PBXFileReference section */
66 |
67 | /* Begin PBXFrameworksBuildPhase section */
68 | D8E6C4C2186B21AC0057C549 /* Frameworks */ = {
69 | isa = PBXFrameworksBuildPhase;
70 | buildActionMask = 2147483647;
71 | files = (
72 | D8C4C4201D03E1ED00137782 /* Photos.framework in Frameworks */,
73 | D8E6C52D187013650057C549 /* AssetsLibrary.framework in Frameworks */,
74 | D8E6C4CB186B21AC0057C549 /* CoreGraphics.framework in Frameworks */,
75 | D8E6C4CD186B21AC0057C549 /* UIKit.framework in Frameworks */,
76 | D8E6C4C9186B21AC0057C549 /* Foundation.framework in Frameworks */,
77 | );
78 | runOnlyForDeploymentPostprocessing = 0;
79 | };
80 | D8E6C4DD186B21AD0057C549 /* Frameworks */ = {
81 | isa = PBXFrameworksBuildPhase;
82 | buildActionMask = 2147483647;
83 | files = (
84 | D8E6C4E2186B21AD0057C549 /* XCTest.framework in Frameworks */,
85 | D8E6C4E4186B21AD0057C549 /* UIKit.framework in Frameworks */,
86 | D8E6C4E3186B21AD0057C549 /* Foundation.framework in Frameworks */,
87 | );
88 | runOnlyForDeploymentPostprocessing = 0;
89 | };
90 | /* End PBXFrameworksBuildPhase section */
91 |
92 | /* Begin PBXGroup section */
93 | D8446D4B18702A3B00375761 /* ZYQAssetPickerController */ = {
94 | isa = PBXGroup;
95 | children = (
96 | D8446D4C18702A3B00375761 /* ZYQAssetPicker.Bundle */,
97 | D8446D4D18702A3B00375761 /* ZYQAssetPickerController.h */,
98 | D8446D4E18702A3B00375761 /* ZYQAssetPickerController.m */,
99 | );
100 | name = ZYQAssetPickerController;
101 | path = ../../ZYQAssetPickerController;
102 | sourceTree = "";
103 | };
104 | D8E6C4BC186B21AC0057C549 = {
105 | isa = PBXGroup;
106 | children = (
107 | D8E6C4CE186B21AC0057C549 /* ZYQAssetPickerControllerDemo */,
108 | D8E6C4E7186B21AD0057C549 /* ZYQAssetPickerControllerDemoTests */,
109 | D8E6C4C7186B21AC0057C549 /* Frameworks */,
110 | D8E6C4C6186B21AC0057C549 /* Products */,
111 | );
112 | sourceTree = "";
113 | };
114 | D8E6C4C6186B21AC0057C549 /* Products */ = {
115 | isa = PBXGroup;
116 | children = (
117 | D8E6C4C5186B21AC0057C549 /* ZYQAssetPickerControllerDemo.app */,
118 | D8E6C4E0186B21AD0057C549 /* ZYQAssetPickerControllerDemoTests.xctest */,
119 | );
120 | name = Products;
121 | sourceTree = "";
122 | };
123 | D8E6C4C7186B21AC0057C549 /* Frameworks */ = {
124 | isa = PBXGroup;
125 | children = (
126 | D8C4C41F1D03E1ED00137782 /* Photos.framework */,
127 | D8E6C52C187013650057C549 /* AssetsLibrary.framework */,
128 | D8E6C4C8186B21AC0057C549 /* Foundation.framework */,
129 | D8E6C4CA186B21AC0057C549 /* CoreGraphics.framework */,
130 | D8E6C4CC186B21AC0057C549 /* UIKit.framework */,
131 | D8E6C4E1186B21AD0057C549 /* XCTest.framework */,
132 | );
133 | name = Frameworks;
134 | sourceTree = "";
135 | };
136 | D8E6C4CE186B21AC0057C549 /* ZYQAssetPickerControllerDemo */ = {
137 | isa = PBXGroup;
138 | children = (
139 | D8446D4B18702A3B00375761 /* ZYQAssetPickerController */,
140 | D8E6C4D7186B21AC0057C549 /* AppDelegate.h */,
141 | D8E6C4D8186B21AC0057C549 /* AppDelegate.m */,
142 | D8E6C4FE186B47410057C549 /* MainViewController.h */,
143 | D8E6C4FF186B47410057C549 /* MainViewController.m */,
144 | D8F0F1CD1AB196FA0036D030 /* Images.xcassets */,
145 | D8E6C4CF186B21AC0057C549 /* Supporting Files */,
146 | );
147 | path = ZYQAssetPickerControllerDemo;
148 | sourceTree = "";
149 | };
150 | D8E6C4CF186B21AC0057C549 /* Supporting Files */ = {
151 | isa = PBXGroup;
152 | children = (
153 | D8E6C4D0186B21AC0057C549 /* ZYQAssetPickerControllerDemo-Info.plist */,
154 | D8E6C4D1186B21AC0057C549 /* InfoPlist.strings */,
155 | D8E6C4D4186B21AC0057C549 /* main.m */,
156 | D8E6C4D6186B21AC0057C549 /* ZYQAssetPickerControllerDemo-Prefix.pch */,
157 | );
158 | name = "Supporting Files";
159 | sourceTree = "";
160 | };
161 | D8E6C4E7186B21AD0057C549 /* ZYQAssetPickerControllerDemoTests */ = {
162 | isa = PBXGroup;
163 | children = (
164 | D8E6C4ED186B21AD0057C549 /* ZYQAssetPickerControllerDemoTests.m */,
165 | D8E6C4E8186B21AD0057C549 /* Supporting Files */,
166 | );
167 | path = ZYQAssetPickerControllerDemoTests;
168 | sourceTree = "";
169 | };
170 | D8E6C4E8186B21AD0057C549 /* Supporting Files */ = {
171 | isa = PBXGroup;
172 | children = (
173 | D8E6C4E9186B21AD0057C549 /* ZYQAssetPickerControllerDemoTests-Info.plist */,
174 | D8E6C4EA186B21AD0057C549 /* InfoPlist.strings */,
175 | );
176 | name = "Supporting Files";
177 | sourceTree = "";
178 | };
179 | /* End PBXGroup section */
180 |
181 | /* Begin PBXNativeTarget section */
182 | D8E6C4C4186B21AC0057C549 /* ZYQAssetPickerControllerDemo */ = {
183 | isa = PBXNativeTarget;
184 | buildConfigurationList = D8E6C4F1186B21AD0057C549 /* Build configuration list for PBXNativeTarget "ZYQAssetPickerControllerDemo" */;
185 | buildPhases = (
186 | D8E6C4C1186B21AC0057C549 /* Sources */,
187 | D8E6C4C2186B21AC0057C549 /* Frameworks */,
188 | D8E6C4C3186B21AC0057C549 /* Resources */,
189 | );
190 | buildRules = (
191 | );
192 | dependencies = (
193 | );
194 | name = ZYQAssetPickerControllerDemo;
195 | productName = ZYQAssetPickerControllerDemo;
196 | productReference = D8E6C4C5186B21AC0057C549 /* ZYQAssetPickerControllerDemo.app */;
197 | productType = "com.apple.product-type.application";
198 | };
199 | D8E6C4DF186B21AD0057C549 /* ZYQAssetPickerControllerDemoTests */ = {
200 | isa = PBXNativeTarget;
201 | buildConfigurationList = D8E6C4F4186B21AD0057C549 /* Build configuration list for PBXNativeTarget "ZYQAssetPickerControllerDemoTests" */;
202 | buildPhases = (
203 | D8E6C4DC186B21AD0057C549 /* Sources */,
204 | D8E6C4DD186B21AD0057C549 /* Frameworks */,
205 | D8E6C4DE186B21AD0057C549 /* Resources */,
206 | );
207 | buildRules = (
208 | );
209 | dependencies = (
210 | D8E6C4E6186B21AD0057C549 /* PBXTargetDependency */,
211 | );
212 | name = ZYQAssetPickerControllerDemoTests;
213 | productName = ZYQAssetPickerControllerDemoTests;
214 | productReference = D8E6C4E0186B21AD0057C549 /* ZYQAssetPickerControllerDemoTests.xctest */;
215 | productType = "com.apple.product-type.bundle.unit-test";
216 | };
217 | /* End PBXNativeTarget section */
218 |
219 | /* Begin PBXProject section */
220 | D8E6C4BD186B21AC0057C549 /* Project object */ = {
221 | isa = PBXProject;
222 | attributes = {
223 | LastUpgradeCheck = 0700;
224 | ORGANIZATIONNAME = heroims;
225 | TargetAttributes = {
226 | D8E6C4C4186B21AC0057C549 = {
227 | DevelopmentTeam = YDDJ83LVSQ;
228 | ProvisioningStyle = Automatic;
229 | };
230 | D8E6C4DF186B21AD0057C549 = {
231 | TestTargetID = D8E6C4C4186B21AC0057C549;
232 | };
233 | };
234 | };
235 | buildConfigurationList = D8E6C4C0186B21AC0057C549 /* Build configuration list for PBXProject "ZYQAssetPickerControllerDemo" */;
236 | compatibilityVersion = "Xcode 3.2";
237 | developmentRegion = English;
238 | hasScannedForEncodings = 0;
239 | knownRegions = (
240 | English,
241 | en,
242 | "zh-Hans",
243 | );
244 | mainGroup = D8E6C4BC186B21AC0057C549;
245 | productRefGroup = D8E6C4C6186B21AC0057C549 /* Products */;
246 | projectDirPath = "";
247 | projectRoot = "";
248 | targets = (
249 | D8E6C4C4186B21AC0057C549 /* ZYQAssetPickerControllerDemo */,
250 | D8E6C4DF186B21AD0057C549 /* ZYQAssetPickerControllerDemoTests */,
251 | );
252 | };
253 | /* End PBXProject section */
254 |
255 | /* Begin PBXResourcesBuildPhase section */
256 | D8E6C4C3186B21AC0057C549 /* Resources */ = {
257 | isa = PBXResourcesBuildPhase;
258 | buildActionMask = 2147483647;
259 | files = (
260 | D8F0F1CE1AB196FA0036D030 /* Images.xcassets in Resources */,
261 | D8E6C4D3186B21AC0057C549 /* InfoPlist.strings in Resources */,
262 | D8446D4F18702A3B00375761 /* ZYQAssetPicker.Bundle in Resources */,
263 | );
264 | runOnlyForDeploymentPostprocessing = 0;
265 | };
266 | D8E6C4DE186B21AD0057C549 /* Resources */ = {
267 | isa = PBXResourcesBuildPhase;
268 | buildActionMask = 2147483647;
269 | files = (
270 | D8E6C4EC186B21AD0057C549 /* InfoPlist.strings in Resources */,
271 | );
272 | runOnlyForDeploymentPostprocessing = 0;
273 | };
274 | /* End PBXResourcesBuildPhase section */
275 |
276 | /* Begin PBXSourcesBuildPhase section */
277 | D8E6C4C1186B21AC0057C549 /* Sources */ = {
278 | isa = PBXSourcesBuildPhase;
279 | buildActionMask = 2147483647;
280 | files = (
281 | D8E6C4D9186B21AC0057C549 /* AppDelegate.m in Sources */,
282 | D8E6C4D5186B21AC0057C549 /* main.m in Sources */,
283 | D8E6C500186B47410057C549 /* MainViewController.m in Sources */,
284 | D8446D5018702A3B00375761 /* ZYQAssetPickerController.m in Sources */,
285 | );
286 | runOnlyForDeploymentPostprocessing = 0;
287 | };
288 | D8E6C4DC186B21AD0057C549 /* Sources */ = {
289 | isa = PBXSourcesBuildPhase;
290 | buildActionMask = 2147483647;
291 | files = (
292 | D8E6C4EE186B21AD0057C549 /* ZYQAssetPickerControllerDemoTests.m in Sources */,
293 | );
294 | runOnlyForDeploymentPostprocessing = 0;
295 | };
296 | /* End PBXSourcesBuildPhase section */
297 |
298 | /* Begin PBXTargetDependency section */
299 | D8E6C4E6186B21AD0057C549 /* PBXTargetDependency */ = {
300 | isa = PBXTargetDependency;
301 | target = D8E6C4C4186B21AC0057C549 /* ZYQAssetPickerControllerDemo */;
302 | targetProxy = D8E6C4E5186B21AD0057C549 /* PBXContainerItemProxy */;
303 | };
304 | /* End PBXTargetDependency section */
305 |
306 | /* Begin PBXVariantGroup section */
307 | D8E6C4D1186B21AC0057C549 /* InfoPlist.strings */ = {
308 | isa = PBXVariantGroup;
309 | children = (
310 | D8E6C4D2186B21AC0057C549 /* en */,
311 | D86038BA18732B460046A5F9 /* zh-Hans */,
312 | );
313 | name = InfoPlist.strings;
314 | sourceTree = "";
315 | };
316 | D8E6C4EA186B21AD0057C549 /* InfoPlist.strings */ = {
317 | isa = PBXVariantGroup;
318 | children = (
319 | D8E6C4EB186B21AD0057C549 /* en */,
320 | D86038BB18732B460046A5F9 /* zh-Hans */,
321 | );
322 | name = InfoPlist.strings;
323 | sourceTree = "";
324 | };
325 | /* End PBXVariantGroup section */
326 |
327 | /* Begin XCBuildConfiguration section */
328 | D8E6C4EF186B21AD0057C549 /* Debug */ = {
329 | isa = XCBuildConfiguration;
330 | buildSettings = {
331 | ALWAYS_SEARCH_USER_PATHS = NO;
332 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
333 | CLANG_CXX_LIBRARY = "libc++";
334 | CLANG_ENABLE_MODULES = YES;
335 | CLANG_ENABLE_OBJC_ARC = YES;
336 | CLANG_WARN_BOOL_CONVERSION = YES;
337 | CLANG_WARN_CONSTANT_CONVERSION = YES;
338 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
339 | CLANG_WARN_EMPTY_BODY = YES;
340 | CLANG_WARN_ENUM_CONVERSION = YES;
341 | CLANG_WARN_INT_CONVERSION = YES;
342 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
343 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
344 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
345 | COPY_PHASE_STRIP = NO;
346 | ENABLE_TESTABILITY = YES;
347 | GCC_C_LANGUAGE_STANDARD = gnu99;
348 | GCC_DYNAMIC_NO_PIC = NO;
349 | GCC_OPTIMIZATION_LEVEL = 0;
350 | GCC_PREPROCESSOR_DEFINITIONS = (
351 | "DEBUG=1",
352 | "$(inherited)",
353 | );
354 | GCC_SYMBOLS_PRIVATE_EXTERN = NO;
355 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
356 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
357 | GCC_WARN_UNDECLARED_SELECTOR = YES;
358 | GCC_WARN_UNINITIALIZED_AUTOS = YES;
359 | GCC_WARN_UNUSED_FUNCTION = YES;
360 | GCC_WARN_UNUSED_VARIABLE = YES;
361 | IPHONEOS_DEPLOYMENT_TARGET = 7.0;
362 | ONLY_ACTIVE_ARCH = YES;
363 | SDKROOT = iphoneos;
364 | TARGETED_DEVICE_FAMILY = "1,2";
365 | };
366 | name = Debug;
367 | };
368 | D8E6C4F0186B21AD0057C549 /* Release */ = {
369 | isa = XCBuildConfiguration;
370 | buildSettings = {
371 | ALWAYS_SEARCH_USER_PATHS = NO;
372 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
373 | CLANG_CXX_LIBRARY = "libc++";
374 | CLANG_ENABLE_MODULES = YES;
375 | CLANG_ENABLE_OBJC_ARC = YES;
376 | CLANG_WARN_BOOL_CONVERSION = YES;
377 | CLANG_WARN_CONSTANT_CONVERSION = YES;
378 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
379 | CLANG_WARN_EMPTY_BODY = YES;
380 | CLANG_WARN_ENUM_CONVERSION = YES;
381 | CLANG_WARN_INT_CONVERSION = YES;
382 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
383 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
384 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
385 | COPY_PHASE_STRIP = YES;
386 | ENABLE_NS_ASSERTIONS = NO;
387 | GCC_C_LANGUAGE_STANDARD = gnu99;
388 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
389 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
390 | GCC_WARN_UNDECLARED_SELECTOR = YES;
391 | GCC_WARN_UNINITIALIZED_AUTOS = YES;
392 | GCC_WARN_UNUSED_FUNCTION = YES;
393 | GCC_WARN_UNUSED_VARIABLE = YES;
394 | IPHONEOS_DEPLOYMENT_TARGET = 7.0;
395 | SDKROOT = iphoneos;
396 | TARGETED_DEVICE_FAMILY = "1,2";
397 | VALIDATE_PRODUCT = YES;
398 | };
399 | name = Release;
400 | };
401 | D8E6C4F2186B21AD0057C549 /* Debug */ = {
402 | isa = XCBuildConfiguration;
403 | buildSettings = {
404 | ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage;
405 | CODE_SIGN_IDENTITY = "Apple Development";
406 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
407 | CODE_SIGN_STYLE = Automatic;
408 | DEVELOPMENT_TEAM = YDDJ83LVSQ;
409 | GCC_PRECOMPILE_PREFIX_HEADER = YES;
410 | GCC_PREFIX_HEADER = "ZYQAssetPickerControllerDemo/ZYQAssetPickerControllerDemo-Prefix.pch";
411 | INFOPLIST_FILE = "ZYQAssetPickerControllerDemo/ZYQAssetPickerControllerDemo-Info.plist";
412 | IPHONEOS_DEPLOYMENT_TARGET = 6.0;
413 | PRODUCT_BUNDLE_IDENTIFIER = ZYQ.ZYQAssetPickerControllerDemo;
414 | PRODUCT_NAME = "$(TARGET_NAME)";
415 | PROVISIONING_PROFILE = "";
416 | PROVISIONING_PROFILE_SPECIFIER = "";
417 | WRAPPER_EXTENSION = app;
418 | };
419 | name = Debug;
420 | };
421 | D8E6C4F3186B21AD0057C549 /* Release */ = {
422 | isa = XCBuildConfiguration;
423 | buildSettings = {
424 | ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage;
425 | CODE_SIGN_IDENTITY = "iPhone Developer: 幻影 灵异 (33FX7C95LQ)";
426 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
427 | CODE_SIGN_STYLE = Manual;
428 | DEVELOPMENT_TEAM = "";
429 | GCC_PRECOMPILE_PREFIX_HEADER = YES;
430 | GCC_PREFIX_HEADER = "ZYQAssetPickerControllerDemo/ZYQAssetPickerControllerDemo-Prefix.pch";
431 | INFOPLIST_FILE = "ZYQAssetPickerControllerDemo/ZYQAssetPickerControllerDemo-Info.plist";
432 | IPHONEOS_DEPLOYMENT_TARGET = 6.0;
433 | PRODUCT_BUNDLE_IDENTIFIER = ZYQ.ZYQAssetPickerControllerDemo;
434 | PRODUCT_NAME = "$(TARGET_NAME)";
435 | PROVISIONING_PROFILE = "";
436 | PROVISIONING_PROFILE_SPECIFIER = "";
437 | WRAPPER_EXTENSION = app;
438 | };
439 | name = Release;
440 | };
441 | D8E6C4F5186B21AD0057C549 /* Debug */ = {
442 | isa = XCBuildConfiguration;
443 | buildSettings = {
444 | BUNDLE_LOADER = "$(BUILT_PRODUCTS_DIR)/ZYQAssetPickerControllerDemo.app/ZYQAssetPickerControllerDemo";
445 | FRAMEWORK_SEARCH_PATHS = (
446 | "$(SDKROOT)/Developer/Library/Frameworks",
447 | "$(inherited)",
448 | "$(DEVELOPER_FRAMEWORKS_DIR)",
449 | );
450 | GCC_PRECOMPILE_PREFIX_HEADER = YES;
451 | GCC_PREFIX_HEADER = "ZYQAssetPickerControllerDemo/ZYQAssetPickerControllerDemo-Prefix.pch";
452 | GCC_PREPROCESSOR_DEFINITIONS = (
453 | "DEBUG=1",
454 | "$(inherited)",
455 | );
456 | INFOPLIST_FILE = "ZYQAssetPickerControllerDemoTests/ZYQAssetPickerControllerDemoTests-Info.plist";
457 | PRODUCT_BUNDLE_IDENTIFIER = "ZYQ.${PRODUCT_NAME:rfc1034identifier}";
458 | PRODUCT_NAME = "$(TARGET_NAME)";
459 | TEST_HOST = "$(BUNDLE_LOADER)";
460 | WRAPPER_EXTENSION = xctest;
461 | };
462 | name = Debug;
463 | };
464 | D8E6C4F6186B21AD0057C549 /* Release */ = {
465 | isa = XCBuildConfiguration;
466 | buildSettings = {
467 | BUNDLE_LOADER = "$(BUILT_PRODUCTS_DIR)/ZYQAssetPickerControllerDemo.app/ZYQAssetPickerControllerDemo";
468 | FRAMEWORK_SEARCH_PATHS = (
469 | "$(SDKROOT)/Developer/Library/Frameworks",
470 | "$(inherited)",
471 | "$(DEVELOPER_FRAMEWORKS_DIR)",
472 | );
473 | GCC_PRECOMPILE_PREFIX_HEADER = YES;
474 | GCC_PREFIX_HEADER = "ZYQAssetPickerControllerDemo/ZYQAssetPickerControllerDemo-Prefix.pch";
475 | INFOPLIST_FILE = "ZYQAssetPickerControllerDemoTests/ZYQAssetPickerControllerDemoTests-Info.plist";
476 | PRODUCT_BUNDLE_IDENTIFIER = "ZYQ.${PRODUCT_NAME:rfc1034identifier}";
477 | PRODUCT_NAME = "$(TARGET_NAME)";
478 | TEST_HOST = "$(BUNDLE_LOADER)";
479 | WRAPPER_EXTENSION = xctest;
480 | };
481 | name = Release;
482 | };
483 | /* End XCBuildConfiguration section */
484 |
485 | /* Begin XCConfigurationList section */
486 | D8E6C4C0186B21AC0057C549 /* Build configuration list for PBXProject "ZYQAssetPickerControllerDemo" */ = {
487 | isa = XCConfigurationList;
488 | buildConfigurations = (
489 | D8E6C4EF186B21AD0057C549 /* Debug */,
490 | D8E6C4F0186B21AD0057C549 /* Release */,
491 | );
492 | defaultConfigurationIsVisible = 0;
493 | defaultConfigurationName = Release;
494 | };
495 | D8E6C4F1186B21AD0057C549 /* Build configuration list for PBXNativeTarget "ZYQAssetPickerControllerDemo" */ = {
496 | isa = XCConfigurationList;
497 | buildConfigurations = (
498 | D8E6C4F2186B21AD0057C549 /* Debug */,
499 | D8E6C4F3186B21AD0057C549 /* Release */,
500 | );
501 | defaultConfigurationIsVisible = 0;
502 | defaultConfigurationName = Release;
503 | };
504 | D8E6C4F4186B21AD0057C549 /* Build configuration list for PBXNativeTarget "ZYQAssetPickerControllerDemoTests" */ = {
505 | isa = XCConfigurationList;
506 | buildConfigurations = (
507 | D8E6C4F5186B21AD0057C549 /* Debug */,
508 | D8E6C4F6186B21AD0057C549 /* Release */,
509 | );
510 | defaultConfigurationIsVisible = 0;
511 | defaultConfigurationName = Release;
512 | };
513 | /* End XCConfigurationList section */
514 | };
515 | rootObject = D8E6C4BD186B21AC0057C549 /* Project object */;
516 | }
517 |
--------------------------------------------------------------------------------
/ZYQAssetPickerController/ZYQAssetPickerController.m:
--------------------------------------------------------------------------------
1 | //
2 | // ZYQAssetPickerController.m
3 | // ZYQAssetPickerControllerDemo
4 | //
5 | // Created by Zhao Yiqi on 13-12-25.
6 | // Copyright (c) 2013年 heroims. All rights reserved.
7 | //
8 |
9 | #import "ZYQAssetPickerController.h"
10 |
11 | #define IS_IOS7 ([[[UIDevice currentDevice] systemVersion] compare:@"7.0" options:NSNumericSearch] != NSOrderedAscending)
12 | #define IS_IOS8 ([[[UIDevice currentDevice] systemVersion] compare:@"8.0" options:NSNumericSearch] != NSOrderedAscending)
13 |
14 | #define kThumbnailLength 78.0f
15 | #define kThumbnailSize CGSizeMake(kThumbnailLength, kThumbnailLength)
16 | #define kPopoverContentSize CGSizeMake(320, 480)
17 |
18 | #pragma mark -
19 |
20 | @interface NSDate (TimeInterval)
21 |
22 | + (NSDateComponents *)componetsWithTimeInterval:(NSTimeInterval)timeInterval;
23 | + (NSString *)timeDescriptionOfTimeInterval:(NSTimeInterval)timeInterval;
24 |
25 | @end
26 |
27 | @implementation NSDate (TimeInterval)
28 |
29 | + (NSDateComponents *)componetsWithTimeInterval:(NSTimeInterval)timeInterval
30 | {
31 | NSCalendar *calendar = [NSCalendar currentCalendar];
32 |
33 | NSDate *date1 = [[NSDate alloc] init];
34 | NSDate *date2 = [[NSDate alloc] initWithTimeInterval:timeInterval sinceDate:date1];
35 |
36 | unsigned int unitFlags =
37 | NSCalendarUnitSecond | NSCalendarUnitMinute | NSCalendarUnitHour |
38 | NSCalendarUnitDay | NSCalendarUnitMonth | NSCalendarUnitYear;
39 |
40 | return [calendar components:unitFlags
41 | fromDate:date1
42 | toDate:date2
43 | options:0];
44 | }
45 |
46 | + (NSString *)timeDescriptionOfTimeInterval:(NSTimeInterval)timeInterval
47 | {
48 | NSString *newTime;
49 | if (timeInterval < 10) {
50 | newTime = [NSString stringWithFormat:@"0:0%zd",(NSInteger)timeInterval];
51 | } else if (timeInterval < 60) {
52 | newTime = [NSString stringWithFormat:@"0:%zd",(NSInteger)timeInterval];
53 | } else {
54 | NSInteger min = timeInterval / 60;
55 | NSInteger sec = timeInterval - (min * 60);
56 | if (sec < 10) {
57 | newTime = [NSString stringWithFormat:@"%zd:0%zd",min,sec];
58 | } else {
59 | newTime = [NSString stringWithFormat:@"%zd:%zd",min,sec];
60 | }
61 | }
62 | return newTime;
63 | }
64 |
65 | @end
66 |
67 | #pragma mark - ZYQAssetsGroup
68 |
69 | @interface ZYQAssetsGroup(){
70 | UIImage *_cacheThumbnail;
71 | }
72 |
73 | @end
74 |
75 | @implementation ZYQAssetsGroup : NSObject
76 |
77 | -(NSString*)groupName{
78 | if (_originAssetGroup) {
79 | if ([_originAssetGroup isKindOfClass:[PHCollection class]]) {
80 | return [(PHCollection*)_originAssetGroup localizedTitle];
81 | }
82 | else if([_originAssetGroup isKindOfClass:[ALAssetsGroup class]]){
83 | return [(ALAssetsGroup*)_originAssetGroup valueForProperty:ALAssetsGroupPropertyName];
84 | }
85 | }
86 | return nil;
87 | }
88 |
89 | -(NSInteger)count{
90 | if (_originAssetGroup) {
91 | if ([_originAssetGroup isKindOfClass:[PHCollection class]]) {
92 | if (!_originFetchResult) {
93 | PHFetchOptions *fetchOptionsAlbums=[[PHFetchOptions alloc] init];
94 |
95 | _originFetchResult=[PHCollection fetchCollectionsInCollectionList:_originAssetGroup options:fetchOptionsAlbums];
96 | }
97 | return [(PHFetchResult*)_originFetchResult count];
98 | }
99 | else if([_originAssetGroup isKindOfClass:[ALAssetsGroup class]]){
100 | return [(ALAssetsGroup*)_originAssetGroup numberOfAssets];
101 | }
102 | }
103 | return 0;
104 | }
105 |
106 | -(void)setGetThumbnail:(void (^)(UIImage *))getThumbnail{
107 | _getThumbnail=getThumbnail;
108 |
109 | if (_originAssetGroup) {
110 | if (_cacheThumbnail) {
111 | _getThumbnail(_cacheThumbnail);
112 | return;
113 | }
114 |
115 | if ([_originAssetGroup isKindOfClass:[ALAssetsGroup class]]) {
116 |
117 | CGImageRef posterImage = [(ALAssetsGroup*)_originAssetGroup posterImage];
118 | size_t height = CGImageGetHeight(posterImage);
119 | float scale = height / kThumbnailLength;
120 |
121 | _cacheThumbnail = [UIImage imageWithCGImage:posterImage scale:scale orientation:UIImageOrientationUp];
122 |
123 | _getThumbnail(_cacheThumbnail);
124 | }
125 | else if ([_originAssetGroup isKindOfClass:[PHCollection class]]){
126 | if (!_originFetchResult) {
127 | PHFetchOptions *fetchOptionsAlbums=[[PHFetchOptions alloc] init];
128 |
129 | _originFetchResult=[PHCollection fetchCollectionsInCollectionList:_originAssetGroup options:fetchOptionsAlbums];
130 | }
131 | PHFetchResult *tmpFetchResult=_originFetchResult;
132 | PHAsset *tmpAsset=[tmpFetchResult objectAtIndex:tmpFetchResult.count-1];
133 |
134 | PHImageRequestOptions *requestOptions = [[PHImageRequestOptions alloc] init];
135 | requestOptions.deliveryMode = PHImageRequestOptionsDeliveryModeOpportunistic;
136 | requestOptions.resizeMode = PHImageRequestOptionsResizeModeExact;
137 | [[PHImageManager defaultManager] requestImageForAsset:tmpAsset targetSize:CGSizeMake(200, 200) contentMode:PHImageContentModeAspectFill options:requestOptions resultHandler:^(UIImage *result, NSDictionary *info){
138 | BOOL downloadFinined = ![[info objectForKey:PHImageCancelledKey] boolValue] && ![info objectForKey:PHImageErrorKey] && ![[info objectForKey:PHImageResultIsDegradedKey] boolValue];
139 |
140 | //设置BOOL判断,确定返回高清照片
141 | if (downloadFinined) {
142 | float scale = result.size.height / kThumbnailLength;
143 |
144 | _cacheThumbnail=[UIImage imageWithCGImage:result.CGImage scale:scale orientation:UIImageOrientationUp];
145 |
146 | _getThumbnail(_cacheThumbnail);
147 |
148 | }
149 | }];
150 | }
151 | }
152 | }
153 |
154 | -(void)enumerateObjectsUsingBlock:(ZYQAssetsGroupEnumerationResultsBlock)enumerationBlock{
155 | if (_originAssetGroup) {
156 | if ([_originAssetGroup isKindOfClass:[PHCollection class]]) {
157 | if (!_originFetchResult) {
158 | PHFetchOptions *fetchOptionsAlbums=[[PHFetchOptions alloc] init];
159 |
160 | _originFetchResult=[PHCollection fetchCollectionsInCollectionList:_originAssetGroup options:fetchOptionsAlbums];
161 | }
162 | return [(PHFetchResult*)_originFetchResult enumerateObjectsUsingBlock:enumerationBlock];
163 | }
164 | else if([_originAssetGroup isKindOfClass:[ALAssetsGroup class]]){
165 | return [(ALAssetsGroup*)_originAssetGroup enumerateAssetsUsingBlock:enumerationBlock];
166 | }
167 | }
168 | }
169 |
170 | @end
171 | #pragma mark - ZYQAsset
172 | @interface ZYQAsset(){
173 | UIImage *_cacheThumbnail;
174 | UIImage *_cacheFullScreenImage;
175 | UIImage *_cacheOriginImage;
176 |
177 | AVAssetExportSession *_cacheExportSession;
178 | }
179 |
180 | @end
181 |
182 | @implementation ZYQAsset : NSObject
183 |
184 | -(void)setGetThumbnail:(void (^)(UIImage *))getThumbnail fromNetwokProgressHandler:(void (^)(double, NSError *, BOOL *, NSDictionary *))progressHandler{
185 | _getThumbnail=getThumbnail;
186 |
187 | if (_originAsset) {
188 | if (_cacheThumbnail) {
189 | _getThumbnail(_cacheThumbnail);
190 | return;
191 | }
192 |
193 | if ([_originAsset isKindOfClass:[ALAsset class]]) {
194 | _cacheThumbnail=[UIImage imageWithCGImage:[(ALAsset*)_originAsset thumbnail]];
195 | _getThumbnail(_cacheThumbnail);
196 | }
197 | else if ([_originAsset isKindOfClass:[PHAsset class]]){
198 | PHImageRequestOptions *requestOptions = [[PHImageRequestOptions alloc] init];
199 | requestOptions.deliveryMode = PHImageRequestOptionsDeliveryModeOpportunistic;
200 | requestOptions.resizeMode = PHImageRequestOptionsResizeModeExact;
201 | requestOptions.progressHandler = ^(double progress, NSError * _Nullable error, BOOL * _Nonnull stop, NSDictionary * _Nullable info) {
202 | if (progressHandler) {
203 | progressHandler(progress,error,stop,info);
204 | }
205 | };
206 | [[PHImageManager defaultManager] requestImageForAsset:_originAsset targetSize:CGSizeMake(200, 200) contentMode:PHImageContentModeAspectFill options:requestOptions resultHandler:^(UIImage *result, NSDictionary *info){
207 | BOOL downloadFinined = NO;
208 |
209 | downloadFinined = ![[info objectForKey:PHImageCancelledKey] boolValue] && ![info objectForKey:PHImageErrorKey] && ![[info objectForKey:PHImageResultIsDegradedKey] boolValue];//设置BOOL判断,确定返回高清照片
210 |
211 | if (downloadFinined) {
212 | _cacheThumbnail=result;
213 | _getThumbnail(_cacheThumbnail);
214 | }
215 | }];
216 | }
217 | }
218 | }
219 |
220 | -(void)setGetExportSession:(void (^)(AVAssetExportSession *))getExportSession exportPreset:(NSString *)exportPreset fromNetwokProgressHandler:(void (^)(double ,NSError * , BOOL *, NSDictionary *))progressHandler{
221 |
222 | _getExportSession=getExportSession;
223 |
224 | if (_originAsset) {
225 | if (_cacheExportSession) {
226 | _getExportSession(_cacheExportSession);
227 | return;
228 | }
229 |
230 | if ([_originAsset isKindOfClass:[ALAsset class]]) {
231 |
232 | AVURLAsset *avasset=[AVURLAsset URLAssetWithURL:[(ALAsset*)_originAsset defaultRepresentation].url options:nil];
233 | _cacheExportSession = [[AVAssetExportSession alloc] initWithAsset:avasset presetName:exportPreset];
234 | _getExportSession(_cacheExportSession);
235 | }
236 | else if ([_originAsset isKindOfClass:[PHAsset class]]){
237 | PHVideoRequestOptions *requestOptions = [[PHVideoRequestOptions alloc] init];
238 | requestOptions.deliveryMode = PHVideoRequestOptionsDeliveryModeMediumQualityFormat;
239 | requestOptions.networkAccessAllowed=YES;
240 |
241 | requestOptions.progressHandler = ^(double progress, NSError * _Nullable error, BOOL * _Nonnull stop, NSDictionary * _Nullable info) {
242 | if (progressHandler) {
243 | progressHandler(progress,error,stop,info);
244 | }
245 | };
246 |
247 | [[PHImageManager defaultManager] requestExportSessionForVideo:_originAsset options:requestOptions exportPreset:exportPreset resultHandler:^(AVAssetExportSession * _Nullable exportSession, NSDictionary * _Nullable info) {
248 |
249 | _cacheExportSession=exportSession;
250 | _getExportSession(_cacheExportSession);
251 | }];
252 | }
253 | }
254 |
255 | }
256 |
257 | -(void)setGetFullScreenImage:(void (^)(UIImage *))getFullScreenImage fromNetwokProgressHandler:(void (^)(double ,NSError * , BOOL *, NSDictionary *))progressHandler{
258 | _getFullScreenImage=getFullScreenImage;
259 |
260 | if (_originAsset) {
261 | if (_cacheFullScreenImage) {
262 | _getFullScreenImage(_cacheFullScreenImage);
263 | return;
264 | }
265 |
266 | if ([_originAsset isKindOfClass:[ALAsset class]]) {
267 | _cacheFullScreenImage=[UIImage imageWithCGImage:[(ALAsset*)_originAsset defaultRepresentation].fullScreenImage];
268 | _getFullScreenImage(_cacheFullScreenImage);
269 | }
270 | else if ([_originAsset isKindOfClass:[PHAsset class]]){
271 | PHImageRequestOptions *requestOptions = [[PHImageRequestOptions alloc] init];
272 | requestOptions.deliveryMode = PHImageRequestOptionsDeliveryModeOpportunistic;
273 | requestOptions.resizeMode = PHImageRequestOptionsResizeModeExact;
274 |
275 | CGFloat photoWidth = [UIScreen mainScreen].bounds.size.width;
276 |
277 | CGFloat aspectRatio = ((PHAsset*)_originAsset).pixelWidth / (CGFloat)((PHAsset*)_originAsset).pixelHeight;
278 | CGFloat multiple = [UIScreen mainScreen].scale;
279 | CGFloat pixelWidth = photoWidth * multiple;
280 | CGFloat pixelHeight = pixelWidth / aspectRatio;
281 |
282 | requestOptions.networkAccessAllowed=YES;
283 |
284 |
285 | requestOptions.progressHandler = ^(double progress, NSError * _Nullable error, BOOL * _Nonnull stop, NSDictionary * _Nullable info) {
286 | if (progressHandler) {
287 | progressHandler(progress,error,stop,info);
288 | }
289 | };
290 |
291 | [[PHImageManager defaultManager] requestImageForAsset:_originAsset targetSize:CGSizeMake(pixelWidth, pixelHeight) contentMode:PHImageContentModeAspectFill options:requestOptions resultHandler:^(UIImage *result, NSDictionary *info){
292 | BOOL downloadFinined = NO;
293 |
294 | downloadFinined = ![[info objectForKey:PHImageCancelledKey] boolValue] && ![info objectForKey:PHImageErrorKey] && ![[info objectForKey:PHImageResultIsDegradedKey] boolValue];//设置BOOL判断,确定返回高清照片
295 |
296 | if (downloadFinined) {
297 | _cacheFullScreenImage=result;
298 | _getFullScreenImage(_cacheFullScreenImage);
299 | }
300 | }];
301 | }
302 | }
303 |
304 | }
305 |
306 | -(void)setGetOriginImage:(void (^)(UIImage *))getOriginImage fromNetwokProgressHandler:(void (^)(double ,NSError * , BOOL *, NSDictionary *))progressHandler{
307 | _getOriginImage=getOriginImage;
308 |
309 | if (_originAsset) {
310 | if (_cacheOriginImage) {
311 | _getOriginImage(_cacheOriginImage);
312 | return;
313 | }
314 |
315 | if ([_originAsset isKindOfClass:[ALAsset class]]) {
316 | ALAssetRepresentation *image_representation=[(ALAsset*)_originAsset defaultRepresentation];
317 | Byte * buffer = (Byte*)malloc(image_representation.size);
318 | NSUInteger length = [image_representation getBytes:buffer fromOffset: 0.0 length:image_representation.size error:nil];
319 |
320 | if (length != 0) {
321 | NSData *adata = [[NSData alloc] initWithBytesNoCopy:buffer length:image_representation.size freeWhenDone:YES];
322 | _cacheOriginImage = [UIImage imageWithData:adata];
323 | }
324 |
325 | _getOriginImage(_cacheOriginImage);
326 | }
327 | else if ([_originAsset isKindOfClass:[PHAsset class]]){
328 | PHImageRequestOptions *requestOptions = [[PHImageRequestOptions alloc] init];
329 | requestOptions.deliveryMode = PHImageRequestOptionsDeliveryModeOpportunistic;
330 | requestOptions.resizeMode = PHImageRequestOptionsResizeModeExact;
331 |
332 | requestOptions.networkAccessAllowed=YES;
333 |
334 | requestOptions.progressHandler = ^(double progress, NSError * _Nullable error, BOOL * _Nonnull stop, NSDictionary * _Nullable info) {
335 | if (progressHandler) {
336 | progressHandler(progress,error,stop,info);
337 | }
338 | };
339 |
340 | [[PHImageManager defaultManager] requestImageForAsset:_originAsset targetSize:CGSizeMake(((PHAsset*)_originAsset).pixelWidth, ((PHAsset*)_originAsset).pixelHeight) contentMode:PHImageContentModeAspectFill options:requestOptions resultHandler:^(UIImage *result, NSDictionary *info){
341 | BOOL downloadFinined = NO;
342 |
343 | downloadFinined = ![[info objectForKey:PHImageCancelledKey] boolValue] && ![info objectForKey:PHImageErrorKey] && ![[info objectForKey:PHImageResultIsDegradedKey] boolValue];//设置BOOL判断,确定返回高清照片
344 |
345 | if (downloadFinined) {
346 | _cacheFullScreenImage=result;
347 | _getFullScreenImage(_cacheFullScreenImage);
348 | }
349 | }];
350 | }
351 | }
352 | }
353 |
354 | -(void)setGetExportSession:(void (^)(AVAssetExportSession *))getExportSession{
355 | [self setGetExportSession:getExportSession exportPreset:AVAssetExportPresetMediumQuality fromNetwokProgressHandler:nil];
356 | }
357 |
358 | -(void)setGetThumbnail:(void (^)(UIImage *))getThumbnail{
359 | [self setGetThumbnail:getThumbnail fromNetwokProgressHandler:nil];
360 | }
361 |
362 | -(void)setGetFullScreenImage:(void (^)(UIImage *))getFullScreenImage{
363 | [self setGetFullScreenImage:getFullScreenImage fromNetwokProgressHandler:nil];
364 | }
365 |
366 | -(void)setGetOriginImage:(void (^)(UIImage *))getOriginImage{
367 | [self setGetOriginImage:getOriginImage fromNetwokProgressHandler:nil];
368 | }
369 |
370 |
371 | -(NSTimeInterval)duration{
372 | if (_originAsset) {
373 | if ([_originAsset isKindOfClass:[ALAsset class]]) {
374 | return [[(ALAsset*)_originAsset valueForProperty:ALAssetPropertyDuration] doubleValue];
375 | }
376 | else if ([_originAsset isKindOfClass:[PHAsset class]]){
377 | return [(PHAsset*)_originAsset duration];
378 | }
379 | }
380 | return 0;
381 | }
382 |
383 | -(CGSize)size{
384 | if (_originAsset) {
385 | if ([_originAsset isKindOfClass:[ALAsset class]]) {
386 | return [(ALAsset*)_originAsset defaultRepresentation].dimensions;
387 | }
388 | else if ([_originAsset isKindOfClass:[PHAsset class]]){
389 | return CGSizeMake(((PHAsset*)_originAsset).pixelWidth, ((PHAsset*)_originAsset).pixelHeight);
390 | }
391 | }
392 | return CGSizeMake(0, 0);
393 |
394 | }
395 | -(NSDate*)modificationDate{
396 | if (_originAsset) {
397 | if ([_originAsset isKindOfClass:[ALAsset class]]) {
398 | return [(ALAsset*)_originAsset valueForProperty:ALAssetPropertyDate];
399 | }
400 | else if ([_originAsset isKindOfClass:[PHAsset class]]){
401 | return [(PHAsset*)_originAsset modificationDate];
402 | }
403 | }
404 | return nil;
405 |
406 | }
407 |
408 | -(ZYQAssetMediaType)mediaType{
409 | if (_originAsset) {
410 | if ([_originAsset isKindOfClass:[ALAsset class]]) {
411 | if ([[(ALAsset*)_originAsset valueForProperty:ALAssetPropertyType] isEqual:ALAssetTypePhoto]) {
412 | return ZYQAssetMediaTypeImage;
413 | }
414 | if ([[(ALAsset*)_originAsset valueForProperty:ALAssetPropertyType] isEqual:ALAssetTypeVideo]) {
415 | return ZYQAssetMediaTypeVideo;
416 | }
417 | }
418 | else if ([_originAsset isKindOfClass:[PHAsset class]]){
419 | switch ([(PHAsset*)_originAsset mediaType]) {
420 | case PHAssetMediaTypeImage:
421 | return ZYQAssetMediaTypeImage;
422 | case PHAssetMediaTypeVideo:
423 | return ZYQAssetMediaTypeVideo;
424 | case PHAssetMediaTypeAudio:
425 | return ZYQAssetMediaTypeAudio;
426 | default:
427 | break;
428 | }
429 | }
430 | }
431 | return ZYQAssetMediaTypeUnknown;
432 | }
433 |
434 | @end
435 |
436 | #pragma mark - ZYQAssetPickerController
437 |
438 | @interface ZYQAssetPickerController ()
439 |
440 | @property (nonatomic, copy) NSArray *indexPathsForSelectedItems;
441 |
442 | @end
443 |
444 | #pragma mark - ZYQVideoTitleView
445 |
446 | @implementation ZYQVideoTitleView
447 |
448 | -(void)drawRect:(CGRect)rect{
449 | CGFloat colors [] = {
450 | 0.0, 0.0, 0.0, 0.0,
451 | 0.7, 0.7, 0.7, 0.6,
452 | 1.0, 1.0, 1.0, 1.0
453 | };
454 |
455 | CGFloat locations [] = {0.0, 0.75, 1.0};
456 |
457 | CGColorSpaceRef baseSpace = CGColorSpaceCreateDeviceRGB();
458 | CGGradientRef gradient = CGGradientCreateWithColorComponents(baseSpace, colors, locations, 2);
459 | CGColorSpaceRelease(baseSpace);
460 |
461 | CGContextRef context = UIGraphicsGetCurrentContext();
462 |
463 | CGFloat height = rect.size.height;
464 | CGPoint startPoint = CGPointMake(0, 0);
465 | CGPoint endPoint = CGPointMake(CGRectGetMaxX(rect), CGRectGetMaxY(rect));
466 |
467 | CGContextDrawLinearGradient(context, gradient, startPoint, endPoint, 0);
468 |
469 | CGGradientRelease(gradient);
470 |
471 | CGSize titleSize = [self.text sizeWithAttributes:@{NSFontAttributeName:self.font,NSForegroundColorAttributeName:self.textColor}];
472 | [self.text drawAtPoint:CGPointMake(rect.size.width - titleSize.width - 2 , (height - 12) / 2) withAttributes:@{NSFontAttributeName:self.font,NSForegroundColorAttributeName:self.textColor}];
473 |
474 | UIImage *videoIcon=[UIImage imageWithContentsOfFile:[[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:@"ZYQAssetPicker.Bundle/Images/AssetsPickerVideo@2x.png"]];
475 |
476 | [videoIcon drawAtPoint:CGPointMake(2, (height - videoIcon.size.height) / 2)];
477 |
478 | }
479 |
480 | @end
481 |
482 | #pragma mark - ZYQTapAssetView
483 |
484 | @interface ZYQTapAssetView ()
485 |
486 | @property(nonatomic,retain)UIImageView *selectView;
487 |
488 | @end
489 |
490 | @implementation ZYQTapAssetView
491 |
492 | static UIImage *checkedIcon;
493 | static UIColor *selectedColor;
494 | static UIColor *disabledColor;
495 |
496 | + (void)initialize
497 | {
498 | checkedIcon = [UIImage imageWithContentsOfFile:[[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:[NSString stringWithFormat:@"ZYQAssetPicker.Bundle/Images/%@@2x.png",(!IS_IOS7) ? @"AssetsPickerChecked~iOS6" : @"AssetsPickerChecked"]]];
499 | selectedColor = [UIColor colorWithWhite:1 alpha:0.3];
500 | disabledColor = [UIColor colorWithWhite:1 alpha:0.9];
501 | }
502 |
503 | -(id)initWithFrame:(CGRect)frame{
504 | if (self=[super initWithFrame:frame]) {
505 | _selectView=[[UIImageView alloc] initWithFrame:CGRectMake(frame.size.width-checkedIcon.size.width, frame.size.height-checkedIcon.size.height, checkedIcon.size.width, checkedIcon.size.height)];
506 | [self addSubview:_selectView];
507 | }
508 | return self;
509 | }
510 |
511 | -(void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event{
512 | if (_disabled) {
513 | return;
514 | }
515 |
516 | if (_delegate!=nil&&[_delegate respondsToSelector:@selector(shouldTap:)]) {
517 | if (![_delegate shouldTap:_selected]&&!_selected) {
518 | return;
519 | }
520 | }
521 |
522 | if ((_selected=!_selected)) {
523 | self.backgroundColor=selectedColor;
524 | [_selectView setImage:checkedIcon];
525 | }
526 | else{
527 | self.backgroundColor=[UIColor clearColor];
528 | [_selectView setImage:nil];
529 | }
530 | if (_delegate!=nil&&[_delegate respondsToSelector:@selector(touchSelect:)]) {
531 | [_delegate touchSelect:_selected];
532 | }
533 | }
534 |
535 | -(void)setDisabled:(BOOL)disabled{
536 | _disabled=disabled;
537 | if (_disabled) {
538 | self.backgroundColor=disabledColor;
539 | }
540 | else{
541 | self.backgroundColor=[UIColor clearColor];
542 | }
543 | }
544 |
545 | -(void)setSelected:(BOOL)selected{
546 | if (_disabled) {
547 | self.backgroundColor=disabledColor;
548 | [_selectView setImage:nil];
549 | return;
550 | }
551 |
552 | _selected=selected;
553 | if (_selected) {
554 | self.backgroundColor=selectedColor;
555 | [_selectView setImage:checkedIcon];
556 | }
557 | else{
558 | self.backgroundColor=[UIColor clearColor];
559 | [_selectView setImage:nil];
560 | }
561 | }
562 |
563 | @end
564 |
565 | #pragma mark - ZYQAssetView
566 |
567 | @interface ZYQAssetView ()
568 |
569 | @property (nonatomic, strong) ZYQAsset *asset;
570 |
571 | @property (nonatomic, weak) id delegate;
572 |
573 | @property (nonatomic, retain) UIImageView *imageView;
574 | @property (nonatomic, retain) ZYQVideoTitleView *videoTitle;
575 | @property (nonatomic, retain) ZYQTapAssetView *tapAssetView;
576 |
577 | @end
578 |
579 | @implementation ZYQAssetView
580 |
581 | static UIFont *titleFont = nil;
582 |
583 | static CGFloat titleHeight;
584 | static UIColor *titleColor;
585 |
586 | + (void)initialize
587 | {
588 | titleFont = [UIFont systemFontOfSize:12];
589 | titleHeight = 20.0f;
590 | titleColor = [UIColor whiteColor];
591 | }
592 |
593 | - (id)initWithFrame:(CGRect)frame
594 | {
595 | if (self = [super initWithFrame:frame])
596 | {
597 | self.opaque = YES;
598 | self.isAccessibilityElement = YES;
599 | self.accessibilityTraits = UIAccessibilityTraitImage;
600 |
601 | _imageView=[[UIImageView alloc] initWithFrame:CGRectMake(0, 0, kThumbnailSize.width, kThumbnailSize.height)];
602 | [self addSubview:_imageView];
603 |
604 | _videoTitle=[[ZYQVideoTitleView alloc] initWithFrame:CGRectMake(0, kThumbnailSize.height-20, kThumbnailSize.width, titleHeight)];
605 | _videoTitle.hidden=YES;
606 | _videoTitle.font=titleFont;
607 | _videoTitle.textColor=titleColor;
608 | _videoTitle.textAlignment=NSTextAlignmentRight;
609 | _videoTitle.backgroundColor=[UIColor colorWithWhite:0 alpha:0.6];
610 | [self addSubview:_videoTitle];
611 |
612 | _tapAssetView=[[ZYQTapAssetView alloc] initWithFrame:CGRectMake(0, 0, frame.size.width, frame.size.height)];
613 | _tapAssetView.delegate=self;
614 | [self addSubview:_tapAssetView];
615 | }
616 |
617 | return self;
618 | }
619 |
620 | - (void)bind:(ZYQAsset*)asset selectionFilter:(NSPredicate*)selectionFilter isSeleced:(BOOL)isSeleced
621 | {
622 | self.asset=asset;
623 |
624 | __weak typeof(self) weakSelf=self;
625 | [_asset setGetThumbnail:^(UIImage *result) {
626 | dispatch_async(dispatch_get_main_queue(), ^{
627 | weakSelf.imageView.image=result;
628 | });
629 | }];
630 |
631 |
632 | if (_asset.mediaType==ZYQAssetMediaTypeVideo) {
633 | _videoTitle.hidden=NO;
634 | _videoTitle.text=[NSDate timeDescriptionOfTimeInterval:_asset.duration];
635 | NSLog(@"%@",_videoTitle.text);
636 |
637 | }
638 | else{
639 | _videoTitle.hidden=YES;
640 | }
641 |
642 | _tapAssetView.disabled=! [selectionFilter evaluateWithObject:_asset];
643 |
644 | _tapAssetView.selected=isSeleced;
645 | }
646 |
647 | #pragma mark - ZYQTapAssetView Delegate
648 |
649 | -(BOOL)shouldTap:(BOOL)select{
650 | if (_delegate!=nil&&[_delegate respondsToSelector:@selector(shouldSelectAsset:select:)]) {
651 | return [_delegate shouldSelectAsset:_asset select:select];
652 | }
653 | return YES;
654 | }
655 |
656 | -(void)touchSelect:(BOOL)select{
657 | if (_delegate!=nil&&[_delegate respondsToSelector:@selector(tapSelectHandle:asset:)]) {
658 | [_delegate tapSelectHandle:select asset:_asset];
659 | }
660 | }
661 |
662 | @end
663 |
664 | #pragma mark - ZYQAssetViewCell
665 |
666 | @interface ZYQAssetViewCell ()
667 |
668 | @end
669 |
670 | @class ZYQAssetViewController;
671 |
672 | @implementation ZYQAssetViewCell
673 |
674 | - (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier{
675 | if (self=[super initWithStyle:style reuseIdentifier:reuseIdentifier]) {
676 | [self setSelectionStyle:UITableViewCellSelectionStyleNone];
677 | }
678 | return self;
679 | }
680 |
681 | - (void)bind:(NSArray *)assets selectionFilter:(NSPredicate*)selectionFilter minimumInteritemSpacing:(float)minimumInteritemSpacing minimumLineSpacing:(float)minimumLineSpacing columns:(int)columns assetViewX:(float)assetViewX{
682 |
683 | if (self.contentView.subviews.count((NSInteger)self.contentView.subviews.count-1)) {
686 | ZYQAssetView *assetView=[[ZYQAssetView alloc] initWithFrame:CGRectMake(assetViewX+(kThumbnailSize.width+minimumInteritemSpacing)*i, minimumLineSpacing-1, kThumbnailSize.width, kThumbnailSize.height)];
687 | [assetView bind:assets[i] selectionFilter:selectionFilter isSeleced:[((ZYQAssetViewController*)_delegate).indexPathsForSelectedItems containsObject:assets[i]]];
688 | assetView.delegate=self;
689 | [self.contentView addSubview:assetView];
690 | }
691 | else{
692 | ((ZYQAssetView*)self.contentView.subviews[i]).frame=CGRectMake(assetViewX+(kThumbnailSize.width+minimumInteritemSpacing)*(i), minimumLineSpacing-1, kThumbnailSize.width, kThumbnailSize.height);
693 | [(ZYQAssetView*)self.contentView.subviews[i] bind:assets[i] selectionFilter:selectionFilter isSeleced:[((ZYQAssetViewController*)_delegate).indexPathsForSelectedItems containsObject:assets[i]]];
694 | }
695 |
696 | }
697 |
698 | }
699 | else{
700 | for (NSInteger i=self.contentView.subviews.count; i>0; i--) {
701 | if (i>assets.count) {
702 | [((ZYQAssetView*)self.contentView.subviews[i-1]) removeFromSuperview];
703 | }
704 | else{
705 | ((ZYQAssetView*)self.contentView.subviews[i-1]).frame=CGRectMake(assetViewX+(kThumbnailSize.width+minimumInteritemSpacing)*(i-1), minimumLineSpacing-1, kThumbnailSize.width, kThumbnailSize.height);
706 | [(ZYQAssetView*)self.contentView.subviews[i-1] bind:assets[i-1] selectionFilter:selectionFilter isSeleced:[((ZYQAssetViewController*)_delegate).indexPathsForSelectedItems containsObject:assets[i-1]]];
707 | }
708 | }
709 | }
710 | }
711 |
712 | #pragma mark - ZYQAssetView Delegate
713 |
714 | -(BOOL)shouldSelectAsset:(ZYQAsset*)asset select:(BOOL)select{
715 | if (_delegate!=nil&&[_delegate respondsToSelector:@selector(shouldSelectAsset:select:)]) {
716 | return [_delegate shouldSelectAsset:asset select:select];
717 | }
718 | return YES;
719 | }
720 |
721 | -(void)tapSelectHandle:(BOOL)select asset:(ZYQAsset*)asset{
722 | if (select) {
723 | if (_delegate!=nil&&[_delegate respondsToSelector:@selector(didSelectAsset:)]) {
724 | [_delegate didSelectAsset:asset];
725 | }
726 | }
727 | else{
728 | if (_delegate!=nil&&[_delegate respondsToSelector:@selector(didDeselectAsset:)]) {
729 | [_delegate didDeselectAsset:asset];
730 | }
731 | }
732 | }
733 |
734 | @end
735 |
736 | #pragma mark - ZYQAssetViewController
737 |
738 | @interface ZYQAssetViewController (){
739 | int columns;
740 |
741 | float minimumInteritemSpacing;
742 | float minimumLineSpacing;
743 |
744 | BOOL unFirst;
745 | }
746 |
747 | @property (nonatomic, strong) NSMutableArray *assets;
748 | @property (nonatomic, assign) NSInteger numberOfPhotos;
749 | @property (nonatomic, assign) NSInteger numberOfVideos;
750 |
751 | @end
752 |
753 | #define kAssetViewCellIdentifier @"AssetViewCellIdentifier"
754 |
755 | @implementation ZYQAssetViewController
756 |
757 | - (id)init
758 | {
759 | if (self = [super init])
760 | {
761 | _indexPathsForSelectedItems=[[NSMutableArray alloc] init];
762 |
763 | if (UIInterfaceOrientationIsLandscape([[UIApplication sharedApplication] statusBarOrientation]))
764 | {
765 | self.tableView.contentInset=UIEdgeInsetsMake(9.0, 2.0, 0, 2.0);
766 |
767 | minimumInteritemSpacing=3;
768 | minimumLineSpacing=3;
769 |
770 | }
771 | else
772 | {
773 | self.tableView.contentInset=UIEdgeInsetsMake(9.0, 0, 0, 0);
774 |
775 | minimumInteritemSpacing=2;
776 | minimumLineSpacing=2;
777 | }
778 |
779 | if ([self respondsToSelector:@selector(setEdgesForExtendedLayout:)])
780 | [self setEdgesForExtendedLayout:UIRectEdgeNone];
781 |
782 | if ([self respondsToSelector:@selector(setContentSizeForViewInPopover:)])
783 | [self setPreferredContentSize:kPopoverContentSize];
784 |
785 | }
786 |
787 | [self.tableView setSeparatorStyle:UITableViewCellSeparatorStyleNone];
788 | return self;
789 | }
790 |
791 | - (void)viewDidLoad
792 | {
793 | [super viewDidLoad];
794 |
795 | [self setupViews];
796 | [self setupButtons];
797 | }
798 |
799 | - (void)viewWillAppear:(BOOL)animated
800 | {
801 | [super viewWillAppear:animated];
802 | if (!unFirst) {
803 | columns=floor(self.view.frame.size.width/(kThumbnailSize.width+minimumInteritemSpacing));
804 |
805 | [self setupAssets];
806 |
807 | unFirst=YES;
808 | }
809 | }
810 |
811 |
812 | #pragma mark - Rotation
813 |
814 | - (void)willAnimateRotationToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration
815 | {
816 | if (UIInterfaceOrientationIsLandscape(toInterfaceOrientation))
817 | {
818 | self.tableView.contentInset=UIEdgeInsetsMake(9.0, 0, 0, 0);
819 |
820 | minimumInteritemSpacing=3;
821 | minimumLineSpacing=3;
822 | }
823 | else
824 | {
825 | self.tableView.contentInset=UIEdgeInsetsMake(9.0, 0, 0, 0);
826 |
827 | minimumInteritemSpacing=2;
828 | minimumLineSpacing=2;
829 | }
830 |
831 | columns=floor(self.view.frame.size.width/(kThumbnailSize.width+minimumInteritemSpacing));
832 |
833 | [self.tableView reloadData];
834 | }
835 |
836 | #pragma mark - Setup
837 |
838 | - (void)setupViews
839 | {
840 | self.tableView.backgroundColor = [UIColor whiteColor];
841 | }
842 |
843 | - (void)setupButtons
844 | {
845 | self.navigationItem.rightBarButtonItem =
846 | [[UIBarButtonItem alloc] initWithTitle:NSLocalizedString(@"完成", nil)
847 | style:UIBarButtonItemStylePlain
848 | target:self
849 | action:@selector(finishPickingAssets:)];
850 | }
851 |
852 | - (void)setupAssets
853 | {
854 | self.title = self.assetsGroup.groupName;
855 | self.numberOfPhotos = 0;
856 | self.numberOfVideos = 0;
857 |
858 | if (!self.assets)
859 | self.assets = [[NSMutableArray alloc] init];
860 | else
861 | [self.assets removeAllObjects];
862 |
863 | ZYQAssetPickerController *picker = (ZYQAssetPickerController *)self.navigationController;
864 |
865 | [self.assetsGroup enumerateObjectsUsingBlock:^(id _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
866 | if (obj)
867 | {
868 | ZYQAsset *asset=[[ZYQAsset alloc] init];
869 | asset.originAsset=obj;
870 |
871 | [self.assets addObject:asset];
872 |
873 | switch ([asset mediaType]) {
874 | case ZYQAssetMediaTypeImage:
875 | self.numberOfPhotos ++;
876 | break;
877 | case ZYQAssetMediaTypeVideo:
878 | self.numberOfVideos ++;
879 | break;
880 | default:
881 | break;
882 | }
883 | }
884 |
885 | if (self.assetsGroup.count-1 == idx)
886 | {
887 |
888 | dispatch_async(dispatch_get_main_queue(), ^{
889 | [self.tableView reloadData];
890 |
891 | if (picker.scrollBottom) {
892 | [self.tableView scrollToRowAtIndexPath:[NSIndexPath indexPathForRow:ceil(self.assets.count*1.0/columns) inSection:0] atScrollPosition:UITableViewScrollPositionBottom animated:NO];
893 | }
894 | });
895 | }
896 |
897 | }];
898 |
899 | /**
900 | 将数组倒序
901 | */
902 | if(picker.timeDescSort){
903 | NSArray *tempArray = [[self.assets reverseObjectEnumerator] allObjects];
904 | [self.assets removeAllObjects];
905 | [self.assets addObjectsFromArray:tempArray];
906 | }
907 |
908 |
909 |
910 | }
911 |
912 | #pragma mark - UITableView DataSource
913 | -(UITableViewCell*)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
914 |
915 | if (indexPath.row==ceil(self.assets.count*1.0/columns)) {
916 | UITableViewCell *cell=[tableView dequeueReusableCellWithIdentifier:@"cellFooter"];
917 |
918 | if (cell==nil) {
919 | cell=[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"cellFooter"];
920 | cell.textLabel.font=[UIFont systemFontOfSize:18];
921 | cell.textLabel.backgroundColor=[UIColor clearColor];
922 | cell.textLabel.textAlignment=NSTextAlignmentCenter;
923 | cell.textLabel.textColor=[UIColor blackColor];
924 | cell.backgroundColor=[UIColor clearColor];
925 | [cell setSelectionStyle:UITableViewCellSelectionStyleNone];
926 | }
927 |
928 | NSString *title;
929 |
930 | if (_numberOfVideos == 0)
931 | title = [NSString stringWithFormat:NSLocalizedString(@"%ld 张照片", nil), (long)_numberOfPhotos];
932 | else if (_numberOfPhotos == 0)
933 | title = [NSString stringWithFormat:NSLocalizedString(@"%ld 部视频", nil), (long)_numberOfVideos];
934 | else
935 | title = [NSString stringWithFormat:NSLocalizedString(@"%ld 张照片, %ld 部视频", nil), (long)_numberOfPhotos, (long)_numberOfVideos];
936 |
937 | cell.textLabel.text=title;
938 | return cell;
939 | }
940 |
941 |
942 | NSMutableArray *tempAssets=[[NSMutableArray alloc] init];
943 | for (int i=0; i= vc.maximumNumberOfSelection&&!select) {
983 | if (vc.delegate!=nil&&[vc.delegate respondsToSelector:@selector(assetPickerControllerDidMaximum:)]) {
984 | [vc.delegate assetPickerControllerDidMaximum:vc];
985 | }
986 | }
987 |
988 | return (selectable && _indexPathsForSelectedItems.count < vc.maximumNumberOfSelection);
989 | }
990 |
991 | - (void)didSelectAsset:(id)asset
992 | {
993 | [_indexPathsForSelectedItems addObject:asset];
994 |
995 | ZYQAssetPickerController *vc = (ZYQAssetPickerController *)self.navigationController;
996 | vc.indexPathsForSelectedItems = _indexPathsForSelectedItems;
997 |
998 | if (vc.delegate!=nil&&[vc.delegate respondsToSelector:@selector(assetPickerController:didSelectAsset:)])
999 | [vc.delegate assetPickerController:vc didSelectAsset:asset];
1000 |
1001 | [self setTitleWithSelectedIndexPaths:_indexPathsForSelectedItems];
1002 | }
1003 |
1004 | - (void)didDeselectAsset:(id)asset
1005 | {
1006 | [_indexPathsForSelectedItems removeObject:asset];
1007 |
1008 | ZYQAssetPickerController *vc = (ZYQAssetPickerController *)self.navigationController;
1009 | vc.indexPathsForSelectedItems = _indexPathsForSelectedItems;
1010 |
1011 | if (vc.delegate!=nil&&[vc.delegate respondsToSelector:@selector(assetPickerController:didDeselectAsset:)])
1012 | [vc.delegate assetPickerController:vc didDeselectAsset:asset];
1013 |
1014 | [self setTitleWithSelectedIndexPaths:_indexPathsForSelectedItems];
1015 | }
1016 |
1017 |
1018 | #pragma mark - Title
1019 |
1020 | - (void)setTitleWithSelectedIndexPaths:(NSArray *)indexPaths
1021 | {
1022 | if (indexPaths.count == 0)
1023 | {
1024 | self.title = self.assetsGroup.groupName;
1025 | return;
1026 | }
1027 |
1028 | BOOL photosSelected = NO;
1029 | BOOL videoSelected = NO;
1030 |
1031 | for (int i=0; i 1) ? NSLocalizedString(@"已选择 %ld 张照片", nil) : NSLocalizedString(@"已选择 %ld 张照片 ", nil);
1052 |
1053 | else if (videoSelected)
1054 | format = (indexPaths.count > 1) ? NSLocalizedString(@"已选择 %ld 部视频", nil) : NSLocalizedString(@"已选择 %ld 部视频 ", nil);
1055 |
1056 | self.title = [NSString stringWithFormat:format, (long)indexPaths.count];
1057 |
1058 | }
1059 |
1060 |
1061 | #pragma mark - Actions
1062 |
1063 | - (void)finishPickingAssets:(id)sender
1064 | {
1065 |
1066 | ZYQAssetPickerController *picker = (ZYQAssetPickerController *)self.navigationController;
1067 |
1068 | if (_indexPathsForSelectedItems.count < picker.minimumNumberOfSelection) {
1069 | if (picker.delegate!=nil&&[picker.delegate respondsToSelector:@selector(assetPickerControllerDidMaximum:)]) {
1070 | [picker.delegate assetPickerControllerDidMaximum:picker];
1071 | }
1072 | }
1073 |
1074 |
1075 | if ([picker.delegate respondsToSelector:@selector(assetPickerController:didFinishPickingAssets:)])
1076 | [picker.delegate assetPickerController:picker didFinishPickingAssets:_indexPathsForSelectedItems];
1077 |
1078 | if (picker.isFinishDismissViewController) {
1079 | [picker.presentingViewController dismissViewControllerAnimated:YES completion:NULL];
1080 | }
1081 | }
1082 |
1083 | @end
1084 |
1085 | #pragma mark - ZYQAssetGroupViewCell
1086 |
1087 | @interface ZYQAssetGroupViewCell ()
1088 |
1089 | @property (nonatomic, strong) ZYQAssetsGroup *assetsGroup;
1090 |
1091 | @end
1092 |
1093 | @implementation ZYQAssetGroupViewCell
1094 |
1095 |
1096 | - (void)bind:(ZYQAssetsGroup*)assetsGroup
1097 | {
1098 | self.assetsGroup = assetsGroup;
1099 |
1100 | __weak typeof(self) weakSelf=self;
1101 |
1102 | [_assetsGroup setGetThumbnail:^(UIImage *result) {
1103 | dispatch_async(dispatch_get_main_queue(), ^{
1104 | weakSelf.imageView.image=result;
1105 | [weakSelf setNeedsLayout];
1106 | });
1107 | }];
1108 |
1109 | self.textLabel.text=_assetsGroup.groupName;
1110 | self.detailTextLabel.text = [NSString stringWithFormat:@"%zi", _assetsGroup.count];
1111 | self.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
1112 | }
1113 |
1114 | - (NSString *)accessibilityLabel
1115 | {
1116 | return [_assetsGroup.groupName stringByAppendingFormat:NSLocalizedString(@"%ld 张照片", nil), (long)_assetsGroup.count];
1117 | }
1118 |
1119 | @end
1120 |
1121 |
1122 | #pragma mark - ZYQAssetGroupViewController
1123 |
1124 | @interface ZYQAssetGroupViewController()
1125 |
1126 | @property (nonatomic, strong) ALAssetsLibrary *assetsLibrary;
1127 | @property (nonatomic, strong) NSMutableArray *groups;
1128 |
1129 | @end
1130 |
1131 | @implementation ZYQAssetGroupViewController
1132 |
1133 | - (id)init
1134 | {
1135 | if (self = [super initWithStyle:UITableViewStylePlain])
1136 | {
1137 | #if __IPHONE_OS_VERSION_MIN_REQUIRED >= __IPHONE_7_0
1138 | self.preferredContentSize=kPopoverContentSize;
1139 | #else
1140 | if ([self respondsToSelector:@selector(setContentSizeForViewInPopover:)])
1141 | [self setContentSizeForViewInPopover:kPopoverContentSize];
1142 | #endif
1143 | }
1144 |
1145 | return self;
1146 | }
1147 |
1148 | - (void)viewDidLoad
1149 | {
1150 | [super viewDidLoad];
1151 | [self setupViews];
1152 | [self setupButtons];
1153 | [self localize];
1154 | [self setupGroup];
1155 | }
1156 |
1157 |
1158 | #pragma mark - Rotation
1159 |
1160 | - (BOOL)shouldAutorotate
1161 | {
1162 | return YES;
1163 | }
1164 |
1165 | - (UIInterfaceOrientationMask)supportedInterfaceOrientations
1166 | {
1167 | return UIInterfaceOrientationMaskAllButUpsideDown;
1168 | }
1169 |
1170 |
1171 | #pragma mark - Setup
1172 |
1173 | - (void)setupViews
1174 | {
1175 | self.tableView.rowHeight = kThumbnailLength + 12;
1176 | self.tableView.separatorStyle = UITableViewCellSeparatorStyleNone;
1177 | }
1178 |
1179 | - (void)setupButtons
1180 | {
1181 | ZYQAssetPickerController *picker = (ZYQAssetPickerController *)self.navigationController;
1182 |
1183 | if (picker.showCancelButton)
1184 | {
1185 | self.navigationItem.rightBarButtonItem =
1186 | [[UIBarButtonItem alloc] initWithTitle:NSLocalizedString(@"取消", nil)
1187 | style:UIBarButtonItemStylePlain
1188 | target:self
1189 | action:@selector(dismiss:)];
1190 | }
1191 | }
1192 |
1193 | - (void)localize
1194 | {
1195 | self.title = NSLocalizedString(@"相簿", nil);
1196 | }
1197 |
1198 | - (void)setupGroup
1199 | {
1200 | if (!self.groups)
1201 | self.groups = [[NSMutableArray alloc] init];
1202 | else
1203 | [self.groups removeAllObjects];
1204 |
1205 |
1206 | if (IS_IOS8) {
1207 | __block BOOL showNotAllowed=YES;
1208 | ZYQAssetPickerController *picker = (ZYQAssetPickerController *)self.navigationController;
1209 |
1210 | PHFetchOptions *fetchOptions = [[PHFetchOptions alloc]init];
1211 |
1212 | PHFetchResult *smartAlbumsFetchResult = [PHAssetCollection fetchAssetCollectionsWithType:PHAssetCollectionTypeSmartAlbum subtype:PHAssetCollectionSubtypeSmartAlbumUserLibrary options:fetchOptions];
1213 | //遍历相机胶卷
1214 | [smartAlbumsFetchResult enumerateObjectsUsingBlock:^(PHAssetCollection * _Nonnull collection, NSUInteger idx, BOOL *stop) {
1215 | showNotAllowed=NO;
1216 | PHFetchOptions *fetchOptionsAlbums=[[PHFetchOptions alloc] init];
1217 |
1218 | switch (picker.assetsFilter) {
1219 | case ZYQAssetsFilterAllVideos:
1220 | fetchOptionsAlbums.predicate = [NSPredicate predicateWithFormat:@"mediaType == %d", PHAssetMediaTypeVideo];
1221 | break;
1222 | case ZYQAssetsFilterAllPhotos:
1223 | fetchOptionsAlbums.predicate = [NSPredicate predicateWithFormat:@"mediaType == %d", PHAssetMediaTypeImage];
1224 | break;
1225 | default:
1226 | break;
1227 | }
1228 | PHFetchResult *fetchResult = [PHAsset fetchAssetsInAssetCollection:collection options:fetchOptionsAlbums];
1229 |
1230 |
1231 | if (![collection.localizedTitle isEqualToString:@"Videos"]) {
1232 | if (fetchResult.count>0) {
1233 | ZYQAssetsGroup *tmpGroup=[[ZYQAssetsGroup alloc] init];
1234 | tmpGroup.originAssetGroup=collection;
1235 | tmpGroup.originFetchResult=fetchResult;
1236 | [self.groups addObject:tmpGroup];
1237 | }
1238 | }
1239 | }];
1240 | //遍历自建相册
1241 | PHFetchResult *customAlbumsFetchResult = [PHAssetCollection fetchTopLevelUserCollectionsWithOptions:fetchOptions];
1242 | [customAlbumsFetchResult enumerateObjectsUsingBlock:^(PHAssetCollection * _Nonnull collection, NSUInteger idx, BOOL *stop) {
1243 | showNotAllowed=NO;
1244 |
1245 | PHFetchOptions *fetchOptionsAlbums=[[PHFetchOptions alloc] init];
1246 |
1247 | switch (picker.assetsFilter) {
1248 | case ZYQAssetsFilterAllVideos:
1249 | fetchOptionsAlbums.predicate = [NSPredicate predicateWithFormat:@"mediaType == %d", PHAssetMediaTypeVideo];
1250 | break;
1251 | case ZYQAssetsFilterAllPhotos:
1252 | fetchOptionsAlbums.predicate = [NSPredicate predicateWithFormat:@"mediaType == %d", PHAssetMediaTypeImage];
1253 | break;
1254 | default:
1255 | break;
1256 | }
1257 | PHFetchResult *fetchResult = [PHAsset fetchAssetsInAssetCollection:collection options:fetchOptionsAlbums];
1258 |
1259 | if (fetchResult.count>0) {
1260 | ZYQAssetsGroup *tmpGroup=[[ZYQAssetsGroup alloc] init];
1261 | tmpGroup.originAssetGroup=collection;
1262 | tmpGroup.originFetchResult=fetchResult;
1263 | [self.groups addObject:tmpGroup];
1264 | }
1265 |
1266 | }];
1267 |
1268 | if (showNotAllowed) {
1269 | [self showNotAllowed];
1270 | }
1271 | else
1272 | {
1273 | [self reloadData];
1274 | }
1275 | }
1276 | else{
1277 | if (!self.assetsLibrary)
1278 | self.assetsLibrary = [self.class defaultAssetsLibrary];
1279 |
1280 | ZYQAssetPickerController *picker = (ZYQAssetPickerController *)self.navigationController;
1281 |
1282 | ALAssetsFilter *assetsFilter = [ALAssetsFilter allAssets];
1283 |
1284 | switch (picker.assetsFilter) {
1285 | case ZYQAssetsFilterAllPhotos:
1286 | assetsFilter=[ALAssetsFilter allPhotos];
1287 | break;
1288 | case ZYQAssetsFilterAllVideos:
1289 | assetsFilter=[ALAssetsFilter allVideos];
1290 | break;
1291 | default:
1292 | break;
1293 | }
1294 |
1295 | ALAssetsLibraryGroupsEnumerationResultsBlock resultsBlock = ^(ALAssetsGroup *group, BOOL *stop) {
1296 |
1297 | if (group)
1298 | {
1299 | [group setAssetsFilter:assetsFilter];
1300 | if (group.numberOfAssets > 0 || picker.showEmptyGroups){
1301 | ZYQAssetsGroup *tmpGroup=[[ZYQAssetsGroup alloc] init];
1302 | tmpGroup.originAssetGroup=group;
1303 | [self.groups addObject:tmpGroup];
1304 | }
1305 | }
1306 | else
1307 | {
1308 | [self reloadData];
1309 | }
1310 | };
1311 |
1312 |
1313 | ALAssetsLibraryAccessFailureBlock failureBlock = ^(NSError *error) {
1314 |
1315 | [self showNotAllowed];
1316 |
1317 | };
1318 |
1319 | // Enumerate Camera roll first
1320 | [self.assetsLibrary enumerateGroupsWithTypes:ALAssetsGroupSavedPhotos
1321 | usingBlock:resultsBlock
1322 | failureBlock:failureBlock];
1323 |
1324 | // Then all other groups
1325 | NSUInteger type =
1326 | ALAssetsGroupLibrary | ALAssetsGroupAlbum | ALAssetsGroupEvent |
1327 | ALAssetsGroupFaces | ALAssetsGroupPhotoStream;
1328 |
1329 | [self.assetsLibrary enumerateGroupsWithTypes:type
1330 | usingBlock:resultsBlock
1331 | failureBlock:failureBlock];
1332 | }
1333 |
1334 | }
1335 |
1336 |
1337 | #pragma mark - Reload Data
1338 |
1339 | - (void)reloadData
1340 | {
1341 | if (self.groups.count == 0)
1342 | [self showNoAssets];
1343 |
1344 | [self.tableView reloadData];
1345 | }
1346 |
1347 |
1348 | #pragma mark - ALAssetsLibrary
1349 |
1350 | + (ALAssetsLibrary *)defaultAssetsLibrary
1351 | {
1352 | static dispatch_once_t pred = 0;
1353 | static ALAssetsLibrary *library = nil;
1354 | dispatch_once(&pred, ^{
1355 | library = [[ALAssetsLibrary alloc] init];
1356 | });
1357 | return library;
1358 | }
1359 |
1360 |
1361 | #pragma mark - Not allowed / No assets
1362 |
1363 | - (void)showNotAllowed
1364 | {
1365 | if ([self respondsToSelector:@selector(setEdgesForExtendedLayout:)])
1366 | [self setEdgesForExtendedLayout:UIRectEdgeLeft | UIRectEdgeRight | UIRectEdgeBottom];
1367 |
1368 | self.title = nil;
1369 |
1370 | UIImageView *padlock = [[UIImageView alloc] initWithImage:[UIImage imageWithContentsOfFile:[[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:@"ZYQAssetPicker.Bundle/Images/AssetsPickerLocked@2x.png"]]];
1371 | padlock.translatesAutoresizingMaskIntoConstraints = NO;
1372 |
1373 | UILabel *title = [UILabel new];
1374 | title.translatesAutoresizingMaskIntoConstraints = NO;
1375 | title.preferredMaxLayoutWidth = 304.0f;
1376 |
1377 | UILabel *message = [UILabel new];
1378 | message.translatesAutoresizingMaskIntoConstraints = NO;
1379 | message.preferredMaxLayoutWidth = 304.0f;
1380 |
1381 | title.text = NSLocalizedString(@"此应用无法使用您的照片或视频。", nil);
1382 | title.font = [UIFont boldSystemFontOfSize:17.0];
1383 | title.textColor = [UIColor colorWithRed:129.0/255.0 green:136.0/255.0 blue:148.0/255.0 alpha:1];
1384 | title.textAlignment = NSTextAlignmentCenter;
1385 | title.numberOfLines = 5;
1386 |
1387 | message.text = NSLocalizedString(@"你可以在「隐私设置」中启用存取。", nil);
1388 | message.font = [UIFont systemFontOfSize:14.0];
1389 | message.textColor = [UIColor colorWithRed:129.0/255.0 green:136.0/255.0 blue:148.0/255.0 alpha:1];
1390 | message.textAlignment = NSTextAlignmentCenter;
1391 | message.numberOfLines = 5;
1392 |
1393 | [title sizeToFit];
1394 | [message sizeToFit];
1395 |
1396 | UIView *centerView = [UIView new];
1397 | centerView.translatesAutoresizingMaskIntoConstraints = NO;
1398 | [centerView addSubview:padlock];
1399 | [centerView addSubview:title];
1400 | [centerView addSubview:message];
1401 |
1402 | NSDictionary *viewsDictionary = NSDictionaryOfVariableBindings(padlock, title, message);
1403 |
1404 | [centerView addConstraint:[NSLayoutConstraint constraintWithItem:padlock attribute:NSLayoutAttributeCenterX relatedBy:NSLayoutRelationEqual toItem:centerView attribute:NSLayoutAttributeCenterX multiplier:1.0f constant:0.0f]];
1405 | [centerView addConstraint:[NSLayoutConstraint constraintWithItem:title attribute:NSLayoutAttributeCenterX relatedBy:NSLayoutRelationEqual toItem:padlock attribute:NSLayoutAttributeCenterX multiplier:1.0f constant:0.0f]];
1406 | [centerView addConstraint:[NSLayoutConstraint constraintWithItem:message attribute:NSLayoutAttributeCenterX relatedBy:NSLayoutRelationEqual toItem:padlock attribute:NSLayoutAttributeCenterX multiplier:1.0f constant:0.0f]];
1407 | [centerView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|[padlock]-[title]-[message]|" options:0 metrics:nil views:viewsDictionary]];
1408 |
1409 | UIView *backgroundView = [UIView new];
1410 | [backgroundView addSubview:centerView];
1411 | [backgroundView addConstraint:[NSLayoutConstraint constraintWithItem:centerView attribute:NSLayoutAttributeCenterX relatedBy:NSLayoutRelationEqual toItem:backgroundView attribute:NSLayoutAttributeCenterX multiplier:1.0f constant:0.0f]];
1412 | [backgroundView addConstraint:[NSLayoutConstraint constraintWithItem:centerView attribute:NSLayoutAttributeCenterY relatedBy:NSLayoutRelationEqual toItem:backgroundView attribute:NSLayoutAttributeCenterY multiplier:1.0f constant:0.0f]];
1413 |
1414 | self.tableView.backgroundView = backgroundView;
1415 | }
1416 |
1417 | - (void)showNoAssets
1418 | {
1419 | if ([self respondsToSelector:@selector(setEdgesForExtendedLayout:)])
1420 | [self setEdgesForExtendedLayout:UIRectEdgeLeft | UIRectEdgeRight | UIRectEdgeBottom];
1421 |
1422 | UILabel *title = [UILabel new];
1423 | title.translatesAutoresizingMaskIntoConstraints = NO;
1424 | title.preferredMaxLayoutWidth = 304.0f;
1425 | UILabel *message = [UILabel new];
1426 | message.translatesAutoresizingMaskIntoConstraints = NO;
1427 | message.preferredMaxLayoutWidth = 304.0f;
1428 |
1429 | title.text = NSLocalizedString(@"没有照片或视频。", nil);
1430 | title.font = [UIFont systemFontOfSize:26.0];
1431 | title.textColor = [UIColor colorWithRed:153.0/255.0 green:153.0/255.0 blue:153.0/255.0 alpha:1];
1432 | title.textAlignment = NSTextAlignmentCenter;
1433 | title.numberOfLines = 5;
1434 |
1435 | message.text = NSLocalizedString(@"您可以使用 iTunes 将照片和视频\n同步到 iPhone。", nil);
1436 | message.font = [UIFont systemFontOfSize:18.0];
1437 | message.textColor = [UIColor colorWithRed:153.0/255.0 green:153.0/255.0 blue:153.0/255.0 alpha:1];
1438 | message.textAlignment = NSTextAlignmentCenter;
1439 | message.numberOfLines = 5;
1440 |
1441 | [title sizeToFit];
1442 | [message sizeToFit];
1443 |
1444 | UIView *centerView = [UIView new];
1445 | centerView.translatesAutoresizingMaskIntoConstraints = NO;
1446 | [centerView addSubview:title];
1447 | [centerView addSubview:message];
1448 |
1449 | NSDictionary *viewsDictionary = NSDictionaryOfVariableBindings(title, message);
1450 |
1451 | [centerView addConstraint:[NSLayoutConstraint constraintWithItem:title attribute:NSLayoutAttributeCenterX relatedBy:NSLayoutRelationEqual toItem:centerView attribute:NSLayoutAttributeCenterX multiplier:1.0f constant:0.0f]];
1452 | [centerView addConstraint:[NSLayoutConstraint constraintWithItem:message attribute:NSLayoutAttributeCenterX relatedBy:NSLayoutRelationEqual toItem:title attribute:NSLayoutAttributeCenterX multiplier:1.0f constant:0.0f]];
1453 | [centerView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|[title]-[message]|" options:0 metrics:nil views:viewsDictionary]];
1454 |
1455 | UIView *backgroundView = [UIView new];
1456 | [backgroundView addSubview:centerView];
1457 | [backgroundView addConstraint:[NSLayoutConstraint constraintWithItem:centerView attribute:NSLayoutAttributeCenterX relatedBy:NSLayoutRelationEqual toItem:backgroundView attribute:NSLayoutAttributeCenterX multiplier:1.0f constant:0.0f]];
1458 | [backgroundView addConstraint:[NSLayoutConstraint constraintWithItem:centerView attribute:NSLayoutAttributeCenterY relatedBy:NSLayoutRelationEqual toItem:backgroundView attribute:NSLayoutAttributeCenterY multiplier:1.0f constant:0.0f]];
1459 |
1460 | self.tableView.backgroundView = backgroundView;
1461 | }
1462 |
1463 |
1464 |
1465 | #pragma mark - Table view data source
1466 |
1467 | - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
1468 | {
1469 | return 1;
1470 | }
1471 |
1472 | - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
1473 | {
1474 | return self.groups.count;
1475 | }
1476 |
1477 | - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
1478 | {
1479 | static NSString *CellIdentifier = @"Cell";
1480 |
1481 | ZYQAssetGroupViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
1482 | if (cell == nil)
1483 | {
1484 | cell = [[ZYQAssetGroupViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier];
1485 | }
1486 |
1487 | [cell bind:[self.groups objectAtIndex:indexPath.row]];
1488 |
1489 | return cell;
1490 | }
1491 |
1492 |
1493 | #pragma mark - UITableView Delegate
1494 |
1495 | - (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
1496 | {
1497 | return kThumbnailLength + 12;
1498 | }
1499 |
1500 | - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
1501 | {
1502 | ZYQAssetViewController *vc = [[ZYQAssetViewController alloc] init];
1503 | vc.assetsGroup = [self.groups objectAtIndex:indexPath.row];
1504 |
1505 | [self.navigationController pushViewController:vc animated:YES];
1506 | }
1507 |
1508 | #pragma mark - Actions
1509 |
1510 | - (void)dismiss:(id)sender
1511 | {
1512 | ZYQAssetPickerController *picker = (ZYQAssetPickerController *)self.navigationController;
1513 |
1514 | if ([picker.delegate respondsToSelector:@selector(assetPickerControllerDidCancel:)])
1515 | [picker.delegate assetPickerControllerDidCancel:picker];
1516 |
1517 | [picker.presentingViewController dismissViewControllerAnimated:YES completion:NULL];
1518 | }
1519 |
1520 | @end
1521 |
1522 | #pragma mark - ZYQAssetPickerController
1523 |
1524 | @implementation ZYQAssetPickerController
1525 |
1526 | @dynamic delegate;
1527 |
1528 | - (id)init
1529 | {
1530 | ZYQAssetGroupViewController *groupViewController = [[ZYQAssetGroupViewController alloc] init];
1531 |
1532 | if (self = [super initWithRootViewController:groupViewController])
1533 | {
1534 | _maximumNumberOfSelection = 10;
1535 | _minimumNumberOfSelection = 0;
1536 | _assetsFilter = ZYQAssetsFilterAllAssets;
1537 | _showCancelButton = YES;
1538 | _showEmptyGroups = NO;
1539 | _selectionFilter = [NSPredicate predicateWithValue:YES];
1540 | _isFinishDismissViewController = YES;
1541 |
1542 | #if __IPHONE_OS_VERSION_MIN_REQUIRED >= __IPHONE_7_0
1543 | self.preferredContentSize=kPopoverContentSize;
1544 | #else
1545 | if ([self respondsToSelector:@selector(setContentSizeForViewInPopover:)])
1546 | [self setContentSizeForViewInPopover:kPopoverContentSize];
1547 | #endif
1548 | }
1549 |
1550 | return self;
1551 | }
1552 |
1553 | - (void)viewDidLoad
1554 | {
1555 | [super viewDidLoad];
1556 | }
1557 |
1558 | - (void)didReceiveMemoryWarning
1559 | {
1560 | [super didReceiveMemoryWarning];
1561 | }
1562 |
1563 | @end
1564 |
--------------------------------------------------------------------------------