我爱模仿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.评论作品对选题的 ...
随机推荐
- 第4章 文本编辑器vim
1. vim常用操作 1.1 vim简介 (1)vim是一个功能强大的全屏幕文本编辑器,是Linux/Unix上最常用的文本编辑器,它的作用是建立.编辑.显示文本文件. (2)vim没有菜单,只有命令 ...
- Java 线程同步
线程同步 1.线程同步的目的是为了保护多个线程访问一个资源时对资源的破坏. 2.线程同步方法是通过锁来实现,每个对象都有切仅有一个锁,这个锁与一个特定的对象关联,线程一旦获取了对象锁,其他访问该对象的 ...
- 嵌入式Linux驱动学习之路(十四)按键驱动-同步、互斥、阻塞
目的:同一个时刻,只能有一个应用程序打开我们的驱动程序. ①原子操作: v = ATOMIC_INIT( i ) 定义原子变量v并初始化为i atomic_read(v) 返回原子变量 ...
- knockoutJS学习笔记03:knockout简介
通常来说,前端的维护难度是比较大的,特别是脚本,虽然像jquery这样的库可以帮助我们减少很多代码,但在稍微复杂的情况下,还是会产生有很多代码.上一篇介绍了模板引擎jsRender,它可以帮我们快速生 ...
- 浅谈Struts2
学过SSH框架很长一段时间了,一直没有很系统的总结一下,这里先简单谈谈Struts2. 为什么要用Struts2? 这里列举一些Servlet的缺点: 1.每写一个servlet在web.xml中都要 ...
- 关于 MonoDevelop on Linux 单步调试问题的解决
在 MonoDevelop 中默认是关闭对外部程序集(.dll)的调试,可通过如下步骤来解决这个问题. 通过菜单[Edit]-[Preferences]-[Debugger]进入到调试器的设置页,把“ ...
- 使用 VS Code 来编辑 markdown 文章
一开始我就用 VS Code 来编辑 markdown 文本,只是因为 VS Code 用起来感觉很好,然后我又去寻找其他的能够预览 markdown 的编辑器,看了好多都不是很方便.突然我发现 VS ...
- jdbc的基本应用
JDBC-----英文全称--------Java Data Base Connectivity是一种用于执行SQL语句的Java API,可以为多种关系数据库提供统一访问,它由一组用Java语言编写 ...
- [MAVEN]一、maven入门之软件的下载及配置到Eclipse中
1.Maven是什么? maven是Apache.org的一个子项目,他通过一个.pom的文件(xml文件)配置可以下载此项目中需要用到的jar包.文档.源码等.Maven提供了命令行的使用方式,我们 ...
- zabbix 监控web网站性能
一直在纠结用什么实例来给大家演示呢?想来想去还是官方的好,那我们怎么用zabbix监控web性能和可用性呢?我们这边分为几个步骤:打开网站.登陆.登陆验证.退出,一共4个小step,看实例. 检测流程 ...