代码地址如下:
http://www.demodashi.com/demo/12776.html

首先看一下效果



状态栏红色是因为使用手机录屏的原因。

1.问题分析

1.导航栏A有两组控件,随着tableView的向上滑动,这一组控件的透明度从1到0,然后另一组控件透明度从0到1,如此反复。

2.导航栏下面的一组控件B,随着tableView向上滑动,也往上滑动,但是滑动值小于tableView的滑动值。透明度逐渐变成0,然后消失。

3.tableView的头部有一个控件C,跟随tableView一起滑动,滑动值相同。(很流畅,无卡顿)

4.tableView即控件D的右侧滚动条从中间开始。

5.滑动控件B,C,D,tableView均能做出反应。

6.如果tableView滑动较少时,导航栏下面的控件B会根据滑动的多少自动折叠或者完全展开。

很多人看到第4条时,可能会认为tableView从中间开始,其实不一定是这样。scrollview有一个属性scrollIndicatorInsets可以设置滚动条的偏移。

我的思路

将控件B,C都加在tableView的视图上面,这样滑动的时候,可以直接跟随tableView滚动(滑动的时候绝度丝滑),另外由于B,C是tableView的子视图,当滑动的时候无法响应滑动手势,然后传递给tableView滑动手势响应,这应解决了问题3,5。这样需要给tableView设置偏移,否则会被B,C挡住一部分。

然后给tableView的scrollIndicatorInsets设置偏移,这样有一种tableView从中间开始的假象。解决了问题4。

创建各个组件的代码

- (void)initView {
CustrmNav * nav = [CustrmNav custrmNav];
//navBShadowView 背后不响应事件,只是上划的时候显示
NavBarBottomView * navBShadowView = [NavBarBottomView navBarBottomView];
navBShadowView.frame = CGRectMake(0, CGRectGetMaxY(nav.frame), Screen_Width, 80);
[self.view addSubview:navBShadowView];
//navBottom 响应事件,在滑动 tableView下滑动到0以后出现
NavBarBottomView * navBottom = [NavBarBottomView navBarBottomView];
navBottom.frame = CGRectMake(0, -320, Screen_Width, 80); TabHeaderView * tabHeader = [TabHeaderView tabHeaderView];
tabHeader.frame = CGRectMake(0, -240, Screen_Width, 240);
CGFloat backH = nav.height + navBottom.height;
CGFloat contentY = tabHeader.height + navBottom.height; //增加背景色View
UIView * backView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, Screen_Width, backH)];
backView.backgroundColor = MP_RGBColor(27, 107, 200);
[self.view insertSubview:backView atIndex:0]; _tableView = [[UITableView alloc] initWithFrame:CGRectMake(0, CGRectGetMaxY(nav.frame), Screen_Width, Screen_Height-nav.height-MP_TabBarHeight) style:UITableViewStylePlain];
_tableView.delegate = self;
_tableView.dataSource = self; //设置偏移量
[_tableView setContentInset:UIEdgeInsetsMake(contentY , 0, 0, 0)];
//假装tableView 从TabHeaderView 的下部开始的
_tableView.scrollIndicatorInsets = UIEdgeInsetsMake(contentY, 0, 0, 0);
//背景透明
_tableView.backgroundColor = [UIColor clearColor];
[self.view addSubview:_tableView];
[_tableView addSubview:navBottom];
[_tableView addSubview:tabHeader];
//放在顶层的 nav 应在在最外层的view
[self.view addSubview:nav]; MJRefreshNormalHeader *mj_header = [MJRefreshNormalHeader headerWithRefreshingBlock:^{
[self refershAction];
}];
_tableView.mj_header = mj_header; [[SlideManger shareSlideManger] slideMangerCustomNav:nav navBottm:navBottom tabHeader:tabHeader navBottomShadowView:navBShadowView];
}

1.解决第一个问题,自定义导航栏,可以通过检测tableView的滑动值,来改变A控件内的视图的透明度来实现。

自定义导航栏代码Xib布局

