我爱模仿app之格瓦拉客户端
最近有很多人问我,这个效果该怎么实现,那个功能该怎么实现。所以我准备开个专题,找一些app模仿,写一些示例代码,以供大家参考。
第一个下手的就是格瓦拉,没用过的可以下载看看,效果做的还是可以的,专场,和 tabBar的实现都觉得挺有意思的。项目代码
项目代码已经提交到github上 https://github.com/qianhongqiang/QHQGewala
首先讲解下如何实现这样的自定义的tabBar
首先创建了继承于UITabBarController的TranslationTabBarViewController,并且讲其自带的tabBar隐藏,并且创建了一个自定义的tabBar。
-(void)setupTabBar {
self.tabBar.hidden = YES;
GewalaTabBar *tabbar = [[GewalaTabBar alloc] initWithFrame:CGRectMake(0, [UIScreen mainScreen].bounds.size.height - 60, [UIScreen mainScreen].bounds.size.width, 60) delegate:self];
[self.view addSubview:tabbar];
}
接着我们就需要实现格瓦拉下面的效果:点击某个按钮后,那个按钮右侧的字,也就是提示文字会出现。然后后面的按钮会往后移,腾出文字的位置。我们可以给每一个button添加1个UIImageView,和一个UILabel,当这个按钮被选中时,增大按钮的宽度,让文本框UILabel显示出来。这里实现一个方法,tabBar的某个按钮被点击后,每个按钮自己移动到对应的位置,并线决定自己是否显示文本等信息。这里味了方便大家看清楚,其实重写setSelected更加好一些。
-(void)tabBar:(GewalaTabBar *)tabBar tabBarItemClickedAtIndex:(NSUInteger)index {
CGRect toRect;
if (index > self.tag) {
toRect = CGRectMake(self.tag * kStandardButtonWidth, 0, kStandardButtonWidth, kStandardButtonHeight);
}else if(index < self.tag) {
toRect = CGRectMake((self.tag + 1) * kStandardButtonWidth, 0, kStandardButtonWidth, kStandardButtonHeight);
}else {
toRect = CGRectMake(self.tag* kStandardButtonWidth, 0, kStandardButtonWidth * 2, kStandardButtonHeight);
}
[UIView animateWithDuration:0.35 delay:0 usingSpringWithDamping:0.8 initialSpringVelocity:0.6 options:0 animations:^{
self.frame = toRect;
if (index > self.tag) {
self.tabBarButtonTitleView.alpha = 0;
self.tabBarButtonTitleView.frame = CGRectMake(0, 0, kStandardButtonWidth, kStandardButtonHeight);
self.tabbarButtonImageView.image = self.item.normalImage;
}else if(index < self.tag) {
self.tabBarButtonTitleView.alpha = 0;
self.tabBarButtonTitleView.frame = CGRectMake(0, 0, kStandardButtonWidth, kStandardButtonHeight);
self.tabbarButtonImageView.image = self.item.normalImage;
}else {
self.tabBarButtonTitleView.alpha = 1;
self.tabBarButtonTitleView.frame = CGRectMake(kStandardButtonWidth, 0, kStandardButtonWidth, kStandardButtonHeight);
self.tabbarButtonImageView.image = self.item.selectedImage;
}
} completion:nil];
}
其中下面方法的参数,如果你不知道怎么调整的话,可以在我上面参数的值附近微调,活着干脆不需要弹簧的效果。
+ (void)animateWithDuration:(NSTimeInterval)duration delay:(NSTimeInterval)delay usingSpringWithDamping:(CGFloat)dampingRatio initialSpringVelocity:(CGFloat)velocity options:(UIViewAnimationOptions)options animations:(void (^)(void))animations completion:(void (^ __nullable)(BOOL finished))completion NS_AVAILABLE_IOS(7_0);
我们继续实现一个专场,我们观察格瓦拉tabbar的切换。显示的页面不是直接切换,而是最后呈现简谐阻尼的震荡,切换有些类似于导航控制器。说到UIViewController这个东西,其实是设计模式的产物,从本质上来讲,就是UIViewController的view在做显示。
TranslationDelegate *delegate = [[TranslationDelegate alloc] init];
self.delegate = delegate;
objc_setAssociatedObject(self, &TranslationTabBarViewControllerDelegateAssociationKey, delegate, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
如果你直接去改变页面的frame也是可以的,但是为了迎合这种设置模式,所以我们最好去实现开放给我们专场的协议。要实现上面那个delegate。
这个代理类里,只有一个方法
-(id<UIViewControllerAnimatedTransitioning>)tabBarController:(UITabBarController *)tabBarController animationControllerForTransitionFromViewController:(UIViewController *)fromVC toViewController:(UIViewController *)toVC {
return [[TranslationAnimator alloc] init];
}
又创建了一个TranslationAnimator,这个对象是真正说明,这个专场该如何切换的。
- (void)animateTransition:(id<UIViewControllerContextTransitioning>)transitionContext
{
UIViewController *fromViewController = [transitionContext viewControllerForKey:UITransitionContextFromViewControllerKey];
UIViewController *toViewController = [transitionContext viewControllerForKey:UITransitionContextToViewControllerKey];
UIView *containerView = transitionContext.containerView;
UIView *fromView;
UIView *toView;
if ([transitionContext respondsToSelector:@selector(viewForKey:)]) {
fromView = [transitionContext viewForKey:UITransitionContextFromViewKey];
toView = [transitionContext viewForKey:UITransitionContextToViewKey];
} else {
fromView = fromViewController.view;
toView = toViewController.view;
}
CGRect fromFrame = [transitionContext initialFrameForViewController:fromViewController];
CGRect toFrame = [transitionContext finalFrameForViewController:toViewController];
fromView.frame = fromFrame;
toView.frame = CGRectOffset(toFrame, toFrame.size.width,0);
[containerView addSubview:toView];
NSTimeInterval transitionDuration = [self transitionDuration:transitionContext];
[UIView animateWithDuration:transitionDuration delay:0 usingSpringWithDamping:0.8 initialSpringVelocity:0.8 options:0 animations:^{
toView.frame = fromFrame;
} completion:^(BOOL finished) {
BOOL wasCancelled = [transitionContext transitionWasCancelled];
[transitionContext completeTransition:!wasCancelled];
}];
}
有点类似于NSInvoke对象,transitionContext就是一个包涵了你所需要的对象,fromView和toView分别对应的是,从哪个view跳转到哪个view。取到所有信息后,首先将toView的frame设置到屏幕的右侧CGRectOffset(toFrame, toFrame.size.width,0)即向右移动屏幕款,接着就执行弹性动画,将页面移动到屏幕中央。
是不是很简单?只要抓住本质,就很容易。
我爱模仿app之格瓦拉客户端的更多相关文章
- 【原创分享·支付宝支付】HBuilder打包APP调用支付宝客户端支付
前言 最近有点空余时间,所以,就研究了一下APP支付.前面很早就搞完APP的微信支付了,但是由于时间上和应用上的情况,支付宝一直没空去研究.然后等我空了的时候,发现支付宝居然升级了支付逻辑,虽然目前还 ...
- 推荐一款App运营工具:AYL爱盈利App榜单监控
对包括开发者.产品运营.投资人在内的诸多移动互联网从业人员而言,国内Android应用市场和IOS应用市场的榜单变化数据时大家的必修功课之一:看看这段时间所关注的垂直领域里最火的是哪几款应用:看看竞争 ...
- 爱pia戏推出PC客户端,为您自动置顶窗口,方便查找
爱pia戏推出PC客户端, 可以在无法使用插件的时候,使用PC客户端, 将为您自动置顶窗口,方便查看剧本. 百度网盘下载地址: 链接: http://pan.baidu.com/s/1pLpvn5p ...
- 王者荣耀交流协会互评Beta版本--爱阅app
测评人:任思佳 爱阅APP软件说明书地址:http://www.cnblogs.com/szjzsd/p/7881686.html 1.根据NABCD评论作品的选题: N(Need):相比α发布来 ...
- Beta版——爱阅APP功能说明书
爱阅APP功能说明书 一.引言 通过Alpha发布和一些用户的反馈信息,了解到我们APP存在的问题.针对这些问题我们做了一些修改.以下内容是Beta版的功能说明书. 二.工具 安卓手机 爱阅APP安装 ...
- 爱今天 APP 闪退怎么办?
爱今天 APP 闪退怎么办? 爱今天是一款简洁优秀的时间记录 APP. 但也有一些小 Bug,可能是因为不同的手机兼容问题,在添加时间时会出现闪退现象. 可能是因为自己修改了添加时间的方式. 可以通过 ...
- Thunder团队Final版爱阅app发布视频
视频链接:https://www.bilibili.com/video/av17008792/ 视频简介:首先出现的是我们团队的logo,接着是Final版爱阅app的功能展示,紧接着是我们团队的开发 ...
- final版——爱阅APP功能说明书
爱阅APP功能说明书 一.引言 以下内容是final版的功能说明书. 新增功能: 1.WiFi传书 2.书友群跳转 3.网址内部打开 4.设置-->关于爱阅 5.设置-->TXT文本的翻页 ...
- Thunder——爱阅app(测评人:方铭)
B.Thunder——爱阅app(测评人:方铭) 一.基于NABCD评论作品,及改进建议 每个小组评论其他小组Alpha发布的作品: 1.根据(不限于)NABCD评论作品的选题: 2.评论作品对选题的 ...
随机推荐
- SQL编程
变量: 变量是一块内存空间的表示, 数组是一连串空间 如何定义一个变量 第一套变量定义 整型 Declare @num int Set @num=10 Print @num 第二套变量定义 字符 ...
- 用纯css改变下拉列表select框的默认样式(不兼容IE10以下)
在这篇文章里,我将介绍如何不依赖JavaScript用纯css来改变下拉列表框的样式. 事情是这样的,您的设计师团队向您发送一个新的PSD(Photoshop文档),它是一个新的网站的最终设计 ...
- 让所有的浏览器都能识别HTML5标签样式的小插件
如今HTML5愈来愈引发大家的关注了,但目前支持HTML5的浏览器还不是主流,特别是国内用户近50%以上仍旧使用IE6,由于支持HTML5的IE9不支持Xp系统安装,这样未来很长一段时间,HTML5的 ...
- SqlMetal.exe ORM代码生成
作甚? 先说说这个工具是干啥的,我们所做的程序,或多或少需要存储一些数据到数据库,当然直接使用Sql语句也可以,甚至有些情况下就是要使用sql语句,但对于一些基本的增删改查,对每张表都要写查询语句就显 ...
- sql where and or优先级 待验证
where 后面如果有and,or的条件,则or自动会把左右的查询条件分开,即先执行and,再执行or.原因就是:and的执行优先级最高! 关系型运算符优先级高到低为:not and or 问题的解决 ...
- SSH整合报错:No result defined for action and result input
目前发现这个问题主要是在Action中的execute返回值时,没有对应的result name而引起的.很有可能是由于程序执行中出错了,但是对 应的Action中没有添加 input的result ...
- redis-介绍与比较
<一>. NoSQL简介: NoSQL是Not-Only-SQL的缩写,是被设计用来替换传统的关系型数据库在某些领域的用,特别针对web2.0站点以及大型的SNS网站,用来满足高并发 ...
- js中let和var定义变量的区别
let变量之前没见过,刚遇到,探探究竟. 以下转自:http://blog.csdn.net/nfer_zhuang/article/details/48781671 声明后未赋值,表现相同 (fun ...
- ajax之 get post请求
get请求 function get(){ $.get( "./Aservlet?id=5", function(data, textStatus, jqXHR){ $(" ...
- Git for Windows - The Program can't start because libiconv2.dll is missing
今天在新装的win10 预览版上面,发现git不能启动了,提示信息主要是: The Program can't start because libiconv2.dll is missing 于是我在网 ...