tableView上下滑動,隱藏導航欄、工具欄

現有許多的app中會要求在UITableView/UICollectionView上滑時顯示,下滑動時慢慢的隱藏導航欄和工具欄,先看張效果圖:
此文章是最初實驗的時候寫的;
比較忙,中間有很久一段時間沒有更新,后面換了一種方法實現;
最終請看demo(在文章的末尾),已有多個項目在使用,已適配ios11及iphoneX

scroll.gif

一般項目的架構有如下三種:

1. 系統的TabBar和系統navigationBar;
2. 自定義的TabBar和系統navigationBar;
3. 前兩者混合使用(某個可能是自定制的),并且在那個界面中又加了多個子控制器addChildViewController;

針對于第一種情況,如果是對UINavigationController的結構不熟悉的,可能就比較麻煩了,但網上也有相關的DEMO,今天在這就不多說了,這文章主要是講三種:

首先UI的層次結構大概是這樣子的:
window > UITabBarController > UINavigationController(可能有多個) > parentViewController > 這里有多個ChildViewController 還有一個自定制的UINavigationBar > ChildViewController里面可能又有UIScrollView;

parentViewController的大致結構:UIScrollView > 裝個多個ChildViewController的view,如下圖:
好了,結構介紹完畢,下面我們分析下實現思路:
1, 讓其跟著上下滑動的偏移來決定上或下移多少,直到隱藏或者完全顯示,那肯定是操作parentViewController的UIScrollViewDelegate代理方法;
2, 到這里你可能會想:這很簡單啊!讓其跟著滑動就可以了;其實不然還得看你的parentViewController里面的子視圖里面的自定制導航欄和scrollView的起始坐標和高度,更多的情況下是:

UINavigationBar的坐標是:{0, 0, screenWidth, 64};
scrollView和坐標是:{0, 64, screenWidth, screenHeight - 64}
然而在這種情況下:scrollView滑動時候讓其UINavigationBar跟著滑動,是可以正常隨著偏移滑動,但是你會發現UINavigationBar與scrollView會中間會出現空白的間隔,且隨著偏移變大面變大;重點問題就在這樣,要怎么解決這個問題?

出現如上的原因是scrollView的Y是64,往上滑動,UINavigationBar也跟著往上走,但scrollView永遠都是在64的位置,那么你再怎么往上滑動,scrollView里面的內容也是無法顯示的,都超出了父控件.你可能會想讓其scrollView也一起往上移,那這樣的用戶體驗性不好,而且你還得考慮到下邊還有個UITabBar正好跟著UINavigationBar反向偏動 ;

正確的方法應該是:

  1. 把parentViewController的scrollView的坐標設置為:self.view.bounds,即跟屏幕一樣大;


    426722A1-8DB7-4036-962A-29C1270EB7CD.png
  2. parentViewController的ChildViewController的view的frame也跟父控件(scrollView)一樣大,


    42C46408-BF93-4684-88F9-8392EFB35476.png
  3. ChildViewController里的tableView的frame設置很關鍵:
    Y必須從0開始,高度與ChildViewController.view的高度一致,這里高度保持一致也是為了tabbar下移的時候,不會出現空白區域;再設置tableView的contentInset內偏移,讓內容往下偏移導航欄的高度,這樣就完美的解決了上下滑動會出現空白區域的問題;
    D254E75C-96D4-4D71-A18F-D1ED46DFCFF8.png
  4. UIScrollViewDelegate的代理方法中實現讓導航欄和工具欄跟著scrollView的contentOffset.y變化;
@implementation NHConcernViewController
- (void)scrollViewDidScroll:(UIScrollView *)scrollView{
    NHTabBarController *tab = (NHTabBarController *)self.tabBarController;
     NHFirstController *parentVC = (NHFirstController *)self.parentViewController;
    CGFloat moveOffset = scrollView.contentOffset.y - _lastPoint.y;
    NSLog(@"%f",moveOffset);
    
    //偏移量小于 -kNavgationHeight時,不需要改變
    if (scrollView.contentOffset.y <= -kNavgationHeight) return;
    
    if (scrollView.contentOffset.y > _lastPoint.y) {
        [tab tabBarControllerShouldMoveTabbarOffset:moveOffset];
        [parentVC didScrollTableViewShouldChangeNavigationBarWithOffset:moveOffset];
        
    }else {
        [tab tabBarControllerShouldMoveTabbarOffset:moveOffset];
        [parentVC didScrollTableViewShouldChangeNavigationBarWithOffset:moveOffset];
    }
    _lastPoint = scrollView.contentOffset;
}
@end
//這里的`NHFirstController`就是文中所說的`parentViewController`
@interface NHFirstController
- (void)didScrollTableViewShouldChangeNavigationBarWithOffset:(CGFloat)newSize;
@end

@implementation NHFirstController
/**
 *  tableView滾動的時候改變導航欄的frame
 *  @param newFrame   new frame
 */
- (void)didScrollTableViewShouldChangeNavigationBarWithOffset:(CGFloat)newPoint{
    CGRect newRect = _navgationView.frame;
    newRect.origin.y += -newPoint ;
    _navgationView.frame = newRect;
    
    if (newRect.origin.y > 0) {
        newRect.origin.y = 0;
        _navgationView.frame = newRect;
    }
    if (newRect.origin.y < -kNavgationHeight) {
        newRect.origin.y = -kNavgationHeight;
        _navgationView.frame = newRect;
    }
}
@end

特別注意:自定制的導航條在要add完scrollView后再add

- (void)viewDidLoad {
    [super viewDidLoad];
    [self addChildViewControllers];
    [self setNavgationBar];
}

你滑一滑試下,是不是OK了.

傳送門:
https://github.com/nenhall/NHBarScrollTool

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容

  • 發現 關注 消息 iOS 第三方庫、插件、知名博客總結 作者大灰狼的小綿羊哥哥關注 2017.06.26 09:4...
    肇東周閱讀 12,232評論 4 61
  • 1. 你說,你愛晨起的朝陽 看那飄飄渺渺的光芒 肆無忌憚地,撒在每一個路人的身上 2. 我們望著,時鐘的方向 一圈...
    木庭兮閱讀 623評論 1 5
  • 偶然在知乎看到有人推薦《站在兩個世界的邊緣》,推薦者說這本書對自己影響極深,現在還會去反復刷作者在知乎的一些評論。...
    簡安月閱讀 172評論 0 0
  • 2017-07-06Kunihiro Matsuki心理專業成長聯盟 精神分析的目的是理解來訪者。為了達成這個目的...
    心理專業成長聯盟閱讀 1,152評論 0 2
  • 前前后后前前 歲月一點點走遠 走到何時能到天邊 停下腳步來回輾轉 不知未來能有多遠 伴隨著花香駛向遠方 有一個地方...
    空瓶小宅閱讀 214評論 0 5