What I had done :-
I had added the code which plays a video when cell is fully visible and when I scrolls down or up it reload the tableview again and plays video again. But, my requirement is different.
What I actually want :
I want to play a video untill the backward or forward cell fully visible. When user scroll downs or up it doesn’t affect untill the backward or forward cell fully visible.
Design
Table Cell Layout Description
-> Video Table Cell (Fix height 393)
-> Content View
-> Main view - (as per Content view of Table view Cell)
-> Title View (0, 0, MainView.width, 57)
-> Video View (0, 57, MainView.width, 200);
-> Description View (0, 257, MainView.width, 136)
Coding :
VideoTableCell.h
#import <UIKit/UIKit.h>
#import <AVFoundation/AVFoundation.h>
@interface VideoTableCell : UITableViewCell
@property (strong, nonatomic) IBOutlet UIView *viewForVideo;
@property (strong, nonatomic) IBOutlet UIImageView *imgThumb;
@property (strong, nonatomic) IBOutlet UIButton *btnPlay;
@property (strong, nonatomic) AVPlayerItem* videoItem;
@property (strong, nonatomic) AVPlayer* videoPlayer;
@property (strong, nonatomic) AVPlayerLayer* avLayer;
@end
VideoTableCell.m
#import "VideoTableCell.h"
@implementation VideoTableCell
- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier {
self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
return self;
}
- (void)layoutSubviews
{
[super layoutSubviews];
[self.avLayer setFrame:CGRectMake(self.viewForVideo.frame.origin.x, self.viewForVideo.frame.origin.y, self.viewForVideo.frame.size.width, self.viewForVideo.frame.size.height)];
}
@end
VideoVC.h
#import <UIKit/UIKit.h>
#import <AVFoundation/AVFoundation.h>
@interface VideoVC : UIViewController <UITableViewDataSource, UITableViewDelegate>
@property (strong, nonatomic) IBOutlet UITableView *tblData;
@end
VideoVC.m
#import "VideoVC.h"
#import "VideoTableCell.h"
@interface VideoVC ()
{
NSArray *arrVideo ;
bool isScrolling;
int index;
BOOL fullvisible ;
}
@end
@implementation VideoVC
- (void)viewDidLoad {
[super viewDidLoad];
arrVideo = [[NSArray alloc]initWithObjects:@"http://video/1.mp4",@"http://video/2.mp4", @"http://video/3.mp4", @"http://video/4.mp4", @"http://video/5.mp4", nil];
fullvisible = YES;
}
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return arrVideo.count;
}
-(UITableViewCell*)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
VideoTableCell *cell = [tableView dequeueReusableCellWithIdentifier:@"VideoTableCell"];
if (cell == nil)
{
cell = [[[NSBundle mainBundle] loadNibNamed:@"VideoTableCell" owner:self options:nil]objectAtIndex:0];
}
int temp = [self getVisibleIndex];
if (temp == indexPath.row && fullvisible)
{
cell.imgThumb.hidden = YES ;
//NSLog(@"fullvisible == 1");
NSURL *url = [NSURL URLWithString:[arrVideo objectAtIndex:indexPath.row]];
cell.videoItem = [AVPlayerItem playerItemWithURL:url];
cell.videoPlayer = [AVPlayer playerWithPlayerItem:cell.videoItem];
cell.avLayer = [AVPlayerLayer playerLayerWithPlayer:cell.videoPlayer];
[cell.avLayer setBackgroundColor:[UIColor whiteColor].CGColor];
// [cell.avLayer setVideoGravity:AVLayerVideoGravityResizeAspectFill];
[cell.contentView.layer addSublayer:cell.avLayer];
[cell.videoPlayer play];
[cell setSelectionStyle:UITableViewCellSelectionStyleNone];
}
else
{
cell.imgThumb.hidden = NO ;
cell.videoPlayer = nil;
[cell.avLayer removeFromSuperlayer];
cell.videoItem = nil;
[cell.videoPlayer pause];
}
return cell ;
}
-(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
return 393 ;
}
-(int)getVisibleIndex
{
for (NSIndexPath *indexPath in _tblData.indexPathsForVisibleRows) {
CGRect cellRect = [_tblData rectForRowAtIndexPath:indexPath];
BOOL isVisible = CGRectContainsRect(_tblData.bounds, cellRect);
if (isVisible)
{
index = (int)indexPath.row ;
}
}
return index ;
}
- (void)scrollViewDidScroll:(UIScrollView *)aScrollView
{
NSArray* cells = _tblData.visibleCells;
for (VideoTableCell* cell in cells)
{
NSIndexPath *path = [_tblData indexPathForCell:cell] ;
index =(int) path.row;
fullvisible = YES;
[_tblData reloadData];
}
}
Write a category for UITableViewCell to check if the cell is fully visible:
UITableViewCell+FullyVisible
And in cellForRowAtIndexpath: check if cell is fully visible. If cell is fully visible play video else stop/pause.
Every
UITableViewCell
subclass has a methodprepareForReuse:
so in yourVideoTableCell
just add a method:And in your controller implement a delegate method:
- (void)tableView:(UITableView *)tableView didEndDisplayingCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath
and in
stopVideo
just add[self.videoPlayer pause]
or[cell.videoPlayer stop]
try this methods in UITableView
should help you.
If this will not fully work for your requirements try override
scrollViewDidScroll
more details there