Repository: arturgrigor/AGImagePickerController Branch: master Commit: 8e952d251c09 Files: 37 Total size: 120.0 KB Directory structure: gitextract_fuleemah/ ├── AGImagePickerController/ │ ├── AGIPCAlbumsController.h │ ├── AGIPCAlbumsController.m │ ├── AGIPCAssetsController.h │ ├── AGIPCAssetsController.m │ ├── AGIPCGridCell.h │ ├── AGIPCGridCell.m │ ├── AGIPCGridItem.h │ ├── AGIPCGridItem.m │ ├── AGIPCToolbarItem.h │ ├── AGIPCToolbarItem.m │ ├── AGImagePickerController+Helper.h │ ├── AGImagePickerController+Helper.m │ ├── AGImagePickerController.h │ ├── AGImagePickerController.m │ ├── AGImagePickerControllerDefines.h │ ├── ALAsset+AGIPC.h │ └── ALAsset+AGIPC.m ├── AGImagePickerController Demo/ │ ├── AGAppDelegate.h │ ├── AGAppDelegate.m │ ├── AGImagePickerController Demo-Info.plist │ ├── AGImagePickerController Demo-Prefix.pch │ ├── AGViewController.h │ ├── AGViewController.m │ ├── en.lproj/ │ │ ├── AGViewController_iPad.xib │ │ ├── AGViewController_iPhone.xib │ │ └── InfoPlist.strings │ └── main.m ├── AGImagePickerController Demo.xcodeproj/ │ ├── project.pbxproj │ ├── project.xcworkspace/ │ │ ├── contents.xcworkspacedata │ │ └── xcuserdata/ │ │ └── arturgrigor.xcuserdatad/ │ │ ├── UserInterfaceState.xcuserstate │ │ └── WorkspaceSettings.xcsettings │ └── xcuserdata/ │ └── arturgrigor.xcuserdatad/ │ ├── xcdebugger/ │ │ └── Breakpoints.xcbkptlist │ └── xcschemes/ │ ├── AGImagePickerController Demo.xcscheme │ └── xcschememanagement.plist ├── AGImagePickerController.podspec ├── LICENSE └── README.md ================================================ FILE CONTENTS ================================================ ================================================ FILE: AGImagePickerController/AGIPCAlbumsController.h ================================================ // // AGIPCAlbumsController.h // AGImagePickerController // // Created by Artur Grigor on 2/16/12. // Copyright (c) 2012 - 2013 Artur Grigor. All rights reserved. // // For the full copyright and license information, please view the LICENSE // file that was distributed with this source code. // #import #import #import "AGImagePickerController.h" @interface AGIPCAlbumsController : UITableViewController @property (strong) AGImagePickerController *imagePickerController; - (id)initWithImagePickerController:(AGImagePickerController *)imagePickerController; @end ================================================ FILE: AGImagePickerController/AGIPCAlbumsController.m ================================================ // // AGIPCAlbumsController.m // AGImagePickerController // // Created by Artur Grigor on 2/16/12. // Copyright (c) 2012 - 2013 Artur Grigor. All rights reserved. // // For the full copyright and license information, please view the LICENSE // file that was distributed with this source code. // #import "AGIPCAlbumsController.h" #import "AGImagePickerController.h" #import "AGIPCAssetsController.h" @interface AGIPCAlbumsController () { NSMutableArray *_assetsGroups; AGImagePickerController *_imagePickerController; } @property (ag_weak, nonatomic, readonly) NSMutableArray *assetsGroups; @end @interface AGIPCAlbumsController () - (void)registerForNotifications; - (void)unregisterFromNotifications; - (void)didChangeLibrary:(NSNotification *)notification; - (void)loadAssetsGroups; - (void)reloadData; - (void)cancelAction:(id)sender; @end @implementation AGIPCAlbumsController #pragma mark - Properties @synthesize imagePickerController = _imagePickerController; - (NSMutableArray *)assetsGroups { if (_assetsGroups == nil) { _assetsGroups = [[NSMutableArray alloc] init]; [self loadAssetsGroups]; } return _assetsGroups; } #pragma mark - Object Lifecycle - (id)initWithImagePickerController:(AGImagePickerController *)imagePickerController { self = [super initWithStyle:UITableViewStylePlain]; if (self) { self.imagePickerController = imagePickerController; } return self; } - (void)didReceiveMemoryWarning { // Releases the view if it doesn't have a superview. [super didReceiveMemoryWarning]; // Release any cached data, images, etc that aren't in use. } #pragma mark - View lifecycle - (void)viewWillAppear:(BOOL)animated { [super viewWillAppear:animated]; [self.navigationController setToolbarHidden:YES animated:YES]; } - (void)viewDidLoad { [super viewDidLoad]; // Fullscreen if (self.imagePickerController.shouldChangeStatusBarStyle) { self.wantsFullScreenLayout = YES; } // Setup Notifications [self registerForNotifications]; // Navigation Bar Items UIBarButtonItem *cancelButton = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemCancel target:self action:@selector(cancelAction:)]; self.navigationItem.leftBarButtonItem = cancelButton; } - (void)viewDidUnload { [super viewDidUnload]; // Destroy Notifications [self unregisterFromNotifications]; } - (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation { return YES; } - (NSUInteger)supportedInterfaceOrientations { return UIInterfaceOrientationMaskAll; } #pragma mark - UITableViewDataSource Methods - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { return self.assetsGroups.count; self.title = NSLocalizedStringWithDefaultValue(@"AGIPC.Loading", nil, [NSBundle mainBundle], @"Loading...", nil); } - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { static NSString *CellIdentifier = @"Cell"; UITableViewCell *cell = [self.tableView dequeueReusableCellWithIdentifier:CellIdentifier]; if (cell == nil) { cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:CellIdentifier]; } ALAssetsGroup *group = (self.assetsGroups)[indexPath.row]; [group setAssetsFilter:[ALAssetsFilter allPhotos]]; NSUInteger numberOfAssets = group.numberOfAssets; cell.textLabel.text = [NSString stringWithFormat:@"%@", [group valueForProperty:ALAssetsGroupPropertyName]]; cell.detailTextLabel.text = [NSString stringWithFormat:@"%d", numberOfAssets]; [cell.imageView setImage:[UIImage imageWithCGImage:[(ALAssetsGroup *)self.assetsGroups[indexPath.row] posterImage]]]; [cell setAccessoryType:UITableViewCellAccessoryDisclosureIndicator]; return cell; } #pragma mark - UITableViewDelegate Methods - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { [self.tableView deselectRowAtIndexPath:indexPath animated:YES]; AGIPCAssetsController *controller = [[AGIPCAssetsController alloc] initWithImagePickerController:self.imagePickerController andAssetsGroup:self.assetsGroups[indexPath.row]]; [self.navigationController pushViewController:controller animated:YES]; } - (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath { return 57; } #pragma mark - Private - (void)loadAssetsGroups { __ag_weak AGIPCAlbumsController *weakSelf = self; [self.assetsGroups removeAllObjects]; dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_LOW, 0), ^{ @autoreleasepool { void (^assetGroupEnumerator)(ALAssetsGroup *, BOOL *) = ^(ALAssetsGroup *group, BOOL *stop) { if (group == nil) { return; } if (weakSelf.imagePickerController.shouldShowSavedPhotosOnTop) { if ([[group valueForProperty:ALAssetsGroupPropertyType] intValue] == ALAssetsGroupSavedPhotos) { [self.assetsGroups insertObject:group atIndex:0]; } else if ([[group valueForProperty:ALAssetsGroupPropertyType] intValue] > ALAssetsGroupSavedPhotos) { [self.assetsGroups insertObject:group atIndex:1]; } else { [self.assetsGroups addObject:group]; } } else { [self.assetsGroups addObject:group]; } dispatch_async(dispatch_get_main_queue(), ^{ [self reloadData]; }); }; void (^assetGroupEnumberatorFailure)(NSError *) = ^(NSError *error) { NSLog(@"A problem occured. Error: %@", error.localizedDescription); [self.imagePickerController performSelector:@selector(didFail:) withObject:error]; }; [[AGImagePickerController defaultAssetsLibrary] enumerateGroupsWithTypes:ALAssetsGroupAll usingBlock:assetGroupEnumerator failureBlock:assetGroupEnumberatorFailure]; } }); } - (void)reloadData { [self.tableView reloadData]; self.title = NSLocalizedStringWithDefaultValue(@"AGIPC.Albums", nil, [NSBundle mainBundle], @"Albums", nil); } - (void)cancelAction:(id)sender { [self.imagePickerController performSelector:@selector(didCancelPickingAssets)]; } #pragma mark - Notifications - (void)registerForNotifications { [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(didChangeLibrary:) name:ALAssetsLibraryChangedNotification object:[AGImagePickerController defaultAssetsLibrary]]; } - (void)unregisterFromNotifications { [[NSNotificationCenter defaultCenter] removeObserver:self name:ALAssetsLibraryChangedNotification object:[AGImagePickerController defaultAssetsLibrary]]; } - (void)didChangeLibrary:(NSNotification *)notification { [self loadAssetsGroups]; } @end ================================================ FILE: AGImagePickerController/AGIPCAssetsController.h ================================================ // // AGIPCAssetsController.h // AGImagePickerController // // Created by Artur Grigor on 17.02.2012. // Copyright (c) 2012 - 2013 Artur Grigor. All rights reserved. // // For the full copyright and license information, please view the LICENSE // file that was distributed with this source code. // #import #import #import #import "AGImagePickerController.h" #import "AGIPCGridItem.h" @interface AGIPCAssetsController : UITableViewController @property (strong) ALAssetsGroup *assetsGroup; @property (ag_weak, readonly) NSArray *selectedAssets; @property (strong) AGImagePickerController *imagePickerController; - (id)initWithImagePickerController:(AGImagePickerController *)imagePickerController andAssetsGroup:(ALAssetsGroup *)assetsGroup; @end ================================================ FILE: AGImagePickerController/AGIPCAssetsController.m ================================================ // // AGIPCAssetsController.m // AGImagePickerController // // Created by Artur Grigor on 17.02.2012. // Copyright (c) 2012 - 2013 Artur Grigor. All rights reserved. // // For the full copyright and license information, please view the LICENSE // file that was distributed with this source code. // #import "AGIPCAssetsController.h" #import "AGImagePickerController+Helper.h" #import "AGIPCGridCell.h" #import "AGIPCToolbarItem.h" @interface AGIPCAssetsController () { ALAssetsGroup *_assetsGroup; NSMutableArray *_assets; AGImagePickerController *_imagePickerController; } @property (nonatomic, strong) NSMutableArray *assets; @end @interface AGIPCAssetsController (Private) - (void)changeSelectionInformation; - (void)registerForNotifications; - (void)unregisterFromNotifications; - (void)didChangeLibrary:(NSNotification *)notification; - (void)didChangeToolbarItemsForManagingTheSelection:(NSNotification *)notification; - (BOOL)toolbarHidden; - (void)loadAssets; - (void)reloadData; - (void)setupToolbarItems; - (NSArray *)itemsForRowAtIndexPath:(NSIndexPath *)indexPath; - (void)doneAction:(id)sender; - (void)selectAllAction:(id)sender; - (void)deselectAllAction:(id)sender; - (void)customBarButtonItemAction:(id)sender; @end @implementation AGIPCAssetsController #pragma mark - Properties @synthesize assetsGroup = _assetsGroup, assets = _assets, imagePickerController = _imagePickerController; - (BOOL)toolbarHidden { if (! self.imagePickerController.shouldShowToolbarForManagingTheSelection) return YES; else { if (self.imagePickerController.toolbarItemsForManagingTheSelection != nil) { return !(self.imagePickerController.toolbarItemsForManagingTheSelection.count > 0); } else { return NO; } } } - (void)setAssetsGroup:(ALAssetsGroup *)theAssetsGroup { @synchronized (self) { if (_assetsGroup != theAssetsGroup) { _assetsGroup = theAssetsGroup; [_assetsGroup setAssetsFilter:[ALAssetsFilter allPhotos]]; [self reloadData]; } } } - (ALAssetsGroup *)assetsGroup { ALAssetsGroup *ret = nil; @synchronized (self) { ret = _assetsGroup; } return ret; } - (NSArray *)selectedAssets { NSMutableArray *selectedAssets = [NSMutableArray array]; for (AGIPCGridItem *gridItem in self.assets) { if (gridItem.selected) { [selectedAssets addObject:gridItem.asset]; } } return selectedAssets; } #pragma mark - Object Lifecycle - (id)initWithImagePickerController:(AGImagePickerController *)imagePickerController andAssetsGroup:(ALAssetsGroup *)assetsGroup { self = [super initWithStyle:UITableViewStylePlain]; if (self) { _assets = [[NSMutableArray alloc] init]; self.assetsGroup = assetsGroup; self.imagePickerController = imagePickerController; self.title = NSLocalizedStringWithDefaultValue(@"AGIPC.Loading", nil, [NSBundle mainBundle], @"Loading...", nil); self.title = [self.assetsGroup valueForProperty:ALAssetsGroupPropertyName]; self.tableView.allowsMultipleSelection = NO; self.tableView.allowsSelection = NO; self.tableView.separatorStyle = UITableViewCellSeparatorStyleNone; // Navigation Bar Items UIBarButtonItem *doneButtonItem = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemDone target:self action:@selector(doneAction:)]; doneButtonItem.enabled = NO; self.navigationItem.rightBarButtonItem = doneButtonItem; // Setup toolbar items [self setupToolbarItems]; // Start loading the assets [self loadAssets]; } return self; } - (void)dealloc { [self unregisterFromNotifications]; } #pragma mark - UITableViewDataSource Methods - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { if (! self.imagePickerController) return 0; double numberOfAssets = (double)self.assetsGroup.numberOfAssets; NSInteger nr = ceil(numberOfAssets / self.imagePickerController.numberOfItemsPerRow); return nr; } - (NSArray *)itemsForRowAtIndexPath:(NSIndexPath *)indexPath { NSMutableArray *items = [NSMutableArray arrayWithCapacity:self.imagePickerController.numberOfItemsPerRow]; NSUInteger startIndex = indexPath.row * self.imagePickerController.numberOfItemsPerRow, endIndex = startIndex + self.imagePickerController.numberOfItemsPerRow - 1; if (startIndex < self.assets.count) { if (endIndex > self.assets.count - 1) endIndex = self.assets.count - 1; for (NSUInteger i = startIndex; i <= endIndex; i++) { [items addObject:(self.assets)[i]]; } } return items; } - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { static NSString *CellIdentifier = @"Cell"; AGIPCGridCell *cell = (AGIPCGridCell *)[self.tableView dequeueReusableCellWithIdentifier:CellIdentifier]; if (cell == nil) { cell = [[AGIPCGridCell alloc] initWithImagePickerController:self.imagePickerController items:[self itemsForRowAtIndexPath:indexPath] andReuseIdentifier:CellIdentifier]; } else { cell.items = [self itemsForRowAtIndexPath:indexPath]; } return cell; } - (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath { CGRect itemRect = self.imagePickerController.itemRect; return itemRect.size.height + itemRect.origin.y; } #pragma mark - View Lifecycle - (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation { return YES; } - (void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration { [super willRotateToInterfaceOrientation:toInterfaceOrientation duration:duration]; [self reloadData]; } - (void)viewWillAppear:(BOOL)animated { // Reset the number of selections [AGIPCGridItem performSelector:@selector(resetNumberOfSelections)]; [super viewWillAppear:animated]; } - (void)viewDidLoad { [super viewDidLoad]; // Fullscreen if (self.imagePickerController.shouldChangeStatusBarStyle) { self.wantsFullScreenLayout = YES; } // Setup Notifications [self registerForNotifications]; } - (void)viewDidUnload { [super viewDidUnload]; // Destroy Notifications [self unregisterFromNotifications]; } #pragma mark - Private - (void)setupToolbarItems { if (self.imagePickerController.toolbarItemsForManagingTheSelection != nil) { NSMutableArray *items = [NSMutableArray array]; // Custom Toolbar Items for (id item in self.imagePickerController.toolbarItemsForManagingTheSelection) { NSAssert([item isKindOfClass:[AGIPCToolbarItem class]], @"Item is not a instance of AGIPCToolbarItem."); ((AGIPCToolbarItem *)item).barButtonItem.target = self; ((AGIPCToolbarItem *)item).barButtonItem.action = @selector(customBarButtonItemAction:); [items addObject:((AGIPCToolbarItem *)item).barButtonItem]; } self.toolbarItems = items; } else { // Standard Toolbar Items UIBarButtonItem *selectAll = [[UIBarButtonItem alloc] initWithTitle:NSLocalizedStringWithDefaultValue(@"AGIPC.SelectAll", nil, [NSBundle mainBundle], @"Select All", nil) style:UIBarButtonItemStyleBordered target:self action:@selector(selectAllAction:)]; UIBarButtonItem *flexibleSpace = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace target:nil action:nil]; UIBarButtonItem *deselectAll = [[UIBarButtonItem alloc] initWithTitle:NSLocalizedStringWithDefaultValue(@"AGIPC.DeselectAll", nil, [NSBundle mainBundle], @"Deselect All", nil) style:UIBarButtonItemStyleBordered target:self action:@selector(deselectAllAction:)]; NSArray *toolbarItemsForManagingTheSelection = @[selectAll, flexibleSpace, deselectAll]; self.toolbarItems = toolbarItemsForManagingTheSelection; } } - (void)loadAssets { [self.assets removeAllObjects]; __ag_weak AGIPCAssetsController *weakSelf = self; dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^{ __strong AGIPCAssetsController *strongSelf = weakSelf; @autoreleasepool { [strongSelf.assetsGroup enumerateAssetsUsingBlock:^(ALAsset *result, NSUInteger index, BOOL *stop) { if (result == nil) { return; } if (strongSelf.imagePickerController.shouldShowPhotosWithLocationOnly) { CLLocation *assetLocation = [result valueForProperty:ALAssetPropertyLocation]; if (!assetLocation || !CLLocationCoordinate2DIsValid([assetLocation coordinate])) { return; } } AGIPCGridItem *gridItem = [[AGIPCGridItem alloc] initWithImagePickerController:self.imagePickerController asset:result andDelegate:self]; // Drawing must be exectued in main thread. springox(20131220) /* if (strongSelf.imagePickerController.selection != nil && [strongSelf.imagePickerController.selection containsObject:result]) { gridItem.selected = YES; } */ //[strongSelf.assets addObject:gridItem]; // Descending photos, springox(20131225) [strongSelf.assets insertObject:gridItem atIndex:0]; }]; } dispatch_async(dispatch_get_main_queue(), ^{ [strongSelf reloadData]; }); }); } - (void)reloadData { // Don't display the select button until all the assets are loaded. [self.navigationController setToolbarHidden:[self toolbarHidden] animated:YES]; [self.tableView reloadData]; //[self setTitle:[self.assetsGroup valueForProperty:ALAssetsGroupPropertyName]]; [self changeSelectionInformation]; /* NSInteger totalRows = [self.tableView numberOfRowsInSection:0]; //Prevents crash if totalRows = 0 (when the album is empty). if (totalRows > 0) { [self.tableView scrollToRowAtIndexPath:[NSIndexPath indexPathForRow:totalRows-1 inSection:0] atScrollPosition:UITableViewScrollPositionBottom animated:NO]; } */ } - (void)doneAction:(id)sender { [self.imagePickerController performSelector:@selector(didFinishPickingAssets:) withObject:self.selectedAssets]; } - (void)selectAllAction:(id)sender { for (AGIPCGridItem *gridItem in self.assets) { gridItem.selected = YES; } } - (void)deselectAllAction:(id)sender { for (AGIPCGridItem *gridItem in self.assets) { gridItem.selected = NO; } } - (void)customBarButtonItemAction:(id)sender { for (id item in self.imagePickerController.toolbarItemsForManagingTheSelection) { NSAssert([item isKindOfClass:[AGIPCToolbarItem class]], @"Item is not a instance of AGIPCToolbarItem."); if (((AGIPCToolbarItem *)item).barButtonItem == sender) { if (((AGIPCToolbarItem *)item).assetIsSelectedBlock) { NSUInteger idx = 0; for (AGIPCGridItem *obj in self.assets) { obj.selected = ((AGIPCToolbarItem *)item).assetIsSelectedBlock(idx, ((AGIPCGridItem *)obj).asset); idx++; } } } } } - (void)changeSelectionInformation { if (self.imagePickerController.shouldDisplaySelectionInformation ) { if (0 == [AGIPCGridItem numberOfSelections] ) { self.navigationController.navigationBar.topItem.prompt = nil; } else { //self.navigationController.navigationBar.topItem.prompt = [NSString stringWithFormat:@"(%d/%d)", [AGIPCGridItem numberOfSelections], self.assets.count]; // Display supports up to select several photos at the same time, springox(20131220) NSInteger maxNumber = _imagePickerController.maximumNumberOfPhotosToBeSelected; if (0 < maxNumber) { self.navigationController.navigationBar.topItem.prompt = [NSString stringWithFormat:@"(%d/%d)", [AGIPCGridItem numberOfSelections], maxNumber]; } else { self.navigationController.navigationBar.topItem.prompt = [NSString stringWithFormat:@"(%d/%d)", [AGIPCGridItem numberOfSelections], self.assets.count]; } } } } #pragma mark - AGGridItemDelegate Methods - (void)agGridItem:(AGIPCGridItem *)gridItem didChangeNumberOfSelections:(NSNumber *)numberOfSelections { self.navigationItem.rightBarButtonItem.enabled = (numberOfSelections.unsignedIntegerValue > 0); [self changeSelectionInformation]; } - (BOOL)agGridItemCanSelect:(AGIPCGridItem *)gridItem { if (self.imagePickerController.selectionMode == AGImagePickerControllerSelectionModeSingle && self.imagePickerController.selectionBehaviorInSingleSelectionMode == AGImagePickerControllerSelectionBehaviorTypeRadio) { for (AGIPCGridItem *item in self.assets) if (item.selected) item.selected = NO; return YES; } else { if (self.imagePickerController.maximumNumberOfPhotosToBeSelected > 0) return ([AGIPCGridItem numberOfSelections] < self.imagePickerController.maximumNumberOfPhotosToBeSelected); else return YES; } } #pragma mark - Notifications - (void)registerForNotifications { [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(didChangeLibrary:) name:ALAssetsLibraryChangedNotification object:[AGImagePickerController defaultAssetsLibrary]]; } - (void)unregisterFromNotifications { [[NSNotificationCenter defaultCenter] removeObserver:self name:ALAssetsLibraryChangedNotification object:[AGImagePickerController defaultAssetsLibrary]]; } - (void)didChangeLibrary:(NSNotification *)notification { [self.navigationController popToRootViewControllerAnimated:YES]; } - (void)didChangeToolbarItemsForManagingTheSelection:(NSNotification *)notification { NSLog(@"here."); } @end ================================================ FILE: AGImagePickerController/AGIPCGridCell.h ================================================ // // AGIPCGridCell.h // AGImagePickerController // // Created by Artur Grigor on 17.02.2012. // Copyright (c) 2012 - 2013 Artur Grigor. All rights reserved. // // For the full copyright and license information, please view the LICENSE // file that was distributed with this source code. // #import #import "AGImagePickerController.h" @interface AGIPCGridCell : UITableViewCell @property (strong) NSArray *items; @property (strong) AGImagePickerController *imagePickerController; - (id)initWithImagePickerController:(AGImagePickerController *)imagePickerController items:(NSArray *)items andReuseIdentifier:(NSString *)identifier; @end ================================================ FILE: AGImagePickerController/AGIPCGridCell.m ================================================ // // AGIPCGridCell.m // AGImagePickerController // // Created by Artur Grigor on 17.02.2012. // Copyright (c) 2012 - 2013 Artur Grigor. All rights reserved. // // For the full copyright and license information, please view the LICENSE // file that was distributed with this source code. // #import "AGIPCGridCell.h" #import "AGIPCGridItem.h" #import "AGImagePickerController.h" #import "AGImagePickerController+Helper.h" @interface AGIPCGridCell () { NSArray *_items; AGImagePickerController *_imagePickerController; } @end @implementation AGIPCGridCell #pragma mark - Properties @synthesize items = _items, imagePickerController = _imagePickerController; - (void)setItems:(NSArray *)items { @synchronized (self) { if (_items != items) { _items = items; for (UIView *view in [self.contentView subviews]) { [view removeFromSuperview]; } for (AGIPCGridItem *gridItem in _items) { [self addSubview:gridItem]; } } } } - (NSArray *)items { NSArray *array = nil; @synchronized (self) { array = _items; } return array; } #pragma mark - Object Lifecycle - (id)initWithImagePickerController:(AGImagePickerController *)imagePickerController items:(NSArray *)items andReuseIdentifier:(NSString *)identifier { self = [super initWithStyle:UITableViewCellStyleDefault reuseIdentifier:identifier]; if (self) { self.imagePickerController = imagePickerController; self.items = items; UIView *emptyView = [[UIView alloc] init]; self.backgroundView = emptyView; } return self; } #pragma mark - Layout - (void)layoutSubviews { CGRect frame = self.imagePickerController.itemRect; CGFloat leftMargin = frame.origin.x; for (AGIPCGridItem *gridItem in self.items) { // Load image with asset when layout grid items. springox(20131218) [gridItem loadImageFromAsset]; [gridItem setFrame:frame]; UITapGestureRecognizer *selectionGestureRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:gridItem action:@selector(tap)]; selectionGestureRecognizer.numberOfTapsRequired = 1; [gridItem addGestureRecognizer:selectionGestureRecognizer]; frame.origin.x = frame.origin.x + frame.size.width + leftMargin; } } @end ================================================ FILE: AGImagePickerController/AGIPCGridItem.h ================================================ // // AGIPCGridItem.h // AGImagePickerController // // Created by Artur Grigor on 17.02.2012. // Copyright (c) 2012 - 2013 Artur Grigor. All rights reserved. // // For the full copyright and license information, please view the LICENSE // file that was distributed with this source code. // #import #import #import "AGImagePickerController.h" @class AGIPCGridItem; @protocol AGIPCGridItemDelegate @optional - (void)agGridItem:(AGIPCGridItem *)gridItem didChangeSelectionState:(NSNumber *)selected; - (void)agGridItem:(AGIPCGridItem *)gridItem didChangeNumberOfSelections:(NSNumber *)numberOfSelections; - (BOOL)agGridItemCanSelect:(AGIPCGridItem *)gridItem; @end @interface AGIPCGridItem : UIView { } @property (assign) BOOL selected; @property (strong) ALAsset *asset; @property (nonatomic, ag_weak) id delegate; @property (strong) AGImagePickerController *imagePickerController; - (id)initWithImagePickerController:(AGImagePickerController *)imagePickerController andAsset:(ALAsset *)asset; - (id)initWithImagePickerController:(AGImagePickerController *)imagePickerController asset:(ALAsset *)asset andDelegate:(id)delegate; - (void)loadImageFromAsset; - (void)tap; + (NSUInteger)numberOfSelections; @end ================================================ FILE: AGImagePickerController/AGIPCGridItem.m ================================================ // // AGIPCGridItem.m // AGImagePickerController // // Created by Artur Grigor on 17.02.2012. // Copyright (c) 2012 - 2013 Artur Grigor. All rights reserved. // // For the full copyright and license information, please view the LICENSE // file that was distributed with this source code. // #import "AGIPCGridItem.h" #import "AGImagePickerController+Helper.h" @interface AGIPCGridItem () { AGImagePickerController *_imagePickerController; ALAsset *_asset; id __ag_weak _delegate; BOOL _selected; UIImageView *_thumbnailImageView; UIView *_selectionView; UIImageView *_checkmarkImageView; } @property (nonatomic, strong) UIImageView *thumbnailImageView; @property (nonatomic, strong) UIView *selectionView; @property (nonatomic, strong) UIImageView *checkmarkImageView; + (void)resetNumberOfSelections; @end static NSUInteger numberOfSelectedGridItems = 0; @implementation AGIPCGridItem #pragma mark - Properties @synthesize imagePickerController = _imagePickerController, delegate = _delegate, asset = _asset, selected = _selected, thumbnailImageView = _thumbnailImageView, selectionView = _selectionView, checkmarkImageView = _checkmarkImageView; - (void)setSelected:(BOOL)selected { @synchronized (self) { if (_selected != selected) { if (selected) { // Check if we can select if ([self.delegate respondsToSelector:@selector(agGridItemCanSelect:)]) { if (![self.delegate agGridItemCanSelect:self]) return; } } _selected = selected; self.selectionView.hidden = !_selected; self.checkmarkImageView.hidden = !_selected; if (_selected) { numberOfSelectedGridItems++; } else { if (numberOfSelectedGridItems > 0) numberOfSelectedGridItems--; } dispatch_async(dispatch_get_main_queue(), ^{ if ([self.delegate respondsToSelector:@selector(agGridItem:didChangeSelectionState:)]) { [self.delegate performSelector:@selector(agGridItem:didChangeSelectionState:) withObject:self withObject:@(_selected)]; } if ([self.delegate respondsToSelector:@selector(agGridItem:didChangeNumberOfSelections:)]) { [self.delegate performSelector:@selector(agGridItem:didChangeNumberOfSelections:) withObject:self withObject:@(numberOfSelectedGridItems)]; } }); } } } - (BOOL)selected { BOOL ret; @synchronized (self) { ret = _selected; } return ret; } - (void)setAsset:(ALAsset *)asset { @synchronized (self) { if (_asset != asset) { _asset = asset; // Drawing must be exectued in main thread. springox(20131218) //self.thumbnailImageView.image = [UIImage imageWithCGImage:_asset.thumbnail]; } } } - (ALAsset *)asset { ALAsset *ret = nil; @synchronized (self) { ret = _asset; } return ret; } #pragma mark - Object Lifecycle - (id)initWithImagePickerController:(AGImagePickerController *)imagePickerController andAsset:(ALAsset *)asset { self = [self initWithImagePickerController:imagePickerController asset:asset andDelegate:nil]; return self; } - (id)initWithImagePickerController:(AGImagePickerController *)imagePickerController asset:(ALAsset *)asset andDelegate:(id)delegate { self = [super init]; if (self) { self.imagePickerController = imagePickerController; self.selected = NO; self.delegate = delegate; CGRect frame = self.imagePickerController.itemRect; CGRect checkmarkFrame = [self.imagePickerController checkmarkFrameUsingItemFrame:frame]; self.thumbnailImageView = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, frame.size.width, frame.size.height)]; // Drawing must be exectued in main thread. springox(20131220) //self.thumbnailImageView.contentMode = UIViewContentModeScaleToFill; [self addSubview:self.thumbnailImageView]; self.selectionView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, frame.size.width, frame.size.height)]; // Drawing must be exectued in main thread. springox(20131220) //self.selectionView.backgroundColor = [UIColor whiteColor]; //self.selectionView.alpha = .5f; //self.selectionView.hidden = !self.selected; [self addSubview:self.selectionView]; // Position the checkmark image in the bottom right corner self.checkmarkImageView = [[UIImageView alloc] initWithFrame:checkmarkFrame]; // Drawing must be exectued in main thread. springox(20131220) //if (IS_IPAD()) // self.checkmarkImageView.image = [UIImage imageNamed:@"AGImagePickerController.bundle/AGIPC-Checkmark-iPad"]; //else // self.checkmarkImageView.image = [UIImage imageNamed:@"AGImagePickerController.bundle/AGIPC-Checkmark-iPhone"]; //self.checkmarkImageView.hidden = !self.selected; [self addSubview:self.checkmarkImageView]; self.asset = asset; } return self; } - (void)layoutSubviews { [super layoutSubviews]; self.thumbnailImageView.contentMode = UIViewContentModeScaleToFill; self.selectionView.backgroundColor = [UIColor whiteColor]; self.selectionView.alpha = .5f; self.selectionView.hidden = !self.selected; if (IS_IPAD()) self.checkmarkImageView.image = [UIImage imageNamed:@"AGImagePickerController.bundle/AGIPC-Checkmark-iPad"]; else self.checkmarkImageView.image = [UIImage imageNamed:@"AGImagePickerController.bundle/AGIPC-Checkmark-iPhone"]; self.checkmarkImageView.hidden = !self.selected; } // Drawing must be exectued in main thread. springox(20131218) - (void)loadImageFromAsset { self.thumbnailImageView.image = [UIImage imageWithCGImage:_asset.thumbnail]; if ([self.imagePickerController.selection containsObject:self]) { self.selected = YES; } } #pragma mark - Others - (void)tap { self.selected = !self.selected; } #pragma mark - Private + (void)resetNumberOfSelections { numberOfSelectedGridItems = 0; } + (NSUInteger)numberOfSelections { return numberOfSelectedGridItems; } @end ================================================ FILE: AGImagePickerController/AGIPCToolbarItem.h ================================================ // // AGIPCToolbarItem.h // AGImagePickerController // // Created by Artur Grigor on 05.03.2012. // Copyright (c) 2012 - 2013 Artur Grigor. All rights reserved. // // For the full copyright and license information, please view the LICENSE // file that was distributed with this source code. // #import #import typedef BOOL (^AGIPCAssetIsSelectedBlock)(NSUInteger index, ALAsset *asset); @interface AGIPCToolbarItem : NSObject { AGIPCAssetIsSelectedBlock assetIsSelectedBlock; UIBarButtonItem *barButtonItem; } @property (strong) UIBarButtonItem *barButtonItem; @property (copy) AGIPCAssetIsSelectedBlock assetIsSelectedBlock; - (id)initWithBarButtonItem:(UIBarButtonItem *)theBarButtonItem; - (id)initWithBarButtonItem:(UIBarButtonItem *)theBarButtonItem andSelectionBlock:(AGIPCAssetIsSelectedBlock)theSelectionBlock; @end ================================================ FILE: AGImagePickerController/AGIPCToolbarItem.m ================================================ // // AGIPCToolbarItem.m // AGImagePickerController // // Created by Artur Grigor on 05.03.2012. // Copyright (c) 2012 - 2013 Artur Grigor. All rights reserved. // // For the full copyright and license information, please view the LICENSE // file that was distributed with this source code. // #import "AGIPCToolbarItem.h" @implementation AGIPCToolbarItem #pragma mark - Properties @synthesize assetIsSelectedBlock, barButtonItem; #pragma mark - Object Lifecycle #pragma mark - Designated Initializer - (id)initWithBarButtonItem:(UIBarButtonItem *)theBarButtonItem andSelectionBlock:(AGIPCAssetIsSelectedBlock)theSelectionBlock { self = [super init]; if (self) { self.barButtonItem = theBarButtonItem; self.assetIsSelectedBlock = theSelectionBlock; } return self; } #pragma mark - Initializers - (id)initWithBarButtonItem:(UIBarButtonItem *)theBarButtonItem { return [self initWithBarButtonItem:theBarButtonItem andSelectionBlock:nil]; } @end ================================================ FILE: AGImagePickerController/AGImagePickerController+Helper.h ================================================ // // AGImagePickerController+Helper.h // AGImagePickerController Demo // // Created by Artur Grigor on 06.02.2013. // Copyright (c) 2013 Artur Grigor. All rights reserved. // #import "AGImagePickerController.h" @interface AGImagePickerController (Helper) // // Configuring Rows // - (NSUInteger)defaultNumberOfItemsPerRow; - (NSUInteger)numberOfItemsPerRow; // // Configuring Selections // - (AGImagePickerControllerSelectionBehaviorType)selectionBehaviorInSingleSelectionMode; // // Appearance Configuration // - (BOOL)shouldDisplaySelectionInformation; - (BOOL)shouldShowToolbarForManagingTheSelection; // // Others // - (AGDeviceType)deviceType; // // Drawing: Item // - (CGPoint)itemTopLeftPoint; - (CGRect)itemRect; // // Drawing: Checkmark // - (CGRect)checkmarkFrameUsingItemFrame:(CGRect)frame; @end @interface NSInvocation (Addon) + (id)invocationWithProtocol:(Protocol *)targetProtocol selector:(SEL)selector andRequiredFlag:(BOOL)isMethodRequired; @end ================================================ FILE: AGImagePickerController/AGImagePickerController+Helper.m ================================================ // // AGImagePickerController+Helper.m // AGImagePickerController Demo // // Created by Artur Grigor on 06.02.2013. // Copyright (c) 2013 Artur Grigor. All rights reserved. // #import "AGImagePickerController.h" #import "AGImagePickerController+Helper.h" #import @implementation AGImagePickerController (Helper) #pragma mark - Configuring Rows - (NSUInteger)numberOfItemsPerRow { if (_pickerFlags.delegateNumberOfItemsPerRowForDevice) { AGDeviceType deviceType = self.deviceType; UIInterfaceOrientation interfaceOrientation = self.interfaceOrientation; SEL selector = @selector(agImagePickerController:numberOfItemsPerRowForDevice:andInterfaceOrientation:); Protocol *protocol = @protocol(AGImagePickerControllerDelegate); NSInvocation *invocation = [NSInvocation invocationWithProtocol:protocol selector:selector andRequiredFlag:NO]; [invocation setSelector:selector]; [invocation setArgument:(__bridge void *)(self) atIndex:2]; [invocation setArgument:&deviceType atIndex:3]; [invocation setArgument:&interfaceOrientation atIndex:4]; [invocation invokeWithTarget:self.delegate]; if (invocation) { NSUInteger length = [[invocation methodSignature] methodReturnLength]; void *buffer = malloc(length); [invocation getReturnValue:buffer]; NSUInteger ret = *(NSUInteger *)buffer; free(buffer); return ret; } else return self.defaultNumberOfItemsPerRow; } else { return self.defaultNumberOfItemsPerRow; } } - (NSUInteger)defaultNumberOfItemsPerRow { NSUInteger numberOfItemsPerRow = 0; if (IS_IPAD()) { if (UIInterfaceOrientationIsPortrait(self.interfaceOrientation)) { numberOfItemsPerRow = AGIPC_ITEMS_PER_ROW_IPAD_PORTRAIT; } else { numberOfItemsPerRow = AGIPC_ITEMS_PER_ROW_IPAD_LANDSCAPE; } } else { if (UIInterfaceOrientationIsPortrait(self.interfaceOrientation)) { numberOfItemsPerRow = AGIPC_ITEMS_PER_ROW_IPHONE_PORTRAIT; } else { numberOfItemsPerRow = AGIPC_ITEMS_PER_ROW_IPHONE_LANDSCAPE; } } return numberOfItemsPerRow; } #pragma mark - Configuring Selections - (AGImagePickerControllerSelectionBehaviorType)selectionBehaviorInSingleSelectionMode { if (_pickerFlags.delegateSelectionBehaviorInSingleSelectionMode) { SEL selector = @selector(selectionBehaviorInSingleSelectionModeForAGImagePickerController:); Protocol *protocol = @protocol(AGImagePickerControllerDelegate); NSInvocation *invocation = [NSInvocation invocationWithProtocol:protocol selector:selector andRequiredFlag:NO]; [invocation setSelector:selector]; [invocation setArgument:(__bridge void *)(self) atIndex:2]; [invocation invokeWithTarget:self.delegate]; if (invocation) { NSUInteger length = [[invocation methodSignature] methodReturnLength]; void *buffer = malloc(length); [invocation getReturnValue:buffer]; AGImagePickerControllerSelectionBehaviorType ret = *(AGImagePickerControllerSelectionBehaviorType *)buffer; free(buffer); return ret; } else return SELECTION_BEHAVIOR_IN_SINGLE_SELECTION_MODE; } else { return SELECTION_BEHAVIOR_IN_SINGLE_SELECTION_MODE; } } #pragma mark - Appearance Configuration - (BOOL)shouldDisplaySelectionInformation { if (_pickerFlags.delegateShouldDisplaySelectionInformationInSelectionMode) { AGImagePickerControllerSelectionMode selectionMode = self.selectionMode; SEL selector = @selector(agImagePickerController:shouldDisplaySelectionInformationInSelectionMode:); Protocol *protocol = @protocol(AGImagePickerControllerDelegate); NSInvocation *invocation = [NSInvocation invocationWithProtocol:protocol selector:selector andRequiredFlag:NO]; [invocation setSelector:selector]; [invocation setArgument:(__bridge void *)(self) atIndex:2]; [invocation setArgument:&selectionMode atIndex:3]; [invocation invokeWithTarget:self.delegate]; if (invocation) { NSUInteger length = [[invocation methodSignature] methodReturnLength]; void *buffer = malloc(length); [invocation getReturnValue:buffer]; BOOL ret = *(BOOL *)buffer; free(buffer); return ret; } else return SHOULD_DISPLAY_SELECTION_INFO; } else { return SHOULD_DISPLAY_SELECTION_INFO; } } - (BOOL)shouldShowToolbarForManagingTheSelection { if (_pickerFlags.delegateShouldShowToolbarForManagingTheSelectionInSelectionMode) { AGImagePickerControllerSelectionMode selectionMode = self.selectionMode; SEL selector = @selector(agImagePickerController:shouldShowToolbarForManagingTheSelectionInSelectionMode:); Protocol *protocol = @protocol(AGImagePickerControllerDelegate); NSInvocation *invocation = [NSInvocation invocationWithProtocol:protocol selector:selector andRequiredFlag:NO]; [invocation setSelector:selector]; [invocation setArgument:(__bridge void *)(self) atIndex:2]; [invocation setArgument:&selectionMode atIndex:3]; [invocation invokeWithTarget:self.delegate]; if (invocation) { NSUInteger length = [[invocation methodSignature] methodReturnLength]; void *buffer = malloc(length); [invocation getReturnValue:buffer]; BOOL ret = *(BOOL *)buffer; free(buffer); return ret; } else return SHOULD_SHOW_TOOLBAR_FOR_MANAGING_THE_SELECTION; } else { return SHOULD_SHOW_TOOLBAR_FOR_MANAGING_THE_SELECTION; } } #pragma mark - Others - (AGDeviceType)deviceType { return (IS_IPAD() ? AGDeviceTypeiPad : AGDeviceTypeiPhone); } #pragma mark - Drawing: Item - (CGRect)itemRect { CGPoint topLeftPoint = self.itemTopLeftPoint; CGSize size = AGIPC_ITEM_SIZE; return CGRectMake(topLeftPoint.x, topLeftPoint.y, size.width, size.height); } - (CGPoint)itemTopLeftPoint { CGRect bounds = [[UIScreen mainScreen] bounds]; CGFloat width = bounds.size.width; if (UIInterfaceOrientationIsLandscape(self.interfaceOrientation)) { width = bounds.size.height; } CGFloat x = 0, y = 0; x = (width - (self.numberOfItemsPerRow * AGIPC_ITEM_SIZE.width)) / (self.numberOfItemsPerRow + 1); y = x; return CGPointMake(x, y); } #pragma mark - Drawing: Checkmark - (CGRect)checkmarkFrameUsingItemFrame:(CGRect)frame { CGRect checkmarkRect = AGIPC_CHECKMARK_RECT; return CGRectMake( frame.size.width - checkmarkRect.size.width - checkmarkRect.origin.x, frame.size.height - checkmarkRect.size.height - checkmarkRect.origin.y, checkmarkRect.size.width, checkmarkRect.size.height ); } @end @implementation NSInvocation (Addon) #pragma mark - Invocation + (id)invocationWithProtocol:(Protocol *)targetProtocol selector:(SEL)selector andRequiredFlag:(BOOL)isMethodRequired { struct objc_method_description desc; desc = protocol_getMethodDescription(targetProtocol, selector, isMethodRequired, YES); if (desc.name == NULL) return nil; NSMethodSignature *sig = [NSMethodSignature signatureWithObjCTypes:desc.types]; NSInvocation *inv = [NSInvocation invocationWithMethodSignature:sig]; [inv setSelector:selector]; return inv; } @end ================================================ FILE: AGImagePickerController/AGImagePickerController.h ================================================ // // AGImagePickerController.h // AGImagePickerController // // Created by Artur Grigor on 2/16/12. // Copyright (c) 2012 - 2013 Artur Grigor. All rights reserved. // // For the full copyright and license information, please view the LICENSE // file that was distributed with this source code. // #import #import #import "AGImagePickerControllerDefines.h" @class AGImagePickerController; @protocol AGImagePickerControllerDelegate @optional #pragma mark - Configuring Rows - (NSUInteger)agImagePickerController:(AGImagePickerController *)picker numberOfItemsPerRowForDevice:(AGDeviceType)deviceType andInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation; #pragma mark - Configuring Selections - (AGImagePickerControllerSelectionBehaviorType)selectionBehaviorInSingleSelectionModeForAGImagePickerController:(AGImagePickerController *)picker; #pragma mark - Appearance Configuration - (BOOL)agImagePickerController:(AGImagePickerController *)picker shouldDisplaySelectionInformationInSelectionMode:(AGImagePickerControllerSelectionMode)selectionMode; - (BOOL)agImagePickerController:(AGImagePickerController *)picker shouldShowToolbarForManagingTheSelectionInSelectionMode:(AGImagePickerControllerSelectionMode)selectionMode; #pragma mark - Managing Selections - (void)agImagePickerController:(AGImagePickerController *)picker didFinishPickingMediaWithInfo:(NSArray *)info; - (void)agImagePickerController:(AGImagePickerController *)picker didFail:(NSError *)error; @end @interface AGImagePickerController : UINavigationController { id __ag_weak _pickerDelegate; struct { unsigned int delegateSelectionBehaviorInSingleSelectionMode:1; unsigned int delegateNumberOfItemsPerRowForDevice:1; unsigned int delegateShouldDisplaySelectionInformationInSelectionMode:1; unsigned int delegateShouldShowToolbarForManagingTheSelectionInSelectionMode:1; unsigned int delegateDidFinishPickingMediaWithInfo:1; unsigned int delegateDidFail:1; } _pickerFlags; BOOL _shouldChangeStatusBarStyle; BOOL _shouldShowSavedPhotosOnTop; UIStatusBarStyle _oldStatusBarStyle; AGIPCDidFinish _didFinishBlock; AGIPCDidFail _didFailBlock; NSUInteger _maximumNumberOfPhotosToBeSelected; NSArray *_toolbarItemsForManagingTheSelection; NSArray *_selection; } @property (nonatomic) BOOL shouldChangeStatusBarStyle; @property (nonatomic) BOOL shouldShowSavedPhotosOnTop; @property (nonatomic) BOOL shouldShowPhotosWithLocationOnly; @property (nonatomic) NSUInteger maximumNumberOfPhotosToBeSelected; @property (nonatomic, ag_weak) id delegate; @property (nonatomic, copy) AGIPCDidFail didFailBlock; @property (nonatomic, copy) AGIPCDidFinish didFinishBlock; @property (nonatomic, strong) NSArray *toolbarItemsForManagingTheSelection; @property (nonatomic, strong) NSArray *selection; @property (nonatomic, readonly) AGImagePickerControllerSelectionMode selectionMode; + (ALAssetsLibrary *)defaultAssetsLibrary; - (id)initWithDelegate:(id)delegate; - (id)initWithFailureBlock:(AGIPCDidFail)failureBlock andSuccessBlock:(AGIPCDidFinish)successBlock; - (id)initWithDelegate:(id)delegate failureBlock:(AGIPCDidFail)failureBlock successBlock:(AGIPCDidFinish)successBlock maximumNumberOfPhotosToBeSelected:(NSUInteger)maximumNumberOfPhotosToBeSelected shouldChangeStatusBarStyle:(BOOL)shouldChangeStatusBarStyle toolbarItemsForManagingTheSelection:(NSArray *)toolbarItemsForManagingTheSelection andShouldShowSavedPhotosOnTop:(BOOL)shouldShowSavedPhotosOnTop; @end ================================================ FILE: AGImagePickerController/AGImagePickerController.m ================================================ // // AGImagePickerController.m // AGImagePickerController // // Created by Artur Grigor on 2/16/12. // Copyright (c) 2012 - 2013 Artur Grigor. All rights reserved. // // For the full copyright and license information, please view the LICENSE // file that was distributed with this source code. // #import "AGImagePickerController.h" #import "AGIPCAlbumsController.h" #import "AGIPCGridItem.h" @interface AGImagePickerController () { } - (void)didFinishPickingAssets:(NSArray *)selectedAssets; - (void)didCancelPickingAssets; - (void)didFail:(NSError *)error; @end @implementation AGImagePickerController #pragma mark - Properties @synthesize delegate = _pickerDelegate, maximumNumberOfPhotosToBeSelected = _maximumNumberOfPhotosToBeSelected, shouldChangeStatusBarStyle = _shouldChangeStatusBarStyle, shouldShowSavedPhotosOnTop = _shouldShowSavedPhotosOnTop; @synthesize didFailBlock, didFinishBlock; @synthesize toolbarItemsForManagingTheSelection = _toolbarItemsForManagingTheSelection, selection = _selection; - (AGImagePickerControllerSelectionMode)selectionMode { return (self.maximumNumberOfPhotosToBeSelected == 1 ? AGImagePickerControllerSelectionModeSingle : AGImagePickerControllerSelectionModeMultiple); } - (void)setDelegate:(id)delegate { _pickerDelegate = delegate; _pickerFlags.delegateSelectionBehaviorInSingleSelectionMode = _pickerDelegate && [_pickerDelegate respondsToSelector:@selector(selectionBehaviorInSingleSelectionModeForAGImagePickerController:)]; _pickerFlags.delegateNumberOfItemsPerRowForDevice = _pickerDelegate && [_pickerDelegate respondsToSelector:@selector(agImagePickerController:numberOfItemsPerRowForDevice:andInterfaceOrientation:)]; _pickerFlags.delegateShouldDisplaySelectionInformationInSelectionMode = _pickerDelegate && [_pickerDelegate respondsToSelector:@selector(agImagePickerController:shouldDisplaySelectionInformationInSelectionMode:)]; _pickerFlags.delegateShouldShowToolbarForManagingTheSelectionInSelectionMode = _pickerDelegate && [_pickerDelegate respondsToSelector:@selector(agImagePickerController:shouldShowToolbarForManagingTheSelectionInSelectionMode:)]; _pickerFlags.delegateDidFinishPickingMediaWithInfo = _pickerDelegate && [_pickerDelegate respondsToSelector:@selector(agImagePickerController:didFinishPickingMediaWithInfo:)]; _pickerFlags.delegateDidFail = _pickerDelegate && [_pickerDelegate respondsToSelector:@selector(agImagePickerController:didFail:)]; } - (void)setShouldChangeStatusBarStyle:(BOOL)shouldChangeStatusBarStyle { if (_shouldChangeStatusBarStyle != shouldChangeStatusBarStyle) { _shouldChangeStatusBarStyle = shouldChangeStatusBarStyle; if (_shouldChangeStatusBarStyle) if (IS_IPAD()) [[UIApplication sharedApplication] setStatusBarStyle:UIStatusBarStyleBlackOpaque animated:YES]; else [[UIApplication sharedApplication] setStatusBarStyle:UIStatusBarStyleBlackTranslucent animated:YES]; else [[UIApplication sharedApplication] setStatusBarStyle:_oldStatusBarStyle animated:YES]; } } + (ALAssetsLibrary *)defaultAssetsLibrary { static ALAssetsLibrary *assetsLibrary = nil; static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ assetsLibrary = [[ALAssetsLibrary alloc] init]; // Workaround for triggering ALAssetsLibraryChangedNotification [assetsLibrary writeImageToSavedPhotosAlbum:nil metadata:nil completionBlock:^(NSURL *assetURL, NSError *error) { }]; }); return assetsLibrary; } #pragma mark - Object Lifecycle - (id)init { return [self initWithDelegate:nil failureBlock:nil successBlock:nil maximumNumberOfPhotosToBeSelected:0 shouldChangeStatusBarStyle:SHOULD_CHANGE_STATUS_BAR_STYLE toolbarItemsForManagingTheSelection:nil andShouldShowSavedPhotosOnTop:SHOULD_SHOW_SAVED_PHOTOS_ON_TOP]; } - (id)initWithDelegate:(id)delegate { return [self initWithDelegate:delegate failureBlock:nil successBlock:nil maximumNumberOfPhotosToBeSelected:0 shouldChangeStatusBarStyle:SHOULD_CHANGE_STATUS_BAR_STYLE toolbarItemsForManagingTheSelection:nil andShouldShowSavedPhotosOnTop:SHOULD_SHOW_SAVED_PHOTOS_ON_TOP]; } - (id)initWithFailureBlock:(AGIPCDidFail)failureBlock andSuccessBlock:(AGIPCDidFinish)successBlock { return [self initWithDelegate:nil failureBlock:failureBlock successBlock:successBlock maximumNumberOfPhotosToBeSelected:0 shouldChangeStatusBarStyle:SHOULD_CHANGE_STATUS_BAR_STYLE toolbarItemsForManagingTheSelection:nil andShouldShowSavedPhotosOnTop:SHOULD_SHOW_SAVED_PHOTOS_ON_TOP]; } - (id)initWithDelegate:(id)delegate failureBlock:(AGIPCDidFail)failureBlock successBlock:(AGIPCDidFinish)successBlock maximumNumberOfPhotosToBeSelected:(NSUInteger)maximumNumberOfPhotosToBeSelected shouldChangeStatusBarStyle:(BOOL)shouldChangeStatusBarStyle toolbarItemsForManagingTheSelection:(NSArray *)toolbarItemsForManagingTheSelection andShouldShowSavedPhotosOnTop:(BOOL)shouldShowSavedPhotosOnTop { self = [super init]; if (self) { _oldStatusBarStyle = [UIApplication sharedApplication].statusBarStyle; self.shouldChangeStatusBarStyle = shouldChangeStatusBarStyle; self.shouldShowSavedPhotosOnTop = shouldShowSavedPhotosOnTop; UIBarStyle barStyle; if (floor(NSFoundationVersionNumber) <= NSFoundationVersionNumber_iOS_6_1) { // iOS 6.1 or earlier barStyle = UIBarStyleBlack; } else { // iOS 7 or later barStyle = UIBarStyleDefault; } self.navigationBar.barStyle = barStyle; self.navigationBar.translucent = YES; self.toolbar.barStyle = barStyle; self.toolbar.translucent = YES; self.toolbarItemsForManagingTheSelection = toolbarItemsForManagingTheSelection; self.selection = nil; self.maximumNumberOfPhotosToBeSelected = maximumNumberOfPhotosToBeSelected; self.delegate = delegate; self.didFailBlock = failureBlock; self.didFinishBlock = successBlock; self.viewControllers = @[[[AGIPCAlbumsController alloc] initWithImagePickerController:self]]; } return self; } #pragma mark - View lifecycle - (NSUInteger)supportedInterfaceOrientations { return UIInterfaceOrientationMaskAll; } #pragma mark - Private - (void)didFinishPickingAssets:(NSArray *)selectedAssets { [self popToRootViewControllerAnimated:NO]; // Reset the number of selections [AGIPCGridItem performSelector:@selector(resetNumberOfSelections)]; if (self.didFinishBlock) self.didFinishBlock(selectedAssets); if (_pickerFlags.delegateDidFinishPickingMediaWithInfo) { [self.delegate performSelector:@selector(agImagePickerController:didFinishPickingMediaWithInfo:) withObject:self withObject:selectedAssets]; } } - (void)didCancelPickingAssets { [self popToRootViewControllerAnimated:NO]; // Reset the number of selections [AGIPCGridItem performSelector:@selector(resetNumberOfSelections)]; if (self.didFailBlock) self.didFailBlock(nil); if (_pickerFlags.delegateDidFail) { [self.delegate performSelector:@selector(agImagePickerController:didFail:) withObject:self withObject:nil]; } } - (void)didFail:(NSError *)error { [self popToRootViewControllerAnimated:NO]; // Reset the number of selections [AGIPCGridItem performSelector:@selector(resetNumberOfSelections)]; if (self.didFailBlock) self.didFailBlock(error); if (_pickerFlags.delegateDidFail) { [self.delegate performSelector:@selector(agImagePickerController:didFail:) withObject:self withObject:error]; } } @end ================================================ FILE: AGImagePickerController/AGImagePickerControllerDefines.h ================================================ // // AGImagePickerControllerDefines.h // AGImagePickerController // // Created by Artur Grigor on 28.02.2012. // Copyright (c) 2012 - 2013 Artur Grigor. All rights reserved. // // For the full copyright and license information, please view the LICENSE // file that was distributed with this source code. // #pragma mark ARC #if __has_feature(objc_arc_weak) #define ag_weak weak #define __ag_weak __weak #elif __has_feature(objc_arc) #define ag_weak unsafe_unretained #define __ag_weak __unsafe_unretained #else #define ag_weak #define __ag_weak #endif #pragma mark - Utilities #define IS_IPAD() ([[UIDevice currentDevice] respondsToSelector:@selector(userInterfaceIdiom)] && \ [[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPad) #pragma mark - Constants #define SHOULD_CHANGE_STATUS_BAR_STYLE 1 #define SHOULD_DISPLAY_SELECTION_INFO 1 #define SHOULD_SHOW_SAVED_PHOTOS_ON_TOP 1 #define SHOULD_SHOW_TOOLBAR_FOR_MANAGING_THE_SELECTION 1 #define SELECTION_BEHAVIOR_IN_SINGLE_SELECTION_MODE 0 // Size in points #define AGIPC_CHECKMARK_WIDTH 28.f #define AGIPC_CHECKMARK_HEIGHT 28.f #define AGIPC_CHECKMARK_RIGHT_MARGIN 4.f #define AGIPC_CHECKMARK_BOTTOM_MARGIN 4.f #define AGIPC_CHECKMARK_BOTTOM_RIGHT_POINT CGPointMake(AGIPC_CHECKMARK_RIGHT_MARGIN, AGIPC_CHECKMARK_BOTTOM_MARGIN) #define AGIPC_CHECKMARK_SIZE CGSizeMake(AGIPC_CHECKMARK_WIDTH, AGIPC_CHECKMARK_HEIGHT) #define AGIPC_CHECKMARK_RECT CGRectMake(AGIPC_CHECKMARK_BOTTOM_RIGHT_POINT.x, AGIPC_CHECKMARK_BOTTOM_RIGHT_POINT.y, AGIPC_CHECKMARK_SIZE.width, AGIPC_CHECKMARK_SIZE.height) #define AGIPC_ITEMS_PER_ROW_IPHONE_PORTRAIT 4 #define AGIPC_ITEMS_PER_ROW_IPHONE_LANDSCAPE 6 #define AGIPC_ITEMS_PER_ROW_IPAD_PORTRAIT 8 #define AGIPC_ITEMS_PER_ROW_IPAD_LANDSCAPE 12 #define AGIPC_ITEM_WIDTH 75.f #define AGIPC_ITEM_HEIGHT 75.f #define AGIPC_ITEM_SIZE CGSizeMake(AGIPC_ITEM_WIDTH, AGIPC_ITEM_HEIGHT) #pragma mark - Types typedef void (^AGIPCDidFinish)(NSArray *info); typedef void (^AGIPCDidFail)(NSError *error); typedef NS_ENUM(NSUInteger, AGDeviceType) { AGDeviceTypeiPad, AGDeviceTypeiPhone }; typedef NS_ENUM(NSUInteger, AGImagePickerControllerSelectionMode) { AGImagePickerControllerSelectionModeSingle, AGImagePickerControllerSelectionModeMultiple }; typedef NS_ENUM(NSUInteger, AGImagePickerControllerSelectionBehaviorType) { AGImagePickerControllerSelectionBehaviorTypeCheckbox, AGImagePickerControllerSelectionBehaviorTypeRadio }; ================================================ FILE: AGImagePickerController/ALAsset+AGIPC.h ================================================ // // ALAsset+AGIPC.h // AGImagePickerController Demo // // Created by Artur Grigor on 19.06.2012. // Copyright (c) 2012 - 2013 Artur Grigor. All rights reserved. // #import @interface ALAsset (AGIPC) - (BOOL)isEqual:(id)object; @end ================================================ FILE: AGImagePickerController/ALAsset+AGIPC.m ================================================ // // ALAsset+AGIPC.m // AGImagePickerController Demo // // Created by Artur Grigor on 19.06.2012. // Copyright (c) 2012 - 2013 Artur Grigor. All rights reserved. // #import "ALAsset+AGIPC.h" @implementation ALAsset (AGIPC) - (BOOL)isEqual:(id)other { if (other == self) return YES; if (!other || ![other isKindOfClass:[self class]]) return NO; ALAsset *otherAsset = (ALAsset *)other; NSDictionary *selfUrls = [self valueForProperty:ALAssetPropertyURLs]; NSDictionary *otherUrls = [otherAsset valueForProperty:ALAssetPropertyURLs]; return [selfUrls isEqualToDictionary:otherUrls]; } @end ================================================ FILE: AGImagePickerController Demo/AGAppDelegate.h ================================================ // // AGAppDelegate.h // AGImagePickerController Demo // // Created by Artur Grigor on 2/16/12. // Copyright (c) 2012 - 2013 Artur Grigor. All rights reserved. // #import @class AGViewController; @interface AGAppDelegate : UIResponder @property (strong, nonatomic) UIWindow *window; @property (strong, nonatomic) AGViewController *viewController; @end ================================================ FILE: AGImagePickerController Demo/AGAppDelegate.m ================================================ // // AGAppDelegate.m // AGImagePickerController Demo // // Created by Artur Grigor on 2/16/12. // Copyright (c) 2012 - 2013 Artur Grigor. All rights reserved. // #import "AGAppDelegate.h" #import "AGViewController.h" @implementation AGAppDelegate @synthesize window = _window; @synthesize viewController = _viewController; - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]]; // Override point for customization after application launch. if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPhone) { self.viewController = [[AGViewController alloc] initWithNibName:@"AGViewController_iPhone" bundle:nil]; } else { self.viewController = [[AGViewController alloc] initWithNibName:@"AGViewController_iPad" bundle:nil]; } self.window.rootViewController = self.viewController; [self.window makeKeyAndVisible]; return YES; } - (void)applicationWillResignActive:(UIApplication *)application { /* 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. 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. */ } - (void)applicationDidEnterBackground:(UIApplication *)application { /* 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. If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. */ } - (void)applicationWillEnterForeground:(UIApplication *)application { /* 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. */ } - (void)applicationDidBecomeActive:(UIApplication *)application { /* 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. */ } - (void)applicationWillTerminate:(UIApplication *)application { /* Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. */ } @end ================================================ FILE: AGImagePickerController Demo/AGImagePickerController Demo-Info.plist ================================================ CFBundleDevelopmentRegion en CFBundleDisplayName ${PRODUCT_NAME} CFBundleExecutable ${EXECUTABLE_NAME} CFBundleIconFiles AGImagePickerController-icon.png AGImagePickerController-icon@2x.png CFBundleIcons CFBundlePrimaryIcon CFBundleIconFiles AGImagePickerController-icon.png AGImagePickerController-icon@2x.png CFBundleIdentifier me.arturgrigor.${PRODUCT_NAME:rfc1034identifier} CFBundleInfoDictionaryVersion 6.0 CFBundleName ${PRODUCT_NAME} CFBundlePackageType APPL CFBundleShortVersionString 1.0 CFBundleSignature ???? CFBundleVersion 1.0 LSRequiresIPhoneOS UIRequiredDeviceCapabilities armv7 UISupportedInterfaceOrientations UIInterfaceOrientationPortrait UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight UISupportedInterfaceOrientations~ipad UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight ================================================ FILE: AGImagePickerController Demo/AGImagePickerController Demo-Prefix.pch ================================================ // // Prefix header for all source files of the 'AGImagePickerController Demo' target in the 'AGImagePickerController Demo' project // #import #ifndef __IPHONE_4_0 #warning "This project uses features only available in iOS SDK 4.0 and later." #endif #ifdef __OBJC__ #import #import #endif ================================================ FILE: AGImagePickerController Demo/AGViewController.h ================================================ // // AGViewController.h // AGImagePickerController Demo // // Created by Artur Grigor on 2/16/12. // Copyright (c) 2012 - 2013 Artur Grigor. All rights reserved. // #import #import "AGImagePickerController.h" @interface AGViewController : UIViewController { NSMutableArray *selectedPhotos; } - (IBAction)openAction:(id)sender; @property (nonatomic, strong) NSMutableArray *selectedPhotos; @end ================================================ FILE: AGImagePickerController Demo/AGViewController.m ================================================ // // AGViewController.m // AGImagePickerController Demo // // Created by Artur Grigor on 2/16/12. // Copyright (c) 2012 - 2013 Artur Grigor. All rights reserved. // #import "AGViewController.h" #import "AGIPCToolbarItem.h" @interface AGViewController () { AGImagePickerController *ipc; } @end @implementation AGViewController #pragma mark - Properties @synthesize selectedPhotos; #pragma mark - Object Lifecycle - (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil { self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil]; if (self) { self.selectedPhotos = [NSMutableArray array]; __block AGViewController *blockSelf = self; ipc = [[AGImagePickerController alloc] initWithDelegate:self]; ipc.didFailBlock = ^(NSError *error) { NSLog(@"Fail. Error: %@", error); if (error == nil) { [blockSelf.selectedPhotos removeAllObjects]; NSLog(@"User has cancelled."); [blockSelf dismissModalViewControllerAnimated:YES]; } else { // We need to wait for the view controller to appear first. double delayInSeconds = 0.5; dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, delayInSeconds * NSEC_PER_SEC); dispatch_after(popTime, dispatch_get_main_queue(), ^(void){ [blockSelf dismissModalViewControllerAnimated:YES]; }); } [[UIApplication sharedApplication] setStatusBarStyle:UIStatusBarStyleDefault animated:YES]; }; ipc.didFinishBlock = ^(NSArray *info) { [blockSelf.selectedPhotos setArray:info]; NSLog(@"Info: %@", info); [blockSelf dismissModalViewControllerAnimated:YES]; [[UIApplication sharedApplication] setStatusBarStyle:UIStatusBarStyleDefault animated:YES]; }; } return self; } - (void)didReceiveMemoryWarning { [super didReceiveMemoryWarning]; // Release any cached data, images, etc that aren't in use. } #pragma mark - View lifecycle - (void)viewDidLoad { [super viewDidLoad]; // Do any additional setup after loading the view, typically from a nib. } - (void)viewDidUnload { [super viewDidUnload]; // Release any retained subviews of the main view. // e.g. self.myOutlet = nil; } - (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation { return YES; } - (NSUInteger)supportedInterfaceOrientations { return UIInterfaceOrientationMaskAll; } #pragma mark - Public methods - (void)openAction:(id)sender { // Show saved photos on top ipc.shouldShowSavedPhotosOnTop = NO; ipc.shouldChangeStatusBarStyle = YES; ipc.selection = self.selectedPhotos; // ipc.maximumNumberOfPhotosToBeSelected = 10; // Custom toolbar items AGIPCToolbarItem *selectAll = [[AGIPCToolbarItem alloc] initWithBarButtonItem:[[UIBarButtonItem alloc] initWithTitle:@"+ Select All" style:UIBarButtonItemStyleBordered target:nil action:nil] andSelectionBlock:^BOOL(NSUInteger index, ALAsset *asset) { return YES; }]; AGIPCToolbarItem *flexible = [[AGIPCToolbarItem alloc] initWithBarButtonItem:[[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace target:nil action:nil] andSelectionBlock:nil]; AGIPCToolbarItem *selectOdd = [[AGIPCToolbarItem alloc] initWithBarButtonItem:[[UIBarButtonItem alloc] initWithTitle:@"+ Select Odd" style:UIBarButtonItemStyleBordered target:nil action:nil] andSelectionBlock:^BOOL(NSUInteger index, ALAsset *asset) { return !(index % 2); }]; AGIPCToolbarItem *deselectAll = [[AGIPCToolbarItem alloc] initWithBarButtonItem:[[UIBarButtonItem alloc] initWithTitle:@"- Deselect All" style:UIBarButtonItemStyleBordered target:nil action:nil] andSelectionBlock:^BOOL(NSUInteger index, ALAsset *asset) { return NO; }]; ipc.toolbarItemsForManagingTheSelection = @[selectAll, flexible, selectOdd, flexible, deselectAll]; // imagePickerController.toolbarItemsForManagingTheSelection = [NSArray array]; // imagePickerController.maximumNumberOfPhotos = 3; [self presentModalViewController:ipc animated:YES]; } #pragma mark - AGImagePickerControllerDelegate methods - (NSUInteger)agImagePickerController:(AGImagePickerController *)picker numberOfItemsPerRowForDevice:(AGDeviceType)deviceType andInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation { if (deviceType == AGDeviceTypeiPad) { if (UIInterfaceOrientationIsLandscape(interfaceOrientation)) return 7; else return 6; } else { if (UIInterfaceOrientationIsLandscape(interfaceOrientation)) return 5; else return 4; } } - (BOOL)agImagePickerController:(AGImagePickerController *)picker shouldDisplaySelectionInformationInSelectionMode:(AGImagePickerControllerSelectionMode)selectionMode { return (selectionMode == AGImagePickerControllerSelectionModeSingle ? NO : YES); } - (BOOL)agImagePickerController:(AGImagePickerController *)picker shouldShowToolbarForManagingTheSelectionInSelectionMode:(AGImagePickerControllerSelectionMode)selectionMode { return (selectionMode == AGImagePickerControllerSelectionModeSingle ? NO : YES); } - (AGImagePickerControllerSelectionBehaviorType)selectionBehaviorInSingleSelectionModeForAGImagePickerController:(AGImagePickerController *)picker { return AGImagePickerControllerSelectionBehaviorTypeRadio; } @end ================================================ FILE: AGImagePickerController Demo/en.lproj/AGViewController_iPad.xib ================================================ 1552 12C60 3084 1187.34 625.00 com.apple.InterfaceBuilder.IBCocoaTouchPlugin 2083 IBProxyObject IBUIButton IBUIView com.apple.InterfaceBuilder.IBCocoaTouchPlugin PluginDependencyRecalculationVersion IBFilesOwner IBIPadFramework IBFirstResponder IBIPadFramework 274 301 {{353, 480}, {63, 44}} _NS:9 NO IBIPadFramework 0 0 1 Open 3 MQA 1 MC4xOTYwNzg0MzQ2IDAuMzA5ODAzOTMyOSAwLjUyMTU2ODY1NgA 3 MC41AA 2 15 Helvetica-Bold 15 16 {{0, 20}, {768, 1004}} 3 MQA 2 2 IBIPadFramework view 3 openAction: 7 5 0 -1 File's Owner -2 2 4 AGViewController com.apple.InterfaceBuilder.IBCocoaTouchPlugin UIResponder com.apple.InterfaceBuilder.IBCocoaTouchPlugin com.apple.InterfaceBuilder.IBCocoaTouchPlugin com.apple.InterfaceBuilder.IBCocoaTouchPlugin 5 AGViewController UIViewController openAction: id openAction: openAction: id IBProjectSource ./Classes/AGViewController.h 0 IBIPadFramework YES 3 2083 ================================================ FILE: AGImagePickerController Demo/en.lproj/AGViewController_iPhone.xib ================================================ 1552 12C60 3084 1187.34 625.00 com.apple.InterfaceBuilder.IBCocoaTouchPlugin 2083 IBProxyObject IBUIButton IBUIView com.apple.InterfaceBuilder.IBCocoaTouchPlugin PluginDependencyRecalculationVersion IBFilesOwner IBCocoaTouchFramework IBFirstResponder IBCocoaTouchFramework 274 301 {{129, 208}, {63, 44}} _NS:9 NO IBCocoaTouchFramework 0 0 1 Open 3 MQA 1 MC4xOTYwNzg0MzQ2IDAuMzA5ODAzOTMyOSAwLjUyMTU2ODY1NgA 3 MC41AA 2 15 Helvetica-Bold 15 16 {{0, 20}, {320, 460}} 3 MC43NQA 2 NO IBCocoaTouchFramework view 7 openAction: 7 9 0 -1 File's Owner -2 6 8 AGViewController com.apple.InterfaceBuilder.IBCocoaTouchPlugin UIResponder com.apple.InterfaceBuilder.IBCocoaTouchPlugin com.apple.InterfaceBuilder.IBCocoaTouchPlugin com.apple.InterfaceBuilder.IBCocoaTouchPlugin 9 AGViewController UIViewController openAction: id openAction: openAction: id IBProjectSource ./Classes/AGViewController.h 0 IBCocoaTouchFramework YES 3 2083 ================================================ FILE: AGImagePickerController Demo/en.lproj/InfoPlist.strings ================================================ /* Localized versions of Info.plist keys */ ================================================ FILE: AGImagePickerController Demo/main.m ================================================ // // main.m // AGImagePickerController Demo // // Created by Artur Grigor on 2/16/12. // Copyright (c) 2012 - 2013 Artur Grigor. All rights reserved. // #import #import "AGAppDelegate.h" int main(int argc, char *argv[]) { @autoreleasepool { return UIApplicationMain(argc, argv, nil, NSStringFromClass([AGAppDelegate class])); } } ================================================ FILE: AGImagePickerController Demo.xcodeproj/project.pbxproj ================================================ // !$*UTF8*$! { archiveVersion = 1; classes = { }; objectVersion = 46; objects = { /* Begin PBXBuildFile section */ 54A1E5551882A31E00D556FD /* CoreLocation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 54A1E5541882A31E00D556FD /* CoreLocation.framework */; }; FE1E332914ED167800F6A6A2 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FE1E332814ED167800F6A6A2 /* UIKit.framework */; }; FE1E332B14ED167800F6A6A2 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FE1E332A14ED167800F6A6A2 /* Foundation.framework */; }; FE1E333314ED167800F6A6A2 /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = FE1E333114ED167800F6A6A2 /* InfoPlist.strings */; }; FE1E333514ED167800F6A6A2 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = FE1E333414ED167800F6A6A2 /* main.m */; }; FE1E333914ED167800F6A6A2 /* AGAppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = FE1E333814ED167800F6A6A2 /* AGAppDelegate.m */; }; FE1E333C14ED167800F6A6A2 /* AGViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = FE1E333B14ED167800F6A6A2 /* AGViewController.m */; }; FE1E333F14ED167800F6A6A2 /* AGViewController_iPhone.xib in Resources */ = {isa = PBXBuildFile; fileRef = FE1E333D14ED167800F6A6A2 /* AGViewController_iPhone.xib */; }; FE1E334214ED167800F6A6A2 /* AGViewController_iPad.xib in Resources */ = {isa = PBXBuildFile; fileRef = FE1E334014ED167800F6A6A2 /* AGViewController_iPad.xib */; }; FE3850CB1501B8A10053C9DD /* README.md in Resources */ = {isa = PBXBuildFile; fileRef = FE3850CA1501B8A10053C9DD /* README.md */; }; FE3851AF1504CF7B00A9F7F8 /* AGIPCToolbarItem.m in Sources */ = {isa = PBXBuildFile; fileRef = FE3851AE1504CF7B00A9F7F8 /* AGIPCToolbarItem.m */; }; FE3BAF8814EE80E7001BF3EC /* AGIPCAssetsController.m in Sources */ = {isa = PBXBuildFile; fileRef = FE3BAF8714EE80E7001BF3EC /* AGIPCAssetsController.m */; }; FE465F991590B25A00C30A1D /* ALAsset+AGIPC.m in Sources */ = {isa = PBXBuildFile; fileRef = FE465F981590B25A00C30A1D /* ALAsset+AGIPC.m */; }; FE4DE10116C2546B0075E499 /* Default-568h@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = FE4DE10016C2546B0075E499 /* Default-568h@2x.png */; }; FE4DE10416C267410075E499 /* AGImagePickerController+Helper.m in Sources */ = {isa = PBXBuildFile; fileRef = FE4DE10316C267410075E499 /* AGImagePickerController+Helper.m */; }; FEA599CC14ED1C500057FF9C /* AGImagePickerController.m in Sources */ = {isa = PBXBuildFile; fileRef = FEA599CA14ED1C500057FF9C /* AGImagePickerController.m */; }; FEA599E814ED38EE0057FF9C /* AGIPCAlbumsController.m in Sources */ = {isa = PBXBuildFile; fileRef = FEA599E714ED38ED0057FF9C /* AGIPCAlbumsController.m */; }; FECDC90114EDB9C30038006D /* AGIPCGridCell.m in Sources */ = {isa = PBXBuildFile; fileRef = FECDC90014EDB9C30038006D /* AGIPCGridCell.m */; }; FECDC90514EDBB690038006D /* AGIPCGridItem.m in Sources */ = {isa = PBXBuildFile; fileRef = FECDC90414EDBB690038006D /* AGIPCGridItem.m */; }; FEDAA95516C2F3D600234FF0 /* AssetsLibrary.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FEA599E114ED30140057FF9C /* AssetsLibrary.framework */; }; FEDAA95716C3089600234FF0 /* AGImagePickerController.bundle in Resources */ = {isa = PBXBuildFile; fileRef = FEDAA95616C3089600234FF0 /* AGImagePickerController.bundle */; }; FEE0F35D16C509EF001A077B /* AGImagePickerController.podspec in Resources */ = {isa = PBXBuildFile; fileRef = FEE0F35C16C509EF001A077B /* AGImagePickerController.podspec */; }; FEF247F2150DF461008FEFAD /* AGImagePickerController-icon.png in Resources */ = {isa = PBXBuildFile; fileRef = FEF247F1150DF461008FEFAD /* AGImagePickerController-icon.png */; }; FEF247F5150DF463008FEFAD /* AGImagePickerController-icon@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = FEF247F4150DF463008FEFAD /* AGImagePickerController-icon@2x.png */; }; /* End PBXBuildFile section */ /* Begin PBXFileReference section */ 54A1E5541882A31E00D556FD /* CoreLocation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreLocation.framework; path = System/Library/Frameworks/CoreLocation.framework; sourceTree = SDKROOT; }; FE1E332414ED167800F6A6A2 /* AGImagePickerController Demo.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "AGImagePickerController Demo.app"; sourceTree = BUILT_PRODUCTS_DIR; }; FE1E332814ED167800F6A6A2 /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; }; FE1E332A14ED167800F6A6A2 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; }; FE1E332C14ED167800F6A6A2 /* CoreGraphics.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreGraphics.framework; path = System/Library/Frameworks/CoreGraphics.framework; sourceTree = SDKROOT; }; FE1E333014ED167800F6A6A2 /* AGImagePickerController Demo-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "AGImagePickerController Demo-Info.plist"; sourceTree = ""; }; FE1E333214ED167800F6A6A2 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/InfoPlist.strings; sourceTree = ""; }; FE1E333414ED167800F6A6A2 /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; FE1E333614ED167800F6A6A2 /* AGImagePickerController Demo-Prefix.pch */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "AGImagePickerController Demo-Prefix.pch"; sourceTree = ""; }; FE1E333714ED167800F6A6A2 /* AGAppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AGAppDelegate.h; sourceTree = ""; }; FE1E333814ED167800F6A6A2 /* AGAppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AGAppDelegate.m; sourceTree = ""; }; FE1E333A14ED167800F6A6A2 /* AGViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AGViewController.h; sourceTree = ""; }; FE1E333B14ED167800F6A6A2 /* AGViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AGViewController.m; sourceTree = ""; }; FE1E333E14ED167800F6A6A2 /* en */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = en; path = en.lproj/AGViewController_iPhone.xib; sourceTree = ""; }; FE1E334114ED167800F6A6A2 /* en */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = en; path = en.lproj/AGViewController_iPad.xib; sourceTree = ""; }; FE3850CA1501B8A10053C9DD /* README.md */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = README.md; sourceTree = SOURCE_ROOT; }; FE3851AD1504CF7B00A9F7F8 /* AGIPCToolbarItem.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AGIPCToolbarItem.h; sourceTree = ""; }; FE3851AE1504CF7B00A9F7F8 /* AGIPCToolbarItem.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AGIPCToolbarItem.m; sourceTree = ""; }; FE3BAF8614EE80E7001BF3EC /* AGIPCAssetsController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AGIPCAssetsController.h; sourceTree = ""; }; FE3BAF8714EE80E7001BF3EC /* AGIPCAssetsController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AGIPCAssetsController.m; sourceTree = ""; }; FE465F971590B25A00C30A1D /* ALAsset+AGIPC.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "ALAsset+AGIPC.h"; sourceTree = ""; }; FE465F981590B25A00C30A1D /* ALAsset+AGIPC.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "ALAsset+AGIPC.m"; sourceTree = ""; }; FE4DE10016C2546B0075E499 /* Default-568h@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "Default-568h@2x.png"; path = "../Default-568h@2x.png"; sourceTree = ""; }; FE4DE10216C267400075E499 /* AGImagePickerController+Helper.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "AGImagePickerController+Helper.h"; sourceTree = ""; }; FE4DE10316C267410075E499 /* AGImagePickerController+Helper.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "AGImagePickerController+Helper.m"; sourceTree = ""; }; FE6E796014FCDC8A006612F0 /* AGImagePickerControllerDefines.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AGImagePickerControllerDefines.h; sourceTree = ""; }; FEA599C914ED1C500057FF9C /* AGImagePickerController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AGImagePickerController.h; sourceTree = ""; }; FEA599CA14ED1C500057FF9C /* AGImagePickerController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AGImagePickerController.m; sourceTree = ""; }; FEA599E114ED30140057FF9C /* AssetsLibrary.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AssetsLibrary.framework; path = System/Library/Frameworks/AssetsLibrary.framework; sourceTree = SDKROOT; }; FEA599E614ED38ED0057FF9C /* AGIPCAlbumsController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AGIPCAlbumsController.h; sourceTree = ""; }; FEA599E714ED38ED0057FF9C /* AGIPCAlbumsController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AGIPCAlbumsController.m; sourceTree = ""; }; FECDC8FF14EDB9C30038006D /* AGIPCGridCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AGIPCGridCell.h; sourceTree = ""; }; FECDC90014EDB9C30038006D /* AGIPCGridCell.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AGIPCGridCell.m; sourceTree = ""; }; FECDC90314EDBB690038006D /* AGIPCGridItem.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AGIPCGridItem.h; sourceTree = ""; }; FECDC90414EDBB690038006D /* AGIPCGridItem.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AGIPCGridItem.m; sourceTree = ""; }; FEDAA95616C3089600234FF0 /* AGImagePickerController.bundle */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.plug-in"; path = AGImagePickerController.bundle; sourceTree = ""; }; FEE0F35C16C509EF001A077B /* AGImagePickerController.podspec */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = AGImagePickerController.podspec; sourceTree = ""; }; FEF247F1150DF461008FEFAD /* AGImagePickerController-icon.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "AGImagePickerController-icon.png"; path = "../AGImagePickerController-icon.png"; sourceTree = ""; }; FEF247F4150DF463008FEFAD /* AGImagePickerController-icon@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "AGImagePickerController-icon@2x.png"; path = "../AGImagePickerController-icon@2x.png"; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ FE1E332114ED167800F6A6A2 /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( 54A1E5551882A31E00D556FD /* CoreLocation.framework in Frameworks */, FEDAA95516C2F3D600234FF0 /* AssetsLibrary.framework in Frameworks */, FE1E332914ED167800F6A6A2 /* UIKit.framework in Frameworks */, FE1E332B14ED167800F6A6A2 /* Foundation.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; /* End PBXFrameworksBuildPhase section */ /* Begin PBXGroup section */ FE1E331914ED167800F6A6A2 = { isa = PBXGroup; children = ( FEE0F35C16C509EF001A077B /* AGImagePickerController.podspec */, FEA599C714ED1A8C0057FF9C /* AGImagePickerController */, FE1E332E14ED167800F6A6A2 /* AGImagePickerController Demo */, FE1E332714ED167800F6A6A2 /* Frameworks */, FE1E332514ED167800F6A6A2 /* Products */, ); sourceTree = ""; }; FE1E332514ED167800F6A6A2 /* Products */ = { isa = PBXGroup; children = ( FE1E332414ED167800F6A6A2 /* AGImagePickerController Demo.app */, ); name = Products; sourceTree = ""; }; FE1E332714ED167800F6A6A2 /* Frameworks */ = { isa = PBXGroup; children = ( 54A1E5541882A31E00D556FD /* CoreLocation.framework */, FEA599E114ED30140057FF9C /* AssetsLibrary.framework */, FE1E332814ED167800F6A6A2 /* UIKit.framework */, FE1E332A14ED167800F6A6A2 /* Foundation.framework */, FE1E332C14ED167800F6A6A2 /* CoreGraphics.framework */, ); name = Frameworks; sourceTree = ""; }; FE1E332E14ED167800F6A6A2 /* AGImagePickerController Demo */ = { isa = PBXGroup; children = ( FE1E333714ED167800F6A6A2 /* AGAppDelegate.h */, FE1E333814ED167800F6A6A2 /* AGAppDelegate.m */, FE1E333A14ED167800F6A6A2 /* AGViewController.h */, FE1E333B14ED167800F6A6A2 /* AGViewController.m */, FE1E333D14ED167800F6A6A2 /* AGViewController_iPhone.xib */, FE1E334014ED167800F6A6A2 /* AGViewController_iPad.xib */, FE1E332F14ED167800F6A6A2 /* Supporting Files */, ); path = "AGImagePickerController Demo"; sourceTree = ""; }; FE1E332F14ED167800F6A6A2 /* Supporting Files */ = { isa = PBXGroup; children = ( FE4DE10016C2546B0075E499 /* Default-568h@2x.png */, FEF247F4150DF463008FEFAD /* AGImagePickerController-icon@2x.png */, FEF247F1150DF461008FEFAD /* AGImagePickerController-icon.png */, FE3850CA1501B8A10053C9DD /* README.md */, FE1E333014ED167800F6A6A2 /* AGImagePickerController Demo-Info.plist */, FE1E333114ED167800F6A6A2 /* InfoPlist.strings */, FE1E333414ED167800F6A6A2 /* main.m */, FE1E333614ED167800F6A6A2 /* AGImagePickerController Demo-Prefix.pch */, ); name = "Supporting Files"; sourceTree = ""; }; FEA599C714ED1A8C0057FF9C /* AGImagePickerController */ = { isa = PBXGroup; children = ( FE4DE10216C267400075E499 /* AGImagePickerController+Helper.h */, FE4DE10316C267410075E499 /* AGImagePickerController+Helper.m */, FEDAA95616C3089600234FF0 /* AGImagePickerController.bundle */, FEA599C914ED1C500057FF9C /* AGImagePickerController.h */, FEA599CA14ED1C500057FF9C /* AGImagePickerController.m */, FE6E796014FCDC8A006612F0 /* AGImagePickerControllerDefines.h */, FEA599E614ED38ED0057FF9C /* AGIPCAlbumsController.h */, FEA599E714ED38ED0057FF9C /* AGIPCAlbumsController.m */, FE3BAF8614EE80E7001BF3EC /* AGIPCAssetsController.h */, FE3BAF8714EE80E7001BF3EC /* AGIPCAssetsController.m */, FECDC8FF14EDB9C30038006D /* AGIPCGridCell.h */, FECDC90014EDB9C30038006D /* AGIPCGridCell.m */, FECDC90314EDBB690038006D /* AGIPCGridItem.h */, FECDC90414EDBB690038006D /* AGIPCGridItem.m */, FE3851AD1504CF7B00A9F7F8 /* AGIPCToolbarItem.h */, FE3851AE1504CF7B00A9F7F8 /* AGIPCToolbarItem.m */, FE465F971590B25A00C30A1D /* ALAsset+AGIPC.h */, FE465F981590B25A00C30A1D /* ALAsset+AGIPC.m */, ); path = AGImagePickerController; sourceTree = ""; }; /* End PBXGroup section */ /* Begin PBXNativeTarget section */ FE1E332314ED167800F6A6A2 /* AGImagePickerController Demo */ = { isa = PBXNativeTarget; buildConfigurationList = FE1E334514ED167800F6A6A2 /* Build configuration list for PBXNativeTarget "AGImagePickerController Demo" */; buildPhases = ( FE1E332014ED167800F6A6A2 /* Sources */, FE1E332114ED167800F6A6A2 /* Frameworks */, FE1E332214ED167800F6A6A2 /* Resources */, ); buildRules = ( ); dependencies = ( ); name = "AGImagePickerController Demo"; productName = "AGImagePickerController Demo"; productReference = FE1E332414ED167800F6A6A2 /* AGImagePickerController Demo.app */; productType = "com.apple.product-type.application"; }; /* End PBXNativeTarget section */ /* Begin PBXProject section */ FE1E331B14ED167800F6A6A2 /* Project object */ = { isa = PBXProject; attributes = { LastUpgradeCheck = 0460; ORGANIZATIONNAME = "Artur Grigor"; }; buildConfigurationList = FE1E331E14ED167800F6A6A2 /* Build configuration list for PBXProject "AGImagePickerController Demo" */; compatibilityVersion = "Xcode 3.2"; developmentRegion = English; hasScannedForEncodings = 0; knownRegions = ( en, ); mainGroup = FE1E331914ED167800F6A6A2; productRefGroup = FE1E332514ED167800F6A6A2 /* Products */; projectDirPath = ""; projectRoot = ""; targets = ( FE1E332314ED167800F6A6A2 /* AGImagePickerController Demo */, ); }; /* End PBXProject section */ /* Begin PBXResourcesBuildPhase section */ FE1E332214ED167800F6A6A2 /* Resources */ = { isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( FE1E333314ED167800F6A6A2 /* InfoPlist.strings in Resources */, FE1E333F14ED167800F6A6A2 /* AGViewController_iPhone.xib in Resources */, FE1E334214ED167800F6A6A2 /* AGViewController_iPad.xib in Resources */, FE3850CB1501B8A10053C9DD /* README.md in Resources */, FEF247F2150DF461008FEFAD /* AGImagePickerController-icon.png in Resources */, FEF247F5150DF463008FEFAD /* AGImagePickerController-icon@2x.png in Resources */, FE4DE10116C2546B0075E499 /* Default-568h@2x.png in Resources */, FEDAA95716C3089600234FF0 /* AGImagePickerController.bundle in Resources */, FEE0F35D16C509EF001A077B /* AGImagePickerController.podspec in Resources */, ); runOnlyForDeploymentPostprocessing = 0; }; /* End PBXResourcesBuildPhase section */ /* Begin PBXSourcesBuildPhase section */ FE1E332014ED167800F6A6A2 /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( FE1E333514ED167800F6A6A2 /* main.m in Sources */, FE1E333914ED167800F6A6A2 /* AGAppDelegate.m in Sources */, FE1E333C14ED167800F6A6A2 /* AGViewController.m in Sources */, FEA599CC14ED1C500057FF9C /* AGImagePickerController.m in Sources */, FEA599E814ED38EE0057FF9C /* AGIPCAlbumsController.m in Sources */, FECDC90114EDB9C30038006D /* AGIPCGridCell.m in Sources */, FECDC90514EDBB690038006D /* AGIPCGridItem.m in Sources */, FE3BAF8814EE80E7001BF3EC /* AGIPCAssetsController.m in Sources */, FE3851AF1504CF7B00A9F7F8 /* AGIPCToolbarItem.m in Sources */, FE465F991590B25A00C30A1D /* ALAsset+AGIPC.m in Sources */, FE4DE10416C267410075E499 /* AGImagePickerController+Helper.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; /* End PBXSourcesBuildPhase section */ /* Begin PBXVariantGroup section */ FE1E333114ED167800F6A6A2 /* InfoPlist.strings */ = { isa = PBXVariantGroup; children = ( FE1E333214ED167800F6A6A2 /* en */, ); name = InfoPlist.strings; sourceTree = ""; }; FE1E333D14ED167800F6A6A2 /* AGViewController_iPhone.xib */ = { isa = PBXVariantGroup; children = ( FE1E333E14ED167800F6A6A2 /* en */, ); name = AGViewController_iPhone.xib; sourceTree = ""; }; FE1E334014ED167800F6A6A2 /* AGViewController_iPad.xib */ = { isa = PBXVariantGroup; children = ( FE1E334114ED167800F6A6A2 /* en */, ); name = AGViewController_iPad.xib; sourceTree = ""; }; /* End PBXVariantGroup section */ /* Begin XCBuildConfiguration section */ FE1E334314ED167800F6A6A2 /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; ARCHS = "$(ARCHS_STANDARD_32_BIT)"; CLANG_WARN_CONSTANT_CONVERSION = YES; CLANG_WARN_ENUM_CONVERSION = YES; CLANG_WARN_INT_CONVERSION = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; CODE_SIGN_IDENTITY = ""; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; COPY_PHASE_STRIP = NO; GCC_C_LANGUAGE_STANDARD = gnu99; GCC_DYNAMIC_NO_PIC = NO; GCC_OPTIMIZATION_LEVEL = 0; GCC_PREPROCESSOR_DEFINITIONS = ( "DEBUG=1", "$(inherited)", ); GCC_SYMBOLS_PRIVATE_EXTERN = NO; GCC_VERSION = com.apple.compilers.llvm.clang.1_0; GCC_WARN_ABOUT_MISSING_PROTOTYPES = YES; GCC_WARN_ABOUT_RETURN_TYPE = YES; GCC_WARN_UNINITIALIZED_AUTOS = YES; GCC_WARN_UNUSED_VARIABLE = YES; IPHONEOS_DEPLOYMENT_TARGET = 5.0; SDKROOT = iphoneos; TARGETED_DEVICE_FAMILY = "1,2"; }; name = Debug; }; FE1E334414ED167800F6A6A2 /* Release */ = { isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; ARCHS = "$(ARCHS_STANDARD_32_BIT)"; CLANG_WARN_CONSTANT_CONVERSION = YES; CLANG_WARN_ENUM_CONVERSION = YES; CLANG_WARN_INT_CONVERSION = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; CODE_SIGN_IDENTITY = ""; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; COPY_PHASE_STRIP = YES; GCC_C_LANGUAGE_STANDARD = gnu99; GCC_VERSION = com.apple.compilers.llvm.clang.1_0; GCC_WARN_ABOUT_MISSING_PROTOTYPES = YES; GCC_WARN_ABOUT_RETURN_TYPE = YES; GCC_WARN_UNINITIALIZED_AUTOS = YES; GCC_WARN_UNUSED_VARIABLE = YES; IPHONEOS_DEPLOYMENT_TARGET = 5.0; OTHER_CFLAGS = "-DNS_BLOCK_ASSERTIONS=1"; SDKROOT = iphoneos; TARGETED_DEVICE_FAMILY = "1,2"; VALIDATE_PRODUCT = YES; }; name = Release; }; FE1E334614ED167800F6A6A2 /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { CLANG_ENABLE_OBJC_ARC = YES; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; GCC_PRECOMPILE_PREFIX_HEADER = YES; GCC_PREFIX_HEADER = "AGImagePickerController Demo/AGImagePickerController Demo-Prefix.pch"; INFOPLIST_FILE = "AGImagePickerController Demo/AGImagePickerController Demo-Info.plist"; IPHONEOS_DEPLOYMENT_TARGET = 4.3; PRODUCT_NAME = "$(TARGET_NAME)"; "PROVISIONING_PROFILE[sdk=iphoneos*]" = ""; WRAPPER_EXTENSION = app; }; name = Debug; }; FE1E334714ED167800F6A6A2 /* Release */ = { isa = XCBuildConfiguration; buildSettings = { CLANG_ENABLE_OBJC_ARC = YES; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; GCC_PRECOMPILE_PREFIX_HEADER = YES; GCC_PREFIX_HEADER = "AGImagePickerController Demo/AGImagePickerController Demo-Prefix.pch"; INFOPLIST_FILE = "AGImagePickerController Demo/AGImagePickerController Demo-Info.plist"; IPHONEOS_DEPLOYMENT_TARGET = 4.3; PRODUCT_NAME = "$(TARGET_NAME)"; WRAPPER_EXTENSION = app; }; name = Release; }; /* End XCBuildConfiguration section */ /* Begin XCConfigurationList section */ FE1E331E14ED167800F6A6A2 /* Build configuration list for PBXProject "AGImagePickerController Demo" */ = { isa = XCConfigurationList; buildConfigurations = ( FE1E334314ED167800F6A6A2 /* Debug */, FE1E334414ED167800F6A6A2 /* Release */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; FE1E334514ED167800F6A6A2 /* Build configuration list for PBXNativeTarget "AGImagePickerController Demo" */ = { isa = XCConfigurationList; buildConfigurations = ( FE1E334614ED167800F6A6A2 /* Debug */, FE1E334714ED167800F6A6A2 /* Release */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; /* End XCConfigurationList section */ }; rootObject = FE1E331B14ED167800F6A6A2 /* Project object */; } ================================================ FILE: AGImagePickerController Demo.xcodeproj/project.xcworkspace/contents.xcworkspacedata ================================================ ================================================ FILE: AGImagePickerController Demo.xcodeproj/project.xcworkspace/xcuserdata/arturgrigor.xcuserdatad/WorkspaceSettings.xcsettings ================================================ HasAskedToTakeAutomaticSnapshotBeforeSignificantChanges SnapshotAutomaticallyBeforeSignificantChanges ================================================ FILE: AGImagePickerController Demo.xcodeproj/xcuserdata/arturgrigor.xcuserdatad/xcdebugger/Breakpoints.xcbkptlist ================================================ ================================================ FILE: AGImagePickerController Demo.xcodeproj/xcuserdata/arturgrigor.xcuserdatad/xcschemes/AGImagePickerController Demo.xcscheme ================================================ ================================================ FILE: AGImagePickerController Demo.xcodeproj/xcuserdata/arturgrigor.xcuserdatad/xcschemes/xcschememanagement.plist ================================================ SchemeUserState AGImagePickerController Demo.xcscheme orderHint 0 SuppressBuildableAutocreation FE1E332314ED167800F6A6A2 primary ================================================ FILE: AGImagePickerController.podspec ================================================ Pod::Spec.new do |s| s.name = "AGImagePickerController" s.version = "2.0.1" s.summary = "AGImagePickerController is a image picker controller that allows you to select multiple photos and can be used for all iOS devices." s.homepage = "https://github.com/arturgrigor/AGImagePickerController" s.license = 'MIT' s.author = { "Artur Grigor" => "arturgrigor@gmail.com" } s.source = { :git => "https://github.com/arturgrigor/AGImagePickerController.git", :tag => s.version.to_s } s.platform = :ios s.source_files = 'AGImagePickerController/*.{h,m}' s.resources = 'AGImagePickerController/AGImagePickerController.bundle' s.framework = 'AssetsLibrary' s.requires_arc = true end ================================================ FILE: LICENSE ================================================ Copyright (c) 2012 - 2013 Artur Grigor Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ================================================ FILE: README.md ================================================ [![No Maintenance Intended](http://unmaintained.tech/badge.svg)](http://unmaintained.tech/) [![CocoaPods Compatible](https://img.shields.io/cocoapods/v/AGImagePickerController.svg)](https://img.shields.io/cocoapods/v/AGImagePickerController.svg) [![Platform](https://img.shields.io/cocoapods/p/AGImagePickerController.svg?style=flat)](http://cocoadocs.org/docsets/AGImagePickerController) [![Twitter](https://img.shields.io/badge/twitter-@arturgrigor-blue.svg?style=flat)](http://twitter.com/arturgrigor) ## AGImagePickerController AGImagePickerController is a image picker controller that allows you to select multiple photos and can be used for all iOS devices. ![Screenshot](http://dl.dropbox.com/u/2387405/Screenshots/AGImagePickerController.png) ## Installation Copy over the files from the AGImagePickerController folder to your project folder. ## Usage Wherever you want to use AGImagePickerController, import the appropriate header file and initialize as follows: ``` objective-c #import "AGImagePickerController.h" ``` ### Basic ``` objective-c AGImagePickerController *imagePickerController = [[AGImagePickerController alloc] initWithFailureBlock:^(NSError *error) { if (error == nil) { NSLog(@"User has cancelled."); [self dismissModalViewControllerAnimated:YES]; } else { NSLog(@"Error: %@", error); // Wait for the view controller to show first and hide it after that double delayInSeconds = 0.5; dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, delayInSeconds * NSEC_PER_SEC); dispatch_after(popTime, dispatch_get_main_queue(), ^(void){ [self dismissModalViewControllerAnimated:YES]; }); } [[UIApplication sharedApplication] setStatusBarStyle:UIStatusBarStyleDefault animated:YES]; } andSuccessBlock:^(NSArray *info) { NSLog(@"Info: %@", info); [self dismissModalViewControllerAnimated:YES]; [[UIApplication sharedApplication] setStatusBarStyle:UIStatusBarStyleDefault animated:YES]; }]; [self presentModalViewController:imagePickerController animated:YES]; [imagePickerController release]; ``` ## Contact - [GitHub](http://github.com/arturgrigor) - [Twitter](http://twitter.com/arturgrigor) Let me know if you're using or enjoying this product.