不使用TableView的plain特性做HeaderView固定效果

上代码。

- (void)viewDidLoad {
  [super viewDidLoad];
  
  self.title = @"跟着学习";
  self.view.backgroundColor = [UIColor whiteColor];
  
  self.automaticallyAdjustsScrollViewInsets = YES;
    /**
     *  [UIViewController setEdgesForExtendedLayout:],它的默认值为UIRectEdgeAll。当你的容器是navigation controller时,默认的布局将从navigation bar的顶部开始。这就是为什么所有的UI元素都往上漂移了44pt。
     */
  self.edgesForExtendedLayout = UIRectEdgeNone;
  
  CGFloat w = [UIScreen mainScreen].bounds.size.width;
  self.headerView = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, w, 80)];
  self.headerView.backgroundColor = [UIColor redColor];
  self.headerView.textAlignment = NSTextAlignmentCenter;
  self.headerView.text = @"我要随着滚动而慢慢消失或者出现-headerView";
  self.headerView.textColor = [UIColor whiteColor];
  [self.view addSubview:self.headerView];
  
  self.stickyView = [[UILabel alloc] initWithFrame:CGRectMake(0, self.headerView.bottomY, w, 50)];
  self.stickyView.backgroundColor = [UIColor greenColor];
  [self.view addSubview:self.stickyView];
  self.stickyView.textColor = [UIColor whiteColor];
  self.stickyView.textAlignment = NSTextAlignmentCenter;
  self.stickyView.text = @"滚动到一定位置就固定-stickyView";
  
  self.tableView = [[UITableView alloc] initWithFrame:CGRectMake(0, self.stickyView.bottomY, w, self.view.height - self.stickyView.bottomY)];
  [self.view addSubview:self.tableView];
  self.tableView.dataSource = self;
  self.tableView.delegate = self;
    /**
     *   decelerationRate的属性来设置,它的值域是(0.0,1.0)
         当decelerationRate设置为0.1时,当手指touch up时就会很慢的停下来。
     */
  self.tableView.decelerationRate = 0.1;
}



#pragma mark - UIScrollViewDelegate
- (void)scrollViewDidScroll:(UIScrollView *)scrollView {
  // 保证是我们的tableivew
  if (scrollView == self.tableView) {
    // 保证我们是垂直方向滚动,而不是水平滚动
    if (scrollView.contentOffset.x == 0) {
     
        CGFloat y = scrollView.contentOffset.y;
        
        /*!
         *  往上是(+)   往下为(-)
         */
//        NSLog(@"Y:%.2f",y);
      
      // 这个是非常关键的变量,用于记录上一次滚动到哪个偏移位置
      static CGFloat previousOffsetY = 0;
      
      // 向上滚动
      if (y > 0) {
          
          /*!
           *  self.headerView.bottomY 开始为80 --> 0
           */
          
//        NSLog(@"Y:%.2f",self.headerView.bottomY);
          
        if (self.headerView.bottomY <= 0) {
          return;
        }
          
          
//        NSLog(@"Y:%.2f",fabs(y - previousOffsetY));

        
        // 计算两次回调的滚动差:fabs(y - previousOffsetY)值
          /*!
           *  上推
           *  1.假如第一次:y直接到了80 之前的为0,bottomY = 80-(80-0) = 0;
           *  2.假如第一次:y直接到了40 之前的为0,bottomY = 80-(40-0) = 40
           *       第二次:y直接到了80 之前的为40,bottomY = 40-(80-40)= 0
           *  下滑
           *  1.假如第一次:y直接到了0 之前的为0,bottomY = 0-(0-0) = 0;
           *  2.假如第一次:y直接到了40 之前的为0,bottomY = 80-(40-0) = 40
           *       第二次:y直接到了80 之前的为40,bottomY = 40-(80-40)= 0
           *
           */
        CGFloat bottomY = self.headerView.bottomY - fabs(y - previousOffsetY);//fabs:取float类型的绝对值
       
        bottomY = bottomY >= 0 ? bottomY : 0;
        self.headerView.bottomY = bottomY;
        self.stickyView.y = self.headerView.bottomY;
        self.tableView.frame = CGRectMake(0, self.stickyView.bottomY,
                                          scrollView.width,
                                          self.view.height - self.stickyView.bottomY);
        
        previousOffsetY = y;
        
//           NSLog(@"Y:%.2f",fabs(previousOffsetY));
          
        // 如果一直不松手滑动,重复向上向下滑动时,如果没有设置还原为0,则会出现马上到顶的情况。
          /*!
           *  因为当往下回的时候,y = 0;
           *  如果 previousOffsetY 不置为0 ,fabs(y - previousOffsetY) = (0-80) = 80,最终的bottomY立马就等于0,立马就固定死了
           *   清空之后,
           *   往下拉,因为y==0,所以不会走到这里,上面就直接return了
           *   往上推,又开始了,
           */
        if (previousOffsetY >= self.headerView.height) {
            previousOffsetY = 0;
        }
      }
      // 向下滚动
      else if (y < 0) {
          
          
//        NSLog(@"Y:%.2f",self.headerView.y);
          
           NSLog(@"Y:%.2f",y);
          
        if (self.headerView.y >= 0) {
          return;
        }
          /*!
           *  fabs(y) = 0--无穷大
           */
        CGFloat bottomY = self.headerView.bottomY + fabs(y);
        bottomY = bottomY <= self.headerView.height ? bottomY : self.headerView.height;
        
        self.headerView.bottomY = bottomY;
        self.stickyView.y = self.headerView.bottomY;
        self.tableView.frame = CGRectMake(0,
                                          self.stickyView.bottomY,
                                          scrollView.width,
                                          self.view.height - self.stickyView.bottomY);
      }
    }
  }
}

#pragma mark - UITableViewDataSource
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
  return 30;
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
  static NSString *cellIdentifier = @"CellIdentifier";
  
  UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier];
  if (!cell) {
    cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault
                                  reuseIdentifier:cellIdentifier];
  }
  
  cell.textLabel.text = @"这只是展示固定数据,没有别的作用。";
  
  return cell;
}
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容