您的位置:首页 > 移动开发 > IOS开发

iOS开发 - OC之MWPhotoBrowser框架的使用步骤

2017-05-11 15:06 956 查看
下载MWPhotoBrowser

地址:https://github.com/mwaterfall/MWPhotoBrowser

突然发现并不像以前那样把框架拖进去导入头文件就可以使用,现在压根都没有封装好的库给我们拖,而且MWPhotoBrowser还依赖其他很多库,所以你不但要各种下载支持库,还要配置。所以推荐使用CocoaPods,轻轻松松完成各种配置。而且框架更新了,还会提示更新。至于有什么好处,怎样使用,自己百度一下吧,下次在整理CocoaPods的使用文章给大家。
使用pod方式



完成之后,不要着急,先运行一次。曾经试过一pod进来运行就出现一大推错误,大多是版本问题,所以pod的时候看看自己的项目是否对应起来,建议pod的时候写上6.0以上的



OK,没问题之后开始使用

看代码吧,直观
先从简单的开始,加载本地图片,把下面代码直接复制到- (void)viewDidLoad方法中

// Browser
NSMutableArray *photos = [[NSMutableArray alloc] init];
NSMutableArray *thumbs = [[NSMutableArray alloc] init];
MWPhoto *photo;
BOOL displayActionButton = YES;
BOOL displaySelectionButtons = YES;
BOOL displayNavArrows = YES;
BOOL enableGrid = YES;
BOOL startOnGrid = YES;

// Photos
photo = [MWPhoto photoWithImage:[UIImage imageWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"MWPhotoBrowser5" ofType:@".png"]]];
// caption图片的描述
photo.caption = @"Fireworks";
[photos addObject:photo];
photo = [MWPhoto photoWithImage:[UIImage imageWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"MWPhotoBrowser5t" ofType:@".png"]]];
photo.caption = @"The London Eye is a giant Ferris wheel situated on the banks of the River Thames, in London, England.";
[photos addObject:photo];
photo = [MWPhoto photoWithImage:[UIImage imageWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"MWPhotoBrowser6" ofType:@".png"]]];
photo.caption = @"York Floods";
[photos addObject:photo];
photo = [MWPhoto photoWithImage:[UIImage imageWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"MWPhotoBrowser6t" ofType:@".png"]]];
photo.caption = @"Campervan";
[photos addObject:photo];

// Options
self.photos = photos;
self.thumbs = thumbs;

//
// Create browser
MWPhotoBrowser *browser = [[MWPhotoBrowser alloc] initWithDelegate:self];
browser.displayActionButton = displayActionButton;//分享按钮,默认是
browser.displayNavArrows = displayNavArrows;//左右分页切换,默认否
browser.displaySelectionButtons = displaySelectionButtons;//是否显示选择按钮在图片上,默认否
browser.alwaysShowControls = displaySelectionButtons;//控制条件控件 是否显示,默认否
browser.zoomPhotosToFill = NO;//是否全屏,默认是
#if __IPHONE_OS_VERSION_MIN_REQUIRED < __IPHONE_7_0
browser.wantsFullScreenLayout = YES;//是否全屏
#endif
browser.enableGrid = enableGrid;//是否允许用网格查看所有图片,默认是
browser.startOnGrid = startOnGrid;//是否第一张,默认否
browser.enableSwipeToDismiss = YES;
[browser showNextPhotoAnimated:YES];
[browser showPreviousPhotoAnimated:YES];
[browser setCurrentPhotoIndex:0];

if (displaySelectionButtons) {
_selections = [NSMutableArray new];
for (int i = 0; i < photos.count; i++) {
[_selections addObject:[NSNumber numberWithBool:NO]];
}
}
// ------------------------这里非常重要,对于基础不扎实的同学。首先你的新工程有没有根控制器UINavigationController或者是UITabBarController,如果没有根控制器,你的ViewController就不是根控制器的子控制器,所以你使用[self.navigationController pushViewController:browser animated:YES];是没有效果的。当然你想只是看看效果,使用[self presentViewController:browser animated:YES completion:nil];就可以了------------------------
//        [self presentViewController:browser animated:YES completion:nil];

