iOS直播界面的上下左右滑動效果

我們看現(xiàn)在主流的直播平臺都有左右滑動去掉直播信息党窜,上下滑動切換頻道的功能:
粉色界面代表直播信息界面搏予,就是觀眾、禮物粉捻、彈幕的界面礁遣。
下面的圖片代表直播的播放界面,用切換圖片代表頻道的切換肩刃。


slidLivingPage.gif

在這我寫了一個小的Demo來說明是怎么實現(xiàn)這個功能的:首先說一下思路

  1. 看到這個界面的第一反應這不就是一個ScrollView嗎祟霍?但仔細把玩一下,ScrollView不好實現(xiàn)這個效果盈包。必須用獲取手指觸摸位置拖動控件的方法沸呐,在有直播信息的界面,移除直播信息界面劃過屏幕寬的大于五分之一才回移除直播信息界面呢燥。在沒有直播信息界面時崭添,必須劃過小于屏幕寬的五分之四才能添加直播信息界面。上下切花頻道叛氨,大于屏幕高的五分之一會切換到下一頻道呼渣,小于負的屏幕高五分之一就會切換到上移頻道。切換頻道需要重新加載界面寞埠。上述滑動條件如果沒有滿足都會回到滑動前的位置屁置。
  2. 首先單獨實現(xiàn)左右滑動,再單獨實現(xiàn)上下滑動
  3. 避免左右滑和上下滑沖突畸裳,區(qū)別開始滑動時缰犁,是上下滑動和還是左右滑動,開始滑動后水平或垂直滑動的方向不能改變怖糊,直到再次開始觸摸
  4. 在結(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

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末鹃答,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子突硝,更是在濱河造成了極大的恐慌测摔,老刑警劉巖,帶你破解...
    沈念sama閱讀 207,113評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件解恰,死亡現(xiàn)場離奇詭異锋八,居然都是意外死亡,警方通過查閱死者的電腦和手機护盈,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,644評論 2 381
  • 文/潘曉璐 我一進店門挟纱,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人腐宋,你說我怎么就攤上這事紊服。” “怎么了胸竞?”我有些...
    開封第一講書人閱讀 153,340評論 0 344
  • 文/不壞的土叔 我叫張陵欺嗤,是天一觀的道長。 經(jīng)常有香客問我卫枝,道長煎饼,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 55,449評論 1 279
  • 正文 為了忘掉前任校赤,我火速辦了婚禮吆玖,結(jié)果婚禮上筒溃,老公的妹妹穿的比我還像新娘。我一直安慰自己沾乘,他們只是感情好怜奖,可當我...
    茶點故事閱讀 64,445評論 5 374
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著意鲸,像睡著了一般烦周。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上怎顾,一...
    開封第一講書人閱讀 49,166評論 1 284
  • 那天,我揣著相機與錄音漱贱,去河邊找鬼槐雾。 笑死,一個胖子當著我的面吹牛幅狮,可吹牛的內(nèi)容都是我干的募强。 我是一名探鬼主播,決...
    沈念sama閱讀 38,442評論 3 401
  • 文/蒼蘭香墨 我猛地睜開眼崇摄,長吁一口氣:“原來是場噩夢啊……” “哼擎值!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起逐抑,我...
    開封第一講書人閱讀 37,105評論 0 261
  • 序言:老撾萬榮一對情侶失蹤鸠儿,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后厕氨,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體进每,經(jīng)...
    沈念sama閱讀 43,601評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,066評論 2 325
  • 正文 我和宋清朗相戀三年命斧,在試婚紗的時候發(fā)現(xiàn)自己被綠了田晚。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 38,161評論 1 334
  • 序言:一個原本活蹦亂跳的男人離奇死亡国葬,死狀恐怖贤徒,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情汇四,我是刑警寧澤接奈,帶...
    沈念sama閱讀 33,792評論 4 323
  • 正文 年R本政府宣布,位于F島的核電站船殉,受9級特大地震影響鲫趁,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜利虫,卻給世界環(huán)境...
    茶點故事閱讀 39,351評論 3 307
  • 文/蒙蒙 一挨厚、第九天 我趴在偏房一處隱蔽的房頂上張望堡僻。 院中可真熱鬧,春花似錦疫剃、人聲如沸钉疫。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,352評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽牲阁。三九已至,卻和暖如春壤躲,著一層夾襖步出監(jiān)牢的瞬間城菊,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,584評論 1 261
  • 我被黑心中介騙來泰國打工碉克, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留凌唬,地道東北人。 一個月前我還...
    沈念sama閱讀 45,618評論 2 355
  • 正文 我出身青樓漏麦,卻偏偏與公主長得像客税,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子撕贞,可洞房花燭夜當晚...
    茶點故事閱讀 42,916評論 2 344

推薦閱讀更多精彩內(nèi)容

  • Android 自定義View的各種姿勢1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 171,527評論 25 707
  • 發(fā)現(xiàn) 關注 消息 iOS 第三方庫更耻、插件、知名博客總結(jié) 作者大灰狼的小綿羊哥哥關注 2017.06.26 09:4...
    肇東周閱讀 12,033評論 4 62
  • 今天我懷著激動的心情返校捏膨,還盼望見到我的好朋友秧均,見到我們的新班主任。 一進教學老看見大樹底下裝滿了花...
    王楊晨閱讀 171評論 0 0
  • 文/郭強強 角落紅花盡脊奋,初冬無覓處熬北。滿園青草綠,不減舊時姿诚隙。臉頰微風掠讶隐,雖輕帶寒意。書生耳畔來久又,習藝伴寒暑巫延。 ...
    俊傑閱讀 597評論 0 0
  • 并發(fā) 通常情況下會有很多用戶同時使用你的應用,并且你也希望應用能夠及時響應用戶的請求地消。那么你就需要使用某種方法去處...
    falm閱讀 1,642評論 0 5