iOS仿今日頭條滑動導航

kscv7889 8年前發布 | 24K 次閱讀 iOS開發 移動開發

來自: http://www.cnblogs.com/5ishare/p/5166331.html

之前寫了篇博客網易首頁導航封裝類、 網易首頁導航封裝類優化 ,今天在前兩個的基礎上仿下今日頭條。

1.網易首頁導航封裝類中主要解決了上面導航的ScrollView和下面的頁面的ScrollView聯動的問題,以及上面導航欄的便宜量。

2. 網易首頁導航封裝類優化 中主要解決iOS7以上滑動返回功能中UIScreenEdgePanGestureRecognizer與ScrollView的滑動的手勢沖突問題。

今天仿今日頭條滑動導航和 網易首頁導航封裝類優化 相似,這個也是解決手勢沖突,UIPanGestureRecognizer與ScrollView的手勢沖突。

一、ViewController的層次

用上面的圖來介紹,左側的個人頁面ViewController上面通過addChildViewController添加了一個以MainViewController為RootViewController的

UINavigationController,通過addSubview將UINavigationController的View添加到個人頁面ViewController的View上。

二、仿今日頭條滑動導航主要有3個問題:

1.UIPanGestureRecognizer與ScrollView的手勢沖突

為了達到拖動滑動的效果,需要給MainViewController添加一個UIPanGestureRecognizer,由于底部是ScrollView和TableView組成的,所以會使UIPanGestureRecognizer與底部的沖突,和 網易首頁導航封裝類優化 類似需要在

- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer中根據gestureRecognizer返回YES來使ScrolView和UIPanGestureRecognizer都識別。

2.UIPanGestureRecognizer滑動結束的位置不正確

用UIPanGestureRecognizer滑動根據便宜量來改變UINavigationController的View的位置,在今日頭條中滑動結束時UINavigationController的View要么在原位要么在右側,不會停在中間,這個問題讓我想起了之前做的果凍效果,手勢有狀態state,根據手勢的狀態來改變UINavigationController的View的位置,特別是在手勢結束時。

3.由于1使ScrolView和UIPanGestureRecognizer都識別,導致返回時ScrolView也會滑動

讓底部的ScrolView能滑動的時間應該是UINavigationController的View在初始位置frame的x為0,所以在它的frame的x>0時,底部的bottomScrollView的

scrollEnabled=NO。

三、 主要實現代碼(導航的代碼就不貼了,只貼主要的)

1.聲明一個拖動手勢

@property(nonatomic,strong) UIPanGestureRecognizer *panGestureRecognizer;

2.為MainViewController添加手勢

 _panGestureRecognizer=[[UIPanGestureRecognizer alloc]initWithTarget:self action:@selector(panGesture:)];
    _panGestureRecognizer.delegate=self;
    [self.navigationController.view addGestureRecognizer:_panGestureRecognizer];

3.手勢識別的方法

//平移
-(void)panGesture:(UIPanGestureRecognizer*)pan
{
    //在View中的位置
//    CGPoint point=[pan locationInView:self.navigationController.view];
    //在View中的移動量 以手指按下的為原點
    CGPoint point1=[pan translationInView:self.navigationController.view];
    if (pan.state==UIGestureRecognizerStateChanged&&pan==_panGestureRecognizer) {

        if (point1.x>0&&self.navigationController.view.frame.origin.x<self.navigationController.view.frame.size.width-100) {
            float x= self.navigationController.view.frame.origin.x+point1.x>self.navigationController.view.frame.size.width-100?self.navigationController.view.frame.size.width-100:self.navigationController.view.frame.origin.x+point1.x;
            self.navigationController.view.frame=CGRectMake(x, self.navigationController.view.frame.origin.y, self.navigationController.view.frame.size.width, self.navigationController.view.frame.size.height);
            NSLog(@"%@",NSStringFromCGRect(self.navigationController.view.frame));
        }
        else if(point1.x<0)
        {
            NSLog(@"aaa  %f",self.navigationController.view.frame.origin.x);
            float x=self.navigationController.view.frame.origin.x+point1.x<0?0:self.navigationController.view.frame.origin.x+point1.x;
            self.navigationController.view.frame=CGRectMake(x, self.navigationController.view.frame.origin.y, self.navigationController.view.frame.size.width, self.navigationController.view.frame.size.height);
        }
    }
    else if(pan.state==UIGestureRecognizerStateEnded)
    {

        if (self.navigationController.view.frame.origin.x>self.navigationController.view.frame.size.width/3) {
            [UIView animateWithDuration:0.2 animations:^{
                self.navigationController.view.frame=CGRectMake(self.navigationController.view.frame.size.width-100, 0, self.navigationController.view.frame.size.width, self.navigationController.view.frame.size.height);
            } completion:^(BOOL finished) {
                 self.bottomScrollView.scrollEnabled=YES;
            }];
        }
        else
        {
            [UIView animateWithDuration:0.2 animations:^{
                self.navigationController.view.frame=CGRectMake(0, 0, self.navigationController.view.frame.size.width, self.navigationController.view.frame.size.height);
            } completion:^(BOOL finished) {
                self.bottomScrollView.scrollEnabled=YES;
            }];

        }
    }
    //偏移量是增加的應該設為0
    [pan setTranslation:CGPointZero inView:self.navigationController.view];
}

4.手勢沖突解決

- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer
{
    if (self.bottomScrollView.contentOffset.x<=0.0&&gestureRecognizer==_panGestureRecognizer) {
        if (self.navigationController.view.frame.origin.x>0) {
           self.bottomScrollView.scrollEnabled=NO;
        }
        else
        {
            self.bottomScrollView.scrollEnabled=YES;

        }
        return YES;
    }
    return NO;
}

四、效果圖

 本文由用戶 kscv7889 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!