[self.navigationController pushViewController:browser animated:YES];
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
[/code]

必须实现代理的方法



#pragma mark - MWPhotoBrowserDelegate
/**
*  告诉他你有多少图片
*
*  @param photoBrowser photoBrowser
*
*  @return count
*/
- (NSUInteger)numberOfPhotosInPhotoBrowser:(MWPhotoBrowser *)photoBrowser {
return _photos.count;
}

/**
*  通过下标获取图片
*/
* (id )photoBrowser:(MWPhotoBrowser *)photoBrowser photoAtIndex:(NSUInteger)index {
if (index < _photos.count)
return [_photos objectAtIndex:index];
return nil;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
[/code]

好了,基本可以使用了。但是很多时候,我们要访问的是我们手机里面的图片,怎么办呢?尼玛,超级复杂。iOS 8.0 以前的使用AssetsLibrary,8.0以后改成了Photos。先不说现在要判断一下系统使用的是哪个,单单使用它们也超级蛋疼。非常蛋疼
先看看代码吧

#pragma mark - Load Assets

- (void)loadAssets {
if (NSClassFromString(@"PHAsset")) {

// Check library permissions
PHAuthorizationStatus status = [PHPhotoLibrary authorizationStatus];
if (status == PHAuthorizationStatusNotDetermined) { // 没有提醒状态
[PHPhotoLibrary requestAuthorization:^(PHAuthorizationStatus status) {
if (status == PHAuthorizationStatusAuthorized) { // 授权成功
// 加载资源
[self performLoadAssets];
}
}];
} else if (status == PHAuthorizationStatusAuthorized) { // 授权成功
// 加载资源
[self performLoadAssets];
}

} else {

// Assets library
// 加载资源
[self performLoadAssets];

}
}

- (void)performLoadAssets {

// Initialise
_assets = [NSMutableArray new];

// Load
if (NSClassFromString(@"PHAsset")) {

// Photos library iOS >= 8
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
// options设置相关参数
PHFetchOptions *options = [PHFetchOptions new];
options.sortDescriptors = @[[NSSortDescriptor sortDescriptorWithKey:@"creationDate" ascending:NO]];
PHFetchResult *fetchResults = [PHAsset fetchAssetsWithOptions:options];
// 遍历
[fetchResults enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
[_assets addObject:obj];
}];

});

} else {

// Assets Library iOS < 8
_ALAssetsLibrary = [[ALAssetsLibrary alloc] init];

// Run in the background as it takes a while to get all assets from the library
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{

NSMutableArray *assetGroups = [[NSMutableArray alloc] init];
NSMutableArray *assetURLDictionaries = [[NSMutableArray alloc] init];

// Process assets
void (^assetEnumerator)(ALAsset *, NSUInteger, BOOL *) = ^(ALAsset *result, NSUInteger index, BOOL *stop) {
if (result != nil) {
// 获取asset类型
NSString *assetType = [result valueForProperty:ALAssetPropertyType];
// 判断类型
if ([assetType isEqualToString:ALAssetTypePhoto] || [assetType isEqualToString:ALAssetTypeVideo]) {
[assetURLDictionaries addObject:[result valueForProperty:ALAssetPropertyURLs]];
NSURL *url = result.defaultRepresentation.url;
[_ALAssetsLibrary assetForURL:url
resultBlock:^(ALAsset *asset) {
if (asset) {
@synchronized(_assets) {
[_assets addObject:asset];
}
}
}
failureBlock:^(NSError *error){
NSLog(@"operation was not successfull!");
}];

}
}
};

// Process groups
void (^ assetGroupEnumerator) (ALAssetsGroup *, BOOL *) = ^(ALAssetsGroup *group, BOOL *stop) {
if (group != nil) {
[group enumerateAssetsWithOptions:NSEnumerationReverse usingBlock:assetEnumerator];
[assetGroups addObject:group];
}
};

// Process!
[_ALAssetsLibrary enumerateGroupsWithTypes:ALAssetsGroupAll
usingBlock:assetGroupEnumerator
failureBlock:^(NSError *error) {
NSLog(@"There is an error");
}];

});

}

}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
[/code]

