3

我几乎完成了我的应用程序,一切似乎都正常,但主要视图。
这是一个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];
}
4

3 回答 3

4

我会尽可能多地移出逻辑cellForRowAtIndexPath:,它需要非常轻量级才能获得良好的滚动性能。你在主线程上做了很多工作,当你从 Parse 取回你的模型对象时我会做更多的工作(如果你可以发布viewDidLoad我可以给你更具体的帮助)并更新表格视图当这些调用完成时:

  • [UIImage imageWithData:data]
  • 任何与NSDateFormatter
  • CLLocationinitWithLatitude: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];
    }
}];]

然后在 中cellForRowAtIndexPath:,获取预先计算的属性并简单地将它们分配给适当的标签、图像视图等。

通过 GCD 在主线程之外完成大部分处理会更好,但这很可能超出了这个问题的范围。有关更多信息,请参阅有效使用 GCD 和块。请记住只从主线程与 UIKit 交互!

于 2013-05-04T15:47:05.407 回答
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];

这是一见钟情,然后我看到了你所有的代码,我意识到使用了很多图像

于 2013-05-04T15:15:25.773 回答
0

因为UITableView需要一些时间来布局单元格。

解决方案:

第1步。将节号和行号设置为0

第2步。重新加载 tableView viewDidAppear

然后你的视图控制器云快速响应然后显示单元格。

于 2018-11-07T05:59:15.883 回答