iOS开发高仿抖音,上下切换横竖屏播放!
Posted iOS大鑫
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了iOS开发高仿抖音,上下切换横竖屏播放!相关的知识,希望对你有一定的参考价值。
好久没写文章了,最近有点时间,模仿了一个抖音视频上下滑动切换播放功能,顾记录下实现方案,共勉。
一、先说下大致思路:
1.UITableView : Cell上展示视频第一帧图片,点赞,评论,头像等参数
2.封装一个视频播放View
3.定义一个属性currentIndex,并添加他的观察属性,当currentIndex属性值改变时,处理视频播放功能
4.UITableView滑动代理,处理视频上下滑动动画操作
5.注意,整个UITableView中,只存在一个视频播放实例方法,这样性能提升
直播功能的界面展示,也同样处理逻辑
开始之前,info.plist 需要增加麦克风,相册权限
因为是demo,所有代码怎么简单怎么来,谅解!!!
下面是具体代码,供参考,自己直接copy到项目中就可以用,如有需要再讲代码上传都codding
涉及图片资源,自己随便找个图顶下就行
欢迎关注公众号:编程大鑫,进群大家一起交流进步!
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Bi9YqM5B-1627022506398)(//upload-images.jianshu.io/upload_images/2151291-109c6326a56f2eaa.png?imageMogr2/auto-orient/strip|imageView2/2/w/722/format/webp)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-DH4vadJr-1627022506399)(//upload-images.jianshu.io/upload_images/2151291-699b477a4032ba83.png?imageMogr2/auto-orient/strip|imageView2/2/w/722/format/webp)]
二、代码实现
1,HomeController.h类中
#import "HomeController.h"
#import "VideoTableCell.h" //自定义Cell
#import "VideoView.h"
//位置:松开后切换视频
#define offsetY 100
@interface HomeController ()<UITableViewDataSource,UITableViewDelegate>{
UITableView * table;
NSArray * dataArray; //存放视频url
NSMutableArray * videoPicArray;//视频第一帧图片,真实情况下后台会返回图片第一帧url
}
@property(nonatomic,strong)VideoView * videoView;//视频播放器
@property(nonatomic,assign)NSInteger currentIndex;//当前tableview indexPath
@end
@implementation HomeController
- (void)viewDidLoad {
[super viewDidLoad];
[self initData];
[self setupView];
//获取视频第一帧
dispatch_async(dispatch_get_global_queue(0,0), ^{
for (int i = 0; i < self->dataArray.count;i++) {
UIImage * image = [self getVideoPreViewImage:[NSURL URLWithString:self->dataArray[i]]];
[self->videoPicArray replaceObjectAtIndex:i withObject:image];
dispatch_async(dispatch_get_main_queue(), ^{
[self->table reloadData];
});
}
});
}
-(void)viewWillAppear:(BOOL)animated{
[super viewWillAppear:animated];
//进入界面时,播放
if(self.videoView){
[self.videoView play];
}
}
-(void)viewWillDisappear:(BOOL)animated{
[super viewWillDisappear:animated];
//离开时暂停播放
if(self.videoView){
[self.videoView pause];
}
}
-(void)initData{
dataArray=@[
@"https://aweme.snssdk.com/aweme/v1/play/?video_id=ba8f4ff0c1fe445dbfdc1cc9565222fa&line=0&ratio=720p&media_type=4&vr_type=0&test_cdn=None&improve_bitrate=0",
@"http://ctgdev.oss-cn-shanghai.aliyuncs.com/zys/04795f79-697b-4647-958b-fed0261b2730.mp4",
@"https://aweme.snssdk.com/aweme/v1/play/?video_id=ba8f4ff0c1fe445dbfdc1cc9565222fa&line=0&ratio=720p&media_type=4&vr_type=0&test_cdn=None&improve_bitrate=0",
@"http://ctgdev.oss-cn-shanghai.aliyuncs.com/zys/04795f79-697b-4647-958b-fed0261b2730.mp4",
@"https://aweme.snssdk.com/aweme/v1/play/?video_id=ba8f4ff0c1fe445dbfdc1cc9565222fa&line=0&ratio=720p&media_type=4&vr_type=0&test_cdn=None&improve_bitrate=0"];
videoPicArray=[NSMutableArray array];
for(int i=0;i<dataArray.count;i++){
[videoPicArray addObject:[UIImage imageNamed:@"img_video_loading"]];
}
}
-(void)setupView{
navView.backgroundColor=MS_RGBA(0, 0, 0, 0);
UILabel * liveLabel = [[UILabel alloc] initWithFrame:CGRectMake(0, StatusHeight+10, 60, 20)];
liveLabel.text=@"直播";
liveLabel.font=[UIFont boldSystemFontOfSize:16];
liveLabel.textAlignment=NSTextAlignmentCenter;
liveLabel.textColor=[UIColor whiteColor];
[navView addSubview:liveLabel];
CGFloat leftX = (SCREEN_WIDTH-150)/3;
UILabel * locationLabel = [[UILabel alloc] initWithFrame:CGRectMake(leftX+50, StatusHeight+10, 50, 20)];
locationLabel.text=@"本地";
locationLabel.font=[UIFont systemFontOfSize:17];
locationLabel.textAlignment=NSTextAlignmentCenter;
locationLabel.textColor=[UIColor whiteColor];
[navView addSubview:locationLabel];
UILabel * likeTitle = [[UILabel alloc] initWithFrame:CGRectMake(CGRectGetMaxX(locationLabel.frame), StatusHeight+10, 50, 20)];
likeTitle.text=@"关注";
likeTitle.font=[UIFont systemFontOfSize:16];
likeTitle.textAlignment=NSTextAlignmentCenter;
likeTitle.textColor=[UIColor whiteColor];
[navView addSubview:likeTitle];
UILabel * hotTitle = [[UILabel alloc] initWithFrame:CGRectMake(CGRectGetMaxX(likeTitle.frame), StatusHeight+10, 50, 20)];
hotTitle.text=@"推荐";
hotTitle.font=[UIFont boldSystemFontOfSize:16];
hotTitle.textAlignment=NSTextAlignmentCenter;
hotTitle.textColor=[UIColor whiteColor];
[navView addSubview:hotTitle];
UILabel * searchLabel = [[UILabel alloc] initWithFrame:CGRectMake(SCREEN_WIDTH-60, StatusHeight+10, 60, 20)];
searchLabel.text=@"搜索";
searchLabel.font=[UIFont boldSystemFontOfSize:16];
searchLabel.textAlignment=NSTextAlignmentCenter;
searchLabel.textColor=[UIColor whiteColor];
[navView addSubview:searchLabel];
table = [[UITableView alloc] initWithFrame:CGRectMake(0,0,SCREEN_WIDTH,SCREEN_HEIGHT)];
table.dataSource = self;
table.showsVerticalScrollIndicator = NO;
table.delegate=self;
table.separatorStyle = UITableViewCellSeparatorStyleNone;
table.rowHeight=table.frame.size.height;
table.backgroundColor=[UIColor blackColor];
table.scrollsToTop=NO;
table.contentInset=UIEdgeInsetsMake(0, 0, TabbarStautsHeight, 0);
if (@available(ios 11.0,*)) {
[table setContentInsetAdjustmentBehavior:UIScrollViewContentInsetAdjustmentNever];
}
[self.view addSubview:table];
[self.view addSubview:navView];
[table registerClass:[VideoTableCell class] forCellReuseIdentifier:@"VideoTableCell"];
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.1 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
[self addObserver:self forKeyPath:@"currentIndex" options:NSKeyValueObservingOptionInitial|NSKeyValueObservingOptionNew context:nil];//添加观察者,重点
});
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return dataArray.count;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
VideoTableCell *cell = [tableView dequeueReusableCellWithIdentifier:@"VideoTableCell" forIndexPath:indexPath];
//显示视频第一帧图片
cell.bgImageView.image=videoPicArray[indexPath.row];
return cell;
}
- (void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate{
dispatch_async(dispatch_get_main_queue(), ^{
CGPoint translatedPoint = [scrollView.panGestureRecognizer translationInView:scrollView];
scrollView.panGestureRecognizer.enabled = NO;
NSLog(@"UITableView禁止响应其他滑动手势");
if(translatedPoint.y < -offsetY && self.currentIndex < (self->dataArray.count - 1)) {
self.currentIndex ++;
NSLog(@"向下滑动索引递增");
}
if(translatedPoint.y > offsetY && self.currentIndex > 0) {
self.currentIndex --;
NSLog(@"向上滑动索引递减");
}
[UIView animateWithDuration:0.15
delay:0.0
options:UIViewAnimationOptionCurveEaseOut animations:^{
[self->table scrollToRowAtIndexPath:[NSIndexPath indexPathForRow:self.currentIndex inSection:0] atScrollPosition:UITableViewScrollPositionTop animated:NO];
} completion:^(BOOL finished) {
scrollView.panGestureRecognizer.enabled = YES;
NSLog(@"UITableView可以响应其他滑动手势");
}];
});
}
//观察currentIndex变化
-(void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSKeyValueChangeKey,id> *)change context:(void *)context {
if ([keyPath isEqualToString:@"currentIndex"]) {
NSLog(@"indexPath发生改变");
/*
整个列表视频播放,只会存在一个播放器
*/
VideoTableCell *cell = [table cellForRowAtIndexPath:[NSIndexPath indexPathForRow:self.currentIndex inSection:0]];
[self.videoView removePlayer];
[self.videoView removeFromSuperview];
self.videoView=[[VideoView alloc] initWithFrame:CGRectMake(0, 0,SCREEN_WIDTH, table.rowHeight) url:dataArray[self.currentIndex] image:videoPicArray[self.currentIndex]];
[cell.contentView addSubview:self.videoView];
[cell insertSubview:cell.middleView belowSubview:self.videoView];
WEAKBLOCK(self);
self.videoView.changeScreen = ^(BOOL isFull) {
STRONGBLOCK(self);
cell.bgImageView.hidden=YES;
if(isFull){
self.tabBarController.tabBar.hidden = YES;
self->navView.hidden=YES;
self->table.scrollEnabled=NO;
cell.middleView.hidden=YES;
}else{
self.tabBarController.tabBar.hidden = NO;
self->navView.hidden=NO;
self->table.scrollEnabled=YES;
cell.middleView.hidden=NO;
cell.bgImageView.hidden=NO;
}
};
}
}
//mark:一般真实项目,后台会返回视频第一帧图片url给端
// 获取网络视频第一帧
- (UIImage*)getVideoPreViewImage:(NSURL *)path
{
AVURLAsset *asset = [[AVURLAsset alloc] initWithURL:path options:nil];
AVAssetImageGenerator *assetGen = [[AVAssetImageGenerator alloc] initWithAsset:asset];
assetGen.appliesPreferredTrackTransform = YES;
CMTime time = CMTimeMakeWithSeconds(0, 1);
NSError *error = nil;
CMTime actualTime;
CGImageRef image = [assetGen copyCGImageAtTime:time actualTime:&actualTime error:&error];
UIImage *videoImage = [[UIImage alloc] initWithCGImage:image];
CGImageRelease(image);
return videoImage;
}
@end
2,VideoTableCell.h
@property(nonatomic,strong)UIImageView * bgImageView;
@property(nonatomic,strong)UIView * middleView;
VideoTableCell.m
#import "VideoTableCell.h"
#import "Config.h"
@implementation VideoTableCell
-(instancetype)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier{
if(self=[super initWithStyle:style reuseIdentifier:reuseIdentifier]){
self.contentView.backgroundColor=[UIColor blackColor];
CGFloat height = SCREEN_HEIGHT;
self.bgImageView = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, SCREEN_WIDTH, height)];
self.bgImageView.tag=100;
self.bgImageView.image=[UIImage imageNamed:@"img_video_loading"];
[self.contentView addSubview:self.bgImageView];
self.middleView=[[UIView alloc] initWithFrame:CGRectMake(SCREEN_WIDTH-80, (height-150-StatusHeight)/2, 80, 50)];
self.middleView.tag=200;
[self.contentView addSubview:self.middleView];
UILabel * titleLabel = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, 80, 50)];
titleLabel.text=@"头像";
titleLabel.font=[UIFont boldSystemFontOfSize:16];
titleLabel.textColor=[UIColor whiteColor];
titleLabel.textAlignment = 1;
[self.middleView addSubview:titleLabel];
UILabel * titleLabel2 = [[UILabel alloc] initWithFrame:CGRectMake(0, CGRectGetMaxY(titleLabel.frame), 80, 50)];
titleLabel2.text=@"点赞";
titleLabel2.font=[UIFont boldSystemFontOfSize:16];
titleLabel2.textColor=[UIColor whiteColor];
titleLabel2.textAlignment = 1;
[self.middleView addSubview:titleLabel2];
UILabel * titleLabel3 = [[UILabel alloc] initWithFrame:CGRectMake(0, CGRectGetMaxY(titleLabel2.frame), 80, 50)];
titleLabel3.text=@"评论";
titleLabel3.font=[UIFont boldSystemFontOfSize:16];
titleLabel3.textColor=[UIColor whiteColor];
titleLabel3.textAlignment = 1;
[self.middleView addSubview:titleLabel3];
}
return self;
}
@end
3,重点来啦,VideoView.h
@interface VideoView : UIView
{
UIView * sliderView;
UIView * bottomView;
UILabel *countTimeLabel;
UIButton * startVideoBtn;
UIButton * changeFullScreenBtn;
}
///真实项目中,直接用dict包裹入参
-(instancetype)initWithFrame:(CGRect)frame url:(NSString*)url image:(UIImage*)image;
@property (nonatomic,strong)AVPlayer *player;//播放器对象
@property(nonatomic,strong) AVPlayerLayer *avLayer; //展示播放View
@property(nonatomic,strong)UILabel * currentTimeLabel;//当前倒计时
@property (nonatomic,strong)UISlider *slider;//滑竿
@property(nonatomic,assign)BOOL isFullScreen; //是否全屏状态 默认NO
@property (nonatomic, assign) CGRect smallFrame; //小屏幕frame
@property (nonatomic, assign) CGRect bigFrame; //全屏frame
///点击全屏,取消全屏回调
@property(nonatomic,copy)void(^changeScreen)(BOOL isFull);
///开始播放
-(void)play;
///暂停
-(void)pause;
///移除观察者
-(void)removePlayer;
VideoView.m
#import "VideoView.h"
#import "Config.h"
@implementation VideoView
-(instancetype)initWithFrame:(CGRect)frame url:(NSString*)url image:(UIImage *)image{
if(self=[super initWithFrame:frame]){
self.isFullScreen = NO;
self.smallFrame = frame;
self.bigFrame = CGRectMake(0, 0,SCREEN_WIDTH, SCREEN_HEIGHT);
CGFloat height = frame.size.height;
CGFloat width = frame.size.width;
//占位,视频第一帧图片
UIImageView* bgImageView = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, width, height)];
bgImageView.image=image;
bgImageView.userInteractionEnabled=YES;
[self addSubview:bgImageView];
//网络视频路径
NSURL *webVideoUrl = [NSURL URLWithString:url];
AVPlayerItem *playerItem = [[AVPlayerItem alloc] initWithURL:webVideoUrl];
self.player = [[AVPlayer alloc] initWithPlayerItem:playerItem];
self.avLayer = [AVPlayerLayer playerLayerWithPlayer:self.player];
self.avLayer.backgroundColor=[UIColor blackColor].CGColor;
self.avLayer.videoGravity = AVLayerVideoGravityResizeAspectFill;
self.avLayer.frame = CGRectMake(0, 0, bgImageView.frame.size.width, bgImageView.frame.size.height);
[bgImageView.layer addSublayer:self.avLayer];
sliderView =[[UIView alloc] initWithFrame:frame];
sliderView.hidden=YES;
[self addSubview:sliderView];
bottomView=[[UIView alloc] initWithFrame:CGRectMake(0, sliderView.frame.size.height-50-TabbarStautsHeight, frame.size.width, 50)];
bottomView.backgroundColor=MS_RGBA(0, 0, 0, 0.5);
[sliderView addSubview:bottomView];
startVideoBtn =[UIButton buttonWithType:UIButtonTypeCustom];
startVideoBtn.frame=CGRectMake(0,0, 50, 50);
[startVideoBtn setImage:[UIImage imageNamed:@"videoPauseBtn"] forState:normal];
[startVideoBtn addTarget:self action:@selector(actStartVideo:) forControlEvents:UIControlEventTouchUpInside];
[bottomView addSubview:startVideoBtn];
self.currentTimeLabel = [[UILabel alloc] initWithFrame:CGRectMake(50, 0, 50, 50)];
self.currentTimeLabel.textColor=[UIColor whiteColor];
self.currentTimeLabel.text=@"00:00";
self.currentTimeLabel.font=[UIFont systemFontOfSize:14];
self.currentTimeLabel.textAlignment=1;
[bottomView addSubview:self.currentTimeLabel];
self.slider=[[UISlider alloc] initWithFrame:CGRectMake(100, 0, SCREEN_WIDTH-200, 50)];
self.slider.minimumValue=0;
self.slider.minimumTrackTintColor=[UIColor whiteColor];
self.slider.maximumTrackTintColor =[UIColor colorWithRed:1 green:1 blue:1 alpha:0.5];
[self.slider addTarget:self action:@selector(avSliderAction) forControlEvents:
UIControlEventTouchUpInside|UIControlEventTouchCancel|UIControlEventTouchUpOutside];
[self.slider setThumbImage:[UIImage imageNamed:@"slider"] forState:normal];
[bottomView addSubview:self.slider];
countTimeLabel = [[UILabel alloc] initWithFrame:CGRectMake(CGRectGetMaxX(self.slider.frame), 0, 50, 50)];
countTimeLabel.textColor=[UIColor whiteColor];
countTimeLabel.text=@"00:00";
countTimeLabel.font=[UIFont systemFontOfSize:14];
countTimeLabel.textAlignment=1;
[bottomView addSubview:countTimeLabel];
changeFullScreenBtn =[UIButton buttonWithType:UIButtonTypeCustom];
changeFullScreenBtn.frame=CGRectMake(CGRectGetMaxX(countTimeLabel.frame),0, 50, 50);
[changeFullScreenBtn setImage:[UIImage imageNamed:@"exitFullScreen"] forState:normal];
[changeFullScreenBtn addTarget:self action:@selector(actChange:) forControlEvents:UIControlEventTouchUpInside];
[bottomView addSubview:changeFullScreenBtn];
changeFullScreenBtn.selected=NO;
WEAKBLOCK(self);
[self.player addPeriodicTimeObserverForInterval:CMTimeMakeWithSeconds(1, NSEC_PER_SEC) queue:NULL usingBlock:^(CMTime time) {
STRONGBLOCK(self);
NSInteger currentTime = CMTimeGetSeconds(self.player.currentItem.currentTime);
NSInteger countTime = CMTimeGetSeconds(self.player.currentItem.duration);
self.currentTimeLabel.text=[self getMMSSFromSS:[NSString stringWithFormat:@"%zi",currentTime]];
self.slider.value=currentTime;
if(currentTime>=countTime){
self.slider.value=0;
[self.player seekToTime:CMTimeMake(0, 1)];
}
}];
[self.player.currentItem addObserver:self forKeyPath:@"status" options:NSKeyValueObservingOptionNew context:nil];
UITapGestureRecognizer *hidenTap = [[UITapGestureRecognizer alloc]initWithTarget:self action:@selector(hiddenBottonView:)];
[self addGestureRecognizer:hidenTap];
}
return self;
}
- (void)hiddenBottonView: (UITapGestureRecognizer *)tap {
if (sliderView.hidden) {
sliderView.hidden = NO;
}else {
sliderView.hidden = YES;
}
}
- (void)avSliderAction{
CGFloat seconds = self.slider.value;
[self startPlayer:seconds];
}
-(void)startPlayer:(CGFloat)seconds{
CMTime startTime = CMTimeMakeWithSeconds(seconds, self.player.currentTime.timescale);
[self.player seekToTime:startTime];
}
-(void)layoutSubviews{
[super layoutSubviews];
self.avLayer.frame=self.bounds;
sliderView.frame=self.bounds;
CGFloat topY = !self.isFullScreen?TabbarStautsHeight:0;
CGFloat leftX = !self.isFullScreen?0:NavigationHeight;
CGFloat spaceWidth = !self.isFullScreen?0:TabbarStautsHeight;
bottomView.frame=CGRectMake(0, sliderView.frame.size.height-topY-50, sliderView.frame.size.width, 50);
startVideoBtn.frame=CGRectMake(leftX, 0, 50, 50);
self.currentTimeLabel.frame = CGRectMake(leftX+50, 0, 50, 50);
self.slider.frame=CGRectMake(CGRectGetMaxX(self.currentTimeLabel.frame), 0, sliderView.frame.size.width-100-spaceWidth-CGRectGetMaxX(self.currentTimeLabel.frame), 50);
countTimeLabel.frame = CGRectMake(sliderView.frame.size.width-100-spaceWidth, 0, 50, 50);
changeFullScreenBtn.frame=CGRectMake(sliderView.frame.size.width-50-spaceWidth, 0, 50, 50);
}
//观察currentIndex变化
-(void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSKeyValueChangeKey,id> *)change context:(void *)context {
if ([keyPath isEqualToString:@"status"]){
//获取playerItem的status属性最新的状态
AVPlayerStatus status = [[change objectForKey:@"new"] intValue];
switch (status) {
case AVPlayerStatusReadyToPlay:{
NSInteger countTime = CMTimeGetSeconds(self.player.currentItem.duration);
self.slider.maximumValue =countTime;
countTimeLabel.text=[self getMMSSFromSS:[NSString stringWithFormat:@"%zi",countTime]];
[self.player play];
break;
}
case AVPlayerStatusFailed:{//视频加载失败,点击重新加载
NSLog(@"视频播放失败");
break;
}
case AVPlayerStatusUnknown:{
NSLog(@"视频播放失败");
break;
}
default:
break;
}
}
}
-(void)play
{
[self.player play];
}
-(void)pause{
[self.player pause];
}
-(void)actStartVideo:(UIButton*)btn{
if(!startVideoBtn.selected){
startVideoBtn.selected=YES;
[startVideoBtn setImage:[UIImage imageNamed:@"videoPlayBtn"] forState:normal];
[self pause];
}else{
startVideoBtn.selected=NO;
[startVideoBtn setImage:[UIImage imageNamed:@"videoPauseBtn"] forState:normal];
[self play];
}
}
-(void)actChange:(UIButton*)btn{
if(!changeFullScreenBtn.selected){
self.isFullScreen=YES;
changeFullScreenBtn.selected=YES;
[changeFullScreenBtn setImage:[UIImage imageNamed:@"exitFullScreen"] forState:normal];
[UIView animateWithDuration:0.3 animations:^{
self.transform = CGAffineTransformMakeRotation(M_PI / 2);
} completion:nil];
self.frame=self.bigFrame;
if(self.changeScreen){
self.changeScreen(self.isFullScreen);
}
}else{
changeFullScreenBtn.selected=NO;
self.isFullScreen=NO;
[changeFullScreenBtn setImage:[UIImage imageNamed:@"kr-video-player-fullscreen"] forState:normal];
[UIView animateWithDuration:0.3 animations:^{
self.transform = CGAffineTransformMakeRotation(M_PI * 2);
} completion:^(BOOL finished) {
if(self.changeScreen){
self.changeScreen(self.isFullScreen);
}
}];
self.frame=self.smallFrame;
}
}
-(void)removePlayer{
[self.player.currentItem removeObserver:self forKeyPath:@"status"];
[self.player pause];
}
-(NSString *)getMMSSFromSS:(NSString *)totalTime{
NSInteger seconds = [totalTime integerValue];
NSString *str_minute = [NSString stringWithFormat:@"%02ld",seconds/60];
NSString *str_second = [NSString stringWithFormat:@"%02ld",seconds%60];
NSString *format_time = [NSString stringWithFormat:@"%@:%@",str_minute,str_second];
return format_time;
}
@end
4,config.h文件里常用方法
#ifndef Config_h
#define Config_h
///判断是否为iPhone X 系列
#define iPhoneX \\
({BOOL isPhoneX = NO;\\
if (@available(iOS 11.0, *)) {\\
isPhoneX = [[UIApplication sharedApplication] delegate].window.safeAreaInsets.bottom > 0.0;\\
}\\
(isPhoneX);})
#define SCREEN_WIDTH ([UIScreen mainScreen].bounds.size.width)
#define SCREEN_HEIGHT ([UIScreen mainScreen].bounds.size.height)
#define GL_isPad ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPad)
#define GL_isIPhone_Xr ([UIScreen instancesRespondToSelector:@selector(currentMode)] ? CGSizeEqualToSize(CGSizeMake(828, 1792), [[UIScreen mainScreen] currentMode].size) && !GL_isPad : NO)
#define GL_isIPhone_Xs ([UIScreen instancesRespondToSelector:@selector(currentMode)] ? CGSizeEqualToSize(CGSizeMake(1125, 2436), [[UIScreen mainScreen] currentMode].size) && !GL_isPad : NO)
#define GL_isIPhone_Xs_Max ([UIScreen instancesRespondToSelector:@selector(currentMode)] ? CGSizeEqualToSize(CGSizeMake(1242, 2688), [[UIScreen mainScreen] currentMode].size) && !GL_isPad : NO)
#define GL_isIPhone_iPhone12_Mini ([UIScreen instancesRespondToSelector:@selector(currentMode)] ? CGSizeEqualToSize(CGSizeMake(1080, 2340), [[UIScreen mainScreen] currentMode].size) && !GL_isPad : NO)
#define GL_isIPhone_X ([UIScreen instancesRespondToSelector:@selector(currentMode)] ? CGSizeEqualToSize(CGSizeMake(1125, 2436), [[UIScreen mainScreen] currentMode].size) && !GL_isPad : NO)
#define GL_isIPhone_iPhone12 ([UIScreen instancesRespondToSelector:@selector(currentMode)] ? CGSizeEqualToSize(CGSizeMake(1170, 2532), [[UIScreen mainScreen] currentMode].size) && !GL_isPad : NO)
#define GL_isIPhone_iPhone12_ProMax ([UIScreen instancesRespondToSelector:@selector(currentMode)] ? CGSizeEqualToSize(CGSizeMake(1284, 2778), [[UIScreen mainScreen] currentMode].size) && !GL_isPad : NO)
///导航栏高度
#define NavigationHeight ((GL_isIPhone_Xr == YES || GL_isIPhone_Xs == YES || GL_isIPhone_Xs_Max == YES || GL_isIPhone_iPhone12_Mini == YES) ? 88.0 : (GL_isIPhone_X == YES) ? 92 : (GL_isIPhone_iPhone12 == YES || GL_isIPhone_iPhone12_ProMax == YES) ? 91 : 64.0)
///若果是iPhoneX 则底部减去一个半圆弧度高
#define TabbarHeight (iPhoneX?34:0)
///状态栏
#define StatusHeight [[UIApplication sharedApplication] statusBarFrame].size.height
#define TabbarStautsHeight (iPhoneX?83:49)
#define MS_RGBA(r,g,b,a) [UIColor colorWithRed:(r)/255.0f green:(g)/255.0f blue:(b)/255.0f \\
alpha:(a)]
///WEAKBLOCK
#define WEAKBLOCK(type) __weak __typeof(type) weak##type = type
///STRONGBLOCK
#define STRONGBLOCK(type) __strong __typeof(type) type = weak##type
#endif /* Config_h */
至此,仿抖音视频上下滑动切换功能已完成。
以上是关于iOS开发高仿抖音,上下切换横竖屏播放!的主要内容,如果未能解决你的问题,请参考以下文章