iOS开发笔记 -- 视频与图片的混合轮播

项目需求:产品详情页的轮播图做成视频与图片的混合轮播,类似于淘宝的界面,第一个图为产品的视频介绍,其余为图片介绍,本篇 demo

demo预览图

思路:
1、轮播图我们可以用UICollectionView或者是UIScrollView来实现,本篇demo使用的是后者。
2、根据数据的类型判断第一张图是否是视频类型。
3、若第一张是视频类型,则将自定义视频的view加入到UIScrollView中。
4、自定义视频的view可以使用系统的AVPlayerViewController,也可以自定义AVPlayer来实现视频的播放。
5、给自定义的视频view加上遮罩,遮罩的作用是控制视频的暂停与播放,显示进度条的进度等等。

一、UIScrollView 轮播图的创建

1、新建一个view,创建一个类方法,进行初始化,传入要显示的数据

+ (instancetype)scrollViewFrame:(CGRect)frame imageStringGroup:(NSArray *)imgArray {
    XQCarousel *carousel = [[self alloc] initWithFrame:frame];
    carousel.contentArray = imgArray;
    return carousel;
}

2、初始化控件,并加载数据,实现UIScrollView的协议,当滑动的时候 控制视频的暂停与播放

- (void)loadUI {

    self.scrollView.contentInsetAdjustmentBehavior = UIScrollViewContentInsetAdjustmentNever;
    self.scrollView = [[UIScrollView alloc]initWithFrame:CGRectMake(0, 0, self.frame.size.width, self.frame.size.height)];
    self.scrollView.contentSize = CGSizeMake(self.frame.size.width * self.contentArray.count, self.frame.size.height);
    self.scrollView.pagingEnabled = YES;
    self.scrollView.showsHorizontalScrollIndicator = NO;
    self.scrollView.delegate = self;
    [self addSubview:self.scrollView];

    for (NSInteger index = 0; index < self.contentArray.count; index ++) {
        UIImageView *img = [[UIImageView alloc]initWithFrame:CGRectMake(self.frame.size.width * index, 0, self.frame.size.width, self.frame.size.height)];
        img.image = [UIImage imageNamed:self.contentArray[index]];
        /** 测试 **/
        if (index == 0) {
            self.videoView = [XQVideoView videoViewFrame:img.frame videoUrl:self.contentArray[index]];
            self.videoView.videoUrl = self.contentArray[index];
            [self.scrollView addSubview:self.videoView];
        }else {
            [self.scrollView addSubview:img];
        }
    }

    self.pageControl = [[UIPageControl alloc]init];
    self.pageControl.frame = CGRectMake(0, self.frame.size.height - 30, self.frame.size.width, 30);
    self.pageControl.numberOfPages = self.contentArray.count;
    self.pageControl.currentPage = 0;
    self.pageControl.currentPageIndicatorTintColor = [UIColor redColor];
    [self addSubview:self.pageControl];

}

- (void)scrollViewDidScroll:(UIScrollView *)scrollView {
    NSInteger currentPage = round(scrollView.contentOffset.x / self.frame.size.width);
    self.pageControl.currentPage = currentPage;

    if (self.videoView.isPlay) {
        if (currentPage == 0) {
            [self.videoView start];
        }else {
            [self.videoView stop];
        }
    }

}

二、新建VideoView,初始化AVPlayerViewController,具体实现见demo,主要用到AVPlayerViewController中AVPlayer的两个方法。


// ****** 获取视频的播放进度 控制进度条的显示 ******
- (id)addPeriodicTimeObserverForInterval:(CMTime)interval queue:(nullable dispatch_queue_t)queue usingBlock:(void (^)(CMTime time))block;

// ****** 控制播放器的播放进度,本篇demo用来控制重新播放 ******
- (void)seekToTime:(CMTime)time toleranceBefore:(CMTime)toleranceBefore toleranceAfter:(CMTime)toleranceAfter completionHandler:(void (^)(BOOL finished))completionHandler NS_AVAILABLE(10_7, 5_0);

三、给VideoView加一个遮罩,在其view上添加开始与重新播放的按钮、进度条和单击手势。

#import "VideoMaskView.h"

@interface VideoMaskView ()

// ******* 底部进度条 *******
@property (nonatomic, strong) UIProgressView *progressView;
// ******* 开始播放按钮 *******
@property (nonatomic, strong) UIButton *stratButton;
// ******* 单击手势 *******
@property (nonatomic, strong) UITapGestureRecognizer *singleTap;
// ******* 重新播放按钮 *******
@property (nonatomic, strong) UIButton *replayButton;

@end

@implementation VideoMaskView

- (instancetype)initWithFrame:(CGRect)frame {
    self = [super initWithFrame:frame];
    if (self) {
        [self loadUI];
    }
    return self;
}

- (void)loadUI {

    [self addSubview:self.stratButton];
    [self addSubview:self.replayButton];
    [self addSubview:self.progressView];

    [self createGesture];

}

/*
 *  创建手势
 */
- (void)createGesture {
    // 单击
    self.singleTap = [[UITapGestureRecognizer alloc]initWithTarget:self action:@selector(singleTapAction:)];
    self.singleTap.numberOfTouchesRequired = 1; //手指数
    self.singleTap.numberOfTapsRequired = 1;
    [self addGestureRecognizer:self.singleTap];
}

- (void)singleTapAction:(UITapGestureRecognizer *)tap {
    if (self.buttonValue) {
        self.buttonValue(XQPlayerStateStart);
    }
}

- (void)setIsStartButton:(BOOL)isStartButton {
    _isStartButton = isStartButton;
    isStartButton ? [self.stratButton setHidden:YES] : [self.stratButton setHidden:NO];
}

- (void)setProgressValue:(CGFloat)progressValue {
    _progressValue = progressValue;
    self.progressView.progress = progressValue;
    progressValue == 1 ? [self.replayButton setHidden:NO] : [self.replayButton setHidden:YES];
}

- (void)playerCurrentTime:(NSInteger)currentTime totalTime:(NSInteger)totalTime sliderValue:(CGFloat)sliderValue {
    self.progressValue = sliderValue;
}

- (UIProgressView *)progressView {
    if (!_progressView) {
        _progressView = [[UIProgressView alloc]initWithFrame:CGRectMake(0, self.frame.size.height - 2, self.frame.size.width, 5)];
        _progressView.progressViewStyle = UIProgressViewStyleDefault;
        _progressView.progressTintColor = [UIColor orangeColor];
        _progressView.progress = 0;
    }
    return _progressView;
}

- (UIButton *)stratButton {
    if (!_stratButton) {
        _stratButton = [UIButton buttonWithType:UIButtonTypeCustom];
        _stratButton.bounds = CGRectMake(0, 0, 40, 40);
        _stratButton.center = self.center;
        [_stratButton setImage:[UIImage imageNamed:@"play"] forState:UIControlStateNormal];
        [_stratButton addTarget:self action:@selector(startButtonTaped) forControlEvents:UIControlEventTouchUpInside];
    }
    return _stratButton;
}

- (UIButton *)replayButton {
    if (!_replayButton) {
        _replayButton = [UIButton buttonWithType:UIButtonTypeCustom];
        _replayButton.bounds = CGRectMake(0, 0, 50, 70);
        _replayButton.center = self.center;
        [_replayButton setImage:[UIImage imageNamed:@"ZFPlayer_repeat_video"] forState:UIControlStateNormal];
        _replayButton.hidden = YES;
        [_replayButton addTarget:self action:@selector(replayButtonTaped) forControlEvents:UIControlEventTouchUpInside];
    }
    return _replayButton;
}

- (void)startButtonTaped {
    if (self.buttonValue) {
        self.buttonValue(XQPlayerStateStart);
    }
}

- (void)replayButtonTaped {
    if (self.buttonValue) {
        self.buttonValue(XQPlayerStateReplay);
    }
}

@end

1、本篇demo只是粗略实现了图片和视频轮播,可在实际的项目中根据需要进行修改,本人只是提供了一个思路。
2、推荐 视频播放的第三方 ZFPlayer 。

你可能感兴趣的:(iOS开发笔记)