#import "CustrmNav.h"
@interface CustrmNav ()
@property (weak, nonatomic) IBOutlet UISearchBar *searchBar;
@property (weak, nonatomic) IBOutlet UIImageView *plusup;
@property (weak, nonatomic) IBOutlet UIImageView *firend;
@property (weak, nonatomic) IBOutlet UIImageView *sao;
@property (weak, nonatomic) IBOutlet UIImageView *pay;
@property (weak, nonatomic) IBOutlet UIImageView *search;
@property (weak, nonatomic) IBOutlet UIImageView *get;
@property (weak, nonatomic) IBOutlet UIImageView *plusdown; @end
@implementation CustrmNav + (id)custrmNav {
NSString * className = NSStringFromClass([self class]);
UINib * nib = [UINib nibWithNibName:className bundle:nil];
CustrmNav * nav = [nib instantiateWithOwner:nil options:nil].firstObject;
[nav updateAlpha:0.0];
nav.frame = CGRectMake(0, 0, Screen_Width, MP_NavBarHeight);
return nav;
} - (void)updateAlpha:(float)alpha {
//上部分
_sao.alpha = (alpha-0.5) * 2;
_pay.alpha = (alpha-0.5) * 2;
_plusup.alpha = (alpha-0.5) * 2;
_get.alpha = (alpha-0.5) * 2;
_search.alpha = (alpha-0.5) * 2;
//下部分
_searchBar.alpha = 1 - alpha * 2;
_plusdown.alpha = 1 - alpha * 2;
_firend.alpha = 1 - alpha * 2;
//当滑到一定的位置,背景变成有色
if (alpha >= 1.0) {
self.backgroundColor = MP_RGBColor(27, 107, 200);
} else {
self.backgroundColor = [UIColor clearColor];
}
}

2.解决问题二,我是为B控件又创建了一个分身B1放到tabelView的背后视图上。当向上滑动的时候,B隐藏B1显示,然后根据tableView的滑动距离,改变B1的Y值。另外改变里面的小组件的透明度

处理各个组件的透明度以及动画效果管理类

#import "SlideManger.h"
#import <UIKit/UIKit.h>
#import "CustrmNav.h"
#import "NavBarBottomView.h"
@interface SlideManger ()<NSCopying, NSMutableCopying>
@property(nonatomic,weak)NavBarBottomView * navBottmView;
@property(nonatomic,weak)NavBarBottomView * navBShadowView;
@property(nonatomic,weak)UIView * tabHeader;
@property(nonatomic,weak)CustrmNav * customNav; @end
static SlideManger * _slideManger = nil;
@implementation SlideManger
+ (id)shareSlideManger {
return [[self alloc] init];
} + (id)allocWithZone:(struct _NSZone *)zone {
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
if (_slideManger == nil) {
_slideManger = [super allocWithZone:zone];
}
});
return _slideManger;
} - (id)copyWithZone:(NSZone *)zone {
return _slideManger;
} - (id)mutableCopyWithZone:(NSZone *)zone {
return _slideManger;
} - (void)slideMangerCustomNav:(UIView *)customNav navBottm:(UIView *)navBottmView tabHeader:(UIView *)tabHeader navBottomShadowView:(UIView *)navBShadowView {
if (navBottmView) {
_navBottmView = (NavBarBottomView *)navBottmView;
}
if (tabHeader) {
_tabHeader = tabHeader;
}
if (customNav) {
_customNav = (CustrmNav *)customNav;
}
if (navBShadowView) {
_navBShadowView = (NavBarBottomView *)navBShadowView;
}
} //滑动的时候
- (void)tableViewSlide:(CGFloat)slide {
if (_navBShadowView && _tabHeader) {
//得到真实的偏移量,让slideY从0开始算起
CGFloat slideY = slide + _navBShadowView.height + _tabHeader.height;
// NSLog(@"******%f",slideY);
[self handleTabHeader:slideY];
[self handleCustomNavNavBottom:slideY];
}
}
//tableView 停止的时候
- (void)tabViewEndSlide:(CGFloat)slide scrollView:(UIScrollView *)scrollView {
if (_navBShadowView && _tabHeader) {
//得到真实的偏移量
CGFloat slideY = slide + _navBShadowView.height + _tabHeader.height;
if (slideY > 0) {
if (slideY >= _navBShadowView.height/2 && slideY < _navBShadowView.height) {
//自动滑到上面
[scrollView setContentOffset:CGPointMake(0, -_tabHeader.height) animated:YES];
} else if (slideY < _navBShadowView.height/2) {
//自动滑下去
[scrollView setContentOffset:CGPointMake(0, -(_navBShadowView.height + _tabHeader.height)) animated:YES];
}
}
}
}
//处理 TabHeader 跟随 tableView 滑动
- (void)handleTabHeader:(CGFloat)slide {
static BOOL isDown = NO;
if (slide <= 0) {
_navBottmView.hidden = NO;
_navBShadowView.hidden = YES;
//tableView往下滑的时候,禁止 _tabHeader与_navBottmView一起下滑
_tabHeader.y = -_tabHeader.height + slide;
_navBottmView.y = -(_navBShadowView.height + _tabHeader.height) + slide;
isDown = YES;
} else {
_navBottmView.hidden = YES;
_navBShadowView.hidden = NO;
if (isDown) {
_tabHeader.y = -_tabHeader.height;
isDown = NO;
}
}
}
//处理customnav 的渐变色问题 以及navbottom 影子 的位置 渐变色问题
- (void)handleCustomNavNavBottom:(CGFloat)slide {
if (slide >= 0) {
CGFloat halfNavBottomH = _navBShadowView.height/2;
CGFloat alpValue = (_navBShadowView.height - slide)?(_navBShadowView.height - slide):0;
[_navBShadowView updateAlpha:alpValue/_navBShadowView.height];
[_customNav updateAlpha:slide/_navBShadowView.height];
if (slide<= _navBShadowView.height) {
_navBShadowView.y = _customNav.height - slide/2;
} else {
_navBShadowView.y = _customNav.height - halfNavBottomH;
}
} else {
[_navBShadowView updateAlpha:1.0];
[_customNav updateAlpha:0.0];
_navBShadowView.y = _customNav.height;
}
} @end

6.解决问题六,主要是scrollView的 代理的滚动停止的方法和拖拽停止的方法确定不会再滚动的时候。依据滚动停止tableView滑动量来确定是展开还是折叠。

//tableView 停止的时候
- (void)tabViewEndSlide:(CGFloat)slide scrollView:(UIScrollView *)scrollView {
if (_navBShadowView && _tabHeader) {
//得到真实的偏移量
CGFloat slideY = slide + _navBShadowView.height + _tabHeader.height;
if (slideY > 0) {
if (slideY >= _navBShadowView.height/2 && slideY < _navBShadowView.height) {
//自动滑到上面
[scrollView setContentOffset:CGPointMake(0, -_tabHeader.height) animated:YES];
} else if (slideY < _navBShadowView.height/2) {
//自动滑下去
[scrollView setContentOffset:CGPointMake(0, -(_navBShadowView.height + _tabHeader.height)) animated:YES];
}
}
}
}

项目结构图

iOS仿支付宝首页效果

代码地址如下:
http://www.demodashi.com/demo/12776.html

注:本文著作权归作者,由demo大师代发,拒绝转载,转载需要作者授权

iOS仿支付宝首页效果的更多相关文章

  1. iOS仿支付宝首页的刷新布局效果

    代码地址如下:http://www.demodashi.com/demo/12753.html XYAlipayRefreshDemo 运行效果 动画效果分析 1.UI需要变动,向上滑动的时候,顶部部 ...

  2. Android控件Gridview实现仿支付宝首页,Fragment底部按钮切换和登录圆形头像

    此案例主要讲的是Android控件Gridview(九宫格)完美实现仿支付宝首页,包含添加和删除功能:Fragment底部按钮切换的效果,包含四个模块,登录页面圆形头像等,一个小项目的初始布局. 效果 ...

  3. iOS 仿支付宝密码支付

    代码地址如下:http://www.demodashi.com/demo/11484.html 一.准备工作 xcode 主要实现输入密码的时候不可见 二.程序实现 实现思路怎样 在支付宝输入密码的时 ...

  4. Android RecyclerView 实现支付宝首页效果

    Android RecyclerView 实现支付宝首页效果 [TOC] 虽然我本人不喜欢支付宝的,但是这个网格本身其实还是不错的,项目更新中更改了一个布局为网格模式,类似支付宝.(估计是产品抄袭的= ...

  5. iOS仿支付宝芝麻信用仪表盘效果

    概述 自定义View之高仿支付宝芝麻信用分数仪表盘动画效果 详细 代码下载:http://www.demodashi.com/demo/10654.html 仿支付宝芝麻信用仪表盘效果 一.主要思路 ...

  6. android支付宝首页、蚂蚁森林效果、视频背景、校园电台、载入收缩动画等源码

    Android精选源码 android实现蚂蚁森林效果源码 android仿支付宝首页应用管理(拖拽排序,添加删除) android校园网络电台客户端源码 android实现按钮伸缩效果源码 一款仿i ...

  7. iOS支付宝 9.x 版本首页效果

    http://www.jianshu.com/p/7516eb852cca 支付宝 9.x 版本首页效果 对于新版支付宝首页的产品功能这里就不说什么了,一大堆人吐槽,我们只想要一个好好的支付工具,阿里 ...

  8. [ios仿系列]仿支付宝手势解码

    呀~.这么快就转到ios阵营了???.android还有那么多坑呢???为此我也仅仅能啃着馒头留下屈辱的眼泪了. . 本次因为开发公司产品的android版,继而ios版也负责一部分.当中一部分就是手 ...

  9. Android控件GridView之仿支付宝钱包首页带有分割线的GridView九宫格的完美实现

    Android控件GridView之仿支付宝钱包首页带有分割线的GridView九宫格的完美实现 2015-03-10 22:38 28419人阅读 评论(17) 收藏 举报  分类: Android ...

随机推荐

  1. linux Centos7 安装Samba服务

    1. 使用Samba服务器需要防火墙开放以下端口 UDP 137 UDP 138 TCP 139 TCP 445 如果碰到 “Unable to save xxxxxxxx 拒绝访问” 的提示,还有最 ...

  2. how to configure team on liunx(RHEL7.x/Centos7.x)

    #install team sofeware yum install teamd -y #check team configuration nmcli con show #Next we create ...

  3. Python与数据库[1] -> 数据库接口/DB-API[2] -> SQL Server 适配器

    SQL_Server适配器 / SQL_Server Adapter 1 环境配置 / Environment Configuration 安装SQL_Server的Python适配器包 pip in ...

  4. Python与数据库[2] -> 关系对象映射/ORM[1] -> sqlalchemy 的基本使用示例

    sqlalchemy 的基本使用示例 下面的例子中将利用sqlalchemy进行数据库的连接,通过orm方式利用类实例属性操作的方式对数据库进行相应操作,同时应用一些常用的函数. 完整代码如下: fr ...

  5. HDU 4417 Super Mario (划分树)(二分)

    Super Mario Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total ...

  6. 初步接触LVS

    今天整理下思绪,定下要掌握LVS原理和使用方法.于是,看了部分关于LVS的概述和文章. 章博士在2002年写的LVS的几篇文章,在我看来,今天都值得一看.http://www.linuxvirtual ...

  7. 每天一个linxu命令6之jps  查看java进程的端口

    jps -- JavaVirtual Machine Process Status Tool 可以列出本机所有Java进程的pid jps [ options ] [ hostid ] 选项 -q 仅 ...

  8. android 代码覆盖率

    背景 项目使用的是small插件.一个app分为main和多个插件,为了统计插件的代码覆盖率. 1 修改插件 修改插件build.gradle buildTypes { release { ... } ...

  9. kubernetes社区项目生态概览

    原文  http://dockone.io/article/2075 作为容器集群管理技术的最流行的技术,kubernetes,自从2014在github上开源后,已经通过多个项目形成了一个生态,以下 ...

  10. react with JSX for {if…else…}

    在react中用jsx渲染dom的时候经常会遇到if条件判断,然而在jsx中竟是不允许if条件判断的.以下有几种判断方式,可以根据自己的应用场景,挑选适合的 https://blog.csdn.net ...