我爱模仿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.评论作品对选题的 ...
随机推荐
- 理解ThreadLocal(之一)
ThreadLocal是什么 在JDK 1.2的版本中就提供java.lang.ThreadLocal,ThreadLocal为解决多线程程序的并发问题提供了一种新的思路.使用这个工具类可以很简洁地编 ...
- Java程序设计之扑克牌
这段代码的主要实现功能扑克牌的洗牌和发牌功能,一副牌,红桃,黑桃,梅花,方片,A~K,不含大小王. 构造一个class. 首先是声明花色: private String[] sign={"方 ...
- 将对象转化成json字符串
public static String getObjectString(Object object){ String ObjectString = null; try { ObjectMapper ...
- MFC---static控件加载图片
IPicture* ppic = NULL; HRESULT hr; hr = OleLoadPicturePath((CComBSTR)picpath.GetBuffer(),(LPUNKNOWN) ...
- 百度数据可视化图表套件echart实战
最近我一直在做数据可视化的前端工作,我用的最多的绘图工具是d3.d3有点像photoshop,功能很强大,例子也很多,但是学习成本也不低,做项目是需要较大人力投入的.3月底由在亚马逊工作的同学介绍下使 ...
- The week in .NET - 1/12/2015
On.NET Last week, we had Mads Torgersen on the show to talk about language design in general, and C# ...
- JavaScript toLowerCase() 方法 把字符串转换为小写
定义和用法 toLowerCase() 方法用于把字符串转换为小写. 语法 stringObject.toLowerCase() 返回值 一个新的字符串,在其中 stringObject 的所有大写字 ...
- caffe的python接口学习(4):mnist实例---手写数字识别
深度学习的第一个实例一般都是mnist,只要这个例子完全弄懂了,其它的就是举一反三的事了.由于篇幅原因,本文不具体介绍配置文件里面每个参数的具体函义,如果想弄明白的,请参看我以前的博文: 数据层及参数 ...
- IDEA 分享项目到 Git@OSC/GitHub
前提:新开项目,需要在 Git@OSC 建立版本库管理. 1.当然是先在Git@OSC上创建仓库,拿到Git@OSC仓库的HTTP连接 https://git.oschina.net/*****/** ...
- .bat文件和Jar包的生成及运行
.bat文件和Jar包的生成及运行 1.Jar包简单介绍 Jar包是Java中所特有的一种压缩文档,有点类似于zip包,区别在于Jar包中有一个META-INF\MANIFEST.MF文件(在生成Ja ...