2014-03-30 2 views
1

데이터를 파싱 한 후 UICollectionView 이미지를로드하는 데 어려움을 겪고 있습니다.UICollectionView 이미지를 스크롤 할 때만 스크롤

이 애플에서 LazyTable 솔루션이며, everythings가있는 tableview에서 작동하지만 난 이동하면

CollectionView 이미지 만 apear. 다른 데이터는 라벨이나 다른 apears와 같습니다.

문제 없이만 이미지가 나에게 문제가됩니다. 여기

내 위임 안에 재 장전 방법 :

__block ParseOperation *weakParser = parser; 

    parser.completionBlock = ^(void) { 
     if (weakParser.appRecordList) { 
      dispatch_async(dispatch_get_main_queue(), ^{ 
       CategroyScreenViewController *rootViewController = (CategroyScreenViewController*)[(UINavigationController*)self.window.rootViewController topViewController]; 

       rootViewController.entries = weakParser.appRecordList; 
       [rootViewController.collectionView reloadData]; 
      }); 
     } 
     self.queue = nil; 
    }; 

    [self.queue addOperation:parser]; 
    self.appListData = nil; 
} 

을하고이 collectionview를 포함 내 CategroyScreenViewController입니다 :

#define kCustomRowCount  7 

@interface CategroyScreemViewController() <UIScrollViewDelegate> 
@property (nonatomic, strong) NSMutableDictionary *imageDownloadsInProgress; 
@property (nonatomic) NSMutableArray* numbers; 
@end 
int num = 0; 
@implementation CategroyScreemViewController 

- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil 
{ 
    self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil]; 
    if (self) { 
     // Custom initialization 
    } 
    return self; 
} 

- (void)viewDidLoad 
{ 
    NSLog(@"view did load"); 
    [super viewDidLoad]; 
    self.imageDownloadsInProgress = [NSMutableDictionary dictionary]; 
    [self.collectionView reloadData]; 


} 

- (CGSize) blockSizeForItemAtIndexPath:(NSIndexPath *)indexPath { 


    NSLog(@"Asking for index paths of non-existant cells!! %d", indexPath.row); 

    if (indexPath.row == 0) return CGSizeMake(2, 2);  
    return CGSizeMake(1, 1); 
} 
- (void) viewDidAppear:(BOOL)animated { 
    NSLog(@"viewDidAppear load"); 
    [self.collectionView reloadData]; 
} 
- (UIEdgeInsets)insetsForItemAtIndexPath:(NSIndexPath *)indexPath { 
     NSLog(@"insetsForItemAtIndexPath load"); 
    return UIEdgeInsetsMake(2, 2, 2, 2); 
} 
- (void)didReceiveMemoryWarning 
{ 
    [super didReceiveMemoryWarning]; 
    NSArray *allDownloads = [self.imageDownloadsInProgress allValues]; 
    [allDownloads makeObjectsPerformSelector:@selector(cancelDownload)]; 

    [self.imageDownloadsInProgress removeAllObjects]; 
} 
-(NSInteger)numberOfSectionsInCollectionView:(UICollectionView *)collectionView 
{ 
    NSLog(@"numberOfSectionsInCollectionView load"); 
    return 1; 
} 