是不是很多代码,然而这只是冰山一角,仅仅是加载了相册的图片资源。数组里面不是PHAsset就是ALAsset,你以为这样就完了,NO。。。。
虽然这两个对象都有图片的各种信息,可是我只要图片。。。。。

看代码

//
// ViewController.m
// TestMWPhotoBrowers
//
// Created by FTY on 16/3/8.
// Copyright © 2016年 FTY. All rights reserved.
//

#import "ViewController.h"
#import <AssetsLibrary/AssetsLibrary.h>
#import <Photos/Photos.h>
#import "MWPhotoBrowser.h"

@interface ViewController () <MWPhotoBrowserDelegate>
{
// 选中的图片
NSMutableArray *_selections;
}
/**
* 图片集合
*/
@property (nonatomic, strong) NSMutableArray *photos;
/**
* 缩略图集合
*/
@property (strong, nonatomic) NSMutableArray *thumbs;
/**
* 相册集合
*/
@property (nonatomic, strong) NSMutableArray *assets;
/**
* ALAssetsLibrary库
*/
@property (nonatomic, strong) ALAssetsLibrary *ALAssetsLibrary;

@end

@implementation ViewController

- (void)viewDidLoad {
[super viewDidLoad];
// 加载资源
[self loadAssets];

UIButton *button = [UIButton buttonWithType:UIButtonTypeContactAdd];
button.frame = CGRectMake(100, 100, 100, 100);
[self.view addSubview:button];
[button addTarget:self action:@selector(test) forControlEvents:UIControlEventTouchUpInside];
}

- (void)test{
// Browser
NSMutableArray *photos = [[NSMutableArray alloc] init];
NSMutableArray *thumbs = [[NSMutableArray alloc] init];

BOOL displayActionButton = YES;
BOOL displaySelectionButtons = YES;
BOOL displayNavArrows = YES;
BOOL enableGrid = YES;
BOOL startOnGrid = YES;

// Options
@synchronized(_assets) {
NSMutableArray *copy = [_assets copy];
if (NSClassFromString(@"PHAsset")) {
// Photos library
UIScreen *screen = [UIScreen mainScreen];
CGFloat scale = screen.scale;
// Sizing is very rough... more thought required in a real implementation
CGFloat imageSize = MAX(screen.bounds.size.width, screen.bounds.size.height) * 1.5;
CGSize imageTargetSize = CGSizeMake(imageSize * scale, imageSize * scale);
CGSize thumbTargetSize = CGSizeMake(imageSize / 3.0 * scale, imageSize / 3.0 * scale);
for (PHAsset *asset in copy) {
[photos addObject:[MWPhoto photoWithAsset:asset targetSize:imageTargetSize]];
[thumbs addObject:[MWPhoto photoWithAsset:asset targetSize:thumbTargetSize]];
}
} else {
// Assets library
for (ALAsset *asset in copy) {
MWPhoto *photo = [MWPhoto photoWithURL:asset.defaultRepresentation.url];
[photos addObject:photo];
MWPhoto *thumb = [MWPhoto photoWithImage:[UIImage imageWithCGImage:asset.thumbnail]];
[thumbs addObject:thumb];
}
}
}

self.photos = photos;
self.thumbs = thumbs;

//
// Create browser
MWPhotoBrowser *browser = [[MWPhotoBrowser alloc] initWithDelegate:self];
browser.displayActionButton = displayActionButton;//分享按钮,默认是
browser.displayNavArrows = displayNavArrows;//左右分页切换,默认否
browser.displaySelectionButtons = displaySelectionButtons;//是否显示选择按钮在图片上,默认否
browser.alwaysShowControls = displaySelectionButtons;//控制条件控件 是否显示,默认否
browser.zoomPhotosToFill = NO;//是否全屏,默认是
#if __IPHONE_OS_VERSION_MIN_REQUIRED < __IPHONE_7_0
browser.wantsFullScreenLayout = YES;//是否全屏
#endif
browser.enableGrid = enableGrid;//是否允许用网格查看所有图片,默认是
browser.startOnGrid = startOnGrid;//是否第一张,默认否
browser.enableSwipeToDismiss = YES;
[browser showNextPhotoAnimated:YES];
[browser showPreviousPhotoAnimated:YES];
[browser setCurrentPhotoIndex:0];

if (displaySelectionButtons) {
_selections = [NSMutableArray new];
for (int i = 0; i < photos.count; i++) {
[_selections addObject:[NSNumber numberWithBool:NO]];
}
}

// [self presentViewController:browser animated:YES completion:nil];

[self.navigationController pushViewController:browser animated:YES];
}

#pragma mark - Load Assets - (void)loadAssets { if (NSClassFromString(@"PHAsset")) { // Check library permissions PHAuthorizationStatus status = [PHPhotoLibrary authorizationStatus]; if (status == PHAuthorizationStatusNotDetermined) { // 没有提醒状态 [PHPhotoLibrary requestAuthorization:^(PHAuthorizationStatus status) { if (status == PHAuthorizationStatusAuthorized) { // 授权成功 // 加载资源 [self performLoadAssets]; } }]; } else if (status == PHAuthorizationStatusAuthorized) { // 授权成功 // 加载资源 [self performLoadAssets]; } } else { // Assets library // 加载资源 [self performLoadAssets]; } } - (void)performLoadAssets { // Initialise _assets = [NSMutableArray new]; // Load if (NSClassFromString(@"PHAsset")) { // Photos library iOS >= 8 dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ // options设置相关参数 PHFetchOptions *options = [PHFetchOptions new]; options.sortDescriptors = @[[NSSortDescriptor sortDescriptorWithKey:@"creationDate" ascending:NO]]; PHFetchResult *fetchResults = [PHAsset fetchAssetsWithOptions:options]; // 遍历 [fetchResults enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) { [_assets addObject:obj]; }]; }); } else { // Assets Library iOS < 8 _ALAssetsLibrary = [[ALAssetsLibrary alloc] init]; // Run in the background as it takes a while to get all assets from the library dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ NSMutableArray *assetGroups = [[NSMutableArray alloc] init]; NSMutableArray *assetURLDictionaries = [[NSMutableArray alloc] init]; // Process assets void (^assetEnumerator)(ALAsset *, NSUInteger, BOOL *) = ^(ALAsset *result, NSUInteger index, BOOL *stop) { if (result != nil) { // 获取asset类型 NSString *assetType = [result valueForProperty:ALAssetPropertyType]; // 判断类型 if ([assetType isEqualToString:ALAssetTypePhoto] || [assetType isEqualToString:ALAssetTypeVideo]) { [assetURLDictionaries addObject:[result valueForProperty:ALAssetPropertyURLs]]; NSURL *url = result.defaultRepresentation.url; [_ALAssetsLibrary assetForURL:url resultBlock:^(ALAsset *asset) { if (asset) { @synchronized(_assets) { [_assets addObject:asset]; } } } failureBlock:^(NSError *error){ NSLog(@"operation was not successfull!"); }]; } } }; // Process groups void (^ assetGroupEnumerator) (ALAssetsGroup *, BOOL *) = ^(ALAssetsGroup *group, BOOL *stop) { if (group != nil) { [group enumerateAssetsWithOptions:NSEnumerationReverse usingBlock:assetEnumerator]; [assetGroups addObject:group]; } }; // Process! [_ALAssetsLibrary enumerateGroupsWithTypes:ALAssetsGroupAll usingBlock:assetGroupEnumerator failureBlock:^(NSError *error) { NSLog(@"There is an error"); }]; }); } }

