ios新手开发——toast提示和旋转图片加载框
不知不觉自学ios已经四个月了,从OC语法到app开发,过程虽然枯燥无味,但是结果还是挺有成就感的,在此分享我的ios开发之路中的小小心得~废话不多说,先上我们今天要实现的效果图:
有过一点做APP经验的都知道,提示框和等待加载框一直是APP首当其中的效果,ios不像android一样,自带toast和progressbarDialog,所以在做ios开发的时候,我首先想到了先封装这两个基础控件~当然网上的资源数不胜数,但是博主抱着一颗自主研究的精神,做出的效果也不错,也已适配了所有iphone型号和版本.望大家多多支持~
YPXToastView实现
接触过安卓开发的ios开发者可能对待toast这么个东西很不陌生,它主要是一种轻量级的提示,代替了复杂的对话框,有的显示在中间,有的显示在屏幕下方,当然,这些都是根据需求而来的.废话不多说,首先清理一下我们实现这个toast的一些必要思路:
1.实现的基础控件------UILabel封装
2.弹出的时间和透明度变化设置
3.显示的位置调整
一.UILabel的封装
首先我们想要实现一下这个效果,首当其冲的肯定想到UILabel,那么接下来就是对UILabel的封装了,首先我们创建一文件继承UIlabel,然后写好要对外暴露的方法:
1 @interface YPXToastView : UILabel 2 3 { 4 @public 5 CGFloat screenWidth,screenHeight; 6 int _corner; 7 int _duration; 8 } 9 10 @property(assign,nonatomic)int corner; 11 @property(assign,nonatomic)int duration; 12 13 14 -(void)showToastViewWithText:(NSString *)text andDuration:(int)duration andParentView:(UIView *)parentView; 15 16 -(void)showToastViewWithText:(NSString *)text andParentView:(UIView *)parentView; 17 18 -(void)showToastViewWithText:(NSString *)text andDuration:(int)duration andCorner:(int)corner andParentView:(UIView *)parentView; 19 20 +(void)showToastViewWithText:(NSString *)text andDuration:(int)duration andParentView:(UIView *)parentView; 21 22 +(void)showToastViewWithText:(NSString *)text andParentView:(UIView *)parentView; 23 24 +(void)showToastViewWithText:(NSString *)text andDuration:(int)duration andCorner:(int)corner andParentView:(UIView *)parentView; 25 26 -(void)setBackgroundWithColor:(UIColor *)color; 27 28 @end
定义了四个全局变量,两个属性,分别制定了提示框的圆角和时间.方法中定义了三个类方法,和四个实例方法,主要是因为我们在使用时并不想实例化一次我们的提示框,所有的实例方法中抽出了三个类方法方便用户调用.
下面我们来看内部主要方法实现:
1 2 3 /** 4 * 新建UI 5 * 6 * @param str 要显示的文本 7 */ 8 -(void)createUIByText:(NSString *)str{ 9 self.textAlignment = NSTextAlignmentCenter; 10 self.backgroundColor = [UIColor colorWithRed:00 green:00 blue:00 alpha:0.5]; 11 self.alpha = 0.8; 12 self.text=str; 13 self.font = [UIFont systemFontOfSize:14]; 14 self.textColor=[UIColor whiteColor]; 15 NSDictionary *attributes = @{NSFontAttributeName:[UIFont systemFontOfSize:self.font.pointSize],}; 16 CGSize textSize = [self.text boundingRectWithSize:CGSizeMake(100, 100) options:NSStringDrawingTruncatesLastVisibleLine attributes:attributes context:nil].size;; 17 self.frame=CGRectMake(screenWidth/2-(textSize.width*1.7)/2, screenHeight*0.5,textSize.width*1.7, 18 textSize.height*2); 19 self.layer.cornerRadius = _corner; 20 self.clipsToBounds = YES; 21 } 22 23 -(void)setBackgroundWithColor:(UIColor *)color{ 24 self.backgroundColor =color; 25 } 26 27 28 /** 29 * 初始化测量数据 30 */ 31 -(void)caculateSize{ 32 screenWidth=[UIScreen mainScreen].bounds.size.width; 33 screenHeight=[UIScreen mainScreen].bounds.size.height; 34 }
方法一目了然,指定了UILabel的居中方式和背景,并设置属性让其宽度自适应,涉及到一些简单的frame计算,主要是定位于屏幕中间,宽度设为文本宽度的1.7倍,看起来比较适中.y点主要就是屏幕高度的一半,理应减去文本的高度的一半,但是博主在这偷个懒,并没有计算label的高度,所以就不赘述了~~
二.弹出的时间和透明度变化设置
原理很简单,就是设定了一个animateWithDuration的block回调,然后设置label的透明度和时间,具体实现如下:
/*** 显示toast** @param parentView <#parentView description#>*/ -(void)showToastByParentView:(UIView *)parentView{[parentView addSubview:self];//animateWithDuration可以控制label显示持续时间[UIView animateWithDuration:_duration animations:^{self.alpha = 1.0;} completion:^(BOOL finished){[self removeFromSuperview];}]; }
默认时间为1秒,思路很清晰,先添加进我们的parentView中,然后指定时间后移除.
到此,我们的YPXToastView已经全部完成,其实内部逻辑主要是对UILabel的定制,思路简单,但是对于ios开发之路的封装思想有很大的帮助.调用时只需要一行代码:
[YPXToastView showToastViewWithText:@"已开启" andDuration:3 andCorner:5 andParentView:self.view];
调用方便简洁,以后测试就不需要用NSLog了嘿嘿~
YPXLoddingView实现
相信在ios的开发中少不了加载等待框的开发,毕竟原生系统中貌似没有这样的对话框,我们在访问网络或者读取数据时可能需要给用户一个等待回馈,这里就用到了我们的等待加载.上面的gif中提供了两种等待加载框的样式,一种是自定义图片的旋转,顺时针或者逆时针,另一种是使用系统的UIActivityIndicatorView,使用大的加载Loadding.具体开发思路如下:
1.继承UIView通过添加UIImageView和UILabel来组合实现
2.控制UIImageView的旋转以及UIlabel的三个点的动态效果
3.显示和隐藏
一.UIView的封装
通过效果我们可以一目了然的知道,实现这个控件至少需要一个UIImageView(或者UIActivityIndicatorView)和UILabel,一个提供加载图片,一个提供加载文本,组合方式为竖直方向,然后设置背景的透明度.具体.h文件如下:
#import <UIKit/UIKit.h>@interface YPXLoaddingView : UIView{@publicint num;CGFloat angle;BOOL isShowLoadding;UIImageView * imageView;UILabel * label;CGFloat width;CGFloat x;CGFloat y,screenWidth,screenHeight;UIView * _parentView;NSString * _text;NSTimer * _timer;UIActivityIndicatorView * _activityView;UIView * view; }@property(retain,nonatomic)NSTimer * timer; @property(copy,nonatomic) NSString * text; @property(retain,nonatomic) UIActivityIndicatorView * activityView;-(void)showLoaddingViewWithText:(NSString *) string;-(void)dismissLoaddingView;-(instancetype)initWithParentView:(UIView *) parentView;+(id)initWithParentView:(UIView *) parentView;-(BOOL)isShowing;-(void)showLoaddingView;-(void)showLoaddingViewWithStyle:(int)style;-(void)showLoaddingViewWithText:(NSString * )text andStyle:(int)style;@end
定义了一些必要的属性,包括计时器和显示文本等,主要功能为show开头的方法,style应该是个枚举类型,但是博主目前还没有写过枚举类,所以直接引用0和1来指定使用图片还是系统的菊花加载.看完.h我们来看看具体的UIView代码实现:
1 2 3 /** 4 * 计算一些必要尺寸 5 * 6 * @param parentView <#parentView description#> 7 */ 8 -(void)caculatSizeWithTarget:(UIView *) parentView 9 { 10 screenWidth=[UIScreen mainScreen].bounds.size.width; 11 screenHeight=[UIScreen mainScreen].bounds.size.height; 12 width=screenWidth*0.3; 13 x= screenWidth/2-width/2; 14 y= screenHeight/2-width/2; 15 angle=0; 16 num=0; 17 isShowLoadding=NO; 18 _parentView=parentView; 19 20 } 21 22 /** 23 * 创建loadding视图 24 */ 25 -(void)creatLoaddingView 26 { 27 view=[[UIView alloc]init]; 28 view.frame=CGRectMake(0, 0, screenWidth, screenHeight); 29 30 imageView=[[UIImageView alloc]init]; 31 imageView.frame=CGRectMake(width/2-width*0.5/2,15, width*0.5,width*0.4); 32 imageView.clipsToBounds=YES; 33 imageView.layer.rasterizationScale=[UIScreen mainScreen].scale; 34 [imageView setImage:[UIImage imageNamed:@"loadding.png"]]; 35 36 _activityView=[[UIActivityIndicatorView alloc]initWithFrame:CGRectMake(width/2-width*0.55/2,15, width*0.55,width*0.45)]; 37 _activityView.activityIndicatorViewStyle=UIActivityIndicatorViewStyleWhiteLarge; 38 39 40 label=[[UILabel alloc]init]; 41 label.textColor=[UIColor whiteColor]; 42 label.font=[UIFont systemFontOfSize:14]; 43 int y2=imageView.frame.size.height+(width-imageView.frame.size.height)/2; 44 label.frame=CGRectMake(0,y2, width, 20); 45 label.textAlignment=NSTextAlignmentCenter; 46 47 }
手动布局,我们指定了imageview和label的frame,通过一系列计算,把imageview设为UIView中上部,并留出四周的边距,看起来更亲切自然一点.label的位置根据imageview的frame来指定,这样就可以完成适配避免在不同屏幕上显示不同的问题.完场上述代码,一个初步的静态效果已经生成,剩下的就是添加动画;
二.UIImageView旋转动画以及UILabel点点动态展示
imageview的动画添加很简单,因为我们只是涉及一点点的旋转动画,其中并没有加速度变化,读者若是想要添加,可以自己尝试一下.旋转动画的实现方式有两种:
一种是用animateWithDuration来动态的旋转一定角度,然后通过延时来改变旋转的速率,好处是简单,但是缺点也很明显,在5s中动画显得僵硬,并伴随着一点点的卡顿,如下是第一种动画方案的代码:
1 /** 2 * 开启loadding动画 3 */ 4 - (void)startAnimation 5 { 6 if(isShowLoadding==YES){ 7 CGAffineTransform endAngle = CGAffineTransformMakeRotation(angle * (M_PI / -180.0f)); 8 [UIView animateWithDuration:0.03f delay:0 options:UIViewAnimationOptionCurveLinear animations:^{ 9 imageView.transform =endAngle; 10 } completion:^(BOOL finished) { 11 if(angle==360){ 12 angle=0; 13 } 14 if(angle==0||angle==360){ 15 label.text=[_text stringByAppendingString:@"..."]; 16 }else if(angle==90){ 17 label.text=_text; 18 }else if(angle==180){ 19 label.text=[_text stringByAppendingString:@"."]; 20 }else if(angle==270){ 21 label.text=[_text stringByAppendingString:@".."]; 22 } 23 angle += 10; 24 25 [self startAnimation]; 26 }]; 27 } 28 29 }
通过改变imageview的角度来旋转图片的方式,使用block回调中的角度关系,我们可以动态的设置提示文本省略号的动态展示.因为实现效果有点卡顿,所以博主采用了第二种实现方式,代码如下:
1 /** 2 * 启动计数定时器 3 */ 4 -(void)UpdateText 5 { 6 num++; 7 if (num>4) { 8 num=0; 9 } 10 if(num==0||num==4){ 11 label.text=[_text stringByAppendingString:@"..."]; 12 }else if(num==1){ 13 label.text=_text; 14 }else if(num==2){ 15 label.text=[_text stringByAppendingString:@"."]; 16 }else if(num==3){ 17 label.text=[_text stringByAppendingString:@".."]; 18 } 19 20 } 21 22 /** 23 * 给imageView添加动画 24 * 25 * @param imageView imageview 26 * 27 * @return imageview 28 */ 29 + (UIImageView *)rotateImageView:(UIImageView *)imageView 30 { 31 CABasicAnimation *animation = [ CABasicAnimation 32 animationWithKeyPath: @"transform" ]; 33 animation.fromValue = [NSValue valueWithCATransform3D:CATransform3DIdentity]; 34 35 //围绕Z轴旋转,垂直与屏幕 36 animation.toValue = [ NSValue valueWithCATransform3D: 37 CATransform3DMakeRotation(M_PI, 0.0, 0.0, 1.0) ]; 38 animation.duration = 0.5; 39 //旋转效果累计,先转180度,接着再旋转180度,从而实现360旋转 40 animation.cumulative = YES; 41 animation.repeatCount = 10000; 42 43 [imageView.layer addAnimation:animation forKey:nil]; 44 return imageView; 45 }
采用CABasicAnimation的动画效果可以达到动画流畅度的完美展示,优点就是增加了旋转性能,缺点就是没有像animateWithDuration那样有动画的回调,这样我们就没有办法动态的去改变label的提示文本,所以细心的读者会发现,博主前面的.h文件中已经申明了一个定时器,那么这个定时器的作用是用来干嘛的呢?我们通过启动定时器,来动态的刷新label的提示文本达到一种动态展示的效果,这种思路在安卓里也同样适用.
完成了我们的图片旋转,基本上这个功能已经完成了百分之八十,剩下就是显示和隐藏了;
三.显示和隐藏
前面介绍.h文件申明的时候,已经把本控件的所有调用方法已经列出来了,其中包含了一系列的.show方法,因为loadding这种控件,我们可能需要对其状态进行判断,而且可能在网络请求中调用多次,为了不浪费内存,我们在这里提倡使用单例模式,并初始化一个Loadding在ViewDidLoad中.后期调用只需要show和dismiss即可,下面我们来看具体的show和dismiss的方法实现:
1 /** 2 * 显示loadding.默认文本为 "正在加载" 3 */ 4 -(void)showLoaddingView 5 { 6 if(isShowLoadding==YES){ 7 return; 8 } 9 if(_text==nil||[_text isEqualToString:@""]){ 10 _text=@"正在加载"; 11 } 12 label.text=_text; 13 isShowLoadding=YES; 14 angle=0; 15 self.hidden=NO; 16 [self addSubview:imageView]; 17 [self addSubview:label]; 18 [view addSubview:self]; 19 [_parentView addSubview:view]; 20 [YPXLoaddingView rotateImageView:imageView]; 21 _timer=[NSTimer scheduledTimerWithTimeInterval:0.5 target:self selector:@selector(UpdateText) userInfo:nil repeats:YES]; 22 23 } 24 25 -(void)showLoaddingViewWithStyle:(int)style 26 { 27 if(style==0){//菊花加载 28 if(isShowLoadding==YES){ 29 return; 30 } 31 if(_text==nil||[_text isEqualToString:@""]){ 32 33 _text=@"正在加载"; 34 } 35 label.text=_text; 36 isShowLoadding=YES; 37 angle=0; 38 self.hidden=NO; 39 [self addSubview:_activityView]; 40 [self addSubview:label]; 41 [imageView removeFromSuperview]; 42 [_activityView startAnimating]; 43 [view addSubview:self]; 44 [_parentView addSubview:view]; 45 _timer=[NSTimer scheduledTimerWithTimeInterval:0.5 target:self selector:@selector(UpdateText) userInfo:nil repeats:YES]; 46 47 }else{//旋转图片加载 48 [self showLoaddingView]; 49 } 50 51 } 52 53 /** 54 * 显示loadding 55 * 56 * @param string 显示的文本 57 */ 58 -(void)showLoaddingViewWithText:(NSString *) string 59 { 60 _text=string; 61 [self showLoaddingView]; 62 } 63 64 65 -(void)showLoaddingViewWithText:(NSString *)text andStyle:(int)style{ 66 _text=text; 67 [self showLoaddingViewWithStyle:style]; 68 } 69 70 71 /** 72 * 消失loadding 73 */ 74 -(void)dismissLoaddingView 75 { 76 self.hidden=YES; 77 isShowLoadding=NO; 78 [_timer invalidate]; 79 [imageView.layer removeAllAnimations]; 80 [_activityView stopAnimating]; 81 [view removeFromSuperview]; 82 }
总体来说show方法中就是单纯的控制了imageview和_activityView通过style来隐藏和显示,思路很简单,再次不做赘述.dismiss中只需要移除我们的view就好,非常简单,同时不要忘记stop我们的_activityView以及关闭定时器就好.
致此,所有的代码实现已经完成,我们在需要调用的地方首先实例化一次,然后使用show和dismiss即可.
总结
下载地址:http://download.csdn.net/detail/qq_16674697/9622230
作者:yangpeixing
QQ:313930500
CSND地址:http://blog.csdn.net/qq_16674697/article/details/53172388
转载请注明出处~谢谢~
转载于:https://www.cnblogs.com/teamblog/p/yangpeixing.html
ios新手开发——toast提示和旋转图片加载框相关推荐
- iOS开发:利用SDWebImage实现图片加载与缓存
iOS开发:利用SDWebImage实现图片加载与缓存 SDWebImage是一套开源框架,这个类库提供一个UIImageView类别以支持加载来自网络的远程图片.具有缓存管理.异步下载.同一个URL ...
- 详谈高大上的图片加载框架Glide -应用篇
在Android设备上,加载网络图片一直是一个头疼的问题,因为Android设备种类繁多(当然最主要的是配置),处理的稍不周到轻则应用卡顿,严重者就会出现OOM的,导致程序挂掉.现如今网络上有很多图片 ...
- ionic开发——图片加载失败或不存在时显示提示图片的解决方法
当图片加载失败或者不存在的时候,我们需要一张提示图片来代替他.用判断就太麻烦了,img有自己的方法onerror , 当找不到图片的时候就会执行onerror里面的代码 例如: <img src ...
- iOS开发学无止境 - 异步图片加载优化与常用开源库分析
作者:罗轩(@luoyibu) 网址:http://www.jianshu.com/p/3b2c95e1404f 1. 网络图片显示大体步骤: 下载图片 图片处理(裁剪,边框等) 写入磁盘 从磁盘 ...
- android图片传输三方框架,Android开发三种第三方图片加载的框架
最近在项目中用到了大量图片加载,第三方优秀框架还不错,下面介绍三款榜首的框架用法和问题,做一个记录. 现在项目使用的是Android Studio开发的,现在也没有多少人使用Eclipse了吧. 一. ...
- 学习Mac开发第四弹 通过NSImageView加载图片
学习Mac开发第四弹 通过NSImageView加载图片 创建NSImageView 1 . 拖拽大法好 Autolayout 创建一个宽高160 *160 的NSImageView 创建是正方形的 ...
- veImageX 演进之路:iOS 高性能图片加载 SDK
动手点关注 干货不迷路 1. SDK简介 图片在业务应用场景是一个常见的元素,veImageX(简称ImageX)为业务提供了灵活.高效的一站式图片处理解决方案,包括了服务端 SDK.上传 SDK ...
- Flutter开发之图片加载(九)
移动开发少不了显示图片,今天就介绍 fluter中如何加载图片,图片加载一般分为本地加载和网络加载. 本地加载 在工程下建一个New Floder 文件夹名:images 将准备好的图片拖到 imag ...
- android 加载进度,Android实现图片加载进度提示
本文实例为大家分享了Android实现图片加载进度提示的具体代码,供大家参考,具体内容如下 先上图: 实现原理: 第一个控件的实现原理是重写ImageView的onDraw()方法,利用Canvas的 ...
最新文章
- Apache日志配置参数说明
- ssm框架搭建和整合流程
- Java FileReader InputStreamReader类源码解析
- 简易 IM 双向通信电脑端 GUI 应用——基于 Netty、WebSocket、JavaFX 、多线程技术等
- JAVA进阶day02
- eclipse简单使用
- raspberry pi_探索Raspberry Pi Sense HAT
- python tkinter滚动条不起作用_求助:tkinter中滚动条为什么不能用
- 【算法导论第13章】红黑树
- 在你的代码中使用Boost智能指针
- Git:tag标签的使用
- 苹果macOS Monterey将支持一键恢复出厂设置,无需重装系统
- 有没有简易的画图软件?这4款软件让画图更简单
- Xshell 安装教程以及踩过的坑
- 学术论文投稿与返修(Rebuttal)经验分享
- 12306的“短信公众号”到底是个啥?
- 【无标题】程序员的一大步
- 2022重装Win7系统(64位)提示Windows update无法搜索新更新错误代码80072EFE
- mysql使用jdbc进行批量插入时把事务设为手动提交比事务自动提交速度快了10倍
- 在Excel中填写空白单元格以完成表格
热门文章
- Word2019上面的MathType7.4插件忽然消失了【终极解决办法记录】
- 服务器内提取文件,linux命令如何提取文件夹内特定文件路径
- java通过ldap添加用户后_ldap连接不上改用户_JAVA通过LDAP做用户登录认证,怎么做业务的异常处理?...
- 项目放到git_Git的基本使用(二)
- matlab在振动信号处理中的应用_Matlab面向对象程序设计及其在地球物理学中的应用(4)——类的属性
- JAVA复习(CharSequence接口、RunTime类、System类、object类中的finalize())
- linux系统在pe下查看ip地址,pe下查看原系统ip的方法_网站服务器运行维护
- 统计 表格_电商运营表格合集,运营统计绩效策划,全套excel表拿来就用
- 编写jmeter测试用例_JMeter 编写接口测试用例遇到的问题及解决
- 人工神经网络_AI产品经理必修课 | 人工智能概论(四)-人工神经网络