2016-01-13 19 views
18

quello che avevo fatto: -TableView il video cellulare autoplay

avevo aggiunto il codice che riproduce un video in cui cella è completamente visibile e quando ho scorrere verso il basso o verso l'alto si ricarica di nuovo e giochi tableView di nuovo video. Ma il mio requisito è diverso.

Quello che vuole realmente:

voglio giocare un video fino alla cella in avanti o indietro completamente visibile. Quando l'utente scorre verso il basso o verso l'alto non ha effetto fino a quando la cella indietro o avanti è completamente visibile.

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]; 

    } 
} 
+0

Forse impostando il 'actionAtItemEnd' per mettere in pausa, controllando con KVO lo stato di pausa, controllare se' player.currentTime == player.currentItem .duration' (è quello che vuoi), e suonare l'oggetto successivo, se è il caso. In altre parole, creando una micro-pausa tra gli elementi ... – Larme

+0

Prova questa risposta: [http://stackoverflow.com/questions/9831485/best-way-to-check-if-uitableviewcell-is-completely-visible ] (http://stackoverflow.com/questions/9831485/best-way-to-check-if-uitableviewcell-is-completely-visible) –

risposta

14

Ogni UITableViewCell sottoclasse ha un metodo prepareForReuse: Quindi nel tuo VideoTableCell è sufficiente aggiungere un metodo:

-(void)prepareForReuse { 
    [super prepareForReuse]; 
    [self.videoPlayer play]; 
} 

E nel controller implementare un metodo delegato: - (void)tableView:(UITableView *)tableView didEndDisplayingCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath

- (void)tableView:(UITableView *)tableView didEndDisplayingCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath { 

    [cell stopVideo]; 
} 

e in stopVideo basta aggiungere [self.videoPlayer pause] o [cell.videoPlayer stop]

-2

Scrivere una categoria per UITableViewCell per verificare se la cella è completamente visibile:

UITableViewCell + FullyVisible

-(BOOL) isFullyVisible { 

UITableView *tableview = (UITableView *)[self parents:[UITableView class]]; 
CGRect rect = [tableview rectForRowAtIndexPath:[tableview indexPathForCell:self]]; 
rect = [tableview convertRect:rect toView:tableview.superview]; 
return CGRectContainsRect(tableview.frame, rect); 
} 

E in cellForRowAtIndexPath: verifica se la cella è completamente visibile. Se la cella è completamente visibile, riproduci il video, ferma/pausa.

4

provare questo metodo in UITableView

func tableView(tableView: UITableView, didEndDisplayingCell cell: UITableViewCell, forRowAtIndexPath indexPath: NSIndexPath) { 
    // stop video 
} 

func tableView(tableView: UITableView, willDisplayCell cell: UITableViewCell, forRowAtIndexPath indexPath: NSIndexPath) { 
    // play video 
} 

dovrebbe aiutare.

Se questo non funziona pienamente alle vostre esigenze cercano ignorare scrollViewDidScroll more details there