#pragma mark - MWPhotoBrowserDelegate
/**
* 告诉他你有多少图片
*
* @param photoBrowser photoBrowser
*
* @return count
*/
- (NSUInteger)numberOfPhotosInPhotoBrowser:(MWPhotoBrowser *)photoBrowser {
return _photos.count;
}

/**
* 通过下标获取图片
*/
- (id )photoBrowser:(MWPhotoBrowser *)photoBrowser photoAtIndex:(NSUInteger)index {
if (index < _photos.count)
return [_photos objectAtIndex:index];
return nil;
}

- (void)photoBrowser:(MWPhotoBrowser *)photoBrowser didDisplayPhotoAtIndex:(NSUInteger)index {
NSLog(@"Did start viewing photo at index %lu", (unsigned long)index);
}

- (BOOL)photoBrowser:(MWPhotoBrowser *)photoBrowser isPhotoSelectedAtIndex:(NSUInteger)index {
return [[_selections objectAtIndex:index] boolValue];
}

- (void)photoBrowser:(MWPhotoBrowser *)photoBrowser photoAtIndex:(NSUInteger)index selectedChanged:(BOOL)selected {
[_selections replaceObjectAtIndex:index withObject:[NSNumber numberWithBool:selected]];
NSLog(@"Photo at index %lu selected %@", (unsigned long)index, selected ? @"YES" : @"NO");
}

- (void)photoBrowserDidFinishModalPresentation:(MWPhotoBrowser *)photoBrowser {
// If we subscribe to this method we must dismiss the view controller ourselves
NSLog(@"Did finish modal presentation");
[self dismissViewControllerAnimated:YES completion:nil];
}

@end
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
[/code]

你会发现,会报错,原因是作业根本没有提供[MWPhoto photoWithAsset:asset targetSize:imageTargetSize]这个类方法给你,而且拿到PHAsset也不会使用。放心,原作者有提供demo,把它补上去。

//
//  MWPhoto.h
//  MWPhotoBrowser
//
//  Created by Michael Waterfall on 17/10/2010.
//  Copyright 2010 d3i. All rights reserved.
//

#import <Foundation/Foundation.h>
#import "MWPhotoProtocol.h"

#import <Photos/Photos.h>
// This class models a photo/image and it's caption
// If you want to handle photos, caching, decompression
// yourself then you can simply ensure your custom data model
// conforms to MWPhotoProtocol
@interface MWPhoto : NSObject <MWPhoto>

@property (nonatomic, strong) NSString *caption;
@property (nonatomic, readonly) UIImage *image;
@property (nonatomic, readonly) NSURL *photoURL;
@property (nonatomic, readonly) NSString *filePath  __attribute__((deprecated("Use photoURL"))); // Depreciated

@property (nonatomic) BOOL isVideo;

+ (MWPhoto *)photoWithImage:(UIImage *)image;
+ (MWPhoto *)photoWithFilePath:(NSString *)path  __attribute__((deprecated("Use photoWithURL: with a file URL"))); // Depreciated
+ (MWPhoto *)photoWithURL:(NSURL *)url;

+ (MWPhoto *)photoWithAsset:(PHAsset *)asset targetSize:(CGSize)targetSize;

- (id)initWithImage:(UIImage *)image;
- (id)initWithURL:(NSURL *)url;
- (id)initWithFilePath:(NSString *)path  __attribute__((deprecated("Use initWithURL: with a file URL"))); // Depreciated

- (id)initWithAsset:(PHAsset *)asset targetSize:(CGSize)targetSize;

@end
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
[/code]
//
//  MWPhoto.m
//  MWPhotoBrowser
//
//  Created by Michael Waterfall on 17/10/2010.
//  Copyright 2010 d3i. All rights reserved.
//

#import "MWPhoto.h"
#import "MWPhotoBrowser.h"
#import "SDWebImageDecoder.h"
#import "SDWebImageManager.h"
#import "SDWebImageOperation.h"
#import <AssetsLibrary/AssetsLibrary.h>

