Why is my UITabeViewContent reorders everytime I refresh it? - ios

i have a UITebleView with costume UITableViewCells. Every time I refresh the them the content is reordering itself. anyone know why?
I am fatching the data from a JSON, I dont do some sort of sorting, I just display the data acording to the TableViewCell indexpath.row
And this is the code I set the UITableViewCell content:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *costumeCell = #"Cell";
StoreCell *cell = [tableView dequeueReusableCellWithIdentifier:costumeCell];
if (!cell) {
cell = [[StoreCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:costumeCell];
}
NSDictionary *dict;
dict = [application objectAtIndex:indexPath.row];
[downloadQueue addOperationWithBlock:^{
name = [dict objectForKey:#"name"];
detileName = [dict objectForKey:#"detailName"];
itmsLink = [dict objectForKey:#"itms-serviceLink"];
icon = [dict objectForKey:#"icon"];
developer = [dict objectForKey:#"developer"];
version = [dict objectForKey:#"version"];
category = [dict objectForKey:#"category"];
rating = [dict objectForKey:#"rating"];
ratingNumbers = [dict objectForKey:#"ratingNumber"];
description = [dict objectForKey:#"description"];
developerEmails = [dict objectForKey:#"developerEmail"];
cell.AppName.text = name;
cell.category.text = category;
cell.rater.text = [NSString stringWithFormat:#"(%#)", ratingNumbers];
if ([rating intValue] == 1) {
cell.rating.image = [UIImage imageNamed:#"1.png"];
}
if ([rating intValue] == 2) {
cell.rating.image = [UIImage imageNamed:#"2.png"];
}
if ([rating intValue] == 3) {
cell.rating.image = [UIImage imageNamed:#"3.png"];
}
if ([rating intValue] == 4) {
cell.rating.image = [UIImage imageNamed:#"4.png"];
}
cell.itms = itmsLink;
[NSURLConnection sendAsynchronousRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:icon]] queue:[NSOperationQueue mainQueue] completionHandler:^(NSURLResponse* response, NSData* data, NSError* error){
if(error)
{
// Error Downloading image data
cell.AppIcon.image = [UIImage imageNamed:#"placeholder.png"];
}
else
{
[cell.AppIcon setImage:[UIImage imageWithData:data]];
}
}];
cell.AppIcon.image = [UIImage imageWithData:[NSData dataWithContentsOfURL:[NSURL URLWithString:icon]]];
cell.number.text = [NSString stringWithFormat:#"%li", (long)indexPath.row + 1];
}];
cell.AppIcon.layer.masksToBounds = YES;
cell.AppIcon.layer.cornerRadius = 16.0;
cell.installButton.layer.masksToBounds = YES;
cell.installButton.layer.cornerRadius = 5.0f;
cell.installButton.layer.borderColor = [UIColor darkGrayColor].CGColor;
cell.installButton.layer.borderWidth = 1.0f;
return cell;
}

Since you're fetching from JSON, the server you got it from may not sort your data for you. Course its impossible for us to know what its doing without you divulging into the the server's APIs.
What you can do, without giving further info is just do a sort after you receive new data from the server:
NSSortDescriptor *descriptor = [[NSSortDescriptor alloc] initWithKey:#"name" ascending:YES];
NSArray *sortedApplicationArray = [application sortedArrayUsingDescriptors:#[descriptor]];
application = sortedApplicationArray;
Just don't put that code inside your cellForRowAtIndexPath, cos it'll do a sort each time a row is created!
I think I know what the problem is.
You have an asynchronous operation in your cellForRowAtIndexPath. You should set the cell UI elements directly with the dict object and outside the operation queue.
The only thing that looks like it needs to be done asynchronously is the image download. I recommend you use SDWebImage from github for that, it handles the download in its own queue and caches the image in memory and on disk.

Related

How to improve load image in UITableview?

I have a problem when i load imageview in table view. It's Loading so slowly. I use a lot of section in my table view. There is my code:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
TrangChuTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"CellTrangchu" forIndexPath:indexPath];
theGame *thegameObj;
if([indexPath section] == 0){
thegameObj = [theZingArray objectAtIndex:indexPath.row];
}else if([indexPath section] == 1){
thegameObj = [theBitArray objectAtIndex:indexPath.row];
}else if([indexPath section] == 2){
thegameObj = [theMobayArray objectAtIndex:indexPath.row];
}else if([indexPath section] == 3){
thegameObj = [theGateArray objectAtIndex:indexPath.row];
}else if([indexPath section] == 4){
thegameObj = [theVcoinArray objectAtIndex:indexPath.row];
}else if([indexPath section] == 5){
thegameObj = [theGarenaArray objectAtIndex:indexPath.row];
}else if([indexPath section] == 6){
thegameObj = [theOncashArray objectAtIndex:indexPath.row];
}else if([indexPath section] == 7){
thegameObj = [theMobiphoneArray objectAtIndex:indexPath.row];
}else if([indexPath section] == 8){
thegameObj = [theVinaphoneArray objectAtIndex:indexPath.row];
}else if([indexPath section] == 9){
thegameObj = [theViettelArray objectAtIndex:indexPath.row];
}
NSURL *urlImage = [NSURL URLWithString:thegameObj.image];
NSData *imageData = [NSData dataWithContentsOfURL:urlImage];
cell.txtQuantity.text=#"1";
UIImage *image= [UIImage imageWithData:imageData];
cell.imageView.layer.cornerRadius=5;
cell.imageView.layer.masksToBounds=YES;
cell.imageView.image = image;
cell.labelName.text = thegameObj.objectName;
if([[AppDelegate appDelegate]checkIP])
{
[cell.txtQuantity setBackgroundColor:[UIColor whiteColor]];
[cell.txtQuantity.layer setBorderColor:[UIColor grayColor].CGColor];
[cell.txtQuantity.layer setBorderWidth:1.0];
[cell.txtQuantity.layer setCornerRadius:5];
cell.labelPrice.text = [NSString stringWithFormat:#"%# (%#)", [NSNumberFormatter localizedStringFromNumber:thegameObj.price numberStyle:NSNumberFormatterDecimalStyle], loadCurrency];
}
else
{
[cell.lbdetail setTitle:#"detail" forState:UIControlStateNormal];
cell.txtQuantity.hidden=YES;
cell.labelPrice.hidden=YES;
cell.lbgia.hidden=YES;
cell.lbsl.hidden=YES;
cell.lbdetail.hidden=YES;
}
cell.objArray = thegameObj;
cell.currency = loadCurrency;
/*
[cell.addToCartButton addTarget:self action:#selector(addToCart:) forControlEvents:UIControlEventTouchUpInside];
cell.addToCartButton.tag = [NSString stringWithFormat:#"%d_%d", (NSInteger)[indexPath section], (NSInteger)[indexPath row]];
*/
cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
return cell;
}
Please help me improve more faster load image with alot of section in UItableview. Thank you for any solution!
One thing that will help is a data structure that matches a sectioned table model, which is an array of arrays. You're almost there, since you have all of the sub-arrays. Build one like this (when all the sub-arrays are built, not in cellForRow):
NSArray *model = #[ theZingArray, theBitArray, /*... and so on */];
That will let you flatten the big conditional to one line:
thegameObj = model[indexPath.section][indexPath.row];
You can use that elsewhere, like in numberRowsInSection
NSArray *sectionArray = model[indexPath.section];
return sectionArray.count;
The slightly tougher problem is to have those images load async and get cached. A fully native approach is discussed here and many others.
Applying this idea to your code, here's a method that returns either a cached image, or fetches, caches and returns...
// declare this and BE SURE TO INITIALIZE IT
#property(strong,nonatomic) NSMutableDictionary *imageCache;
// return an image found at the url string, if one is cached return it, otherwise,
// fetch it, cache it and return it
- (void)imageAtURLString:(NSString *)urlString completion:(void(^)(UIImage *, BOOL))completion {
if (self.imageCache[urlString]) { // if it's cached
completion(self.imageCache[urlString], YES);
} else { // fetch and cahce
NSURL *url = [NSURL URLWithString:urlString];
NSURLSessionTask *task = [[NSURLSession sharedSession] dataTaskWithURL:url completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
if (data) {
UIImage *image = [UIImage imageWithData:data];
if (image) {
self.imageCache[urlString] = image;
dispatch_async(dispatch_get_main_queue(), ^{
completion(image, NO);
});
}
}
}];
[task resume];
}
}
Now your simplified cellForRowAtIndexPath can look like this:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"cellid"]; // fixme
theGame *thegameObj = model[indexPath.section][indexPath.row];
NSString *urlString = thegameObj.image;
UIImageView *imageView = cell.imageView;
[self imageAtURLString:urlString completion:^(UIImage *image, BOOL wasCached) {
if (wasCached) imageView.image = image;
else [tableView reloadRowsAtIndexPaths:#[indexPath] withRowAnimation:UITableViewRowAnimationAutomatic];
}];
return cell;
}
The idea here is that you either have a cached image, in which case, just set the cell's imageView image to that, or you had to fetch one. In the case of the fetch, it's uncertain whether the row got scrolled away during the fetch. Reload the current row to cause it to update with the (now cached) image.
There is concept of image caching with which image view loads images asynchronously in background. Refer following link
https://github.com/nicklockwood/AsyncImageView
Use following awesome library for download image in background.
https://github.com/rs/SDWebImage
UIImageView * thumbnail = [[UIImageView alloc] init];
NSURL *urlToPicture1 = [NSURL URLWithString:currentMarker.thumbnail];
[thumbnail sd_setImageWithURL:urlToPicture1 placeholderImage:[UIImage imageNamed:#"placeholder.png"] options:SDWebImageProgressiveDownload completed:^(UIImage * image, NSError * error,SDImageCacheType cachedType, NSURL * imageURL){
if(image){
[thumbnail setImage:image];
NSLog(#"Complete = %d, error = %#",cachedType, error);
}
}];

ios tableview image load duplicate when scrolling tableview

I make two custom cell and display in single UITableView in odd even orders, but when i scroll UITableView all image and schedule data color will change randomly and duplicate data will displayed but name,exp., pri-zone, and rate which is in string they all display proper,only image and color of schedule text will change.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath: (NSIndexPath *)indexPath
{
if (indexPath.row % 2 == 0) {
static NSString *cellIdentifier=#"MyCustomCell";
TableViewCell *cell=[tblResponseData dequeueReusableCellWithIdentifier:cellIdentifier];
if (cell == nil)
{
cell = [[TableViewCell alloc] initWithStyle:UITableViewCellStyleValue1
reuseIdentifier:cellIdentifier];
}
NSString *imgPath=[[arrData objectAtIndex:indexPath.row]valueForKey:#"Pic"];
// NSString *imgPath=[[appDelegate.arrData
objectAtIndex:indexPath.row]valueForKey:#"image"];
NSURL *url = [NSURL URLWithString:[imgPath
stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]];
NSString *schedule =[[arrData objectAtIndex:indexPath.row]valueForKey:#"Schedule"];
NSArray *strings = [schedule componentsSeparatedByString:#","];
//NSURL *url = [NSURL URLWithString:url];
[NSURLConnection sendAsynchronousRequest:[NSURLRequest requestWithURL:url]
queue:[NSOperationQueue currentQueue]
completionHandler:^(NSURLResponse * resp, NSData * data, NSError
* error)
{
if(error == NULL){
// here is our image
UIImage *image = [UIImage imageWithData:data];
cell.imgThumbnail.image=image;
}
else{
cell.imgThumbnail.image=[UIImage imageNamed:#"no preview 2.jpeg"];
}
}];
for (NSString *item in strings)
{
if ([item isEqualToString:#"Su"]) {
cell.lblsu.textColor = [UIColor greenColor];
}else if ([item isEqualToString:#"Tu"]){
cell.lblt.textColor = [UIColor greenColor];
}else if ([item isEqualToString:#"Th"]){
cell.lblth.textColor = [UIColor greenColor];
}
else if ([item isEqualToString:#"M"]){
cell.lblm.textColor = [UIColor greenColor];
}
else if ([item isEqualToString:#"F"]){
cell.lblf.textColor = [UIColor greenColor];
}
else if ([item isEqualToString:#"S"]){
cell.lbls.textColor = [UIColor greenColor];
}
else if ([item isEqualToString:#"W"]){
cell.lblw.textColor = [UIColor greenColor];
}
}
cell.lblname.text = [[arrData objectAtIndex:indexPath.row] valueForKey:#"Worker Name"];
cell.lblexperience.text=[[arrData o
bjectAtIndex:indexPath.row]valueForKey:#"Experience"];
cell.lblprizone.text=[[arrData objectAtIndex:indexPath.row]valueForKey:#"Primary
Zone"];
cell.lblrate.text=[[arrData objectAtIndex:indexPath.row]valueForKey:#"Rate"];
return cell;
} else {
static NSString *cellIdentifier1=#"MyCustomCell1";
TableViewCell *cell1=[tblResponseData d
equeueReusableCellWithIdentifier:cellIdentifier1];
if (cell1 == nil)
{
cell1 = [[TableViewCell alloc] initWithStyle:UITableViewCellStyleValue1
reuseIdentifier:cellIdentifier1];
}
NSString *imgPath=[[arrData objectAtIndex:indexPath.row]valueForKey:#"Pic"];
// NSString *imgPath=[[appDelegate.arrData
objectAtIndex:indexPath.row]valueForKey:#"image"];
NSURL *url = [NSURL URLWithString:[imgPath
stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]];
//NSURL *url = [NSURL URLWithString:url];
[NSURLConnection sendAsynchronousRequest:[NSURLRequest requestWithURL:url]
queue:[NSOperationQueue currentQueue]
completionHandler:^(NSURLResponse * resp, NSData * data, NSError
* error)
{
if(error == NULL){
// here is our image
UIImage *image = [UIImage imageWithData:data];
cell1.imgThumbnail.image=image;
}
else{
cell1.imgThumbnail.image=[UIImage imageNamed:#"no preview 2.jpeg"];
}
}];
// NSURL *imageUrl = [NSURL URLWithString:imgPath];
// NSData *imageData = [NSData dataWithContentsOfURL:url];
// UIImage *image=[[UIImage alloc]initWithData:imageData];
// cell.imgThumbnail.image=image;
NSString *schedule =[[arrData objectAtIndex:indexPath.row]valueForKey:#"Schedule"];
NSArray *strings = [schedule componentsSeparatedByString:#","];
for (NSString *item in strings)
{
if ([item isEqualToString:#"Su"]) {
cell1.lblsu.textColor = [UIColor greenColor];
}else if ([item isEqualToString:#"Tu"]){
cell1.lblt.textColor = [UIColor greenColor];
}else if ([item isEqualToString:#"Th"]){
cell1.lblth.textColor = [UIColor greenColor];
}
else if ([item isEqualToString:#"M"]){
cell1.lblm.textColor = [UIColor greenColor];
}
else if ([item isEqualToString:#"F"]){
cell1.lblf.textColor = [UIColor greenColor];
}
else if ([item isEqualToString:#"S"]){
cell1.lbls.textColor = [UIColor greenColor];
}
else if ([item isEqualToString:#"W"]){
cell1.lblw.textColor = [UIColor greenColor];
}
}
cell1.lblname.text = [[arrData objectAtIndex:indexPath.row] valueForKey:#"Worker N
ame"];
cell1.lblexperience.text=[[arrData
objectAtIndex:indexPath.row]valueForKey:#"Experience"];
cell1.lblprizone.text=[[arrData objectAtIndex:indexPath.row]valueForKey:#"Primary
Zone"];
cell1.lblrate.text=[[arrData objectAtIndex:indexPath.row]valueForKey:#"Rate"];
return cell1;
}
}
I think it might be because you load your images by NSURLConnection sendAsynchronousRequest. Because the completitionhandler isn't called immediately, but when the data is returned to the request. So the images will be set after the cells are loaded.
Try to replace
[NSURLConnection sendAsynchronousRequest:[NSURLRequest requestWithURL:url]
queue:[NSOperationQueue currentQueue]
completionHandler:^(NSURLResponse * resp, NSData * data, NSError
* error)
{
if(error == NULL){
// here is our image
UIImage *image = [UIImage imageWithData:data];
cell1.imgThumbnail.image=image;
}
else{
cell1.imgThumbnail.image=[UIImage imageNamed:#"no preview 2.jpeg"];
}
}];
with code that will set imgThumbnail.image to an image that is in your project and see whether you still get radomly changing cells.
Problem: You are using dequeueReusableCellWithIdentifier so the same cell is reused when you are scrolling the tableview and you are send a AsynchronousRequest in that cell so the previously sent cell response we are receiving on another cell so it is showing different result.
For example: Cell 2 you are sending a request and then you scrolled the table view so the same cell is reused for cell 10 by that time you will receive the response of cell 2 send request and that image (response data) is displayed in cell 10.
Solution: send the request in separate method and save the images in array or dictionary then reload the corresponding cells based on the the received response.
For Example:EGOImageView is sending request asynchronously and saving in cache and displaying after receiving response please check that once
try this one ,for loading the images From webservices.
NSString *imgUrl = [[arrCategoryDetails objectAtIndex:indexPath.row]valueForKey:#"Image"];
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
NSData *imgData = [NSData dataWithContentsOfURL:[NSURL URLWithString:imgUrl]];
if (imgData) {
UIImage *image = [UIImage imageWithData:imgData];
if (image) {
dispatch_async(dispatch_get_main_queue(), ^{
CategoryDetailsTableCell *updateCell = (id)[tableView cellForRowAtIndexPath:indexPath];
if (updateCell)
updateCell.imgForCategoryDetailCell.image = image;
});
}
}
});

Loading imageviews with AFNetworking via JSON hierarchy and objectForKey

Very new to AFNetworking, but after many SO questions... I've concluded that this is the solution to my issue.
I've got a hierarchy of JSON data loading my TableViewController cells dynamically. All of my text strings are loading appropriately but the image from my URL is not making it to my imageview.
Before utilizing the AFNetworking library, I had the images loaded, but I was experiencing some issues with the photos not staying loaded when I scrolled away and returned (they had to load again.)
What am I missing to get my images in there?
TableViewController.m
-(void)viewDidLoad {
[super viewDidLoad];
// Set the side bar button action. When it's tapped, it'll show up the sidebar.
siderbarButton.target = self.revealViewController;
siderbarButton.action = #selector(revealToggle:);
// Set the gesture
[self.view addGestureRecognizer:self.revealViewController.panGestureRecognizer];
self.tableView.backgroundColor = [UIColor whiteColor];
self.parentViewController.view.backgroundColor = [UIColor colorWithRed:1.0 green:1.0 blue:1.0 alpha:1];
self.navigationItem.titleView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:#"logo_app_white.png"]];
NSURL *myURL = [[NSURL alloc]initWithString:#"http://domain.com/json2.php"];
NSData *myData = [[NSData alloc]initWithContentsOfURL:myURL];
NSError *error;
jsonArray = [NSJSONSerialization JSONObjectWithData:myData options:NSJSONReadingMutableContainers error:&error];
[tableView reloadData]; // if tableView is unidentified make the tableView IBOutlet
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
// Return the number of rows in the section.
return jsonArray.count;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
NeedCardTableViewCell *cell = (NeedCardTableViewCell *) [tableView dequeueReusableCellWithIdentifier:#"needCard"];
if (cell == nil)
{
cell = [[NeedCardTableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:#"needCard"];
}
NSDictionary *needs = jsonArray[indexPath.row]; // get the data dict for the row
cell.textNeedTitle.text = [needs objectForKey: #"needTitle"];
cell.textNeedPoster.text = [needs objectForKey: #"needPoster"];
cell.textNeedDescrip.text = [needs objectForKey: #"needDescrip"];
AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];
[manager GET:#"userImage" parameters:nil success:^(AFHTTPRequestOperation *operation, id responseObject) {
NSLog(#"JSON: %#", responseObject);
_imageProfPic.image = responseObject;
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
NSLog(#"Error: %#", error);
}];
return cell;
}
Have you tried using the AFNetworking+UIImageView category? You can then call:
[_imageProfPic setImage:[NSURL URLWithString:#"http://myimageurl.com/imagename.jpg"]];
This will make a request and then set the returned image to your UIImageView's UIImage without you having to do anything else. You should also consider initializing NSURLCache in your AppDelegate:
NSURLCache *cache = [[NSURLCache alloc] initWithMemoryCapacity:4 * 1024 * 1024
diskCapacity:10 * 1024 * 1024
diskPath:nil];
[NSURLCache setSharedURLCache:cache];
Take a look at NSHipster's run down on NSURLCache. This will help reload images, and all your requests, much faster the second time around. This is increasingly important when dealing with images and tables.
Manage to figure this one out with the use of this tutorial:
Networking Made Easy with AFNetworking
I used the final snippet of code to get my desired result:
NSURL *url = [[NSURL alloc] initWithString:[movie objectForKey:#"artworkUrl100"]];
[cell.imageView setImageWithURL:url placeholderImage:[UIImage imageNamed:#"placeholder"]];
I cut the second line of his code because I already have an if statement in my PHP/JSON
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
NeedCardTableViewCell *cell = (NeedCardTableViewCell *) [tableView dequeueReusableCellWithIdentifier:#"needCard"];
if (cell == nil)
{
cell = [[NeedCardTableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:#"needCard"];
}
NSDictionary *needs = jsonArray[indexPath.row]; // get the data dict for the row
cell.textNeedTitle.text = [needs objectForKey: #"needTitle"];
cell.textNeedPoster.text = [needs objectForKey: #"needPoster"];
cell.textNeedDescrip.text = [needs objectForKey: #"needDescrip"];
NSURL *url = [[NSURL alloc] initWithString:[needs objectForKey:#"userImage"]];
[cell.imageProfPic setImageWithURL:url];
return cell;
}
It worked like a charm, and the tutorial was pretty helpful since I'm a rookie with AFNetworking.

Populate UITableView via a string?

I have a simple iOS app which parses multiple JSON feeds and stores the data in multiple strings. I know exactly which strings to use for what and how long the count is because the JSON feeds are feeds that I control from some of my websites.
However, even though I have specified this in the "tableView cellForRowAtIndexPath" method, the UITableView still won't populate..
Is this because I am using strings to populate the UITableView? And if so, do you HAVE to use arrays to populate a UITableView.
Thanks for you're time :)
UPDATE: Here is m code:
-(NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return 1;
}
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return 5;
}
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
NSLog(#"Printing table view.");
static NSString *CellIdentifier = #"Cell";
AccountCell *cell = (AccountCell *)[account_table dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
NSArray *nib = [[NSBundle mainBundle] loadNibNamed:#"AccountCell" owner:self options:nil];
cell = [nib objectAtIndex: 0];
// Draws the cell background.
cell.backgroundView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:#"uiFeedletsnglass5.png"]];
// Draws the pressed cell background.
cell.selectedBackgroundView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:#"cell-on.png"]];
// Round of edges of content view in Carousel.
cell.layer.cornerRadius = 5;
cell.layer.masksToBounds = YES;
cell.layer.borderWidth = 1.0f;
cell.layer.borderColor = [[UIColor grayColor] CGColor];
cell.profilepic.layer.cornerRadius = 5;
cell.profilepic.layer.masksToBounds = YES;
cell.profilepic.layer.borderWidth = 1.0f;
cell.profilepic.layer.borderColor = [[UIColor grayColor] CGColor];
}
if ((facebook_printed == 0) && (logged_facebook == 1)) {
NSString *full_name = [NSString stringWithFormat:#"%# %#", facebook_first_name, facebook_last_name];
cell.username.text = [NSString stringWithFormat:#"%#", full_name];
cell.account_type_name.text = [NSString stringWithFormat:#"Facebook"];
NSData *facebook_imageData = [[NSData alloc] initWithContentsOfURL:[NSURL URLWithString: facebook_proffile_pic]];
UIImage *facebook_image = [[UIImage alloc] initWithData:facebook_imageData];
cell.profilepic.image = facebook_image;
facebook_printed = 1;
}
else if ((youtube_printed == 0) && (logged_youtube == 1)) {
cell.username.text = [NSString stringWithFormat:#"%#", youtube_profilename];
cell.account_type_name.text = [NSString stringWithFormat:#"YouTube"];
NSData *youtube_imageData = [[NSData alloc] initWithContentsOfURL:[NSURL URLWithString: youtube_profilepic]];
UIImage *youtube_image = [[UIImage alloc] initWithData:youtube_imageData];
cell.profilepic.image = youtube_image;
youtube_printed = 1;
}
else if ((instagram_printed == 0) && (logged_instagram == 1)) {
cell.username.text = [NSString stringWithFormat:#"%#", instagram_name_tag];
cell.account_type_name.text = [NSString stringWithFormat:#"Instagram"];
NSData *instagram_imageData = [[NSData alloc] initWithContentsOfURL:[NSURL URLWithString: instagram_profilepicture]];
UIImage *instagram_image = [[UIImage alloc] initWithData:instagram_imageData];
cell.profilepic.image = instagram_image;
instagram_printed = 1;
}
else if ((googleplus_printed == 0) && (logged_googleplus == 1)) {
cell.username.text = [NSString stringWithFormat:#"%#", googleplus_profilename];
cell.account_type_name.text = [NSString stringWithFormat:#"Google Plus"];
NSData *googleplus_imageData = [[NSData alloc] initWithContentsOfURL:[NSURL URLWithString: googleplus_profilepic]];
UIImage *googleplus_image = [[UIImage alloc] initWithData:googleplus_imageData];
cell.profilepic.image = googleplus_image;
googleplus_printed = 1;
}
[[UIApplication sharedApplication] setNetworkActivityIndicatorVisible:NO];
return cell;
}
Maybe try reloading the table view's data once you obtain the value of the string?
[tableView reloadData];
Right after much frustration and pretty much a lot of trial and error I finally figured out that it is because of if (cell == nil) that my Custom Cell was not loading (showing in the UITableView).
I was not aware of this at all, but from what I have read online it seems that when using UiTableViews in Storyboard UI's with Custom Cells, you are NOT meant to use the control statement if (cell == nil)
Thanks to everyone who commented on this post though. I appreciate you're help.

redundant calculations slowing down UITableView

I am creating a scrollable UITableView in which each cell requires to make a call to the Google Directions Matrix API.For some reason,each time I scroll it makes the call and does the calculations separately which significantly takes a toll on the responsiveness of the scrolling.Here's the code:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
if(tableView.tag == 1) {
return [self specialTableViewCell: tableView];
}
static NSString *CellIdentifier = #"OfferCell";
OTNOfferCell *cell = (OTNOfferCell*)[tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil)
{
// create cell using style Subtitle
cell = [[OTNOfferCell alloc] initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:CellIdentifier];
}
PFObject *venue = [self.venues objectAtIndex:indexPath.section];
cell.backgroundView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:#"MainPage Item.png"]];
cell.selectedBackgroundView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:#"MainPageItemSelected.png"]];
cell.clubNameLabel.text = [venue valueForKey: #"name"] ;
PFFile *photo = [venue objectForKey:#"logo"];
NSData *data = [photo getData];
UIImage *image = [UIImage imageWithData: data];
cell.clubLogoImageView.image = image;
int count = [[venue valueForKey:#"events"] count];
if(count == 1)
{
cell.numberOfEventsLabel.text = #"1 Event";
}
else
{
cell.numberOfEventsLabel.text = [NSString stringWithFormat:#"%d Events", count];
}
PFGeoPoint *destinationLocation = [venue objectForKey:#"geopoint"];
locationManager = [[CLLocationManager alloc] init];
locationManager.distanceFilter = kCLDistanceFilterNone;
locationManager.desiredAccuracy = kCLLocationAccuracyHundredMeters;
[locationManager startUpdatingLocation];
PFGeoPoint *currentLocation = [PFGeoPoint geoPointWithLatitude:locationManager.location.coordinate.latitude longitude:locationManager.location.coordinate.longitude];
NSString *current = [venue objectForKey:#"address"];
NSLog(#"%#",current);
NSString *urlString = [NSString stringWithFormat:#"http://maps.googleapis.com/maps/api/distancematrix/json?origins=%#&destinations=San+Francisco&mode=driving&language=en&sensor=true&units=imperial",current];
NSURL *url = [NSURL
URLWithString:[urlString
stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]];
NSData *googledata = [NSData dataWithContentsOfURL:url];
NSError *error;
NSMutableDictionary *json = [NSJSONSerialization JSONObjectWithData:googledata options:kNilOptions error:&error];
NSString *result = [[[[[[json objectForKey:#"rows"] objectAtIndex: 0] objectForKey:#"elements"] objectAtIndex:0]objectForKey:#"distance"]objectForKey:#"text"];
double tempd = [currentLocation distanceInMilesTo:destinationLocation];
NSString *distance = [NSString stringWithFormat:#"%f",tempd];
NSString *distanceTrunc = [distance substringToIndex: MIN(3, [distance length])];
cell.distanceLabel.text = [NSString stringWithFormat:#"%# mi", distanceTrunc];
return cell;
}
Is there any way to fix this,wherein the calculation is done only once.
You should not be making these calculations in the cell. UITableViewCells are part of the view layer.
You should make the requests in your controller and store the results in something like an NSArray. Then cellForRowAtIndexPath should just pull data from that array.

Resources