私は、MWPhotoBrowser のサンプル プロジェクトのコード全体を永遠に読んで理解しようとすることはできません。このプロジェクトが写真データをどこで取得するのかわかりません。私は先週からプロジェクトを理解しようとしてきました。
これが問題です。この MWPhotoBrowser ( https://github.com/mwaterfall/MWPhotoBrowser/blob/master/README.md ) オープン ソース プロジェクト/ライブラリを使用するアプリを作成しようとしています。私の携帯電話のすべてのアルバムを閲覧できるが、MWPhotoBrowser を使用するアプリ。
MWPhotoBrowser のサンプル プロジェクトには、電話のローカル写真を参照する方法のサンプル コードがあります。多くの例がありますが、それらのいくつかを削除し、最後の 1 つのオプションだけを保持することができました。- ライブラリの写真とビデオ (コードを見る場合はケース:9)。
私がこれまでに行ったこと:
developer.apple.com のオープン ソース プロジェクト (Gallery Viewer App) を実装します - 実装は成功しましたが、MWPhotoBrowser の方が優れていてクールなので満足できません。
MWPhotoBrowser のサンプル プロジェクトを編集します。
コード:
//
// Menu.m
// MWPhotoBrowser
//
// Created by Michael Waterfall on 21/10/2010.
// Copyright 2010 d3i. All rights reserved.
//
#import <Photos/Photos.h>
#import "Menu.h"
#import "SDImageCache.h"
#import "MWCommon.h"
@implementation Menu
#pragma mark -
#pragma mark View
- (void)viewDidLoad {
[super viewDidLoad];
// Test toolbar hiding
// [self setToolbarItems: @[[[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemAdd target:nil action:nil]]];
// [[self navigationController] setToolbarHidden:NO animated:NO];
NSLog(@"view did load....");
self.title = @"MWPhotoBrowser";
// Clear cache for testing
[[SDImageCache sharedImageCache] clearDisk];
[[SDImageCache sharedImageCache] clearMemory];
[self loadAssets];
}
- (void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
// self.navigationController.navigationBar.barTintColor = [UIColor greenColor];
// self.navigationController.navigationBar.translucent = NO;
// [self.navigationController setNavigationBarHidden:YES animated:YES];
}
- (void)viewWillDisappear:(BOOL)animated {
[super viewWillDisappear:animated];
// [self.navigationController setNavigationBarHidden:NO animated:YES];
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
return YES;
}
- (BOOL)prefersStatusBarHidden {
return NO;
}
- (UIStatusBarAnimation)preferredStatusBarUpdateAnimation {
return UIStatusBarAnimationNone;
}
#pragma mark -
#pragma mark Table view data source
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
NSInteger rows = 1;
@synchronized(_assets) {
if (_assets.count) rows++;
}
return rows;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
// Create
static NSString *CellIdentifier = @"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier];
}
cell.accessoryType = _segmentedControl.selectedSegmentIndex == 0 ? UITableViewCellAccessoryDisclosureIndicator : UITableViewCellAccessoryNone;
// Configure
switch (indexPath.row) {
case 0: {
cell.textLabel.text = @"Library photos and videos";
cell.detailTextLabel.text = @"media from device library";
break;
}
default: break;
}
return cell;
}
#pragma mark -
#pragma mark Table view delegate
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
NSLog(@"Did Select...");
// Browser
NSMutableArray *photos = [[NSMutableArray alloc] init];
NSMutableArray *thumbs = [[NSMutableArray alloc] init];
MWPhoto *photo, *thumb;
BOOL displayActionButton = YES;
BOOL displaySelectionButtons = NO;
BOOL displayNavArrows = NO;
BOOL enableGrid = YES;
BOOL startOnGrid = NO;
BOOL autoPlayOnAppear = NO;
//@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];
if ([asset valueForProperty:ALAssetPropertyType] == ALAssetTypeVideo) {
photo.videoURL = asset.defaultRepresentation.url;
thumb.isVideo = true;
}
}
}
//}
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 = YES;
browser.enableGrid = enableGrid;
browser.startOnGrid = startOnGrid;
browser.enableSwipeToDismiss = NO;
browser.autoPlayOnAppear = autoPlayOnAppear;
[browser setCurrentPhotoIndex:0];
// Test custom selection images
// browser.customImageSelectedIconName = @"ImageSelected.png";
// browser.customImageSelectedSmallIconName = @"ImageSelectedSmall.png";
// Reset selections
if (displaySelectionButtons) {
_selections = [NSMutableArray new];
for (int i = 0; i < photos.count; i++) {
[_selections addObject:[NSNumber numberWithBool:NO]];
}
}
// Show
[self.navigationController pushViewController:browser animated:YES];
}
#pragma mark - MWPhotoBrowserDelegate
- (NSUInteger)numberOfPhotosInPhotoBrowser:(MWPhotoBrowser *)photoBrowser {
return _photos.count;
}
- (id <MWPhoto>)photoBrowser:(MWPhotoBrowser *)photoBrowser photoAtIndex:(NSUInteger)index {
if (index < _photos.count)
return [_photos objectAtIndex:index];
return nil;
}
- (id <MWPhoto>)photoBrowser:(MWPhotoBrowser *)photoBrowser thumbPhotoAtIndex:(NSUInteger)index {
if (index < _thumbs.count)
return [_thumbs objectAtIndex:index];
return nil;
}
//- (MWCaptionView *)photoBrowser:(MWPhotoBrowser *)photoBrowser captionViewForPhotoAtIndex:(NSUInteger)index {
// MWPhoto *photo = [self.photos objectAtIndex:index];
// MWCaptionView *captionView = [[MWCaptionView alloc] initWithPhoto:photo];
// return [captionView autorelease];
//}
- (void)photoBrowser:(MWPhotoBrowser *)photoBrowser actionButtonPressedForPhotoAtIndex:(NSUInteger)index {
NSLog(@"ACTION!");
}
- (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];
}
//- (NSString *)photoBrowser:(MWPhotoBrowser *)photoBrowser titleForPhotoAtIndex:(NSUInteger)index {
// return [NSString stringWithFormat:@"Photo %lu", (unsigned long)index+1];
//}
- (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");
}
//////////////
#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), ^{
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];
}];
if (fetchResults.count > 0) {
// [self.tableView performSelectorOnMainThread:@selector(reloadData) withObject:nil waitUntilDone:NO];
}
});
} 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) {
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];
if (_assets.count == 1) {
// Added first asset so reload data
[self.tableView performSelectorOnMainThread:@selector(reloadData) withObject:nil waitUntilDone:NO];
}
}
}
}
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");
}];
});
}
}
@end
次に、サンプル プロジェクトの Storyboard 内に ViewController を作成しようとしましたが、Navigation Controller と Table View Controller の間の接続を切断しました。ナビゲーション コントローラーを ViewController に接続しました。次に、MainViewController.m という名前の新しく作成したクラスをストーリーボードの ViewController に割り当てました。
すべてのコードをコピーしたというより、Main.m (サンプル プロジェクトの Table View に接続されたクラス) 内のすべてのコードの実装を MainViewController.m にコピーしました。これまでの私のコードは次のとおりです。
//
// MainViewController.m // MWPhotoBrowser // // 2015 年 9 月 28 日に Glenn によって作成されました。// 著作権 (
c) 2015 年のマイケルの滝。全著作権所有。///
#import "MainViewController.h"
#import <Photos/Photos.h>
// #import "Menu.h"
#import "SDImageCache.h"
#import "MWCommon.h"
@interface MainViewController ()
{
MWPhotoBrowser *browser;
}
@end
@implementation MainViewController
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view.
[self mwSetup];
self.title = @"MWPhotoBrowser";
// Clear cache for testing
[[SDImageCache sharedImageCache] clearDisk];
[[SDImageCache sharedImageCache] clearMemory];
[self loadAssets];
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
- (void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
// self.navigationController.navigationBar.barTintColor = [UIColor greenColor];
// self.navigationController.navigationBar.translucent = NO;
// [self.navigationController setNavigationBarHidden:YES animated:YES];
}
- (void)viewWillDisappear:(BOOL)animated {
[super viewWillDisappear:animated];
// [self.navigationController setNavigationBarHidden:NO animated:YES];
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
return YES;
}
- (BOOL)prefersStatusBarHidden {
return NO;
}
- (UIStatusBarAnimation)preferredStatusBarUpdateAnimation {
return UIStatusBarAnimationNone;
}
- (void)mwSetup
{
NSLog(@"Did Select...");
// Browser
NSMutableArray *photos = [[NSMutableArray alloc] init];
NSMutableArray *thumbs = [[NSMutableArray alloc] init];
MWPhoto *photo, *thumb;
BOOL displayActionButton = YES;
BOOL displaySelectionButtons = NO;
BOOL displayNavArrows = NO;
BOOL enableGrid = YES;
BOOL startOnGrid = NO;
BOOL autoPlayOnAppear = NO;
//@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];
if ([asset valueForProperty:ALAssetPropertyType] == ALAssetTypeVideo) {
photo.videoURL = asset.defaultRepresentation.url;
thumb.isVideo = true;
}
}
}
//}
self.photos = photos;
self.thumbs = thumbs;
// Create browser
browser = [[MWPhotoBrowser alloc] initWithDelegate:self];
browser.displayActionButton = displayActionButton;
browser.displayNavArrows = displayNavArrows;
browser.displaySelectionButtons = displaySelectionButtons;
browser.alwaysShowControls = displaySelectionButtons;
browser.zoomPhotosToFill = YES;
browser.enableGrid = enableGrid;
browser.startOnGrid = startOnGrid;
browser.enableSwipeToDismiss = NO;
browser.autoPlayOnAppear = autoPlayOnAppear;
[browser setCurrentPhotoIndex:0];
// Test custom selection images
// browser.customImageSelectedIconName = @"ImageSelected.png";
// browser.customImageSelectedSmallIconName = @"ImageSelectedSmall.png";
// Reset selections
if (displaySelectionButtons) {
_selections = [NSMutableArray new];
for (int i = 0; i < photos.count; i++) {
[_selections addObject:[NSNumber numberWithBool:NO]];
}
}
// Show
[self.navigationController pushViewController:browser animated:YES];
//[self.view addSubview:browser.view];
}
#pragma mark - MWPhotoBrowserDelegate
- (NSUInteger)numberOfPhotosInPhotoBrowser:(MWPhotoBrowser *)photoBrowser {
return _photos.count;
}
- (id <MWPhoto>)photoBrowser:(MWPhotoBrowser *)photoBrowser photoAtIndex:(NSUInteger)index {
if (index < _photos.count)
return [_photos objectAtIndex:index];
return nil;
}
- (id <MWPhoto>)photoBrowser:(MWPhotoBrowser *)photoBrowser thumbPhotoAtIndex:(NSUInteger)index {
if (index < _thumbs.count)
return [_thumbs objectAtIndex:index];
return nil;
}
//- (MWCaptionView *)photoBrowser:(MWPhotoBrowser *)photoBrowser captionViewForPhotoAtIndex:(NSUInteger)index {
// MWPhoto *photo = [self.photos objectAtIndex:index];
// MWCaptionView *captionView = [[MWCaptionView alloc] initWithPhoto:photo];
// return [captionView autorelease];
//}
- (void)photoBrowser:(MWPhotoBrowser *)photoBrowser actionButtonPressedForPhotoAtIndex:(NSUInteger)index {
NSLog(@"ACTION!");
}
- (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];
}
//- (NSString *)photoBrowser:(MWPhotoBrowser *)photoBrowser titleForPhotoAtIndex:(NSUInteger)index {
// return [NSString stringWithFormat:@"Photo %lu", (unsigned long)index+1];
//}
- (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");
}
#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), ^{
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];
}];
if (fetchResults.count > 0) {
[browser reloadData]; }
});
} 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) {
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];
if (_assets.count == 1) {
// Added first asset so reload data
[browser reloadData];
}
}
}
}
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");
}];
});
}
}
@end
助けてください。そして、誰かが私の2番目のコードのフォーマットを編集するのを手伝ってくれますか? ありがとう。