/* Copyright (c) 2013 Katsuma Tanaka 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. */ #import "QBAssetCollectionViewController.h" // Views #import "QBImagePickerAssetCell.h" #import "QBImagePickerFooterView.h" @interface QBAssetCollectionViewController () @property (nonatomic, strong) NSMutableArray *assets; @property (nonatomic, strong) NSMutableOrderedSet *selectedAssets; @property (nonatomic, strong) UITableView *tableView; @property (nonatomic, strong) UIBarButtonItem *doneButton; @property (nonatomic, assign) UIView *navigationBarView; - (void)reloadData; - (void)updateRightBarButtonItem; - (void)updateDoneButton; - (void)done; - (void)cancel; @end @implementation QBAssetCollectionViewController - (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil { self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil]; if(self) { /* Initialization */ self.assets = [NSMutableArray array]; self.selectedAssets = [NSMutableOrderedSet orderedSet]; self.imageSize = CGSizeMake(75, 75); // Table View UITableView *tableView = [[UITableView alloc] initWithFrame:CGRectMake(0, JX_SCREEN_TOP, JX_SCREEN_WIDTH, JX_SCREEN_HEIGHT - JX_SCREEN_TOP) style:UITableViewStylePlain]; tableView.dataSource = self; tableView.delegate = self; tableView.separatorStyle = UITableViewCellSeparatorStyleNone; tableView.allowsSelection = YES; tableView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight; [self.view addSubview:tableView]; self.tableView = tableView; // [tableView release]; } return self; } - (void)viewWillAppear:(BOOL)animated { [super viewWillAppear:animated]; // Reload [self reloadData]; self.navigationController.navigationBar.hidden = YES; [self createNavgationBar]; [self updateRightBarButtonItem]; if(self.fullScreenLayoutEnabled) { // Set bar styles self.navigationController.navigationBar.barStyle = UIBarStyleBlack; self.navigationController.navigationBar.translucent = YES; [[UIApplication sharedApplication] setStatusBarStyle:UIStatusBarStyleLightContent animated:NO]; // CGFloat top = 0; // if(![[UIApplication sharedApplication] isStatusBarHidden]) top = top + 20; // if(!self.navigationController.navigationBarHidden) top = top + 44; // self.tableView.contentInset = UIEdgeInsetsMake(top, 0, 0, 0); // self.tableView.scrollIndicatorInsets = UIEdgeInsetsMake(top, 0, 0, 0); // // [self setWantsFullScreenLayout:YES]; } // Scroll to bottom // [self.tableView setContentOffset:CGPointMake(0, self.tableView.contentSize.height) animated:NO]; } - (void) createNavgationBar { UIView *view = [[UIView alloc] initWithFrame:CGRectMake(0, 0, JX_SCREEN_WIDTH, JX_SCREEN_TOP)]; if (THESIMPLESTYLE) { view.backgroundColor = [UIColor whiteColor]; }else { view.backgroundColor = THEMECOLOR; } [self.view addSubview:view]; UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(0, JX_SCREEN_TOP - 30, 200, 20)]; label.font = [UIFont systemFontOfSize:17]; label.textColor = [UIColor whiteColor]; label.textAlignment = NSTextAlignmentCenter; label.text = self.title; label.center = CGPointMake(view.frame.size.width / 2, label.center.y); [view addSubview:label]; UIButton *btn = [[UIButton alloc] initWithFrame:CGRectMake(8, JX_SCREEN_TOP - 38, 31, 31)]; [btn setBackgroundImage:[UIImage imageNamed:@"title_back"] forState:UIControlStateNormal]; [btn addTarget:self action:@selector(actionQuit) forControlEvents:UIControlEventTouchUpInside]; [view addSubview:btn]; self.navigationBarView = view; } - (void)actionQuit { [self.navigationController popViewControllerAnimated:YES]; } - (void)viewDidAppear:(BOOL)animated { [super viewDidAppear:animated]; // Flash scroll indicators [self.tableView flashScrollIndicators]; } - (void)setShowsCancelButton:(BOOL)showsCancelButton { _showsCancelButton = showsCancelButton; [self updateRightBarButtonItem]; } - (void)setAllowsMultipleSelection:(BOOL)allowsMultipleSelection { _allowsMultipleSelection = allowsMultipleSelection; [self updateRightBarButtonItem]; } - (void)dealloc { // [_assetsGroup release]; // // [_assets release]; // [_selectedAssets release]; // // [_tableView release]; // [_doneButton release]; // // [super dealloc]; } #pragma mark - Instance Methods - (void)reloadData { // Reload assets [self.assetsGroup enumerateAssetsUsingBlock:^(ALAsset *result, NSUInteger index, BOOL *stop) { if(result) { [self.assets addObject:result]; } }]; [self.tableView reloadData]; // Set footer view self.showsFooterDescription = NO; if(self.showsFooterDescription) { [self.assetsGroup setAssetsFilter:[ALAssetsFilter allPhotos]]; NSUInteger numberOfPhotos = self.assetsGroup.numberOfAssets; [self.assetsGroup setAssetsFilter:[ALAssetsFilter allVideos]]; NSUInteger numberOfVideos = self.assetsGroup.numberOfAssets; switch(self.filterType) { case QBImagePickerFilterTypeAllAssets: [self.assetsGroup setAssetsFilter:[ALAssetsFilter allAssets]]; break; case QBImagePickerFilterTypeAllPhotos: [self.assetsGroup setAssetsFilter:[ALAssetsFilter allPhotos]]; break; case QBImagePickerFilterTypeAllVideos: [self.assetsGroup setAssetsFilter:[ALAssetsFilter allVideos]]; break; } QBImagePickerFooterView *footerView = [[QBImagePickerFooterView alloc] initWithFrame:CGRectMake(0, 0, self.view.bounds.size.width, 48)]; if(self.filterType == QBImagePickerFilterTypeAllAssets) { footerView.titleLabel.text = [self.delegate assetCollectionViewController:self descriptionForNumberOfPhotos:numberOfPhotos numberOfVideos:numberOfVideos]; } else if(self.filterType == QBImagePickerFilterTypeAllPhotos) { footerView.titleLabel.text = [self.delegate assetCollectionViewController:self descriptionForNumberOfPhotos:numberOfPhotos]; } else if(self.filterType == QBImagePickerFilterTypeAllVideos) { footerView.titleLabel.text = [self.delegate assetCollectionViewController:self descriptionForNumberOfVideos:numberOfVideos]; } self.tableView.tableFooterView = footerView; // [footerView release]; } else { QBImagePickerFooterView *footerView = [[QBImagePickerFooterView alloc] initWithFrame:CGRectMake(0, 0, self.view.bounds.size.width, 4)]; self.tableView.tableFooterView = footerView; // [footerView release]; } [self gotoLastRow:NO]; } - (void)updateRightBarButtonItem { if(self.allowsMultipleSelection) { // Set done button // UIBarButtonItem *doneButton = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemDone target:self action:@selector(done)]; // doneButton.enabled = NO; UIButton *doneButton = [[UIButton alloc] initWithFrame:CGRectMake(JX_SCREEN_WIDTH -90, JX_SCREEN_TOP - 34, 80, 25)]; doneButton.enabled = NO; [doneButton setTitle:Localized(@"JX_Finish") forState:UIControlStateNormal]; doneButton.titleLabel.font = [UIFont systemFontOfSize:17]; [doneButton setTitleColor:[UIColor blueColor] forState:UIControlStateNormal]; [doneButton setTitleColor:[UIColor lightGrayColor] forState:UIControlStateDisabled]; [doneButton addTarget:self action:@selector(done) forControlEvents:UIControlEventTouchUpInside]; [self.navigationBarView addSubview:doneButton]; // [self.navigationItem setRightBarButtonItem:doneButton animated:NO]; self.doneButton = [[UIBarButtonItem alloc] initWithCustomView:doneButton]; // [doneButton release]; } else if(self.showsCancelButton) { // Set cancel button UIBarButtonItem *cancelButton = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemCancel target:self action:@selector(cancel)]; [self.navigationItem setRightBarButtonItem:cancelButton animated:NO]; // [cancelButton release]; } else { [self.navigationItem setRightBarButtonItem:nil animated:NO]; } } - (void)updateDoneButton { if(self.limitsMinimumNumberOfSelection) { self.doneButton.enabled = (self.selectedAssets.count >= self.minimumNumberOfSelection); } else { self.doneButton.enabled = (self.selectedAssets.count > 0); } } - (void)done { [self.delegate assetCollectionViewController:self didFinishPickingAssets:self.selectedAssets.array]; } - (void)cancel { [self.delegate assetCollectionViewControllerDidCancel:self]; } #pragma mark - UITableViewDataSource - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView { return 1; } - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { NSInteger numberOfRowsInSection = 0; switch(section) { /* case 0: case 1: { if(self.allowsMultipleSelection && !self.limitsMaximumNumberOfSelection && self.showsHeaderButton) { numberOfRowsInSection = 1; } } break;*/ case 0: { NSInteger numberOfAssetsInRow = self.view.bounds.size.width / self.imageSize.width; numberOfRowsInSection = self.assets.count / numberOfAssetsInRow; if((self.assets.count - numberOfRowsInSection * numberOfAssetsInRow) > 0) numberOfRowsInSection++; } break; } return numberOfRowsInSection; } - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { UITableViewCell *cell = nil; switch(indexPath.section) { /* case 0: { NSString *cellIdentifier = @"HeaderCell"; cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier]; if(cell == nil) { cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellIdentifier] autorelease]; cell.selectionStyle = UITableViewCellSelectionStyleBlue; } if(self.selectedAssets.count == self.assets.count) { cell.textLabel.text = [self.delegate descriptionForDeselectingAllAssets:self]; // Set accessory view UIImageView *accessoryView = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, 23, 23)]; accessoryView.image = [UIImage imageNamed:@"QBImagePickerController.bundle/minus.png"]; accessoryView.layer.shadowColor = [[UIColor colorWithWhite:0 alpha:1.0] CGColor]; accessoryView.layer.shadowOpacity = 0.70; accessoryView.layer.shadowOffset = CGSizeMake(0, 1.4); accessoryView.layer.shadowRadius = 2; cell.accessoryView = accessoryView; [accessoryView release]; } else { cell.textLabel.text = [self.delegate descriptionForSelectingAllAssets:self]; // Set accessory view UIImageView *accessoryView = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, 23, 23)]; accessoryView.image = [UIImage imageNamed:@"QBImagePickerController.bundle/plus.png"]; accessoryView.layer.shadowColor = [[UIColor colorWithWhite:0 alpha:1.0] CGColor]; accessoryView.layer.shadowOpacity = 0.70; accessoryView.layer.shadowOffset = CGSizeMake(0, 1.4); accessoryView.layer.shadowRadius = 2; cell.accessoryView = accessoryView; [accessoryView release]; } } break; case 1: { NSString *cellIdentifier = @"SeparatorCell"; cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier]; if(cell == nil) { cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellIdentifier] autorelease]; cell.selectionStyle = UITableViewCellSelectionStyleNone; // Set background view UIView *backgroundView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, self.view.bounds.size.width, 1)]; backgroundView.backgroundColor = [UIColor colorWithWhite:0.878 alpha:1.0]; cell.backgroundView = backgroundView; [backgroundView release]; } } break;*/ case 0: { NSString *cellIdentifier = @"AssetCell"; cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier]; if(cell == nil) { NSInteger numberOfAssetsInRow = self.view.bounds.size.width / self.imageSize.width; CGFloat margin = round((self.view.bounds.size.width - self.imageSize.width * numberOfAssetsInRow) / (numberOfAssetsInRow + 1)); cell = [[QBImagePickerAssetCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellIdentifier imageSize:self.imageSize numberOfAssets:numberOfAssetsInRow margin:margin]; cell.selectionStyle = UITableViewCellSelectionStyleNone; [(QBImagePickerAssetCell *)cell setDelegate:self]; [(QBImagePickerAssetCell *)cell setAllowsMultipleSelection:self.allowsMultipleSelection]; } // Set assets NSInteger numberOfAssetsInRow = self.view.bounds.size.width / self.imageSize.width; NSInteger offset = numberOfAssetsInRow * indexPath.row; NSInteger numberOfAssetsToSet = (offset + numberOfAssetsInRow > self.assets.count) ? (self.assets.count - offset) : numberOfAssetsInRow; NSMutableArray *assets = [NSMutableArray array]; for(NSUInteger i = 0; i < numberOfAssetsToSet; i++) { ALAsset *asset = [self.assets objectAtIndex:(offset + i)]; [assets addObject:asset]; } [(QBImagePickerAssetCell *)cell setAssets:assets]; // Set selection states for(NSUInteger i = 0; i < numberOfAssetsToSet; i++) { ALAsset *asset = [self.assets objectAtIndex:(offset + i)]; if([self.selectedAssets containsObject:asset]) { [(QBImagePickerAssetCell *)cell selectAssetAtIndex:i]; } else { [(QBImagePickerAssetCell *)cell deselectAssetAtIndex:i]; } } } break; } return cell; } #pragma mark - UITableViewDelegate - (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath { CGFloat heightForRow = 0; switch(indexPath.section) { /* case 0: { heightForRow = 44; } break; case 1: { heightForRow = 1; } break;*/ case 0: { NSInteger numberOfAssetsInRow = self.view.bounds.size.width / self.imageSize.width; CGFloat margin = round((self.view.bounds.size.width - self.imageSize.width * numberOfAssetsInRow) / (numberOfAssetsInRow + 1)); heightForRow = margin + self.imageSize.height; } break; } return heightForRow; } - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { if(indexPath.section == 0 && indexPath.row == 0) { if(self.selectedAssets.count == self.assets.count) { // Deselect all assets [self.selectedAssets removeAllObjects]; } else { // Select all assets [self.selectedAssets addObjectsFromArray:self.assets]; } // Set done button state [self updateDoneButton]; // // Update assets // [tableView reloadSections:[NSIndexSet indexSetWithIndex:2] withRowAnimation:UITableViewRowAnimationNone]; // // Update header text // [tableView reloadSections:[NSIndexSet indexSetWithIndex:0] withRowAnimation:UITableViewRowAnimationFade]; // Cancel table view selection [tableView deselectRowAtIndexPath:indexPath animated:YES]; } } #pragma mark - QBImagePickerAssetCellDelegate - (BOOL)assetCell:(QBImagePickerAssetCell *)assetCell canSelectAssetAtIndex:(NSUInteger)index { BOOL canSelect = YES; if(self.allowsMultipleSelection && self.limitsMaximumNumberOfSelection) { canSelect = (self.selectedAssets.count < self.maximumNumberOfSelection); } return canSelect; } - (void)assetCell:(QBImagePickerAssetCell *)assetCell didChangeAssetSelectionState:(BOOL)selected atIndex:(NSUInteger)index { NSIndexPath *indexPath = [self.tableView indexPathForCell:assetCell]; NSInteger numberOfAssetsInRow = self.view.bounds.size.width / self.imageSize.width; NSInteger assetIndex = indexPath.row * numberOfAssetsInRow + index; ALAsset *asset = [self.assets objectAtIndex:assetIndex]; if(self.allowsMultipleSelection) { if(selected) { [self.selectedAssets addObject:asset]; } else { [self.selectedAssets removeObject:asset]; } // Set done button state [self updateDoneButton]; // Update header text if((selected && self.selectedAssets.count == self.assets.count) || (!selected && self.selectedAssets.count == self.assets.count - 1)) { [self.tableView reloadRowsAtIndexPaths:[NSArray arrayWithObject:[NSIndexPath indexPathForRow:0 inSection:0]] withRowAnimation:UITableViewRowAnimationFade]; } } else { [self.delegate assetCollectionViewController:self didFinishPickingAsset:asset]; } } - (void) gotoLastRow:(BOOL)animated{ NSInteger n = [self.tableView numberOfRowsInSection:0]-1; if(n>=1) [self.tableView scrollToRowAtIndexPath:[NSIndexPath indexPathForRow:n inSection:0] atScrollPosition:UITableViewScrollPositionBottom animated:animated]; } @end