我差不多完成了我的应用程序,一切似乎都有效,但主要观点
它是UIViewController
,嵌入了UITableView
我正在使用Parse作为后端,我在viewDidLoad
方法中得到了一个我需要的对象数组。
每个单元格都包含一些我在tableView:cellForRowAtIndexPath
中提取的数据,我担心这就是为什么我的表视图如此滞后,但我不知道如何获取数据我需要我的数组中的每个对象而没有indexPath.row
数字。
我已经按照其他答案中的建议将每个单元格元素设置为“不透明”。
这是我的代码,非常感谢任何帮助:
- (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;
}
编辑:这是单元格代码:
+ (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;
}
第二次编辑:这是viewDidLoad
方法中的代码:
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];
}
答案 0 :(得分:4)
我会尽可能多地移动cellForRowAtIndexPath:
的逻辑,它需要非常轻量级才能获得良好的滚动性能。你在主线程上做了很多工作,当你从Parse返回你的模型对象时我会做更多的工作(如果你可以发布viewDidLoad
我可以给你更具体的帮助)完成这些调用后更新表视图:
[UIImage imageWithData:data]
NSDateFormatter
CLLocation
的{{1}} 这些都不依赖于表视图的状态,因此可以在模型对象中有效地预先计算和缓存它们。如果你只是简单地在桌子上滚动,你就会一遍又一遍地做同样的工作,从而导致你的表现无效。
更新了提问者的最新代码:
我不会在此处包含您的所有功能,但这应该会给您一个想法:
initWithLatitude:longitude:
然后在// 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];
}
}];]
中,获取预先计算的属性,只需将它们分配给相应的标签,图片视图等。
通过GCD从主线程中完成大部分处理会更好,但这很可能超出了这个问题的范围。有关详细信息,请参阅Using GCD and Blocks Effectively。请记住,只从主线程中与UIKit进行交互!
答案 1 :(得分:1)
尝试删除
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];
这是乍一看,然后我看到你所有的代码,我意识到使用了很多图像
答案 2 :(得分:0)
因为UITableView
需要一些时间来布置单元格。
解决方案:
步骤1。将节号和行号设置为0
。
步骤2。在viewDidAppear
中重新加载tableView。
然后您的视图控制器云响应迅速,然后显示单元格。