github https://github.com/1271284056/HeadImageTransform
现在app商业项目中手势全屏返回十分重要,网上的实现方式有很多种,你把demo里面的UINavigationController+GestureBack这个文件放到你的项目中,这个功能就实现了,不用你加任何代码.效果图如下
手势返回
核心实现思路就是用运行时的方法交换拦截系统的pushViewController方法,替换成自定义的jd_pushViewController方法,为系统增加一个自定义的UIPanGestureRecognizer手势,系统从左侧滑动就有返回功能,我们用全屏手势也执行这个系统方法.方法交换写在+ (void)load {}方法里面,在类被加载到运行时的时候,就会执行,用运行时替换系统的手势方法,把这个分类放到项目里就实现了全屏返回功能.
- (void)jd_pushViewController:(UIViewController *)viewController animated:(BOOL)animated {
if (![self.interactivePopGestureRecognizer.view.gestureRecognizers containsObject:self.jd_popGestureRecognizer]) {
[self.interactivePopGestureRecognizer.view addGestureRecognizer:self.jd_popGestureRecognizer];
NSArray *targets = [self.interactivePopGestureRecognizer valueForKey:@"targets"];
id internalTarget = [targets.firstObject valueForKey:@"target"];
SEL internalAction = NSSelectorFromString(@"handleNavigationTransition:");
//在代理里面规定手势效果什么时候可以用
self.jd_popGestureRecognizer.delegate = [self fullScreenPopGestureRecognizerDelegate];
//系统从左侧滑动就有返回功能,我们用全屏手势也执行这个系统方法
[self.jd_popGestureRecognizer addTarget:internalTarget action:internalAction];
// 禁用系统的交互手势
self.interactivePopGestureRecognizer.enabled = NO;
}
if (![self.viewControllers containsObject:viewController]) {
[self jd_pushViewController:viewController animated:animated];
}}
TableView顶部图片放大缩小
我们建立一个ViewController,在顶部加一个View+ImageView,下面放TableView
- 首先我们要隐藏导航栏,导航栏隐藏时候要在viewWillAppear里面设置,要不可能会导致导航栏错乱.顶部图片和tableView会有一个空白高度,因为ViewController + NAV 会自动调整 tableView 的 contentInset .要用 self.automaticallyAdjustsScrollViewInsets = NO;
禁用自动调整 .
- 在上下滑动时候scrollViewDidScroll 这个代理方法里面判断滑动的大小,从而实时改变顶视图高度和控制位置,以及改变图片的透明度.
(void)scrollViewDidScroll:(UIScrollView*)scrollView
{
// offset < 0 往下滑动 >0往上滑动
CGFloat offset = scrollView.contentOffset.y + scrollView.contentInset.top;
// 放大 往下滑动
if (offset <= 0) {
// 调整 headView 顶部置顶 高度变大
_headerView.y = 0;
_headerView.heightS = kHeaderHeight - offset;
_headerImageView.alpha = 1;
}
else {
// 整体移动 网上滑动 变小
_headerView.heightS = kHeaderHeight;
// headerView 最小 y 值 让移动到剩64时候不能往上移动
CGFloat min = kHeaderHeight - 64;
_headerView.y = -MIN(min, offset);
// 设置透明度
// 根据输出可以知道 offset / min == 1 时候为上移剩余64时
CGFloat progress = 1 - (offset / min);
_headerImageView.alpha = progress;
// 根据透明度,来修改状态栏的颜色 <0.5时候往上移动
_statusBarStyle = (progress < 0.5) ? UIStatusBarStyleDefault : UIStatusBarStyleLightContent;
// 主动更新状态栏
[self.navigationController setNeedsStatusBarAppearanceUpdate];
}
// 设置图像高度
_headerImageView.heightS = _headerView.heightS;
// 设置分隔线的位置
_lineView.y = _headerView.heightS - _lineView.heightS;
}