IOS- Adding date and time in TableViewCell with text [duplicate] - ios

This question already has answers here:
Formatting date and time in UITableView cells
(3 answers)
Closed 7 years ago.
in my project i am working on comment section i take a UITextfield to enter a comment and a UITableView to show the comments when Post comment button pressed.
All i want to show the Current date and time along with the commented text in the same cell like as in faceBook which shows date and time with comment.
please suggest me some code what i have to apply to show it
currently i am using the following code to put text input to UITableView
here i created custom label in table view cell
detaillabel = [[UILabel alloc]initWithFrame:CGRectMake(100, 0, 55, 45) ];
detaillabel.text = #"";
[cell.contentView addSubview:detaillabel];
Post Comment codes:
-(IBAction)postcomment:(id)sender;
{
NSError *error;
NSDate *currDate = [NSDate date];
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc]init];
[dateFormatter setDateFormat:#"dd.MM.YY HH:mm:ss"];
NSString *dateString = [dateFormatter stringFromDate:currDate];
detaillabel.text=dateString;
NSFileManager *filemanager = [NSFileManager defaultManager];
NSMutableDictionary *messageDictionary = [NSMutableDictionary new];
NSArray *array = NSSearchPathForDirectoriesInDomains(NSDocumentationDirectory, NSUserDomainMask, YES);
NSString *messageString = [array objectAtIndex:0];
NSString *datallist =[messageString stringByAppendingPathComponent:#"message.plist"];
if(commentsarray == Nil)
{
commentsarray = [[NSMutableArray alloc]init];
}
NSInteger contactid = 0;
if(datallist)
{
BOOL isFileExist = [filemanager fileExistsAtPath:datallist];
if(isFileExist)
{
commentsarray = [NSMutableArray arrayWithContentsOfFile:datallist];
}
}
if(commentsarray.count >0)
{
NSDictionary *dic = [commentsarray objectAtIndex:(commentsarray.count - 1)];
NSInteger val = [[dic objectForKey:#"id"] integerValue];
contactid = val+1;
}
else{
contactid = 1;
}
[messageDictionary setObject:[NSNumber numberWithInteger:contactid] forKey:#"id"];
[messageDictionary setObject:messageText.text forKey:#"id"];
[commentsarray addObject:messageDictionary];
NSData *data = [NSPropertyListSerialization dataFromPropertyList:commentsarray format:NSPropertyListXMLFormat_v1_0 errorDescription:&error];
if(data)
{
[data writeToFile:datallist atomically:YES];
[commentstable reloadData];
//[messagingtable scrollToRowAtIndexPath:[NSIndexPath indexPathForRow: messagearray.count-1 inSection:0] atScrollPosition:UITableViewScrollPositionBottom animated:YES];
[commentstable scrollToRowAtIndexPath:[NSIndexPath indexPathForRow:commentsarray.count-1 inSection:0] atScrollPosition:UITableViewScrollPositionBottom animated:YES];
}
else
{
NSLog(#"Error in save data: %#",error);
}
}

You can use NSDateComponent and NSDate. See Apple's Date and Time Programming Guide

Related

Parse filename for label Xcode

The code below returns weather data. All works fine except for the current weather description. For example, if todaysimage file name is partlycloudyv3.png. The description shows as partlycloudy in my app. How can I make it appear as partly cloudy?
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
NSArray *theView = [[NSBundle mainBundle] loadNibNamed:#"HipSkin01" owner:self options:nil];
UIView *nv = [theView objectAtIndex:0];
NSString *filePathDocArray = [DOCUMENTS stringByAppendingPathComponent:#"r.plist"];
NSFileManager *fileManager = [NSFileManager defaultManager];
if ([fileManager fileExistsAtPath:filePathDocArray]) {
NSLog(#"The file exists");
dataz = [[NSMutableDictionary alloc] initWithContentsOfFile:filePathDocArray];
NSLog(#"The file exists %#",dataz);
NSLog(#"The array: %i",(int) [dataz count]);
}
NSString *todaysimage = [dataz valueForKey:#"icon"];
[self.weatherIcon setImage:[UIImage imageNamed:[NSString stringWithFormat:#"%#v3.png", todaysimage]]];
NSArray *arr1 = [dataz objectForKey:#"display_location"];
NSString *plasez = [arr1 valueForKey:#"full"];
//NSString *plasez = [arr1 valueForKey:#"city"];
[self.plase setText:plasez];
//DataFormater
NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
[formatter setDateFormat:#"MMM dd, YYYY"];
[formatter setDateStyle:NSDateFormatterMediumStyle];
NSString *dateToday = [formatter stringFromDate:[NSDate date]];
[self.dataLable setText:dateToday];
[self.nameWeather setText:todaysimage];
//temp
NSString *tempzC = [dataz valueForKey:#"feelslike_c"];
NSString *tempzF = [dataz valueForKey:#"feelslike_f"];
NSString *terC = [NSString stringWithFormat:#"%#°C",tempzC];
NSString *terF = [NSString stringWithFormat:#"%#°F",tempzF];
[self.temprC setText:terC];
[self.temprF setText:terF];
[self addSubview:nv];
}
return self;
}
I added these lines and the parsing issue was solved. I was referencing the incorrect item in the weather API.
NSString *todaysimage2 = [dataz valueForKey:#"weather"];
[self.weatherIcons setImage:[UIImage imageNamed:[NSString stringWithFormat:#"%#v3.png", todaysimage]]];
[self.weatherData setText:dateToday];
[self.weatherText setText:todaysimage2];

Loading text from .txt file iOS

I've been trying to convert a Quiz app that was based for Mac OS to iOS because I liked the idea of loading all questions from a single .txt file.
I'm still pretty new in the Objective-C language as I've used C# before.
The questions and answers are loaded via this function:
- (void)loadQuestionsAndAnswersArray {
NSString *filePath = [[NSBundle mainBundle] pathForResource:#"Quiz1" ofType:#"txt"];
NSString *textFileString = [NSString stringWithContentsOfFile:filePath encoding:NSStringEncodingConversionAllowLossy error:NULL];
NSArray *seperatedQA = [textFileString componentsSeparatedByString:#"\n\n"];
for (NSString *QA in seperatedQA) {
NSString *questionString = [[[QA componentsSeparatedByString:#"\n"] objectAtIndex:0] stringByReplacingOccurrencesOfString:#"Q:" withString:#""];
NSMutableArray *answers = [[QA componentsSeparatedByString:#"A:"] mutableCopy];
[answers removeObjectAtIndex:0];
int correctAnswerLoc = 0;
for (int i = 0; i < answers.count; i++) {
NSString *answer = [answers objectAtIndex:i];
NSString *editedAnswer = [answer stringByReplacingOccurrencesOfString:#"\n" withString:#""];
editedAnswer = [editedAnswer stringByTrimmingCharactersInSet:
[NSCharacterSet whitespaceAndNewlineCharacterSet]];
[answers removeObjectAtIndex:i];
[answers insertObject:editedAnswer atIndex:i];
answer = editedAnswer;
if ([answer rangeOfString:#"[CORRECT]"].location != NSNotFound) {
correctAnswerLoc = [answers indexOfObject:answer];
NSString *editedAnswer = [answer stringByReplacingOccurrencesOfString:#"[CORRECT]" withString:#""];
[answers removeObjectAtIndex:i];
[answers insertObject:editedAnswer atIndex:i];
}
}
NSLog(#"answers = %#", answers);
NSDictionary *QADictionary = [NSDictionary dictionaryWithObjectsAndKeys:questionString, #"question", answers, #"answers", [NSNumber numberWithInt:correctAnswerLoc], #"correctAnswerLocation", nil];
[questionsAndAnswers addObject:QADictionary];
}
resultsArray = [[NSMutableArray alloc] initWithCapacity:[questionsAndAnswers count]];
}
The app then has a text field for the question and then 3 buttons, one for each answer. And when a new questions appears it changes the text within the text field and the title of the buttons.
This code works like a charm on the Mac App but on the iOS version it's like it can't find the txt file, the buttons etc is left blank.
I've been sitting on this for a week or so about now and that's the reason for this post.
The iOS app is based on this Github Mac app: https://github.com/SquaredTiki/Quizzer
If you want to have a look at how I've tried to convert the app here's a link to that to:
https://www.dropbox.com/s/1jqz9ue97p3v2h1/iTrafikk.zip?dl=0
And of course I'm not asking you to solve the whole issue for me, maybe just push me in the right direction if possible :)
I checked your project. And it seems that you are not calling loadQuestionsAndAnswersArray anywhere in your code. Also you are not initializing the questionsAndAnswers anywhere in the project.
Change your code like:
- (void)viewDidLoad
{
[super viewDidLoad];
[self loadQuestionsAndAnswersArray];
}
- (void)loadQuestionsAndAnswersArray
{
NSString *filePath = [[NSBundle mainBundle] pathForResource:#"Quiz1" ofType:#"txt"];
NSString *textFileString = [NSString stringWithContentsOfFile:filePath encoding:NSStringEncodingConversionAllowLossy error:NULL];
NSArray *seperatedQA = [textFileString componentsSeparatedByString:#"\n\n"];
for (NSString *QA in seperatedQA)
{
NSString *questionString = [[[QA componentsSeparatedByString:#"\n"] objectAtIndex:0] stringByReplacingOccurrencesOfString:#"Q:" withString:#""];
NSMutableArray *answers = [[QA componentsSeparatedByString:#"A:"] mutableCopy];
[answers removeObjectAtIndex:0];
int correctAnswerLoc = 0;
for (int i = 0; i < answers.count; i++)
{
NSString *answer = [answers objectAtIndex:i];
NSString *editedAnswer = [answer stringByReplacingOccurrencesOfString:#"\n" withString:#""];
editedAnswer = [editedAnswer stringByTrimmingCharactersInSet:
[NSCharacterSet whitespaceAndNewlineCharacterSet]];
[answers removeObjectAtIndex:i];
[answers insertObject:editedAnswer atIndex:i];
answer = editedAnswer;
if ([answer rangeOfString:#"[CORRECT]"].location != NSNotFound)
{
correctAnswerLoc = [answers indexOfObject:answer];
NSString *editedAnswer = [answer stringByReplacingOccurrencesOfString:#"[CORRECT]" withString:#""];
[answers removeObjectAtIndex:i];
[answers insertObject:editedAnswer atIndex:i];
}
}
NSLog(#"answers = %#", answers);
NSDictionary *QADictionary = [NSDictionary dictionaryWithObjectsAndKeys:questionString, #"question", answers, #"answers", [NSNumber numberWithInt:correctAnswerLoc], #"correctAnswerLocation", nil];
if (!questionsAndAnswers)
{
questionsAndAnswers = [[NSMutableArray alloc] init];
}
[questionsAndAnswers addObject:QADictionary];
}
resultsArray = [[NSMutableArray alloc] initWithCapacity:[questionsAndAnswers count]];
[self loadQuestionsAndAnswersIntoInterface];
}

How to populate JSON data in UITableView using NSUrlConnection? [duplicate]

This question already has answers here:
populating a tableview with data using JSON and AFNetworking NSDictionary
(1 answer)
JSON data is not loading in slow internet connection? [closed]
(1 answer)
Closed 8 years ago.
I'm building an article reading app.I'm parsing JSON data using NSData in UITableView.
I'm facing an issue that is data is not load in slow internet speed(2g or 3g)means UI is empty.I want to implement NSUrlConnection
but i'm new in iOS development unable to implement NSUrlConnection in my code.
this is my code:
- (void)viewDidLoad
{
[super viewDidLoad];
BOOL myBool = [self isNetworkAvailable];
if (myBool)
{
#try {
// for table cell seperator line color
self.tableView.separatorColor = [UIColor colorWithRed:190/255.0 green:190/255.0 blue:190/255.0 alpha:1.0];
UIBarButtonItem *backbutton1 = [[UIBarButtonItem alloc] initWithTitle:#"" style:UIBarButtonItemStyleBordered target:nil action:nil];
[[self navigationItem] setBackBarButtonItem:backbutton1];
_Title1 = [[NSMutableArray alloc] init];
_Author1 = [[NSMutableArray alloc] init];
_Images1 = [[NSMutableArray alloc] init];
_Details1 = [[NSMutableArray alloc] init];
_link1 = [[NSMutableArray alloc] init];
_Date1 = [[NSMutableArray alloc] init];
NSData* data = [NSData dataWithContentsOfURL:ysURL];
NSArray *ys_avatars = [NSJSONSerialization JSONObjectWithData:data options:0 error:nil];
if(ys_avatars){
for (int j=0;j<ys_avatars.count;j++)
{
if( ys_avatars[j][#"title"]==[NSNull null] ){
[_Title1 addObject: #""];
}
else{
[_Title1 addObject:ys_avatars[j][#"title"]];
}
if( ys_avatars[j][#"author"]==[NSNull null] ){
[_Author1 addObject: #""];
}
[_Author1 addObject: ys_avatars[j][#"author"]];
if( ys_avatars[j][#"featured_img"]==[NSNull null] ){
[_Images1 addObject: #""];
}
else{
[_Images1 addObject: ys_avatars[j][#"featured_img"]];
}
if( ys_avatars[j][#"content"]==[NSNull null] ){
[_Details1 addObject: #""];
}else{
[_Details1 addObject:ys_avatars[j][#"content"]];
}
if( ys_avatars[j][#"permalink"]==[NSNull null] ){
[_link1 addObject: #""];
}
else{
[_link1 addObject:ys_avatars[j][#"permalink"]];
}
if( ys_avatars[j][#"date"]==[NSNull null] ){
[_Date1 addObject: #""];
}
else{
NSString *newStr=[ys_avatars[j][#"date"] substringToIndex:[ys_avatars[j][#"date"] length]-3];
[_Date1 addObject:newStr];
}
}
}
else
{
NSLog(#"asd");
}
}
#catch (NSException *exception) {
}
}
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *Cellidentifier1 = #"ysTableViewCell";
ysTableViewCell *cell1 = [tableView dequeueReusableCellWithIdentifier:Cellidentifier1 forIndexPath:indexPath];
long row = [indexPath row];
cell1.TitleLabel1.text = _Title1[row];
cell1.AuthorLabel1.text = _Author1[row];
NSString *StoryUrl = [_Images1[indexPath.row] stringByAddingPercentEscapesUsingEncoding:NSASCIIStringEncoding];
if(StoryUrl) {
NSArray *subStringsUrl = [yourStoryUrl componentsSeparatedByString:#"/"];
NSString *stripedName = [subStringsUrl lastObject];
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString* filePath =[documentsDirectory stringByAppendingPathComponent: [NSString stringWithFormat:#"%#",stripedName]];
if(filePath) {
UIImage *image = [UIImage imageWithContentsOfFile:filePath];
if(image) {
ysTableViewCell *updateCell =(id)[tableView cellForRowAtIndexPath:indexPath];
if(updateCell)
updateCell.ThumbImage1.image=image;
cell1.ThumbImage1.image=image;
} else {
dispatch_queue_t taskQ = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
dispatch_async(taskQ, ^{
NSURL *Imageurl = [NSURL URLWithString:yourStoryUrl];
NSData *data = [NSData dataWithContentsOfURL:Imageurl];
UIImage *images1 = [[UIImage alloc] initWithData:data];
NSData *imageData = UIImagePNGRepresentation(images1);
if (![imageData writeToFile:filePath atomically:NO])
{
NSLog((#"Failed to cache image data to disk"));
}
else
{
NSLog(#"the cachedImagedPath is %#",filePath);
}
dispatch_sync(dispatch_get_main_queue(), ^{
ysTableViewCell *updateCell =(id)[tableView cellForRowAtIndexPath:indexPath];
if(updateCell)
updateCell.ThumbImage1.image=images1;
cell1.ThumbImage1.image=images1;
});
});
}
return cell1;
}
Help is appreciated.
Thanks in advance.
This looks really messy, and i suggest you change your whole design.
A basic and cleaner way (but probably not the best/cleanest way) :
Create class to handle outside-of-view related work (JSON parsing here)
Call that class in viewDidLoad to start parsing
Call a method that refreshes your table view with the newly parsed data when the parsing is done (in the JSON class).
That way, the table view will load your placeholders first and then reload itself when it has the data.
In my opinion, a better way would be to populate it before loading it so there is no wait time.
Can you find what you need yourself, or code it alone? or do you need help? If so, with what?
EDIT : You could/should also use the AFNetworking framework that will make your life 10 times easier with JSON/Internet related code.
I usually create a class that handles the load of my data, whether from a URL or local store. You could use AFNetworking, but there is a ton of extra stuff you might not need. The basics of using NSUrlConnection is really easy.
Try this tutorial, it will help you to understand how Apple's implementation works before you add a third party library that masks it for you.
NSUrlConnection Tutorial

GCD slow updating UI

Im using GCD to download a plist file from the internet then enter the data into an array then load it into a tableView.
The data is being downloaded and converted alright but the table view is taking ages to update. I have the app Logging something when it calls [self.tableView reloadData] but the table view updates about 10 seconds later.
I don't think this is about the table view because I tried changing the title of the Navigation Bar inside the GCD and there was also a delay. So it might be a delay updating the user interface?
This is my GCD code:
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
Thanks for you help
EDIT:
This is my code:
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
UERootArray = [[NSArray alloc] initWithContentsOfURL:[NSURL URLWithString:#"url to file"]];
NSLog(#"Array: %#", UERootArray);
//NSLog(#"count %#",count);
NSString *currentName;
NSString *currentLoaction;
NSString *currentDate;
int currentEventInt = 0;
NSArray *currentEventArr = [UERootArray objectAtIndex:0];
while (currentEventArr.count > currentEventInt)
{
currentName = [currentEventArr objectAtIndex:0];
currentLoaction = [currentEventArr objectAtIndex:1];
currentDate = #"7pm 17/11"; //[currentEventArr objectAtIndex:2];
NSLog (#"Title: %#", currentName);
NSLog (#"News: %#", currentLoaction);
NSLog (#"Date: %#", currentDate);
UEEvent *currentTask = [[UEEvent alloc] initWithName:currentName location:currentLoaction date:currentDate];
[self.upcommingEvents addObject:currentTask];
currentEventInt = currentEventInt + 1;
}
UEDownloaded = YES;
[self.tableView reloadData];
Edit 2:
- (void)downloadUEData
{
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
UERootArray = [[NSArray alloc] initWithContentsOfURL:[NSURL URLWithString:#"url to file"]];
[self processUEData];
});
}
- (void)processUEData
{
NSLog(#"Array: %#", UERootArray);
//NSLog(#"count %#",count);
NSString *currentName;
NSString *currentLoaction;
NSString *currentDate;
int currentEventInt = 0;
NSArray *currentEventArr = [UERootArray objectAtIndex:0];
while (currentEventArr.count > currentEventInt)
{
currentName = [currentEventArr objectAtIndex:0];
currentLoaction = [currentEventArr objectAtIndex:1];
currentDate = #"7pm 17/11"; //[currentEventArr objectAtIndex:2];
NSLog (#"Title: %#", currentName);
NSLog (#"News: %#", currentLoaction);
NSLog (#"Date: %#", currentDate);
UEEvent *currentTask = [[UEEvent alloc] initWithName:currentName location:currentLoaction date:currentDate];
[self.upcommingEvents addObject:currentTask];
currentEventInt = currentEventInt + 1;
}
UEDownloaded = YES;
[self.tableView reloadData];
}
i think following code will solve your problem ...
- (void)downloadUEData
{
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
UERootArray = [[NSArray alloc] initWithContentsOfURL:[NSURL URLWithString:#"http://www.nytrex.webs.com/Linx/upcommingEvents.plist"]];
[self processUEData];
});
}
- (void)processUEData
{
NSLog(#"Array: %#", UERootArray);
//NSLog(#"count %#",count);
NSString *currentName;
NSString *currentLoaction;
NSString *currentDate;
int currentEventInt = 0;
NSArray *currentEventArr = [UERootArray objectAtIndex:0];
while (currentEventArr.count > currentEventInt)
{
currentName = [currentEventArr objectAtIndex:0];
currentLoaction = [currentEventArr objectAtIndex:1];
currentDate = #"7pm 17/11"; //[currentEventArr objectAtIndex:2];
NSLog (#"Title: %#", currentName);
NSLog (#"News: %#", currentLoaction);
NSLog (#"Date: %#", currentDate);
UEEvent *currentTask = [[UEEvent alloc] initWithName:currentName location:currentLoaction date:currentDate];
[self.upcommingEvents addObject:currentTask];
currentEventInt = currentEventInt + 1;
}
UEDownloaded = YES;
dispatch_async(dispatch_get_main_queue(), ^{ // update your UI in main thread
[self.tableView reloadData];
});
}

UITableView with complex cells is slow and laggy

I've almost finished my app and everything seems to work but the main view.
It's an UIViewController with an embedded UITableView.
I'm using Parse as the backend, and I get an array of the objects I need in my viewDidLoad method.
Each cell contains some data that I'm fetching in the tableView:cellForRowAtIndexPath and I'm afraid that this is the reason why my table view is so laggy, but I don't know how to fetch the data I need for each object in my array without having the indexPath.row number.
I've already made each cell element "opaque" as suggested in other answers.
This is my code, any help would be greatly appreciated:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"cellHT";
CellHT *cell = (CellHT *)[tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (!cell) {
cell = [[CellHT alloc]
initWithStyle:UITableViewCellStyleDefault
reuseIdentifier:CellIdentifier];
}
// self.hH is an NSArray containing all the objects
NSUserDefaults *prefs = [NSUserDefaults standardUserDefaults];
cell.lblTitle.text = [self.hH[indexPath.row] objectForKey:#"title"];
cell.lblVenueName.text = [self.hH[indexPath.row] objectForKey:#"venueName"];
cell.lblDistance.text = NSLocalizedString(#"Distance from you", nil);
self.geo = [self.hH[indexPath.row] objectForKey:#"coordinates"];
// the formatters are initialized in the viewDidLoad: method
self.formatData = [NSDateFormatter dateFormatFromTemplate:#"dd/MM" options:0 locale:[NSLocale currentLocale]];
[self.formatterData setDateFormat:self.formatData];
self.formatOra = [NSDateFormatter dateFormatFromTemplate:#"j:mm" options:0 locale:[NSLocale currentLocale]];
[self.formatterOra setDateFormat:self.formatOra];
self.dal = NSLocalizedString(#"from", nil);
self.ore = NSLocalizedString(#"at", nil);
CLLocation *vLoc = [[CLLocation alloc] initWithLatitude:self.geo.latitude longitude:self.geo.longitude];
CLLocation *user = [[CLLocation alloc] initWithLatitude:self.userGeo.latitude longitude:self.userGeo.longitude];
CLLocationDistance distance = [user distanceFromLocation:venueLoc];
if ([[prefs objectForKey:#"unit"] isEqualToString:#"km"]) {
cell.lblDist.text = [NSString stringWithFormat:#"%.1f Km", distance /1000];
} else {
cell.lblDist.text = [NSString stringWithFormat:#"%.1f Miles", distance /1609];
}
// compare the object's starting date with the current date to set some images in the cell
NSComparisonResult startCompare = [[self.hH[indexPath.row] objectForKey:#"startDate"] compare: [NSDate date]];
if (startCompare == NSOrderedDescending) {
cell.quad.image = [UIImage imageNamed:#"no_HT"];
cell.lblStartTime.textColor = [UIColor redColor];
} else {
cell.quad.image = [UIImage imageNamed:#"yes_HT"];
cell.lblStartTime.textColor = [UIColor colorWithRed:104.0/255.0 green:166.0/255.0 blue:66.0/255.0 alpha:1.0];
}
NSString *dataInizio = [NSString stringWithFormat:#"%# %# %# %#", self.dal, [self.formatterData stringFromDate:[self.hH[indexPath.row] objectForKey:#"startDate"]], self.ore, [self.formatterOra stringFromDate:[self.hH[indexPath.row] objectForKey:#"endDate"]]];
cell.lblStartTime.text = dataInizio;
PFObject *cat = [self.hH[indexPath.row] objectForKey:#"catParent"];
NSString *languageCode = [[NSLocale preferredLanguages] objectAtIndex:0];
if ([languageCode isEqualToString:#"it"]) {
cell.lblCategory.text = [cat objectForKey:#"nome_it"];
} else if ([languageCode isEqualToString:#"es"]) {
cell.lblCategory.text = [cat objectForKey:#"nome_es"];
} else {
cell.lblCategory.text = [cat objectForKey:#"nome_en"];
}
//getting the image data from the Parse PFFile
PFFile *theImage = [self.hH[indexPath.row] objectForKey:#"photo"];
[theImage getDataInBackgroundWithBlock:^(NSData *data, NSError *error) {
if (!error) {
cell.cellImageView.image = [UIImage imageWithData:data];
}
}];
//getting the cell object's owner and his profile
PFUser *usr = [self.hH[indexPath.row] objectForKey:#"parent"];
PFQuery *prof = [PFQuery queryWithClassName:#"Profile"];
prof.cachePolicy = kPFCachePolicyCacheThenNetwork;
[prof whereKey:#"parent" equalTo:usr];
[prof getFirstObjectInBackgroundWithBlock:^(PFObject *object, NSError *error) {
if (!error) {
//getting the object's rating and the number of votes
PFQuery *rateQuery = [PFQuery queryWithClassName:#"Rating"];
[rateQuery whereKey:#"parent" equalTo:object];
[rateQuery getFirstObjectInBackgroundWithBlock:^(PFObject *object, NSError *error) {
if (!error) {
float vote = [[object objectForKey:#"rate"] floatValue];
float temp = ((vote * 2) + 0.5);
int tempvote = (int)temp;
float roundedVote = (float)tempvote / 2;
// drawing the stars number, depending on the rating obtained
UIImage *starsImage = [UIImage imageNamed:#"stars"];
UIGraphicsBeginImageContextWithOptions(cell.imgVoto.frame.size, NO, 0);
CGPoint starPoint = (CGPoint) {
.y = (cell.imgVoto.frame.size.height * (2 * roundedVote + 1)) - (starsImage.size.height)
};
[starsImage drawAtPoint:starPoint];
cell.imgVoto.image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
cell.lblVoto.text = [NSString stringWithFormat:#"(%d)", [[object objectForKey:#"voters"] intValue]];
}
}];
}
}];
return cell;
}
EDIT: this is the cell code:
+ (void)initialize {
if (self != [HH class]) {
return;
}
}
-(id)initWithCoder:(NSCoder *)aDecoder {
if ( !(self = [super initWithCoder:aDecoder]) ) return nil;
self.cellImageView.image = [UIImage imageNamed:#"icona_foto"];
self.cellImageView.contentMode = UIViewContentModeScaleToFill;
self.formatterData = [[NSDateFormatter alloc] init];
self.formatData = [[NSString alloc] init];
self.formatterOra = [[NSDateFormatter alloc] init];
self.formatOra = [[NSString alloc] init];
self.formatData = [NSDateFormatter dateFormatFromTemplate:#"dd/MM" options:0 locale:[NSLocale currentLocale]];
[self.formatterData setDateFormat:self.formatData];
self.formatOra = [NSDateFormatter dateFormatFromTemplate:#"j:mm" options:0 locale:[NSLocale currentLocale]];
[self.formatterOra setDateFormat:self.formatOra];
self.lblVoto.text = #"(0)";
return self;
}
SECOND EDIT: this is the code in the viewDidLoad method:
PFQuery *hours = [PFQuery queryWithClassName:#"HH"];
hours.cachePolicy = kPFCachePolicyCacheThenNetwork;
// here I'm making lots of query constraints that I'll not include
[hours findObjectsInBackgroundWithBlock:^(NSArray *objects, NSError *error) {
if (!error) {
self.objectsNumber = objects.count;
self.hH = [[NSArray alloc] initWithArray:objects];
}
}];
[self.tableView reloadData];
}
I would move as much of the logic out of cellForRowAtIndexPath: as you can, it needs to be very light-weight to get good scrolling performance. You're doing a lot of work on the main thread, and I would do a lot more of this work when you get your model objects back from Parse (if you could post viewDidLoad I can give you more specific help) and update the table view when these calls are done:
[UIImage imageWithData:data]
anything to do with NSDateFormatter
CLLocation's initWithLatitude:longitude:
creating the rating stars image
None of these depend on the state of the table view, so they can be effectively precomputed and cached in a model object. If you simply scroll up and down the table, you're doing allo f the same work over and over, killing your performance.
Updated for the questioner's newest code:
I won't include all of your functionality here but this should give you an idea:
// create a single shared formatter instead of one per object
NSDateFormatter *dateFormatter = [NSDateFormatter dateFormatFromTemplate:#"dd/MM" options:0 locale:[NSLocale currentLocale]];
NSDateFormatter *timeFormatter = [NSDateFormatter dateFormatFromTemplate:#"j:mm" options:0 locale:[NSLocale currentLocale]];
[hours findObjectsInBackgroundWithBlock:^(NSArray *objects, NSError *error) {
if (!error) {
self.objectsNumber = objects.count;
for (SomeObject *modelObj in objects) {
// if you can add properties to your model object directly, do that
// otherwise write a category on the Parse object to add the ones you need
modelObj.dateString = [NSString stringWithFormat:#"%# %# %# %#", modelObj.dal, [self.dateFormatter stringFromDate:[modelObj objectForKey:#"startDate"]], modelObj.ore, [self.timeFormatter stringFromDate:[modelObj objectForKey:#"endDate"]]];
// create your locations, images, etc in here too
}
self.hH = [[NSArray alloc] initWithArray:objects];
}
}];]
Then in cellForRowAtIndexPath:, take the precomputed properties and simply assign them to the appropriate labels, image views, etc.
It would be even better to do most of this processing off the main thread via GCD, but that is most likely out of scope for this question. See Using GCD and Blocks Effectively for more information. Just remember do only interact with UIKit from the main thread!
have a try by removing
CLLocation *vLoc = [[CLLocation alloc] initWithLatitude:self.geo.latitude longitude:self.geo.longitude];
CLLocation *user = [[CLLocation alloc] initWithLatitude:self.userGeo.latitude long itude:self.userGeo.longitude];
CLLocationDistance distance = [user distanceFromLocation:venueLoc];
This was at first sight , then I see your all your code and I realize a lot of image are used
Because UITableView takes some time to layout cells.
Solution:
step1. Set section number and row number to 0.
step2. Reload tableView in viewDidAppear.
Then your view controller cloud response quickly and then show cells.

Resources