仿知乎主頁,上滑隱藏NavigationBar,下滑顯示
阿新 • • 發佈:2019-02-11
最近在仿作知乎客戶端,知乎首頁的 navigationBar 會隨著下方的 tableView 滑動而改變,上滑隱藏,下拉顯示,並且下拉需要一定速度才會觸發顯示。在網上查了一下,看到一個隨 TableView 滑動改變 NavigationBar 透明度的demo,雖然和自己的需求不一樣,但提供了利用 KVO 實現的思路,有了思路就著手做了,除錯了幾次和知乎官方實現效果稍有不同,但基本需求實現了,如果需要做到完全相同,只要再加一些條件判斷就好了,主要程式碼如下:
#import "TestTableViewController.h" @interface TestTableViewController () @end @implementation TestTableViewController { BOOL _isHidding; } - (void)viewDidLoad { [super viewDidLoad]; [self setupScrollHideNavigationBar]; self.navigationItem.title = @"TEST DEMO"; } - (void)didReceiveMemoryWarning { [super didReceiveMemoryWarning]; // Dispose of any resources that can be recreated. } #pragma mark - Table view data source - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView { return 1; } - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { return 50; } - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"cell"]; if (!cell) { cell = [[UITableViewCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"cell"]; } cell.textLabel.text = [NSString stringWithFormat:@"%d",(int)indexPath.row]; return cell; } #pragma mark - 上拉隱藏navigation bar - (void)setupScrollHideNavigationBar { // self.tableView.contentOffset [self.tableView addObserver:self forKeyPath:@"contentOffset" options:NSKeyValueObservingOptionOld|NSKeyValueObservingOptionNew context:nil]; } - (void)removeScrollHideNavigationBar { //remove [self.tableView removeObserver:self forKeyPath:@"contentOffset"]; } #pragma mark KVO - (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSString *,id> *)change context:(void *)context { if ([object isEqual:self.tableView] && [keyPath isEqualToString:@"contentOffset"]) { CGFloat newY = [change[@"new"] CGPointValue].y; CGFloat oldY = [change[@"old"] CGPointValue].y; float i = newY - oldY; //i>0上滑, i<0下滑 if (self.tableView.contentOffset.y>-64&&self.tableView.contentOffset.y<=24) {//邊界條件,此處不精確 if (i<=0&&_isHidding == NO&&self.navigationController.navigationBar.frame.origin.y==20) { //下拉+bar 已經顯示的狀態,不再移動 return; } _isHidding = NO; self.navigationController.navigationBar.frame = CGRectMake(0, -44-self.tableView.contentOffset.y, 320, 44); }else if (self.tableView.contentOffset.y > 24) { if (i>10) {//更改數值大小可以控制觸發 navigation bar 的滑動速度 _isHidding = YES; }else if(i<-10) { _isHidding = NO; }else { } } [self.navigationController setNavigationBarHidden:_isHidding animated:YES]; } }
程式碼很簡單就不詳解了,附上各種情況的判斷(上滑指手指上滑):
最終效果:
其他:當NavigationController 需要 push/pop ViewController 的時候注意需要取消KVO,否則在其他介面可能會出現 NavigationBar 隱藏的情況。
參考: