2013-05-22 4 views
8

Pracuję nad aplikacją, w której chcę wyświetlać obrazy, prawie tak duże, jak ekranizowane, w widoku UITableView z niestandardowymi komórkami. Obrazy ładują się dobrze, są trochę wolne, ale ładują się, ale kiedy przewijam w TableView, pojawiają się w niewłaściwej komórce (na przykład Obraz1 w Komorze 5, gdzie powinien pojawić się obrazek5) po 1 lub 2 sekundach pojawia się poprawny obraz. aby nie trzeba wiele datatraffic myślałem o „pamięci podręcznej” -jak przechowywania URL/Obraz tak:Obrazy w UITableViewCells ładują się nieprawidłowo

- (id) init 
{ 
    if (self = [super init]) { 
     self.cacheStoreDictionary = [NSMutableDictionary new]; 
    } 
    return self; 
} 

- (void) startLoadingImageWithUrl:(NSString *)urlString forItem:(id)item 
{ 
    if (self.cacheStoreDictionary[urlString]) { 
     UIImage *image = self.cacheStoreDictionary[urlString]; 
     [self.delegate lcCachedImageLoader:self didLoadImage:image forItem:item wasCacheHit:YES]; 
    } else { 
     dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0), ^{ 
      NSData *data = [NSData dataWithContentsOfURL:[NSURL URLWithString:urlString]]; 
      UIImage *image = [UIImage imageWithData:data]; 
      dispatch_async(dispatch_get_main_queue(), ^{ 
       [self.cacheStoreDictionary setObject:image forKey:urlString]; 
       [self.delegate lcCachedImageLoader:self didLoadImage:image forItem:item wasCacheHit:NO]; 
      }); 
     }); 
    } 
} 

URL i reszta danych muszę ja ładowania poprzez AFNetwork tak :

- (void)fetchTicketEvents 
{ 
    // Login URL 
    NSURL *eventsURL = [NSURL URLWithString:TH_API_BASEURL]; 

    AFHTTPClient *httpClient = [[AFHTTPClient alloc] initWithBaseURL:eventsURL]; 
    httpClient.parameterEncoding = AFJSONParameterEncoding; 

    // Set request parameters 
    NSDictionary *params = nil; 
    NSMutableURLRequest *request = [httpClient requestWithMethod:@"GET" 
                  path:TH_API_PATH_TICKET_EVENT_INDEX 
                 parameters:params]; 
    request.cachePolicy = NSURLRequestReloadIgnoringLocalCacheData; 

    // Prepare request 
    AFJSONRequestOperation *eventsRequest = [AFJSONRequestOperation JSONRequestOperationWithRequest:request success:^(NSURLRequest *request, NSHTTPURLResponse *response, id JSON) { 
     if ([self.delegate respondsToSelector:@selector(thAPITicket:didLoadTicketEvents:response:errorCode:)]) { 
      NSArray *jsonEventArray = JSON; 
      NSMutableArray *event = [[NSMutableArray alloc] initWithCapacity:jsonEventArray.count]; 
      for (NSDictionary *eventDictionary in [JSON allObjects]) { 
       [event addObject:[LCEvent eventFromDictionary:eventDictionary]]; 
      } 
      [self.delegate thAPITicket:self 
          didLoadTicketEvents:YES 
             response:@{@"response" : response, @"json" : JSON, @"event" : event} 
             errorCode:TH_API_ERR_TICKETINDEX_NO_ERROR]; 
#if LOG_NETWORKING 
      [self printJSON:JSON]; 
#endif 
      //Network indicator off 
      [LCSharedInstance hideNetworkActivity]; 

      //Allow Slide-To-Refresh 
      [LCSharedInstance singletone].allowSlideToRefresh = YES; 
      [LCSharedInstance singletone].isShownLoadingMessage = NO; 
      [LCSharedInstance singletone].isLoading = NO; 
     } 
    } failure:^(NSURLRequest *request, NSHTTPURLResponse *response, NSError *error, id JSON) { 
     if ([self.delegate respondsToSelector:@selector(thAPITicket:didLoadTicketEvents:response:errorCode:)]) { 
      if (nil == JSON) { 
       JSON = @{}; 
      } 
      [self.delegate thAPITicket:self 
          didLoadTicketEvents:NO 
             response:@{@"response" : response, @"json" : JSON} 
             errorCode:TH_API_ERR_TICKETINDEX_NO_ERROR]; 
      [LCSharedInstance hideNetworkActivity]; 

     } 
     //Network indicator off 
     [LCSharedInstance hideNetworkActivity]; 
    }]; 
    [LCSharedInstance showNetworkActivity]; 
    // Send request 
    [eventsRequest start]; 
} 

Oto jak wypełnić TableViewCell:

- (void) lcCachedImageLoader:(LCCachedImageLoader *)cachedImageLoader didLoadImage:(UIImage *)teaserImage forItem:(id)item wasCacheHit:(BOOL)wasCacheHit 
{ 
    //Teaser Image Implementation 
    UIImageView *imageView = ((UIImageView*)[((UIView*)item)viewWithTag:100]); 
    imageView.alpha = 0.2; 
    imageView.image = teaserImage; 
    imageView.contentMode = UIViewContentModeScaleToFill; 
    [UIView animateWithDuration:0.5 animations:^{ 
     imageView.alpha = 1.0; 
    }]; 
} 


#pragma mark - tableview delegation 
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath 
{ 
    static NSString *CellIdentifier = @"offerCell"; 
    LCEvent *event = self.eventArray[indexPath.row]; 
    tableView = self.tableView; 
    LCClusterViewController *clusterVC = [tableView dequeueReusableCellWithIdentifier:CellIdentifier]; 

#pragma mark - Cell Config and Style Attributes 
    clusterVC.titleLabel.attributedText = LCAttrText(event.titleString, LCFontStyleEventName); 
    clusterVC.ticketDetailsLabel.attributedText = LCAttrText(event.subtitleString, LCFontStyleEventTitle); 
    clusterVC.oldPriceLabel.attributedText = LCAttrText(event.oldPriceString, LCFontStyleEventOldPrice); 
    clusterVC.actualPriceLabel.attributedText = LCAttrText(event.actualPriceString, LCFontStyleEventPrice); 
    clusterVC.timeLabel.attributedText = LCAttrText(event.timeString, LCFontStyleEventInfoText); 
    clusterVC.ticketCountLabel.attributedText = LCAttrText(event.stockString, LCFontStyleEventInfoText); 
    clusterVC.dateLabel.attributedText = LCAttrText(event.dateString, LCFontStyleEventDateText); 
... and on and on 

więc dzięki za wszelkie pomocne wskazówki

Odpowiedz

3

widoku tabeli komórki są poddawane ponownie użyte ze względu na wydajność, więc zachowują poprzednio używany obraz w UIImageView, jeśli nie ustawisz go do niczego przed załadowaniem obrazu.

Bezpośrednio przed wywołaniem funkcji startLoadingImageWithUrl można najpierw ustawić początkowy obraz obrazu z obrazem zastępczym lub dodać wskaźnik ładowania na wierzchu obrazu. Ale pamiętaj, aby usunąć wskaźnik ładowania, gdy załadowany jest prawdziwy obraz.

- (void) startLoadingImageWithUrl:(NSString *)urlString forItem:(id)item 
{ 
    UIImageView *imageView = ((UIImageView*)[((UIView*)item)viewWithTag:100]); 
    imageView.image = placeholderImage; 
    if (self.cacheStoreDictionary[urlString]) { 
     UIImage *image = self.cacheStoreDictionary[urlString]; 
     [self.delegate lcCachedImageLoader:self didLoadImage:image forItem:item wasCacheHit:YES]; 
    } else { 
     dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0), ^{ 
      NSData *data = [NSData dataWithContentsOfURL:[NSURL URLWithString:urlString]]; 
      UIImage *image = [UIImage imageWithData:data]; 
      dispatch_async(dispatch_get_main_queue(), ^{ 
       [self.cacheStoreDictionary setObject:image forKey:urlString]; 
       [self.delegate lcCachedImageLoader:self didLoadImage:image forItem:item wasCacheHit:NO]; 
      }); 
     }); 
    } 
} 

I dla obrazu pojawiającego się w niewłaściwym komórce po załadowaniu obrazu, to dlatego, że przechodzą element, który jest ponownie wykorzystane komórkę, jako parametr w startLoadingImage i didLoadImage. Spróbuj przekazać właściwość indexPath i zlokalizuj poprawną komórkę za pomocą właściwości indexPath, aktualizując widok obrazu komórki.

UITableViewCell *cell = [self.tableView cellForRowAtIndexPath:indexPath];

+0

Tak próbowałem, że też, ale to sprawiło, że cały imageloading wolniej i tak naprawdę nie rozwiązuje problemu. Niektóre Obrazy są nadal na niewłaściwych pozycjach przez krótki czas. – d3p0nit

+0

Gdzie nazywasz startLoadingImageWithUrl: (NSString *) urlString element forItem: (id)? –

+0

na końcu mojej komórkiForRowAtIndexpath: – d3p0nit

1

po prostu napisać ten kod, gdzie można przypisać obraz, jeśli nie załadowano następnie

cell.imageView.image = Nil; 

jeśli załadowany następnie przypisać obraz, jeśli inny jak ten

cell.imageView.image = Nil; 
if([dictionary objectForKey:@"Image"]) 
{ 
    cell.imageView.image = [dictionary objectForKey:@"Image"]; 

}else 
{ 
    cell.imageView.image = Nil; 
}