我們看現(xiàn)在主流的直播平臺都有左右滑動去掉直播信息党窜,上下滑動切換頻道的功能:
粉色界面代表直播信息界面搏予,就是觀眾、禮物粉捻、彈幕的界面礁遣。
下面的圖片代表直播的播放界面,用切換圖片代表頻道的切換肩刃。
在這我寫了一個小的Demo來說明是怎么實現(xiàn)這個功能的:首先說一下思路
- 看到這個界面的第一反應這不就是一個ScrollView嗎祟霍?但仔細把玩一下,ScrollView不好實現(xiàn)這個效果盈包。必須用獲取手指觸摸位置拖動控件的方法沸呐,在有直播信息的界面,移除直播信息界面劃過屏幕寬的大于五分之一才回移除直播信息界面呢燥。在沒有直播信息界面時崭添,必須劃過小于屏幕寬的五分之四才能添加直播信息界面。上下切花頻道叛氨,大于屏幕高的五分之一會切換到下一頻道呼渣,小于負的屏幕高五分之一就會切換到上移頻道。切換頻道需要重新加載界面寞埠。上述滑動條件如果沒有滿足都會回到滑動前的位置屁置。
- 首先單獨實現(xiàn)左右滑動,再單獨實現(xiàn)上下滑動
- 避免左右滑和上下滑沖突畸裳,區(qū)別開始滑動時缰犁,是上下滑動和還是左右滑動,開始滑動后水平或垂直滑動的方向不能改變怖糊,直到再次開始觸摸
- 在結(jié)束觸摸的方法中判斷帅容,實現(xiàn)上下滑動切換頻道播放,左右滑動添加和移除直播信息界面
在控制器上加上直播信息LivingInfoView伍伤,下面代碼中的注釋已經(jīng)說的很清楚了
手勢分兩部分
播放控制器的代碼:
#define Screen_width [UIScreen mainScreen].bounds.size.width
#define Screen_height [UIScreen mainScreen].bounds.size.height
@interface ViewController ()
@property (weak, nonatomic) LivingInfoView *livingInfoView;
@property (assign, nonatomic) BOOL isBeginSlid;//記錄開始觸摸的方向
@property (weak, nonatomic) UIImageView *playLayer;
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
self.view.backgroundColor = [UIColor whiteColor];
// 播放層
UIImageView *playLayer = [[UIImageView alloc]initWithFrame:CGRectMake(0, 0, Screen_width, Screen_height)];
[self.view addSubview:playLayer];
self.playLayer = playLayer;
playLayer.image = [UIImage imageNamed:@"PlayView"];
playLayer.userInteractionEnabled = YES;
// 播放信息層
LivingInfoView *livingInfoView = [[LivingInfoView alloc]initWithFrame:CGRectMake(0, 0, Screen_width, Screen_height)];
[playLayer addSubview:livingInfoView];
self.livingInfoView = livingInfoView;
livingInfoView.backgroundColor = [UIColor colorWithRed:242 / 255.0 green:156 / 255.0 blue:177 / 255.0 alpha:0.6];
}
#pragma mark - 界面的滑動
- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
self.isBeginSlid = YES;
}
開始記錄觸摸方向并徘,touchMove的方法是滑動中記錄手指移動的位置,是界面滑動的核心方法扰魂,直播信息界面的touchMove方法會傳到下層的直播播放界面麦乞,所以播放頁的touchMove方法可以和直播信息界面的touchMove方法合并蕴茴。
- (void)touchesMoved:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
// 1.獲取手指
UITouch *touch = [touches anyObject];
// 2.獲取觸摸的上一個位置
CGPoint lastPoint;
CGPoint currentPoint;
// 3.獲取偏移位置
CGPoint tempCenter;
if (self.isBeginSlid) {//首次觸摸進入
lastPoint = [touch previousLocationInView:self.playLayer];
currentPoint = [touch locationInView:self.playLayer];
//判斷是左右滑動還是上下滑動
if (ABS(currentPoint.x - lastPoint.x) > ABS(currentPoint.y - lastPoint.y)) {
// 3.獲取偏移位置
tempCenter = self.livingInfoView.center;
tempCenter.x += currentPoint.x - lastPoint.x;//左右滑動
//禁止向左劃
if (self.livingInfoView.frame.origin.x == 0 && currentPoint.x -lastPoint.x > 0) {//滑動開始是從0點開始的,并且是向右滑動
self.livingInfoView.center = tempCenter;
}
// else if(self.livingInfoView.frame.origin.x > 0){
// self.livingInfoView.center = tempCenter;
// }
// NSLog(@"%@-----%@",NSStringFromCGPoint(tempCenter),NSStringFromCGPoint(self.livingInfoView.center));
}else{
// 3.獲取偏移位置
tempCenter = self.playLayer.center;
tempCenter.y += currentPoint.y - lastPoint.y;//上下滑動
self.playLayer.center = tempCenter;
}
}else{//滑動開始后進入姐直,滑動方向要么水平要么垂直
if (self.playLayer.frame.origin.y != 0){//垂直的優(yōu)先級高于左右滑倦淀,因為左右滑的判定是不等于0
lastPoint = [touch previousLocationInView:self.playLayer];
currentPoint = [touch locationInView:self.playLayer];
tempCenter = self.playLayer.center;
tempCenter.y += currentPoint.y -lastPoint.y;
self.playLayer.center = tempCenter;
}else if (self.livingInfoView.frame.origin.x != 0) {
lastPoint = [touch previousLocationInView:self.livingInfoView];
currentPoint = [touch locationInView:self.livingInfoView];
tempCenter = self.livingInfoView.center;
tempCenter.x += currentPoint.x -lastPoint.x;
//禁止向左劃
if (self.livingInfoView.frame.origin.x == 0 && currentPoint.x -lastPoint.x > 0) {//滑動開始是從0點開始的,并且是向右滑動
self.livingInfoView.center = tempCenter;
}else if(self.livingInfoView.frame.origin.x > 0){
self.livingInfoView.center = tempCenter;
}
}
}
self.isBeginSlid = NO;
}
滑動完成后要判斷滑動結(jié)束時的位置
LivingInfoView上的手勢:
touchEnd和touchCancell的代碼是一樣的声畏,判定滑動結(jié)束時直播信息界面的位置撞叽,來確定粉色信息界面的去向。
- (void)touchesEnded:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
// 水平手勢判斷
if (self.frame.origin.x > Screen_width * 0.2) {
[UIView animateWithDuration:0.15 animations:^{
CGRect frame = self.frame;
frame.origin.x = Screen_width;
self.frame = frame;
}];
}else{
[UIView animateWithDuration:0.06 animations:^{
CGRect frame = self.frame;
frame.origin.x = 0;
self.frame = frame;
}];
}
}
- (void)touchesCancelled:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{
if (self.frame.origin.x > Screen_width * 0.2) {
[UIView animateWithDuration:0.15 animations:^{
CGRect frame = self.frame;
frame.origin.x = Screen_width;
self.frame = frame;
}];
}else{
[UIView animateWithDuration:0.06 animations:^{
CGRect frame = self.frame;
frame.origin.x = 0;
self.frame = frame;
}];
}
}
這是控制器滑動結(jié)束時的判定插龄,最終決定了愿棋,上下滑動切換頻道,左右滑動添加或移除直播信息均牢。
- (void)touchesEnded:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
// NSLog(@"%.2f-----%.2f",livingInfoView.frame.origin.y,Screen_height * 0.8);
// 水平滑動判斷
//在控制器這邊滑動判斷如果滑動范圍沒有超過屏幕的十分之八livingInfoView還是離開屏幕
if (self.livingInfoView.frame.origin.x > Screen_width * 0.8) {
[UIView animateWithDuration:0.06 animations:^{
CGRect frame = self.livingInfoView.frame;
frame.origin.x = Screen_width;
self.livingInfoView.frame = frame;
}];
}else{//否則則回到屏幕0點
[UIView animateWithDuration:0.2 animations:^{
CGRect frame = self.livingInfoView.frame;
frame.origin.x = 0;
self.livingInfoView.frame = frame;
}];
}
// 上下滑動判斷
if (self.playLayer.frame.origin.y > Screen_height * 0.2) {
// 切換到下一頻道
self.playLayer.image = [UIImage imageNamed:@"PlayView2"];
}else if (self.playLayer.frame.origin.y < - Screen_height * 0.2){
// 切換到上一頻道
self.playLayer.image = [UIImage imageNamed:@"PlayView"];
}
// 回到原始位置等待界面重新加載
CGRect frame = self.playLayer.frame;
frame.origin.y = 0;
self.playLayer.frame = frame;
}
- (void)touchesCancelled:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{
// 水平滑動判斷
//在控制器這邊滑動判斷如果滑動范圍沒有超過屏幕的十分之八livingInfoView還是離開屏幕
if (self.livingInfoView.frame.origin.x > Screen_width * 0.8) {
[UIView animateWithDuration:0.06 animations:^{
CGRect frame = self.livingInfoView.frame;
frame.origin.x = Screen_width;
self.livingInfoView.frame = frame;
}];
}else{//否則則回到屏幕0點
[UIView animateWithDuration:0.2 animations:^{
CGRect frame = self.livingInfoView.frame;
frame.origin.x = 0;
self.livingInfoView.frame = frame;
}];
}
// 上下滑動判斷
if (self.livingInfoView.frame.origin.y > Screen_height * 0.2) {
// 切換到下一頻道糠雨,重新加載界面,這里用切換圖片做演示徘跪。
self.livingInfoView.backgroundColor = [UIColor colorWithRed:arc4random_uniform(256) / 255.0 green:arc4random_uniform(256) / 255.0 blue:arc4random_uniform(256) / 255.0 alpha:0.5];
}else if (self.livingInfoView.frame.origin.y < - Screen_height * 0.2){
// 切換到上一頻道甘邀,重新加載界面,這里用切換圖片做演示真椿。
self.livingInfoView.backgroundColor = [UIColor colorWithRed:arc4random_uniform(256) / 255.0 green:arc4random_uniform(256) / 255.0 blue:arc4random_uniform(256) / 255.0 alpha:0.5];
}
// 回到原始位置等待界面重新加載
CGRect frame = self.livingInfoView.frame;
frame.origin.y = 0;
self.livingInfoView.frame = frame;
}
具體代碼下載GitHub:https://github.com/D-james/SlidPageDemo