Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

playing videos in UITableViewCell

Tags:

ios

I am trying to play videos in the cells itself instead of a fullscreen video display. I am using MPMoviePlayerController for this purpose.

I have defined

MPMoviePlayerController *moviePlayer;

in the implementation section

Then in cellForRowAtIndexPath:

I do this

cell = [tableView dequeueReusableCellWithIdentifier:simpleTableVideoIdentifier];

            if (cell == nil){
                cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:simpleTableVideoIdentifier];
            }
            NSDictionary *dictionary = [dataArray objectAtIndex:indexPath.section];
            NSDictionary *data = dictionary;
            if ([data[@"type_of_post"] isEqualToString:@"video"]) {
                NSString *path = data[@"video"];
                NSURL *videoURL = [NSURL URLWithString:path];
                moviePlayer = [[MPMoviePlayerController alloc] initWithContentURL:videoURL];
                [moviePlayer setControlStyle:MPMovieControlStyleNone];
                moviePlayer.scalingMode = MPMovieScalingModeAspectFit;
                [moviePlayer.view setFrame:CGRectMake(10.0, 0.0, 300.0 , 400.0)];
                [cell addSubview:moviePlayer.view];
                 moviePlayer.view.hidden = NO;
                [moviePlayer prepareToPlay];
                [moviePlayer play];
            }else{
                //do something else
            }

and obviously I assign it a height in heightForRowAtIndexPath:

but the point it as MPMoviePlayerController *moviePlayer; is defined globally it doesn't stick to just its cell but keeps on coming down as I scroll down. I am not sure what other way to implement this other than what I described, which clearly doesn't seem the right way to go about it. I would really appreciate if someone can guide me to the right direction.

Thanks

like image 307
Jonathan Avatar asked Apr 02 '13 02:04

Jonathan


3 Answers

Never add a subview to the cell:

[cell addSubview:moviePlayer.view];

Add it only to the contentView:

[cell.contentView addSubview:moviePlayer.view];

The other big mistake you're making is that you're forgetting that this cell can be reused; as the user scrolls, the cell be used for a different row of the table. So it gets reused, and now the movie player view is still in it even though this is now the wrong row of the table. You need not only to add the movie player view to the right cell, you need to remove it from all the wrong cells (in the else part of your code).

like image 196
matt Avatar answered Nov 12 '22 09:11

matt


You really shouldn't alloc new objects every time the cell comes on screen. You should subclass a UITableViewCell and add a MPMoviePlayerController as a Property which can be set to play or stop and hide the view if no video. So your code should look something more like :

#import CustomCell.h    
CustomCell *cell = [tableView dequeueReusableCellWithIdentifier:@"cellIdent"];
    if (!cell) {
        cell = [[CustomCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"cellIdent"]];
    }

    NSDictionary *dict = dataArray[indexPath.row];
    if ([dict[@"type_of_post"] isEqualToString:@"video"]) {
        NSString *path = @"http://<path to your video>";
        [cell.movie setContentURL:[NSURL URLWithString:path]];
        [cell.movie prepareToPlay];
        [cell.movie play];
        cell.movie.view.hidden = NO;
    } else {
         [cell.movie stop];
         cell.movie.view.hidden = YES;
         }

Now in case you don't know how a cell should look CustomCell.h:

@interface CustomCell : UITableViewCell
@property (nonatomic, retain) MPMoviePlayerController *movie;
@end

CustomCell.m:

@implementation CustomCell
- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier {
    self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
    if (self) {
        self.movie = [[MPMoviePlayerController alloc] init];
        self.movie.controlStyle = MPMovieControlStyleNone;
        self.movie.scalingMode = MPMovieScalingModeAspectFit;
        [self.contentView addSubview:self.movie.view];
    }
    return self;
 }
 - (void)layoutSubviews {
     [super layoutSubviews];
     self.movie.frame = CGRectMake(10, 0, self.bounds.size.width - 20, self.bounds.size.height);
 }
@end
like image 8
Alex Blokker Avatar answered Nov 12 '22 08:11

Alex Blokker


Instead of creating the player for every cell, you could create and overlay it on the cell when the following UITableViewDelegate method is called. You could still have an image that looks like the player, added to each cell in order to give the look and feel as if each cell is a player.

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
like image 2
sixthcent Avatar answered Nov 12 '22 09:11

sixthcent