0

I'm populating cells with images and videos. Some have images and some have videos.

For images, no problem. However when displaying pictures AND videos, things go weird. A cell that contains a video would be blank but the next cell would show the video which never happens with images.

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath object:(PFObject *)object{
static NSString *simpleTableIdentifier = @"cell";

self.cell = [tableView dequeueReusableCellWithIdentifier:simpleTableIdentifier];
if (self.cell == nil) {
    self.cell = [[SearchCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:simpleTableIdentifier];
}


PFFile *videoFile = [object objectForKey:@"video"];
PFFile *imageFile = [object objectForKey:@"photo"];

if (imageFile != nil) {

    self.cell.movie.view.hidden = YES;
    [self.cell.movie stop];        
    self.cell.photo.hidden = NO;
    self.cell.photo.file = imageFile;
    [self.cell.photo loadInBackground];
}

else {
       dispatch_async(dispatch_get_main_queue(), ^(void){                

            [self.cell.movie setContentURL:[NSURL URLWithString:videoFile.url]];
            [self.cell.movie prepareToPlay];
            [self.cell.movie play];
            self.cell.movie.view.hidden = NO;

            self.cell.photo.hidden = YES;
    });

}

In customCell.m

- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier{
self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
if (self) {

    UIWindow *window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];


    self.opaque = NO;
    self.selectionStyle = UITableViewCellSelectionStyleNone;
    self.accessoryType = UITableViewCellAccessoryNone;
    self.clipsToBounds = NO;

    self.backgroundColor = [UIColor colorWithRed:140.0f/255.0f green:129.0f/255.0f blue:126.0f/255.0f alpha:1.0f];


    self.photo = [[PFImageView alloc]initWithFrame:CGRectMake(0, 0, window.frame.size.width, window.frame.size.width)];
    self.photo.backgroundColor = [UIColor colorWithRed:191.0f/255.0f green:191.0f/255.0f blue:191.0f/255.0f alpha:1.0f];        

    self.movie = [[MPMoviePlayerController alloc] init];
    self.movie.controlStyle = MPMovieControlStyleNone;
    self.movie.shouldAutoplay = NO;
    self.movie.repeatMode = MPMovieRepeatModeOne;
    self.movie.scalingMode = MPMovieScalingModeAspectFit;
    self.movie.movieSourceType = MPMovieSourceTypeStreaming;
    self.movie.view.backgroundColor = [UIColor clearColor];


- (void)layoutSubviews {
[super layoutSubviews];
self.movie.view.frame = CGRectMake(0, 0, self.bounds.size.width, self.bounds.size.width);}
durazno
  • 559
  • 2
  • 7
  • 25

1 Answers1

0

Your problem is that you are using dispatch function that works async and when cell is dequeued you perform loading from URL, in the same time you scroll down and reach photo cell that also tries to fetch some thing async using [self.cell.photo loadInBackground].

To solve this you need to store some reference on async operation like NSOperation and when you try to dequeue the cell you need to cancel previous downloading process.

What I can suggest is to google or create NSOperation queue to fetch video data and use, for example, AFNetworking setImageWithURL: to fetch image with caching.

vlad.grb
  • 339
  • 4
  • 16
  • Thanks. Now you make me wonder, why NSOperation instead of dispatch_async? I've noticed some people on SO recommend dispatch_async and some others NSOperation. – durazno Sep 09 '15 at 00:08
  • @durazno `dispatch` it is a low level API when `NSOperation` it's good API from the kit in ObjC way, where you can cancel, pause, manage your operations. Read more [here](http://stackoverflow.com/a/10375616/962964) – vlad.grb Sep 09 '15 at 04:58