Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP

Loading…

AssetTablePicker behaves like iOS Photos: loads scrolled to the bottom and loads quickly #24

Closed
wants to merge 9 commits into from

4 participants

@ehopealot
  • Loads the picker so that the tableview is initially scrolled to the bottom
  • Loads the last ~25 images in the library first, so the picker screen comes up snappily even for very large libraries. This makes the image picker behave just like iOS Photos, as far as I can tell.
ehopealot added some commits
@ehopealot ehopealot Launches image picker controller with image picker scrolled to bottom 0ce25d2
@ehopealot ehopealot Stops showing the partially loaded photos, since that causes a jarrin…
…g jump to the bottom when the full photo list loads
5fc678d
@ehopealot ehopealot Makes the picker snappy like regular iOS Photos by preloading the las…
…t ~25 images before loading the rest
eb76b91
@ehopealot ehopealot Adds a comment explaining what is going on efd86fc
@ehopealot ehopealot AssetTablePicker behaves like iOS Photos: loads scrolled to the botto…
…m and loads quickly

* Loads the picker so that the tableview is initially scrolled to the bottom
* Loads the last ~25 images in the library first, so the picker screen comes up
  snappily even for very large libraries. This makes the image picker behave
  just like iOS Photos, as far as I can tell.
9b50ab7
@ehopealot ehopealot closed this
@ehopealot ehopealot reopened this
ehopealot added some commits
@ehopealot ehopealot AssetTablePicker behaves like iOS Photos: loads scrolled to the botto…
…m and loads quickly

* Loads the picker so that the tableview is initially scrolled to the bottom
* Loads the last ~25 images in the library first, so the picker screen comes up
  snappily even for very large libraries. This makes the image picker behave
  just like iOS Photos, as far as I can tell.
a1eddff
@ehopealot ehopealot Resolves crash when you press done before all the photos have loaded 7ae475f
@ehopealot ehopealot load the first 100 rather than first 25 photos da0d7f5
@ehopealot ehopealot Includes the changes to make the picker load the first 100 images,
and also resolves problem of crashing if you pick images before the whole
gallery has loaded
3295e2b
@ehopealot ehopealot closed this
@ehopealot ehopealot reopened this
@jimzhao2012

-(void)preparePhotos
is called in background thread, can not update UI, plz use dispatch_async.. force change to main thread to to such a job.

@omricohen

looks good @jimzhao2012 he is calling performSelectorOnMainThread in that function, allowing for UI manipulation...

@jvanmetre

We have decided to go in a different direction by not creating as many UIImageViews for the tableView, but any version after 0.0.3 should be much snappier.

@jvanmetre jvanmetre closed this
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Commits on Jul 6, 2012
  1. @ehopealot
  2. @ehopealot

    Stops showing the partially loaded photos, since that causes a jarrin…

    ehopealot authored
    …g jump to the bottom when the full photo list loads
  3. @ehopealot

    Makes the picker snappy like regular iOS Photos by preloading the las…

    ehopealot authored
    …t ~25 images before loading the rest
  4. @ehopealot
  5. @ehopealot

    AssetTablePicker behaves like iOS Photos: loads scrolled to the botto…

    ehopealot authored
    …m and loads quickly
    
    * Loads the picker so that the tableview is initially scrolled to the bottom
    * Loads the last ~25 images in the library first, so the picker screen comes up
      snappily even for very large libraries. This makes the image picker behave
      just like iOS Photos, as far as I can tell.
Commits on Jul 18, 2012
  1. @ehopealot

    AssetTablePicker behaves like iOS Photos: loads scrolled to the botto…

    ehopealot authored
    …m and loads quickly
    
    * Loads the picker so that the tableview is initially scrolled to the bottom
    * Loads the last ~25 images in the library first, so the picker screen comes up
      snappily even for very large libraries. This makes the image picker behave
      just like iOS Photos, as far as I can tell.
  2. @ehopealot
  3. @ehopealot
  4. @ehopealot

    Includes the changes to make the picker load the first 100 images,

    ehopealot authored
    and also resolves problem of crashing if you pick images before the whole
    gallery has loaded
This page is out of date. Refresh to see the latest.
Showing with 54 additions and 26 deletions.
  1. +1 −0  Classes/ELCAssetTablePicker.h
  2. +53 −26 Classes/ELCAssetTablePicker.m
