image on tableview cell repeating due to reusability issue - ios

I have a table view cell,having labels and images,on scrolling the images and labels get changed,this is due to the cell dequeue feature.I tried to resolve it by setting the imageview to nil,but it doesn't work.
The problem of repeatition is with PinImageView,that takes image from an array of images,its not with the one which takes images from URL.
-(UITableViewCell*)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
static NSString *cellIdentifier=#"cellIdentifier";
TripInfoListCell *cell=[tableView dequeueReusableCellWithIdentifier:cellIdentifier];
if (cell==nil) {
cell=(TripInfoListCell *)[[[NSBundle mainBundle] loadNibNamed:#"TripInfoListCell" owner:self options:nil] firstObject];
}
cell.PinImageView.image = nil;
NSString *direction=[dict123 valueForKey:#"direction" ] ;
NSString *drive_status=[dict123 valueForKey:#"driver_or_rider"];
if((indexPath.row==totalRow-1)&&[direction isEqual:#"From"])
{
__weak TripInfoListCell *weakCell = cell;
cell.PinImageView.image=[UIImage imageNamed:#"pin7#2x.png"];
cell.userNameLabel.text=loggedUser.profile_name;
cell.riderDriverSlNo.text=#"Driver";
if([drive_status isEqual:#"Ride"])
{
cell.riderDriverSlNo.text=#"Driver";
cell.userNameLabel.text=#"Driver"; //In case of "Rider" "From" name in the last row
}
else{
cell.availabiltyInfoLabel.text=#"You";
}
NSString *imagePic = [[NSUserDefaults standardUserDefaults] objectForKey:#"user_image"];
NSURLRequest *request=[NSURLRequest requestWithURL:[NSURL URLWithString:imagePic]];
[cell.userImageView setImageWithURLRequest:request placeholderImage:nil success:^(NSURLRequest *request, NSHTTPURLResponse *response, UIImage *image) {
weakCell.userImageView.image=image;
} failure:^(NSURLRequest *request, NSHTTPURLResponse *response, NSError *error) {
NSLog(#"%#",error);
}];
}
else if((indexPath.row==totalRow-1)&&[direction isEqual:#"To"])
{
cell.PinImageView.image=[UIImage imageNamed:#"pin7#2x.png"];
cell.userNameLabel.text=[_tripDetails objectForKey:#"park_name"];
NSString *image=[NSString stringWithFormat:#"%#",[dict123 objectForKey:#"parkBannerImageUrl"]];
[[ImageHandler sharedInstance] getImageFromURL:image withCompletion:^(UIImage *image) {
if (image) {
[cell.userImageView setImage:image];
}
}];
}
else
if ([tableGoersList count] > indexPath.row)
{
NSDictionary *goersInfo=[tableGoersList objectAtIndex:indexPath.row];
[[NSUserDefaults standardUserDefaults]setObject:[goersInfo valueForKey:#"user_image_url"] forKey:#"user_image"];
[[NSUserDefaults standardUserDefaults]synchronize];
__weak TripInfoListCell *weakCell = cell;
NSURLRequest *request=[NSURLRequest requestWithURL:[NSURL URLWithString:goersInfo[#"user_image_url"]]];
[cell.userImageView setImageWithURLRequest:request placeholderImage:nil success:^(NSURLRequest *request, NSHTTPURLResponse *response, UIImage *image) {
weakCell.userImageView.image=image;
} failure:^(NSURLRequest *request, NSHTTPURLResponse *response, NSError *error) {
NSLog(#"%#",error);
}];
if((indexPath.row==0)&&[direction isEqual:#"To"]) {
if([drive_status isEqual:#"Drive"]){
cell.riderDriverSlNo.text=#"Driver";
cell.PinImageView.image=[UIImage imageNamed:#"pin1#2x.png"];
cell.userNameLabel.text=loggedUser.profile_name;
cell.availabiltyInfoLabel.text=#"You";
}
else{
}
}
else if((indexPath.row==0)&&[direction isEqual:#"From"]) {
if([drive_status isEqual:#"Drive"])
{
cell.PinImageView.image=[UIImage imageNamed:#"pin1#2x.png"];
cell.userNameLabel.text=[_tripDetails objectForKey:#"park_name"];
cell.riderDriverSlNo.text=#"";
cell.availabiltyInfoLabel.text=#"";
NSString *image=[NSString stringWithFormat:#"%#",[dict123 objectForKey:#"parkBannerImageUrl"]];
[[ImageHandler sharedInstance] getImageFromURL:image withCompletion:^(UIImage *image) {
if (image) {
[cell.userImageView setImage:image];
}
}];
}
else{
NSLog(#"rider from");
cell.riderDriverSlNo.text=#"";
}
}
else{
imageNameArray = [[NSArray alloc] initWithObjects:#"pin2#2x.png", #"pin3#2x.png", #"pin4#2x.png", #"pin5#2x.png", #"pin6#2x.png",#"pin8#2x.png",#"pin9#2x.png", nil];
NSString* nameStr=[goersInfo valueForKey:#"name"];
NSArray * nameStrArray = [nameStr componentsSeparatedByString: #"'s"];
nameStr=[nameStrArray objectAtIndex:0];
cell.riderDriverSlNo.text=[NSString stringWithFormat:#"Rider %ld",(long)indexPath.row];
index = [TripInfoVC ifNameExists:_arrName Name:nameStr];
if(index == 0)
{
cell.PinImageView.image=[UIImage imageNamed:[imageNameArray objectAtIndex:0]];
[_arrName addObject:nameStr];
}
if(index == 1)
{
cell.PinImageView.image=[UIImage imageNamed:[imageNameArray objectAtIndex:1]];
}
if(index == 2)
{
cell.PinImageView.image=[UIImage imageNamed:[imageNameArray objectAtIndex:2]];
}
if(index == 3)
{
cell.PinImageView.image=[UIImage imageNamed:[imageNameArray objectAtIndex:3]];
}
if(index == 4)
{
cell.PinImageView.image=[UIImage imageNamed:[imageNameArray objectAtIndex:4]];
}
if(index == 5)
{
cell.PinImageView.image=[UIImage imageNamed:[imageNameArray objectAtIndex:5]];
}
if(index == 6)
{
cell.PinImageView.image=[UIImage imageNamed:[imageNameArray objectAtIndex:6]];
}
if(index == 7)
{
cell.PinImageView.image=[UIImage imageNamed:[imageNameArray objectAtIndex:0]];
}
if(index == 8)
{
cell.PinImageView.image=[UIImage imageNamed:[imageNameArray objectAtIndex:1]];
}
if(index == 9)
{
cell.PinImageView.image=[UIImage imageNamed:[imageNameArray objectAtIndex:2]];
}
if(index == 10)
{
cell.PinImageView.image=[UIImage imageNamed:[imageNameArray objectAtIndex:3]];
}
} // this pinImageView is the pin image which is repeated on scrolling
return cell;
}
Please help me solving this issue.

you may be faces the closure collision. when you declare completion block
[cell.userImageView setImageWithURLRequest:request placeholderImage:nil success:^(NSURLRequest *request, NSHTTPURLResponse *response, UIImage *image) {
weakCell.userImageView.image=image;
} failure:^(NSURLRequest *request, NSHTTPURLResponse *response, NSError *error) {
NSLog(#"%#",error);
}];
weakCell is the pointer to cell object that was requested by UITableView delegate. it maybe reused later when you scroll the table and at that moment your completion block may actually be invoked, because downloading
process is not immediate.
How to handle it? I would use etc. UITableViewCell.tag property for identification of what exactly image I requested at the moment when cell was required and does it match the image I am trying to put to that cell when completion block is running. maybe some other downloading was fired later and overwritten tag property.

You have to implement load images in the fly or lazy loading by adding your code into delegate method of UICollection cellForRowAtIndexPath method on operation queue.
And, if you are doing something on UI that you have placed inside main thread, here is another example:
Lazy loading images in UICollectionView with SDWebImageManager

Related

Appending image in collectionView using AFNetworking

I am new for Ios app development. I am using AFNetworking for image and data load, data are binned in collection view but unable to bind image.
This is my code for collection view and service:
#import "ViewController.h"
#import "LabelCollectionViewCell.h"
#interface ViewController ()
{
NSMutableArray *idArray;
NSMutableArray *namelabelArray;
UIImage *imagArray;
NSMutableArray *dic ;
}
#end
#implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
[[self userCollection]setDataSource:self];
[[self userCollection]setDelegate:self];
[self dataJson];
NSLog(#"array: %#", namelabelArray);
}
-(NSInteger)numberOfSectionsInCollectionView:(UICollectionView *)collectionView
{
return 1;
}
-(NSInteger) collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section
{
return [namelabelArray count];
}
-(UICollectionViewCell *) collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *cellIdentifier = #"cell";
LabelCollectionViewCell *customCell = [collectionView dequeueReusableCellWithReuseIdentifier:cellIdentifier forIndexPath:indexPath];
[[customCell nameLabel]setText:[namelabelArray objectAtIndex:indexPath.item]];
[[customCell idLabel]setText:[idArray objectAtIndex:indexPath.item]];
return customCell;
}
-(void)dataJson
{
NSString *zipcode;
NSString *url = [NSString stringWithFormat:#"%#",#"http://inveera.biz/lowkall_api/index.php/product_cat"];
NSDictionary *params =[NSDictionary dictionaryWithObjectsAndKeys: zipcode,#"35005",nil];
NSLog(#"Login URL %#", params);
AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];
[manager POST:url parameters:params success:^(AFHTTPRequestOperation *operation, id responseObject) {
NSLog(#"Login JSON: %#", responseObject);
NSString *data = [responseObject valueForKey:#"data"];
idArray = [data valueForKey:#"id"];
namelabelArray =[data valueForKey:#"name"];
imagArray =[data valueForKey:#"img_path"];
NSLog(#"Error image: %#", imagArray);
[self.userCollection reloadData];
}
failure:^(AFHTTPRequestOperation *operation, NSError *error)
{
NSLog(#"Error: %#", error);
}];
}
My json response is
{
"status":"true",
"city":[{"cityname":"Acmar"}],
"data":[
{"id":"1","name":"Appliances","img_path":"categories\/1\/ac1.png","status":"1"},
{"id":"2","name":"Electronics","img_path":"categories\/2\/ac2.png","status":"1"},
{"id":"3","name":"Furniture","img_path":"categories\/3\/ac3.png","status":"1"},
{"id":"4","name":"Cars","img_path":"categories\/4\/ac4.png","status":"1"},
{"id":"5","name":"Pet Supplies","img_path":"categories\/5\/ac5.png","status":"1"},
{"id":"6","name":"Others","img_path":"categories\/6\/ac6.png","status":"1"}
]
}
I am able to bind name but unable to bind image with full path with domain
name.
Please help me out. Thanks in advance.
In AFNetworking Lib itself they have added one category class for UIImageView called UIImageView+AFNetworking to load images from URL, You need call below method with valid URL request.
- (void)setImageWithURLRequest:(NSURLRequest *)urlRequest
placeholderImage:(UIImage *)placeholderImage
success:(void (^)(NSURLRequest *request, NSHTTPURLResponse * _Nullable response, UIImage *image))success
failure:(void (^)(NSURLRequest *request, NSHTTPURLResponse * _Nullable response, NSError *error))failure
-(UICollectionViewCell *) collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *cellIdentifier = #"cell";
LabelCollectionViewCell *customCell = [collectionView dequeueReusableCellWithReuseIdentifier:cellIdentifier forIndexPath:indexPath];
[[customCell nameLabel]setText:[namelabelArray objectAtIndex:indexPath.item]];
[[customCell idLabel]setText:[idArray objectAtIndex:indexPath.item]];
[[customCell imageView] setImageWithURLRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:[imagArray objectAtIndex:indexPath.row]]]
placeholderImage:nil
success:nil
failure:^(NSURLRequest * _Nonnull request, NSHTTPURLResponse * _Nullable response, NSError * _Nonnull error) {
}];
return customCell;
}
First of all, instead of UIImage *imageArray; it should be NSString *imageURLString;
and then since you are using AFNetworking better to load images async (use #import UIImageView+AFNetworking.h).
NSURL *imageURL = [NSURL URLWithString:[NSString stringWithFormat:#"%#%#", self.baseURL, imageURLString]];
[self setImageWithURLRequest:[NSURLRequest requestWithURL:imageURL]
placeholderImage:placeholder
success:^(NSURLRequest *request, NSHTTPURLResponse *response, UIImage *image) {
if (image)
{
weakSelf.image = image;
}
} failure:^(NSURLRequest *request, NSHTTPURLResponse *response, NSError *error) {
}];

cellForItemAtIndexPath is Changing Multiple Cells When Should Change One

I may be not understanding the reusing of cells behaviour by the UICollectionView but can someone tell me why two cells are having their properties changed in cellForItemAtIndexPath when it should just be the one cell.
Here's my code.
-(UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath
{
PhotoCollectionViewCell *cell = (PhotoCollectionViewCell *) [collectionView dequeueReusableCellWithReuseIdentifier:#"PhotoCollectionViewCell" forIndexPath:indexPath];
if (![[self.userPhotos objectAtIndex:indexPath.row] isEqualToString:#""]){
NSString *photoUrl = [self.userPhotos objectAtIndex:indexPath.row];
NSURL *imageURL = [NSURL URLWithString: photoUrl];
NSURLRequest *imageRequest = [NSURLRequest requestWithURL:imageURL];
[cell.photoImageView setImageWithURLRequest:imageRequest placeholderImage:[UIImage imageNamed:#"anImage"] success:^(NSURLRequest *request, NSHTTPURLResponse *response, UIImage *image) {
cell.photoImageView.image = image;
cell.photoImageView.frame = CGRectMake(0, 0, 100.0f,100.0f);
cell.photoImageView.contentMode = UIViewContentModeScaleAspectFit;
[cell.deleteImageView setFrame:CGRectMake(-4.0f,-4.0f,28.0f,28.0f)];
cell.deleteImageView.layer.cornerRadius = cell.deleteImageView.frame.size.width / 2;
[cell.deleteImageView setAlpha:0.8f];
cell.deleteImageView.layer.borderWidth = 1.0f;
cell.deleteImageView.layer.borderColor = [UIColor redColor].CGColor;
} failure:^(NSURLRequest *request, NSHTTPURLResponse *response, NSError *error) {
NSLog(#"%#",[error localizedDescription]);
}];
}else{
cell.photoImageView.image = [UIImage imageNamed:#"camera"];
cell.photoImageView.layer.borderWidth = 1.0f;
cell.photoImageView.layer.borderColor = [UIColor lightGrayColor].CGColor;
NSLog(#"setting alpha & hiding delete");
cell.photoImageView.alpha = 0.4f;
[cell.deleteImageView setHidden:YES];
}
The code in the else part is being executed on cells 2 and 6 for example when it should just be 6. Although the logging says it's just executed on 6
Any idea where I'm going wrong?
Thanks.

How to Download Faster and Faster Image From Json Parsing with SDWebImageLibrary?

I make a Application that contain tableview with image and it Contain JSON Data.it is working Good But image downloading take upto 15minutes how do i fast?
My code for image Cache is
#define kBgQueue dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH,0)
- (void)viewDidLoad
{
[self.spinner startAnimating];
[super viewDidLoad];
Reachability *networkReachability = [Reachability reachabilityForInternetConnection];
NetworkStatus networkStatus = [networkReachability currentReachabilityStatus];
if (networkStatus == NotReachable)
{
UIAlertView *alert=[[UIAlertView alloc]initWithTitle:#"No Internet Avaliable" message:#"Please Check YOur Internet Connection" delegate:self cancelButtonTitle:#"Ok" otherButtonTitles:nil, nil];
[alert show];
}
else
{
pageNum=0;
self.imageArray =[[NSMutableArray alloc]init];
NSURL * url=[NSURL URLWithString:[NSString stringWithFormat:#"http://www.truemanindiamagazine.com/webservice/news.php?page=%d",pageNum]];
[self.newsTable setShowsHorizontalScrollIndicator:NO];
[self.newsTable setShowsVerticalScrollIndicator:NO];
[super viewDidLoad];
dispatch_async(kBgQueue, ^{
data = [NSData dataWithContentsOfURL: url];
[self performSelectorOnMainThread:#selector(fetchedData:) withObject:data waitUntilDone:YES];
});
}
}
-(void)fetchedData:(NSData *)responsedata
{
if (responsedata.length >0)
{
NSError* error;
self.json = [NSJSONSerialization JSONObjectWithData:responsedata options:kNilOptions error:&error];
if ([[_json objectForKey:#"data"] isKindOfClass:[NSArray class]])
{
NSArray *arr = (NSArray *)[_json objectForKey:#"data"];
[self.imageArray addObjectsFromArray:arr];
[self.newsTable reloadData];
NSLog(#"images,%#",self.imageArray);
}
if (self.imageArray.count == 0)
{
self.newsTable.scrollEnabled=NO;
}
else
{
self.newsTable.scrollEnabled=YES;
}
}
[self.spinner stopAnimating];
self.spinner.hidesWhenStopped=YES;
}
-(NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return self.imageArray.count;
}
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
if (self.imageArray == nil || self.imageArray.count <1)
{
return 0;
}
else
{
return 1;
}
}
-(CustumCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *Cellidentifier=#"Cell";
CustumCell *cell=[tableView dequeueReusableCellWithIdentifier:Cellidentifier];
if (cell ==nil)
{
NSArray *nib = [[NSBundle mainBundle] loadNibNamed:#"CustumCell" owner:self options:nil];
cell = [nib objectAtIndex:0];
}
{
[cell.spinner startAnimating];
NSDictionary *dict = [self.imageArray objectAtIndex:indexPath.section];
NSString *img2=[dict valueForKey:#"post_image"];
[cell.imagePhoto sd_setImageWithURL:[NSURL URLWithString:[img2 stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]] placeholderImage:[UIImage imageNamed:#"Setting.png"] options:SDWebImageHighPriority completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType, NSURL *imageURL)
{
[cell.spinner stopAnimating];
cell.spinner.hidesWhenStopped=YES;
}];
it Shows CashedImage Perfectly but take a time to Downloaded image that can not be cashed
please Give me Solution For that.

why the table view cells are messed up after refreshing some rows?

I am using UITableView to list some images from Internet. So i use AFNetworking's setImageWithURLRequest:placeholderImage:success:failure:methord, when the image is downloaded, i need to do some process then display. In order to refresh the processed image i use
[wTableView beginUpdates];
[wTableView reloadRowsAtIndexPaths:[NSArray arrayWithObjects:indexPath, nil] withRowAnimation:UITableViewRowAnimationNone];
[wTableView endUpdates];
in the success block. It seems this works when first time loaded, but when i scroll the tableview, the rows are messed up, also one row is disappeared and its easy to crash in the [wTableView endUpdates]; method. what's wrong with this method?
The related code snippet is as follows:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *tableIdentifier = #"cell";
CouponTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:tableIdentifier];
if (!cell) {
cell = [[CouponTableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:tableIdentifier];
}
[cell prepareForReuse];
NSArray *coupons = [mCoupons objectAtIndex:indexPath.section];
CouponDB *couponDB = [coupons objectAtIndex:indexPath.row];
NSString *thumbLink;
if (couponDB) {
[cell.textLabel setText:couponDB.couponInfo.company];
[cell.textLabel setFont:[UIFont boldSystemFontOfSize:CELL_LABEL_FONT_SIZE]];
[cell.textLabel setTextColor:[UIColor grayColor]];
[cell.textLabel setBackgroundColor:[UIColor clearColor]];
[cell.detailTextLabel setText:[NSString stringWithFormat:#"Expires:%#",couponDB.couponInfo.deadline]];
[cell.detailTextLabel setBackgroundColor:[UIColor clearColor]];
thumbLink = [self thumbLink:couponDB.couponInfo.imgURL];
[cell setNeedsLayout];
if (couponDB.redeem_status) {
UIImageView * __weak imageView = cell.imageView;
CouponTableController * __weak table = self;
UITableView *__weak wTableView = mTableView;
[cell.imageView setImageWithURLRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:thumbLink]] placeholderImage:nil success:^(NSURLRequest *request, NSHTTPURLResponse *response, UIImage *image) {
imageView.image = [table crossedImage:image];
#synchronized(wTableView){
[wTableView beginUpdates];
[wTableView reloadRowsAtIndexPaths:[NSArray arrayWithObjects:indexPath, nil] withRowAnimation:UITableViewRowAnimationNone];
[wTableView endUpdates];
}
} failure:^(NSURLRequest *request, NSHTTPURLResponse *response, NSError *error) {
NSLog(#"cell imageview load error:%#",error);
}];
} else {
[cell.imageView setImageWithURL:[NSURL URLWithString:thumbLink] placeholderImage:[UIImage imageNamed:#"default_cover.jpg"]];
}
}
if (![cell.backgroundView isKindOfClass:[CouponTableCellBackgroud class]]) {
cell.backgroundView = [[CouponTableCellBackgroud alloc] init];
}
return cell;
}
the first time the table is loaded(no scroll) is like this:
when you scroll down and up the table rows are messed up, which is like below:
Any suggestions are appreciated.
Try this, instead of reloading the cell. Declare a weak pointer to the cell
__weak UITableViewCell *weakCell = cell;
[cell.imageView setImageWithURLRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:thumbLink]] placeholderImage:nil success:^(NSURLRequest *request, NSHTTPURLResponse *response, UIImage *image) {
weakCell.imageView.image = [table crossedImage:image];
[weakCell setNeedsLayout];
} failure:^(NSURLRequest *request, NSHTTPURLResponse *response, NSError *error) {
NSLog(#"cell imageview load error:%#",error);
}];
Can you try this:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *SimpleTableIdentifier = #"YourResuseIdentifier";
CouponTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:tableIdentifier];
if(cell == nil)
{
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:SimpleTableIdentifier];
}
else
{
for (UIView *subview in cell.contentView.subviews)
[subview removeFromSuperview];
}
NSArray *coupons = [mCoupons objectAtIndex:indexPath.section];
CouponDB *couponDB = [coupons objectAtIndex:indexPath.row];
NSString *thumbLink;
if (couponDB) {
[cell.textLabel setText:couponDB.couponInfo.company];
[cell.textLabel setFont:[UIFont boldSystemFontOfSize:CELL_LABEL_FONT_SIZE]];
[cell.textLabel setTextColor:[UIColor grayColor]];
[cell.textLabel setBackgroundColor:[UIColor clearColor]];
[cell.detailTextLabel setText:[NSString stringWithFormat:#"Expires:%#",couponDB.couponInfo.deadline]];
[cell.detailTextLabel setBackgroundColor:[UIColor clearColor]];
thumbLink = [self thumbLink:couponDB.couponInfo.imgURL];
if (couponDB.redeem_status) {
UIImageView * __weak imageView = cell.imageView;
CouponTableController * __weak table = self;
UITableView *__weak wTableView = mTableView;
[cell.imageView setImageWithURLRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:thumbLink]] placeholderImage:nil success:^(NSURLRequest *request, NSHTTPURLResponse *response, UIImage *image) {
imageView.image = [table crossedImage:image];
[wTableView beginUpdates];
[wTableView reloadRowsAtIndexPaths:[NSArray arrayWithObjects:indexPath, nil] withRowAnimation:UITableViewRowAnimationNone];
[wTableView endUpdates];
} failure:^(NSURLRequest *request, NSHTTPURLResponse *response, NSError *error) {
NSLog(#"cell imageview load error:%#",error);
}];
} else {
[cell.imageView setImageWithURL:[NSURL URLWithString:thumbLink] placeholderImage:[UIImage imageNamed:#"default_cover.jpg"]];
}
}
if (![cell.backgroundView isKindOfClass:[CouponTableCellBackgroud class]]) {
cell.backgroundView = [[CouponTableCellBackgroud alloc] init];
}
return cell;
}
I change the load image code to
UIImageView * __weak imageView = cell.imageView;
CouponTableController * __weak table = self;
[cell.imageView setImageWithURLRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:thumbLink]] placeholderImage:[UIImage imageNamed:#"default_cover.jpg"] success:^(NSURLRequest *request, NSHTTPURLResponse *response, UIImage *image) {
imageView.image = [table crossedImage:image];
} failure:^(NSURLRequest *request, NSHTTPURLResponse *response, NSError *error) {
NSLog(#"cell imageview load error:%#",error);
}];
Only add one placeholder image and remove the tableview updates. then it refresh cells automatically.

iOS objectAtIndex beyond bounds

I have a table that is populated by an array of objects and whenever I call my refresh method that re-populates the array and reloads the table, when I try to read my array in cellForRowAtIndexPath I get a beyond bounds error. I have NSLogged my array to make sure it is populated correctly, and it is. It always is trying to read an index 1 larger than the array is actually. I have no idea why. Any help would be greatly appreciated!
cellForRowAtIndexPath:
- (UITableViewCell *)tableView:(UITableView *)theTableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
NSLog(#"IndexPath = %d", indexPath.row);
// Returns the cell for the given indexPath
static NSString *cellidentifier1 = #"cell1";
static NSString *cellidentifier2 = #"cell2";
self.tableView.backgroundColor = [UIColor colorWithPatternImage:[UIImage imageNamed:#"dark-background.jpg"]];
self.tableView.separatorColor = [UIColor colorWithPatternImage:[UIImage imageNamed:#"dark-background.jpg"]];
// Invisible Cell
if (indexPath.row % 2 == 0) {
UITableViewCell *cell2 = [theTableView dequeueReusableCellWithIdentifier:cellidentifier2];
if (cell2 == nil) {
cell2 = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellidentifier2];
}
[cell2.contentView setAlpha:0];
[cell2 setUserInteractionEnabled:NO];
[cell2 setBackgroundColor:[UIColor clearColor]];
return cell2;
}
// Standard Cell
FCTableViewCell *cell = (FCTableViewCell *)[theTableView dequeueReusableCellWithIdentifier:cellidentifier1];
if (cell == nil) {
cell = [[FCTableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellidentifier1];
}
FCCall *currentCall = [[dataController calls] objectAtIndex:((indexPath.row - 1 ) / 2)];
cell.callLabel.text = currentCall.call;
cell.locationLabel.text = currentCall.location;
cell.wcccaNumberLabel.text = currentCall.wcccaNumber;
cell.callNumberLabel.text = currentCall.callnumber;
// Remove leading white space from units string
NSString *units = [currentCall.units stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
cell.unitsLabel.text = units;
cell.stationLabel.text = currentCall.station;
if ([currentCall.county isEqualToString:#"W"]) {
cell.countyImageView.image = [UIImage imageNamed:#"blue.png"];
}
else {
cell.countyImageView.image = [UIImage imageNamed:#"green.png"];
}
if ([currentCall.callType isEqualToString:#"F"]) {
cell.callTypeImageView.image = [UIImage imageNamed:#"red.png"];
}
else {
cell.callTypeImageView.image = [UIImage imageNamed:#"yellow.png"];
}
[cell.unitButton addTarget:self action:#selector(unitButtonTapped:) forControlEvents:UIControlEventTouchUpInside];
cell.unitButton.tag = ((indexPath.section & 0xFFFF) << 16) |
(indexPath.row & 0xFFFF);
[cell.directionsButton addTarget:self action:#selector(directionsButtonTapped:) forControlEvents:UIControlEventTouchUpInside];
cell.directionsButton.tag = ((indexPath.section & 0xFFFF) << 16) |
(indexPath.row & 0xFFFF);
return cell;
}
numberOfRowsInSection:
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
// Returns the number of rows per section
return [dataController calls].count * 2;
}
refresh method:
[dataController refreshData:self success:^(NSURLRequest *request, NSURL *url, NSArray *calls) {
[self setWork:calls];
NSLog(#"Array = %#", work);
// Reset the pull controller and reload the table
[pull finishedLoading];
[tableView reloadData];
} failure:^(NSURLRequest *request, NSURL *url, NSError *error) {
// Reset pull indicator
[pull finishedLoading];
// Reload table
[tableView reloadData];
}];
refresh method:
- (void)refreshData:(id)object success:(void (^)(NSURLRequest *request, NSURL *url, NSArray *calls))success failure:(void (^)(NSURLRequest *request, NSURL *url, NSError *error))failure
{
NSLog(#"Refresh Started");
// Start the network activity indicator
[[UIApplication sharedApplication] setNetworkActivityIndicatorVisible:YES];
// Check to make sure we can even make an HTTP request
NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:#"http://www.wccca.com/PITS"]];
AFHTTPRequestOperation *requestOperation = [[AFHTTPRequestOperation alloc] initWithRequest:request];
[requestOperation setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject) {
NSLog(#"Reachable");
// Get the URL we are going to use to parse with
[FCDataController parserURL:[NSURL URLWithString:#"http://www.wccca.com/PITS"] completion:^(NSURL *url) {
NSURLRequest *parserRequest = [NSURLRequest requestWithURL:url];
AFXMLRequestOperation *operation = [AFXMLRequestOperation XMLParserRequestOperationWithRequest:parserRequest success:^(NSURLRequest *request, NSHTTPURLResponse *response, NSXMLParser *XMLParser) {
// Initialize our calls array that will control our calls
calls = [[NSMutableArray alloc] init];
// Set the delegate for the XMLParser and start the parse operation
XMLParser.delegate = self;
BOOL successful = [XMLParser parse];
// Determine if the parse operation was a success or not
if (!successful) {
// Return the failure block because the parser failed
failure(request, url, [FCErrors parserError]);
// Stop the network activity indicator
[[UIApplication sharedApplication] setNetworkActivityIndicatorVisible:NO];
}
else {
// Return the success block
success(request, url, calls);
// Stop the network activity indicator
[[UIApplication sharedApplication] setNetworkActivityIndicatorVisible:NO];
}
NSLog(#"Refresh Finished");
} failure:^(NSURLRequest *request, NSHTTPURLResponse *response, NSError *error, NSXMLParser *XMLParser) {
NSLog(#"AFXMLOperation Error: %#", error.localizedDescription);
// Remove all data from our previous calls aray
[self setCalls:nil];
failure(parserRequest, url, [FCErrors badURLError]);
// Stop the network activity indicator
[[UIApplication sharedApplication] setNetworkActivityIndicatorVisible:NO];
NSLog(#"Refresh Finished");
}];
[operation start];
}];
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
NSLog(#"Unreachable. AFHTTPRequestOperation Error: %#", error.localizedDescription);
// Remove all data from our previous calls aray
[self setCalls:nil];
failure(request, nil, [FCErrors networkError]);
// Stop the network activity indicator
[[UIApplication sharedApplication] setNetworkActivityIndicatorVisible:NO];
NSLog(#"Refresh Finished");
}];
[requestOperation start];
}

Resources