1 din 2
1
Performante afisare thumburi din libraria locala.
  [ Ignoră ]
Avatar
RankRankRankRank
Moderator
Din: Cluj-Napoca
Macuser din: 26.01.06

Ce strategie ati adopta ca sa afisati exact ce afiseaza si Photos app, o lista de thumburi cate 4 pe linie?
Eu am ales sa fac un UITableView si pe fiecare linie am 4 coloane, in fiecare coloana incarc thumbul unei poze intr-un nou thread dar asta nu pare sa aibe niciun efect, fie ca incarc intr-un nou thread fie ca nu, tabelul cam sacadeaza la scroll. Am o chestie echivalenta pentru incarcat poze de pe net si functioneaza f smooth, diferenta e ca construiesc UIImage din NSData.
Photos app se misca asa de bine incat am impresia ca thumburile sunt deja preincarcate intr-un scrollview.

- (voidloadImageFromLibrary:(NSURL *)url {
    
    
// Load image in a new thread
    
[NSThread detachNewThreadSelector:@selector(loadImageCG:)
                             
toTarget:self
                           withObject
:url];
}
- (voidloadImageCG:(NSURL*)url {
    ALAssetsLibraryAssetForURLResultBlock resultblock 
= ^(ALAsset *myasset){
        
        [self performSelectorOnMainThread
:@selector(displayImageWithCGImage:)
                               
withObject:[myasset thumbnail]
                            waitUntilDone
:NO];
    
};
    
ALAssetsLibraryAccessFailureBlock failureblock  = ^(NSError *myerror){
        NSLog
(@"booya, cant get image - %@"[myerror localizedDescription]);
    
};
    
    
ALAssetsLibrary *assetslibrary [[ALAssetsLibrary alloc] init];
    
[assetslibrary assetForURL:url resultBlock:resultblock failureBlock:failureblock];
}
- (voiddisplayImageWithCGImage:(CGImageRef)imageRef {
    imageView
.image [UIImage imageWithCGImage:imageRef];
 Semnătură 

Mcintoshing…

Profil
 
  [ Ignoră ]   [ # 1 ]
RankRank
Jr. Member
Din: Bucuresti
Macuser din: 26.03.10

http://developer.apple.com/library/ios/#documentation/UIKit/Reference/UICollectionView_class/Reference/Reference.html

e mai greu de invatat putin ca si UITableView da’ dupa ce reusesti sa-l configurezi se misca perfect! smile spor!

 Semnătură 

 iPhone 5 16GB black, iOS 7 beta 5
 MacBook Pro 15” Unibody, Late 2011 2,4 Ghz Intel Core i7, 8GB RAM, 128GB SSD, Radeon 6770 1GB, HiRes Display, OS X 10.8.3
 Thunderbolt Display

Profil
 
  [ Ignoră ]   [ # 2 ]
Avatar
RankRankRankRank
Moderator
Din: Cluj-Napoca
Macuser din: 26.01.06

Interesanta clasa, dar e pt ios6 iar Photos se misca bine dintotdeauna. L-ai incercat pt ce-mi trebuie mie? Eu cred ca fiind poze locale totul este practic instant si se creeaza pozele toate succesiv fara pauza si asta blocheaza tabelul.

 Semnătură 

Mcintoshing…

Profil
 
  [ Ignoră ]   [ # 3 ]
RankRank
Jr. Member
Din: Bucuresti
Macuser din: 26.03.10

pai poti folosi UICollectionView si cell-urile le tratezi ca pe UITableView, le incarci asincron! doar ca-ti usureaza mult mai tare munca cu layout-ul, mai ales pe landscape!

sunt multe librarii de la Apple care au fost private si au ajuns publice pana la urma, deci sa nu te mire ca Photos se misca bine dintotdeauna! raspberry

 Semnătură 

 iPhone 5 16GB black, iOS 7 beta 5
 MacBook Pro 15” Unibody, Late 2011 2,4 Ghz Intel Core i7, 8GB RAM, 128GB SSD, Radeon 6770 1GB, HiRes Display, OS X 10.8.3
 Thunderbolt Display

Profil
 
  [ Ignoră ]   [ # 4 ]
Avatar
RankRank
Jr. Member
Din: Cluj Napoca
Macuser din: 26.08.11

UICollectionView e ok ca varianta, dar esti limitat la ios6. Cand am de afisat imagini pe grupuri cu care sa poti interactiona cand selectezi o poza folosesc butoane in care adaug ca subview imaginea de tip CSAsyncImageView. Folosesc asincron tocmai pentru a nu bloca scroll-ul si totul merge fluent smile


for (int i = 0; i < [[self.selectedEvent objectForKey:@“pressList”] count]; i++)
  {
      UIButton *button = [[UIButton alloc] initWithFrame:CGRectMake(i*60+5, 0, 57, 57)];
     
      //image
      CGRect frame;
      frame.size.width = 57;
      frame.size.height = 57;
      frame.origin.x = 0;
      frame.origin.y = 0;
     
      CSAsyncImageView* asyncImage = [[[CSAsyncImageView alloc] initWithFrame:frame] autorelease];
      asyncImage.tag = 999;
     
      [asyncImage loadImageFromURL:[NSURL URLWithString:[[[self.selectedEvent objectForKey:@“pressList”] objectAtIndex:i] objectForKey:@“thumbnail”]] andName:@”“];

     
      [button addSubview: asyncImage ];
      asyncImage.userInteractionEnabled = NO;
     
     
     
      button.tag = [[[[self.selectedEvent objectForKey:@“pressList”] objectAtIndex:i] objectForKey:@“userId”] intValue];
 
      [button addTarget:self action:@selector(buttonPressedForPress:) forControlEvents:UIControlEventTouchUpInside];
   
      [self.scrollForPress addSubview:button];
  }

 Semnătură 

rMBP 15” late 2013
iPhone 6S+ 64GB

Profil
 
  [ Ignoră ]   [ # 5 ]
Avatar
RankRankRankRank
Moderator
Din: Cluj-Napoca
Macuser din: 26.01.06

ios6 n-ar trebui sa fie o problema pt ca pana si 3gs il suporta, pentru ceva mai slab nici nu vreau sa fac. O sa pun in aplicare collectionview sa vad ce iese.

 Semnătură 

Mcintoshing…

Profil
 
  [ Ignoră ]   [ # 6 ]
Avatar
RankRank
Jr. Member
Din: Cluj Napoca
Macuser din: 26.08.11

Varianta oferita de mine e cea mai ok pentru incarcat pozele de pe mediu online, deoarece le poti aranja cum doresti, fara limitari(codul dat e doar pentru scroll orizontal, pentru vertical inca un for si un buton :D). Bafta

 Semnătură 

rMBP 15” late 2013
iPhone 6S+ 64GB

Profil
 
  [ Ignoră ]   [ # 7 ]
Avatar
RankRankRankRank
Moderator
Din: Cluj-Napoca
Macuser din: 26.01.06

Vaianta ta nu este chiar asa de ok pentru ca daca ai sute-mii de elemente ai dat de dracu si cu memoria si cu performantele.
Apoi nici nu trebuie sa creezi un UIButton si sa adaugi din exterior imaginea cand imaginea poate sa extinda UIControl direct.

Am avut la prima mea aplicatie thumburi puse intr-un scrollview aranjate pe linii si coloane, n-au fost probleme pentru ca nu aveam multe poze, dar nu asa se face.

 Semnătură 

Mcintoshing…

Profil
 
  [ Ignoră ]   [ # 8 ]
RankRank
Jr. Member
Din: Bucuresti
Macuser din: 26.03.10

dequeueReusableCellWithIdentifier FTW

 Semnătură 

 iPhone 5 16GB black, iOS 7 beta 5
 MacBook Pro 15” Unibody, Late 2011 2,4 Ghz Intel Core i7, 8GB RAM, 128GB SSD, Radeon 6770 1GB, HiRes Display, OS X 10.8.3
 Thunderbolt Display

Profil
 
  [ Ignoră ]   [ # 9 ]
Avatar
RankRankRankRank
Moderator
Din: Cluj-Napoca
Macuser din: 26.01.06

Mda, am implementat colectia, cod mai putin si mai simplu dar tot sacadeaza. Problema este exact cum credeam, la cum incarc pozele.

 Semnătură 

Mcintoshing…

Profil
 
  [ Ignoră ]   [ # 10 ]
Avatar
RankRankRankRank
Moderator
Din: Cluj-Napoca
Macuser din: 26.01.06

cred ca trebuie cacheuite in avans imaginile, am reusit sa obtin ceva multumitor daca fac thumburile mai mari si view-ul mai mic, deci mai putine poze. nu-mi dau seama daca chiar sacadeaza sau faptul ca apar cu un mic delay imi dau impresia asta.

 Semnătură 

Mcintoshing…

Profil
 
  [ Ignoră ]   [ # 11 ]
Avatar
RankRankRankRank
Sr. Member
Din: Bucuresti
Macuser din: 22.09.06

Pentru < 6.0 iti recomand https://github.com/steipete/PSTCollectionView
.ral:cr: nu vad de ce ar sacada daca faci totul async.
UIImage e thread-safe, esti sigur ca faci totul in backgroun si doar update-ul de UI in main thread?
si imageWithData: ar trebui apelat tot in background si doar cand setezi UIImage-ul sa o faci pe main thread.
Am folosit si eu la ultimul proiect CollectionView si merge perfect, daca sacadeaza sigur ai ceva ce blocheaza UI-ul.

 Semnătură 

A man should look for what is, and not for what he thinks should be.—Albert Einstein

Profil
 
  [ Ignoră ]   [ # 12 ]
Avatar
RankRankRankRank
Sr. Member
Din: Bucuresti
Macuser din: 22.09.06

.ral:cr: tocmai am facut mai devreme un update pe gutHub la libraria asta, am testat-o si pare sa mearga ok, daca ai timp o poti incerca sa imi spui daca mai ai aceasi problema cu imaginile.
https://github.com/lucianboboc/LBCache-DemoProject

 Semnătură 

A man should look for what is, and not for what he thinks should be.—Albert Einstein

Profil
 
  [ Ignoră ]   [ # 13 ]
Avatar
RankRankRankRank
Moderator
Din: Cluj-Napoca
Macuser din: 26.01.06

Cred ca am sa ma intorc la problema zilele urmatoare, pana atunci uite codul pe care-l folosesc. Am incercat sa creez UIImage in alt thread dar tot la fel face.
In comparatie cu cealalta metoda cu tableview acum sacadeaza si la imaginile de pe net.

UICollectionViewFlowLayout *layout [[UICollectionViewFlowLayout alloc] init];
    
layout.itemSize CGSizeMake(8080);
    
layout.minimumInteritemSpacing 0;
    
    
self.collectionView [[UICollectionView alloc] initWithFrame:rect collectionViewLayout:layout];
    
self.collectionView.delegate self;
    
self.collectionView.dataSource self;
    
self.collectionView.backgroundColor [UIColor colorWithWhite:0.3 alpha:0.5];
    
self.collectionView.autoresizingMask UIViewAutoresizingFlexibleWidth UIViewAutoresizingFlexibleHeight UIViewAutoresizingFlexibleRightMargin UIViewAutoresizingFlexibleLeftMargin UIViewAutoresizingFlexibleBottomMargin;
    
[self.collectionView registerClass:[CollectionCell class] forCellWithReuseIdentifier:identif];
    
[self.view addSubview:self.collectionView];
    
- (
UICollectionViewCell *)collectionView:(UICollectionView *)collectionView_ cellForItemAtIndexPath:(NSIndexPath *)indexPath {
    
    CollectionCell 
*cell = (CollectionCell*)[collectionView_ dequeueReusableCellWithReuseIdentifier:identif forIndexPath:indexPath];
    
    if (
cell == nil{
        cell 
[[CollectionCell alloc] initWithFrame:CGRectMake(008080)];
    
}
    
    cell
.index indexPath.item;
    
    if (
fb_photos == nil{
        
        [cell loadImageFromLibrary
:[images objectAtIndex:indexPath.item]];
        
[cell select:[[imagesSelectedState objectAtIndex:indexPath.item] boolValue]];
    
}
    
else {
        [cell loadImageFromUrl
:[[fb_photos objectAtIndex:indexPath.item] thumb]];
        
[cell select:[[imagesSelectedState objectAtIndex:indexPath.item] boolValue]];
    
}
    
    
return cell;

Si CollectionCell

- (id)initWithFrame:(CGRect)frame {
    
    self 
[super initWithFrame:frame];
    if (
self{
        
// Initialization code
        
imageView [[UIImageView alloc] initWithFrame:CGRectMake(00frame.size.widthframe.size.height)];
        
imageView.contentMode  UIViewContentModeScaleAspectFill;
        
imageView.clipsToBounds YES;
        
[self addSubview:imageView];
        
        
markImage [[UIImageView alloc] initWithFrame:CGRectMake(661616)];
        
markImage.image [UIImage imageNamed:@"Checkmark"];
        
markImage.hidden YES;
        
[self addSubview:markImage];
    
}
    
return self;
}

- (void)select:(BOOL)sel {
    
    markImage
.hidden = !sel;
    
    if (
sel{
        [UIView beginAnimations
:@"zoom" context:NULL];
        
[UIView setAnimationDuration:0.2];
        
imageView.frame CGRectMake(00self.frame.size.widthself.frame.size.height);
        
imageView.alpha 1;
        
[UIView commitAnimations];
    
}
    
else {
        imageView
.frame CGRectMake(66self.frame.size.width-12self.frame.size.height-12);
        
imageView.alpha 0.6;
    
}
}

- (voidloadImageFromLibrary:(NSURL *)url {
    
    isLoading 
NO;
    
imageView.image nil;
    
    
// Load image in a new thread
    
[NSThread detachNewThreadSelector:@selector(loadImageCG:)
                             
toTarget:self
                           withObject
:url];
}
- (voidloadImageCG:(NSURL*)url {
    ALAssetsLibraryAssetForURLResultBlock resultblock 
= ^(ALAsset *myasset){
        isLoading 
YES;
        
[self performSelectorOnMainThread:@selector(displayImage:)
                               
withObject:[UIImage imageWithCGImage:[myasset thumbnail]]
                            waitUntilDone
:NO];
    
};
    
ALAssetsLibraryAccessFailureBlock failureblock  = ^(NSError *myerror){
        NSLog
(@"Cant get image - %@"[myerror localizedDescription]);
    
};
    
    
ALAssetsLibrary *assetslibrary [[ALAssetsLibrary alloc] init];
    
[assetslibrary assetForURL:url resultBlock:resultblock failureBlock:failureblock];
}


- (voidloadImageFromUrl:(NSString *)url {
    
    isLoading 
YES;
    
imageView.image nil;
    
    
// Load image in a new thread
    
[NSThread detachNewThreadSelector:@selector(loadImageData:)
                             
toTarget:self
                           withObject
:url];
}
- (voidloadImageData:(NSString *)url {
    
    
// Load image
    
NSData *imageData [[NSData alloc] initWithContentsOfURL:[NSURL URLWithString:url]];
    
    
[self performSelectorOnMainThread:@selector(displayImage:)
                           
withObject:[[UIImage alloc] initWithData:imageData]
                        waitUntilDone
:NO];
}

- (voiddisplayImage:(UIImage*)image {
    
if (isLoading{
        isLoading 
NO;
        
imageView.image image;
    
}
 Semnătură 

Mcintoshing…

Profil
 
  [ Ignoră ]   [ # 14 ]
Avatar
RankRankRankRank
Sr. Member
Din: Bucuresti
Macuser din: 22.09.06

UICollectionView e Ui element, nu e thread safe, posibil aici sa fie problema:
  [NSThread detachNewThreadSelector:@selector(loadImageCG:)
                    toTarget:self
                  withObject:url];

Eu inteleg ca asta apeleaza pe alt thread: [cell loadImageCGWithObject: url]  sau ceva de genul.
Eu as face alta clasa “model” image fetcher si as face delegare pt a returna imaginea catre cell cand e gata. sau as muta in controller metodele pt load.

 Semnătură 

A man should look for what is, and not for what he thinks should be.—Albert Einstein

Profil
 
  [ Ignoră ]   [ # 15 ]
Avatar
RankRankRankRank
Sr. Member
Din: Bucuresti
Macuser din: 22.09.06

Da, cum banuiam:

detachNewThreadSelector:toTarget:withObject:
Detaches a new thread and uses the specified selector as the thread entry point.

aTarget
The object that will receive the message aSelector on the new thread.
Accesand cell-ul pe alt thread e problema.
Mai bine regandesti modelul, cum am zis eu am crea o clasa ImageFether, i-as pune un UIImage ca proprietate eventual si url-ul cu sursa, si as crea atatea insante ale clasei, cate cell-uri ai avea nevoie si le-as adauga toate intr-in array.
in cellForItemAtIndexPath as crea verifica proprietatea image a fiecarei instane ImageFetcher pt fiecare cell.
Daca image nu exista as apela:

dispatch_async(dispatch_get_global_queue(0,0),^{    
     
// aici functiile pt load imagine din sursa ta
     // cand ai UIImage-ul setat ca proprietate la imageFetcher-ul din artay-ul tau de la index-ul corespunzator

      
dispatch_async(dispatch_get_main_queue(),{
        cell
.image imageFetcher.image;
      
});


 
});
 
 
// daca imaginea exista deja in imageFetcher-ul de la index-ul reapectiv, setata direct cell.image = imageFetcher.image; 
 Semnătură 

A man should look for what is, and not for what he thinks should be.—Albert Einstein

Profil
 
   
1 din 2
1