1.先看个效果图(我的模拟器抽风了,真机上效果上是好的)
2.解析,里面有3个问题
1.切换的时候 要清空代理(防止切换的时候 影响当前的tableView) 2.addsubview (避免不必要的addsubView) 3.交互的时候 segment和导航条的变化
3.代码结构
底部scrollView 和 多个tableViewVC(偏移一个headerView+ segment的高度)
下面是tableviewVC 的父类
//
// WXTableViewController.h
// 优化滑动
//
// Created by apple on 16/6/28.
// Copyright © 2016年 李重阳. All rights reserved.
//
#import
@class WXTableViewController;
/* 交互的代理 **/
@protocol WXTableViewControllerDelegate
@optional
/* 滚动的代理 **/
- (void)wxTableViewDidScrollWithTableViewVC:(WXTableViewController *)tableViewVC;
@end
/* 数据的代理**/
@protocol WXTableViewControllerDataSource
@optional
//tableView的 内容偏移量是
- (CGFloat)wxTableViewContentInsetTop;
@end
@interface WXTableViewController : UITableViewController
@property (nonatomic,weak) id delegate;
@property (nonatomic,weak) iddataSource;
@property (nonatomic,assign) CGFloat preOffsetY;
@end
//
// WXTableViewController.m
// 优化滑动
//
// Created by apple on 16/6/28.
// Copyright © 2016年 李重阳. All rights reserved.
//
#import "WXTableViewController.h"
@interface WXTableViewController ()
@end
@implementation WXTableViewController
- (void)viewDidLoad {
[super viewDidLoad];
self.automaticallyAdjustsScrollViewInsets = NO;
CGFloat contentInsetTop = 0;
if ([self.dataSource respondsToSelector:@selector(wxTableViewContentInsetTop)]) {
contentInsetTop = [self.dataSource wxTableViewContentInsetTop];
}
/* 偏移量 **/
self.tableView.contentInset = UIEdgeInsetsMake(contentInsetTop, 0, 0, 0);
self.preOffsetY = self.tableView.contentOffset.y;
}
- (void)scrollViewDidScroll:(UIScrollView *)scrollView {
if ([self.delegate respondsToSelector:@selector(wxTableViewDidScrollWithTableViewVC:)]) {
[self.delegate wxTableViewDidScrollWithTableViewVC:self];
}
}
#pragma mark - Table view data source
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return 0;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return 0;
}
/*
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:<#@"reuseIdentifier"#> forIndexPath:indexPath];
// Configure the cell...
return cell;
}
*/
/*
// Override to support conditional editing of the table view.
- (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath {
// Return NO if you do not want the specified item to be editable.
return YES;
}
*/
/*
// Override to support editing the table view.
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath {
if (editingStyle == UITableViewCellEditingStyleDelete) {
// Delete the row from the data source
[tableView deleteRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationFade];
} else if (editingStyle == UITableViewCellEditingStyleInsert) {
// Create a new instance of the appropriate class, insert it into the array, and add a new row to the table view
}
}
*/
/*
// Override to support rearranging the table view.
- (void)tableView:(UITableView *)tableView moveRowAtIndexPath:(NSIndexPath *)fromIndexPath toIndexPath:(NSIndexPath *)toIndexPath {
}
*/
/*
// Override to support conditional rearranging of the table view.
- (BOOL)tableView:(UITableView *)tableView canMoveRowAtIndexPath:(NSIndexPath *)indexPath {
// Return NO if you do not want the item to be re-orderable.
return YES;
}
*/
/*
#pragma mark - Navigation
// In a storyboard-based application, you will often want to do a little preparation before navigation
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
// Get the new view controller using [segue destinationViewController].
// Pass the selected object to the new view controller.
}
*/
@end
segment 和 导航条的交互
- (void)wxTableViewDidScrollWithTableViewVC:(WXTableViewController *)tableViewVC {
// 获取当前偏移量
CGFloat offsetY = tableViewVC.tableView.contentOffset.y;
// 获取偏移量差值
CGFloat delta = offsetY - tableViewVC.preOffsetY;
NSLog(@"offsetY = %f,delta = %f",offsetY,delta);
/* 记录上一个值 **/
tableViewVC.preOffsetY = offsetY;
NSLog(@"offsetY = %f,min = %f,max = %f",offsetY,self.minTableViewOffsetY,self.maxTableViewOffsetY);
/*
//offsetY 默认是segment 的maxY 值 = 264
//1.当往上滑动的时候,偏移量的值是增加的 eg:-264 、-250、-(导航高度 +segmentH),当增加到 -(64+segmentH) +x 的时候我们需要判断 不能再大了
//2.当往下滑动的时候,偏移量是减少的 从 0、-100、-150、-264(也就是刚开始的segment 的maxY 值) ,这是就不能再减少了
**/
if (offsetY >= -self.minTableViewOffsetY) {
_segmentView.y = self.minTableViewOffsetY - _segmentView.height;
}else if (offsetY <= -self.maxTableViewOffsetY ) {
_segmentView.y = self.maxTableViewOffsetY - _segmentView.height;
}else {
_segmentView.y -= delta;
}
_headerView.y = _segmentView.y - _headerView.height;
// 计算透明度
/*
* alpha的间距 其实就是 初始的segment 的maxY - 导航条的 =》(self.maxTableViewOffsetY - self.minTableViewOffsetY)
* 变量就是 segment的 y值 到 导航的距离
**/
CGFloat alpha = 1- (_segmentView.y - self.navView.height) / (self.maxTableViewOffsetY - self.minTableViewOffsetY);
self.navView.alpha = alpha;
}
代码下载