@interface MWPhoto () {

BOOL _loadingInProgress;
id <SDWebImageOperation> _webImageOperation;
PHImageRequestID _assetRequestID;
}

@property (nonatomic, strong) PHAsset *asset;
@property (nonatomic) CGSize assetTargetSize;

- (void)imageLoadingComplete;

@end

@implementation MWPhoto

@synthesize underlyingImage = _underlyingImage; // synth property from protocol

#pragma mark - Class Methods

+ (MWPhoto *)photoWithImage:(UIImage *)image {
return [[MWPhoto alloc] initWithImage:image];
}

// Deprecated
+ (MWPhoto *)photoWithFilePath:(NSString *)path {
return [MWPhoto photoWithURL:[NSURL fileURLWithPath:path]];
}

+ (MWPhoto *)photoWithURL:(NSURL *)url {
return [[MWPhoto alloc] initWithURL:url];
}

+ (MWPhoto *)photoWithAsset:(PHAsset *)asset targetSize:(CGSize)targetSize {
return [[MWPhoto alloc] initWithAsset:asset targetSize:targetSize];
}

#pragma mark - Init

- (id)initWithImage:(UIImage *)image {
if ((self = [super init])) {
_image = image;
}
return self;
}

// Deprecated
- (id)initWithFilePath:(NSString *)path {
if ((self = [super init])) {
_photoURL = [NSURL fileURLWithPath:path];
}
return self;
}

- (id)initWithURL:(NSURL *)url {
if ((self = [super init])) {
_photoURL = [url copy];
}
return self;
}
- (id)initWithAsset:(PHAsset *)asset targetSize:(CGSize)targetSize {
if ((self = [super init])) {
self.asset = asset;
self.assetTargetSize = targetSize;
self.isVideo = asset.mediaType == PHAssetMediaTypeVideo;
}
return self;
}

#pragma mark - MWPhoto Protocol Methods

- (UIImage *)underlyingImage {
return _underlyingImage;
}

- (void)loadUnderlyingImageAndNotify {
NSAssert([[NSThread currentThread] isMainThread], @"This method must be called on the main thread.");
if (_loadingInProgress) return;
_loadingInProgress = YES;
@try {
if (self.underlyingImage) {
[self imageLoadingComplete];
} else {
[self performLoadUnderlyingImageAndNotify];
}
}
@catch (NSException *exception) {
self.underlyingImage = nil;
_loadingInProgress = NO;
[self imageLoadingComplete];
}
@finally {
}
}

// Set the underlyingImage
- (void)performLoadUnderlyingImageAndNotify {

// Get underlying image
if (_image) {

// We have UIImage!
self.underlyingImage = _image;
[self imageLoadingComplete];

} else if (_photoURL) {

// Check what type of url it is
if ([[[_photoURL scheme] lowercaseString] isEqualToString:@"assets-library"]) {

// Load from asset library async
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
@autoreleasepool {
@try {
ALAssetsLibrary *assetslibrary = [[ALAssetsLibrary alloc] init];
[assetslibrary assetForURL:_photoURL
resultBlock:^(ALAsset *asset){
ALAssetRepresentation *rep = [asset defaultRepresentation];
CGImageRef iref = [rep fullScreenImage];
if (iref) {
self.underlyingImage = [UIImage imageWithCGImage:iref];
}
[self performSelectorOnMainThread:@selector(imageLoadingComplete) withObject:nil waitUntilDone:NO];
}
failureBlock:^(NSError *error) {
self.underlyingImage = nil;
MWLog(@"Photo from asset library error: %@",error);
[self performSelectorOnMainThread:@selector(imageLoadingComplete) withObject:nil waitUntilDone:NO];
}];
} @catch (NSException *e) {
MWLog(@"Photo from asset library error: %@", e);
[self performSelectorOnMainThread:@selector(imageLoadingComplete) withObject:nil waitUntilDone:NO];
}
}
});

} else if ([_photoURL isFileReferenceURL]) {

// Load from local file async
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
@autoreleasepool {
@try {
self.underlyingImage = [UIImage imageWithContentsOfFile:_photoURL.path];
if (!_underlyingImage) {
MWLog(@"Error loading photo from path: %@", _photoURL.path);
}
} @finally {
[self performSelectorOnMainThread:@selector(imageLoadingComplete) withObject:nil waitUntilDone:NO];
}
}
});

} else {

// Load async from web (using SDWebImage)
@try {
SDWebImageManager *manager = [SDWebImageManager sharedManager];
_webImageOperation = [manager downloadImageWithURL:_photoURL
options:0
progress:^(NSInteger receivedSize, NSInteger expectedSize) {
if (expectedSize > 0) {
float progress = receivedSize / (float)expectedSize;
NSDictionary* dict = [NSDictionary dictionaryWithObjectsAndKeys:
[NSNumber numberWithFloat:progress], @"progress",
self, @"photo", nil];
[[NSNotificationCenter defaultCenter] postNotificationName:MWPHOTO_PROGRESS_NOTIFICATION object:dict];
}
}
completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType, BOOL finished, NSURL *imageURL) {
if (error) {
MWLog(@"SDWebImage failed to download image: %@", error);
}
_webImageOperation = nil;
self.underlyingImage = image;
[self imageLoadingComplete];
}];
} @catch (NSException *e) {
MWLog(@"Photo from web: %@", e);
_webImageOperation = nil;
[self imageLoadingComplete];
}

}

}
else if (_asset){
[self _performLoadUnderlyingImageAndNotifyWithAsset: _asset targetSize:_assetTargetSize];

} else {

// Failed - no source
@throw [NSException exceptionWithName:@"Failed - no source" reason:nil userInfo:nil];

}
}

// Load from photos library
- (void)_performLoadUnderlyingImageAndNotifyWithAsset:(PHAsset *)asset targetSize:(CGSize)targetSize {

PHImageManager *imageManager = [PHImageManager defaultManager];

PHImageRequestOptions *options = [PHImageRequestOptions new];
options.networkAccessAllowed = YES;
options.resizeMode = PHImageRequestOptionsResizeModeFast;
options.deliveryMode = PHImageRequestOptionsDeliveryModeHighQualityFormat;
options.synchronous = false;
options.progressHandler = ^(double progress, NSError *error, BOOL *stop, NSDictionary *info) {
NSDictionary* dict = [NSDictionary dictionaryWithObjectsAndKeys:
[NSNumber numberWithDouble: progress], @"progress",
self, @"photo", nil];
[[NSNotificationCenter defaultCenter] postNotificationName:MWPHOTO_PROGRESS_NOTIFICATION object:dict];
};

_assetRequestID = [imageManager requestImageForAsset:asset targetSize:targetSize contentMode:PHImageContentModeAspectFit options:options resultHandler:^(UIImage *result, NSDictionary *info) {
dispatch_async(dispatch_get_main_queue(), ^{
self.underlyingImage = result;
[self imageLoadingComplete];
});
}];

}

// Release if we can get it again from path or url
- (void)unloadUnderlyingImage {
_loadingInProgress = NO;
self.underlyingImage = nil;
}

- (void)imageLoadingComplete {
NSAssert([[NSThread currentThread] isMainThread], @"This method must be called on the main thread.");
// Complete so notify
_loadingInProgress = NO;
// Notify on next run loop
[self performSelector:@selector(postCompleteNotification) withObject:nil afterDelay:0];
}

- (void)postCompleteNotification {
[[NSNotificationCenter defaultCenter] postNotificationName:MWPHOTO_LOADING_DID_END_NOTIFICATION
object:self];
}

- (void)cancelAnyLoading {
if (_webImageOperation != nil) {
[_webImageOperation cancel];
_loadingInProgress = NO;
} else if (_assetRequestID != PHInvalidImageRequestID) {
[[PHImageManager defaultManager] cancelImageRequest:_assetRequestID];
_assetRequestID = PHInvalidImageRequestID;
}
}

@end
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
[/code]

自己找不同。。。。。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