-(NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section 
{ 
    NSUInteger count = [self.entries count]; 
     NSLog(@"numberOfItemsInSection load"); 
    if (count == 0) 
    { 
     return kCustomRowCount; 
    } 
    return count; 
} 
-(UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath 
{ 
    CategoryScreenCell *myCell = [collectionView dequeueReusableCellWithReuseIdentifier:@"MyCell" forIndexPath:indexPath]; 
    UILabel *label = (UILabel *)[myCell.contentView viewWithTag:10]; 
    NSUInteger nodeCount = [self.entries count]; 
    if (nodeCount > 0) 
    { 
     AppRecord *appRecord = [self.entries objectAtIndex:indexPath.row]; 
     [label setText:appRecord.appName]; 
     if (!appRecord.appIcon) 
     { 

      if (self.collectionView.dragging == NO && self.collectionView.decelerating == NO) 
      { 

       [self startIconDownload:appRecord forIndexPath:indexPath]; 
      } 
      myCell.imageView.image = [UIImage imageNamed:@"Placeholder.png"]; 
     } 
     else 
     { 

      myCell.imageView.image = appRecord.appIcon; 
     } 

    } 

    return myCell; 
} 
- (UIColor*) colorForNumber:(NSNumber*)num { 
    return [UIColor colorWithHue:((19 * num.intValue) % 255)/255.f saturation:1.f brightness:1.f alpha:1.f]; 
} 
- (void)startIconDownload:(AppRecord *)appRecord forIndexPath:(NSIndexPath *)indexPath 
{ 
    IconDownloader *iconDownloader = [self.imageDownloadsInProgress objectForKey:indexPath]; 
    if (iconDownloader == nil) 
    { 
     iconDownloader = [[IconDownloader alloc] init]; 
     iconDownloader.appRecord = appRecord; 
     [iconDownloader setCompletionHandler:^{ 

      CategoryScreenCell *myCell = [self.collectionView dequeueReusableCellWithReuseIdentifier:@"MyCell" forIndexPath:indexPath]; 
      myCell.imageView.image = appRecord.appIcon; 
      myCell.imageView.layer.masksToBounds = YES; 
      [self.imageDownloadsInProgress removeObjectForKey:indexPath]; 

     }]; 
     [self.imageDownloadsInProgress setObject:iconDownloader forKey:indexPath]; 
     [iconDownloader startDownload]; 
    } 
} 
- (void)loadImagesForOnscreenRows 
{ 
    NSLog(@"loadImagesForOnscreenRows"); 
    if ([self.entries count] > 0) 
    { 
     NSArray *visiblePaths = [self.collectionView indexPathsForVisibleItems]; 
     for (NSIndexPath *indexPath in visiblePaths) 
     { 
      AppRecord *appRecord = [self.entries objectAtIndex:indexPath.item]; 

      if (!appRecord.appIcon) 
       // Avoid the app icon download if the app already has an icon 
      { 
       [self startIconDownload:appRecord forIndexPath:indexPath]; 
      } 
     } 
    } 
} 

- (void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate 
{ 
    NSLog(@"scrollViewDidEndDragging"); 

    if (!decelerate) 
    { 
     NSLog(@"decelerate"); 
     [self loadImagesForOnscreenRows]; 
    } 
} 


- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView 
{ 
    NSLog(@"scrollViewDidEndDecelerating"); 
    [self loadImagesForOnscreenRows]; 
} 

@end 

확인 필자는이 변경 후 :에

 CategoryScreenCell *myCell = [self.collectionView dequeueReusableCellWithReuseIdentifier:@"MyCell" forIndexPath:indexPath]; 

을 이 하나 :

CategoryScreenCell *myCell = [self.collectionView cellForItemAtIndexPath:indexPath]; 

프로그램이 잘 작동하지만, 나에게이 경고 제공 : 유형의 식 'CategoryScreenCell *를'초기화 "호환되지 않는 포인터 타입을 'UICollectionViewCell *'

당신은 단지 주조에 의해 경고 제거 할 수

답변

1

나는이 방법으로 볼 수있는 문제는 IconDownloader의 완료 핸들러에서, 당신은 항상 셀을 대기열에서 그것을 채우는하고 있다는 것입니다 , 보이지 않더라도 표시되지 않을 수도 있습니다. 얼마나 많은 오버 헤드인지는 잘 모르겠습니다. 얼마나 많은 셀이 있고 얼마나 빨리 사람들이 스크롤 할 것인가에 달려 있습니다.

한 가지 대안은 모든 셀이 등록 할 완료 핸들러에 알림을 게시하는 것입니다. 통지가 발생할 때 호출되는 메소드에서 셀은 통지의 userInfo에있는 AppRecord이 현재 셀에 있는지 여부를 확인하고 해당 이미지를 갱신합니다.

다른 문제는 스크롤 한 모든 셀에 대해 이미지 다운로드를 대기열에 추가하기 때문에 사용자가 컬렉션보기의 맨 아래로 빠르게 스크롤하면 위의 모든 이미지가 먼저로드 될 때까지 기다려야합니다. 이를 해결할 수있는 방법은 두 가지가 있습니다.

1) 대기열에서 큐를 제거 할 때 셀에 IconDownloader에 대한 참조를 지정합니다. 그런 다음 셀의 prepareForReuse에서 아직 보류중인 경우 다운로드를 취소하십시오.

2) 보류중인 다운로드를 취소하고 싶지 않지만 표시되는 셀이 가능한 빨리 업데이트되도록하려면 다운로드를 우선 순위 대기열에 넣고 새로 만들 때마다 우선 순위를 높일 수 있습니다 IconDownloader 인스턴스.

+0

감사합니다. 귀하의 접근 방식은 많은 도움이됩니다. –

1

셀 유형, 가정 당신이 필요한 유형이 될 것 알고

CategoryScreenCell *myCell = (CategoryScreenCell *)[self.collectionView cellForItemAtIndexPath:indexPath]; 
+0

감사합니다. –

관련 문제