View
1  Classes/ELCAssetTablePicker.h
@@ -24,6 +24,7 @@
@property (nonatomic, assign) ALAssetsGroup *assetGroup;
@property (nonatomic, retain) NSMutableArray *elcAssets;
@property (nonatomic, retain) IBOutlet UILabel *selectedAssetsLabel;
+@property (nonatomic) BOOL reloadData;
-(int)totalSelectedAssets;
-(void)preparePhotos;
View
79 Classes/ELCAssetTablePicker.m
@@ -12,13 +12,15 @@
@implementation ELCAssetTablePicker
-
+{
+ NSInteger start;
+}
@synthesize parent;
@synthesize selectedAssetsLabel;
-@synthesize assetGroup, elcAssets;
+@synthesize assetGroup, elcAssets, reloadData;
-(void)viewDidLoad {
-
+ self.reloadData = YES;
[self.tableView setSeparatorColor:[UIColor clearColor]];
[self.tableView setAllowsSelection:NO];
@@ -30,10 +32,35 @@ -(void)viewDidLoad {
[self.navigationItem setRightBarButtonItem:doneButtonItem];
[self.navigationItem setTitle:@"Loading..."];
+ NSInteger count = self.assetGroup.numberOfAssets;
+ NSInteger startNumberOfAssets = 96 + count%4;
+ start = MAX(0, count-startNumberOfAssets);
+
+ // Set up the first ~100 photos
+ NSIndexSet *indexSet = [NSIndexSet indexSetWithIndexesInRange:NSMakeRange(start, count > startNumberOfAssets ? startNumberOfAssets : count)];
+ for (int i = 0; i < start; i++){
+ [self.elcAssets addObject:[NSNull null]];
+ }
+ [self.assetGroup enumerateAssetsAtIndexes:indexSet options:0 usingBlock:^(ALAsset *result, NSUInteger index, BOOL *stop) {
+ if(result == nil)
+ {
+ return;
+ }
+ ELCAsset *elcAsset = [[[ELCAsset alloc] initWithAsset:result] autorelease];
+ [elcAsset setParent:self];
+ [self.elcAssets addObject:elcAsset];
+ }];
+ [self.tableView reloadData];
+
+ [self.tableView scrollToRowAtIndexPath:[NSIndexPath indexPathForRow:ceil(assetGroup.numberOfAssets / 4.0)-1 inSection:0] atScrollPosition:UITableViewScrollPositionBottom animated:NO];
+
+ // For some reason it only scrolls about 80% through the final image... This scrolls
+ // the table view all the way to the bottom. 50 is just a number thats bigger than the
+ // sliver of the image thats covered up.
+ [self.tableView setContentOffset:CGPointMake(0, self.tableView.contentOffset.y+50)];
+
[self performSelectorInBackground:@selector(preparePhotos) withObject:nil];
- // Show partial while full list loads
- [self.tableView performSelector:@selector(reloadData) withObject:nil afterDelay:.5];
}
-(void)preparePhotos {
@@ -42,21 +69,19 @@ -(void)preparePhotos {
NSLog(@"enumerating photos");
- [self.assetGroup enumerateAssetsUsingBlock:^(ALAsset *result, NSUInteger index, BOOL *stop)
- {
- if(result == nil)
- {
- return;
- }
-
- ELCAsset *elcAsset = [[[ELCAsset alloc] initWithAsset:result] autorelease];
- [elcAsset setParent:self];
- [self.elcAssets addObject:elcAsset];
- }];
+
+ NSIndexSet *newIndexSet = [NSIndexSet indexSetWithIndexesInRange:NSMakeRange(0, start)];
+ [self.assetGroup enumerateAssetsAtIndexes:newIndexSet options:0 usingBlock:^(ALAsset *result, NSUInteger index, BOOL *stop) {
+ if(result == nil)
+ {
+ return;
+ }
+ ELCAsset *elcAsset = [[[ELCAsset alloc] initWithAsset:result] autorelease];
+ [elcAsset setParent:self];
+ [self.elcAssets replaceObjectAtIndex:index withObject:elcAsset];
+ }];
NSLog(@"done enumerating photos");
-
- [self.tableView reloadData];
- [self.navigationItem setTitle:@"Pick Photos"];
+ [self.navigationItem performSelectorOnMainThread:@selector(setTitle:) withObject:@"Pick Photos" waitUntilDone:NO];
[pool release];
@@ -65,15 +90,14 @@ -(void)preparePhotos {
- (void) doneAction:(id)sender {
NSMutableArray *selectedAssetsImages = [[[NSMutableArray alloc] init] autorelease];
-
- for(ELCAsset *elcAsset in self.elcAssets)
+ NSArray *currentlyLoadedAssets = [self.elcAssets copy];
+ for(ELCAsset *elcAsset in currentlyLoadedAssets)
{
- if([elcAsset selected]) {
+ if(elcAsset != (id)[NSNull null] && [elcAsset selected]) {
[selectedAssetsImages addObject:[elcAsset asset]];
}
}
-
[(ELCAlbumPickerController*)self.parent selectedAssets:selectedAssetsImages];
}
@@ -86,7 +110,7 @@ - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
- return ceil([self.assetGroup numberOfAssets] / 4.0);
+ return ceil(assetGroup.numberOfAssets / 4.0);
}
- (NSArray*)assetsForIndexPath:(NSIndexPath*)_indexPath {
@@ -135,14 +159,17 @@ - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(N
ELCAssetCell *cell = (ELCAssetCell*)[tableView dequeueReusableCellWithIdentifier:CellIdentifier];
+ NSMutableArray *assets = [[self assetsForIndexPath:indexPath] mutableCopy];
+ [assets removeObjectIdenticalTo:[NSNull null]];
if (cell == nil)
{
- cell = [[[ELCAssetCell alloc] initWithAssets:[self assetsForIndexPath:indexPath] reuseIdentifier:CellIdentifier] autorelease];
+ cell = [[[ELCAssetCell alloc] initWithAssets:assets reuseIdentifier:CellIdentifier] autorelease];
}
else
{
- [cell setAssets:[self assetsForIndexPath:indexPath]];
+ [cell setAssets:assets];
}
+
return cell;
}
Something went wrong with that request. Please try again.