0

I have an odd problem. I have a table view, and it's cells contain a video. I set the AVPlayerLayer to stretch to the size of the cell, but when the tableview first loads, it doesn't do that, for only the first 2 cells. For cells 3 + it loads correctly, and when I scroll back up the tableview from bottom to top, then the cells do load correctly for the first 2. I have created a 13 second youtube video to show exactly what I mean. Notice the white space at the bottom of the first 2 cells during the first few seconds of the video. When I scroll back up, that space isn't there, the bounds of the AVPlayerLayer are correct.

https://www.youtube.com/watch?v=q7BlZd77QVU

Here is my code that sets up the tableView cell, in cellForRowAtIndexPath:

  NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
  NSString *documentsDirectory = [paths objectAtIndex:0];

  NSString *mov = @".mov";
  NSString *fullComponent = [NSString stringWithFormat: @"%@%@", self.videoChallengeID, mov];
  NSString *fullPath = [documentsDirectory stringByAppendingPathComponent:fullComponent];
  NSURL *url = [NSURL fileURLWithPath:fullPath];

  UIView *blueView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, videoCell.frame.size.width, videoCell.frame.size.height)];
  blueView.backgroundColor = [UIColor blueColor];
  [videoCell.contentView insertSubview:blueView belowSubview:videoCell.bottomView];
  videoCell.item = [AVPlayerItem playerItemWithURL:url];
  self.player = [[AVPlayer alloc] initWithPlayerItem:videoCell.item];
  [self.player setMuted:YES];
  self.player.actionAtItemEnd = AVPlayerActionAtItemEndNone;
  AVPlayerLayer *playerLayer = [AVPlayerLayer playerLayerWithPlayer:self.player];
  playerLayer.frame = CGRectMake(0, 0, videoCell.frame.size.width, videoCell.frame.size.height);
  playerLayer.backgroundColor = [UIColor lightGrayColor].CGColor;
  playerLayer.videoGravity = AVLayerVideoGravityResize;
  [blueView.layer addSublayer:playerLayer];
  [self.player play];

I clearly set the frame correctly, and it works, except for the first 2 cells that load, the first time the tableview loads. Every other time it functions correctly. Any idea what could be going on?

jjjjjjjj
  • 4,203
  • 11
  • 53
  • 72
  • 1
    Because the first time the cell is instanciated, the frame of the cell itself isn't set to what it should be. When they are reused, it's fine but not when they are first instanciated. What you should do is created a custom UItableViewCell subclass, and then set the frame of the video layer properly in the `layoutSubviews` function – Marc-Alexandre Bérubé Mar 30 '16 at 12:00
  • put this as an answer and I will mark it correct. thanks! – jjjjjjjj Mar 30 '16 at 22:36

2 Answers2

1

override

-(void)layoutSubviews {
    [super layoutSubviews]
}

On your cell and set the layer frame

layer.frame = self.bounds

Your cell seems setup horribly inefficiently and you should reuse stuff like views and layers for optimal performance and just pass in your player.

Sean Lintern
  • 3,103
  • 22
  • 28
  • I have tried that previously. But as others have found, that leads to significant performance issues: http://stackoverflow.com/questions/25352155/changing-playeritem-of-avplayer-in-uitableview – jjjjjjjj Mar 31 '16 at 07:06
  • Even if replaceItem is laggy reusing the BlueView and AVPlayerLayer is still possible. – Sean Lintern Mar 31 '16 at 13:49
1

Because the first time the cell is instanciated, the frame of the cell itself isn't set to what it should be. When they are reused, it's fine but not when they are first instanciated.

What you should do is create a custom UItableViewCell subclass, and then set the frame of the video layer properly in the layoutSubviews function