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,然后写好要对外暴露的方法:
@interface YPXToastView : UILabel
{
@public
CGFloat screenWidth,screenHeight;
int _corner;
int _duration;
}
@property(assign,nonatomic)int corner;
@property(assign,nonatomic)int duration;
-(void)showToastViewWithText:(NSString *)text andDuration:(int)duration andParentView:(UIView *)parentView;
-(void)showToastViewWithText:(NSString *)text andParentView:(UIView *)parentView;
-(void)showToastViewWithText:(NSString *)text andDuration:(int)duration andCorner:(int)corner andParentView:(UIView *)parentView;
+(void)showToastViewWithText:(NSString *)text andDuration:(int)duration andParentView:(UIView *)parentView;
+(void)showToastViewWithText:(NSString *)text andParentView:(UIView *)parentView;
+(void)showToastViewWithText:(NSString *)text andDuration:(int)duration andCorner:(int)corner andParentView:(UIView *)parentView;
-(void)setBackgroundWithColor:(UIColor *)color;
@end
定义了四个全局变量,两个属性,分别制定了提示框的圆角和时间.方法中定义了三个类方法,和四个实例方法,主要是因为我们在使用时并不想实例化一次我们的提示框,所有的实例方法中抽出了三个类方法方便用户调用.
下面我们来看内部主要方法实现:
/**
* 新建UI
*
* @param str 要显示的文本
*/
-(void)createUIByText:(NSString *)str{
self.textAlignment = NSTextAlignmentCenter;
self.backgroundColor = [UIColor colorWithRed: green: blue: alpha:0.5];
self.alpha = 0.8;
self.text=str;
self.font = [UIFont systemFontOfSize:];
self.textColor=[UIColor whiteColor];
NSDictionary *attributes = @{NSFontAttributeName:[UIFont systemFontOfSize:self.font.pointSize],};
CGSize textSize = [self.text boundingRectWithSize:CGSizeMake(, ) options:NSStringDrawingTruncatesLastVisibleLine attributes:attributes context:nil].size;;
self.frame=CGRectMake(screenWidth/-(textSize.width*1.7)/, screenHeight*0.5,textSize.width*1.7,
textSize.height*);
self.layer.cornerRadius = _corner;
self.clipsToBounds = YES;
} -(void)setBackgroundWithColor:(UIColor *)color{
self.backgroundColor =color;
} /**
* 初始化测量数据
*/
-(void)caculateSize{
screenWidth=[UIScreen mainScreen].bounds.size.width;
screenHeight=[UIScreen mainScreen].bounds.size.height;
}
方法一目了然,指定了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: andCorner: 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
{
@public
int 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代码实现:
/**
* 计算一些必要尺寸
*
* @param parentView <#parentView description#>
*/
-(void)caculatSizeWithTarget:(UIView *) parentView
{
screenWidth=[UIScreen mainScreen].bounds.size.width;
screenHeight=[UIScreen mainScreen].bounds.size.height;
width=screenWidth*0.3;
x= screenWidth/-width/;
y= screenHeight/-width/;
angle=;
num=;
isShowLoadding=NO;
_parentView=parentView; } /**
* 创建loadding视图
*/
-(void)creatLoaddingView
{
view=[[UIView alloc]init];
view.frame=CGRectMake(, , screenWidth, screenHeight); imageView=[[UIImageView alloc]init];
imageView.frame=CGRectMake(width/-width*0.5/,, width*0.5,width*0.4);
imageView.clipsToBounds=YES;
imageView.layer.rasterizationScale=[UIScreen mainScreen].scale;
[imageView setImage:[UIImage imageNamed:@"loadding.png"]]; _activityView=[[UIActivityIndicatorView alloc]initWithFrame:CGRectMake(width/-width*0.55/,, width*0.55,width*0.45)];
_activityView.activityIndicatorViewStyle=UIActivityIndicatorViewStyleWhiteLarge; label=[[UILabel alloc]init];
label.textColor=[UIColor whiteColor];
label.font=[UIFont systemFontOfSize:];
int y2=imageView.frame.size.height+(width-imageView.frame.size.height)/;
label.frame=CGRectMake(,y2, width, );
label.textAlignment=NSTextAlignmentCenter; }
手动布局,我们指定了imageview和label的frame,通过一系列计算,把imageview设为UIView中上部,并留出四周的边距,看起来更亲切自然一点.label的位置根据imageview的frame来指定,这样就可以完成适配避免在不同屏幕上显示不同的问题.完场上述代码,一个初步的静态效果已经生成,剩下的就是添加动画;
二.UIImageView旋转动画以及UILabel点点动态展示
imageview的动画添加很简单,因为我们只是涉及一点点的旋转动画,其中并没有加速度变化,读者若是想要添加,可以自己尝试一下.旋转动画的实现方式有两种:
一种是用animateWithDuration来动态的旋转一定角度,然后通过延时来改变旋转的速率,好处是简单,但是缺点也很明显,在5s中动画显得僵硬,并伴随着一点点的卡顿,如下是第一种动画方案的代码:
/**
* 开启loadding动画
*/
- (void)startAnimation
{
if(isShowLoadding==YES){
CGAffineTransform endAngle = CGAffineTransformMakeRotation(angle * (M_PI / -180.0f));
[UIView animateWithDuration:0.03f delay: options:UIViewAnimationOptionCurveLinear animations:^{
imageView.transform =endAngle;
} completion:^(BOOL finished) {
if(angle==){
angle=;
}
if(angle==||angle==){
label.text=[_text stringByAppendingString:@"..."];
}else if(angle==){
label.text=_text;
}else if(angle==){
label.text=[_text stringByAppendingString:@"."];
}else if(angle==){
label.text=[_text stringByAppendingString:@".."];
}
angle += ; [self startAnimation];
}];
} }
通过改变imageview的角度来旋转图片的方式,使用block回调中的角度关系,我们可以动态的设置提示文本省略号的动态展示.因为实现效果有点卡顿,所以博主采用了第二种实现方式,代码如下:
/**
* 启动计数定时器
*/
-(void)UpdateText
{
num++;
if (num>) {
num=;
}
if(num==||num==){
label.text=[_text stringByAppendingString:@"..."];
}else if(num==){
label.text=_text;
}else if(num==){
label.text=[_text stringByAppendingString:@"."];
}else if(num==){
label.text=[_text stringByAppendingString:@".."];
} } /**
* 给imageView添加动画
*
* @param imageView imageview
*
* @return imageview
*/
+ (UIImageView *)rotateImageView:(UIImageView *)imageView
{
CABasicAnimation *animation = [ CABasicAnimation
animationWithKeyPath: @"transform" ];
animation.fromValue = [NSValue valueWithCATransform3D:CATransform3DIdentity]; //围绕Z轴旋转,垂直与屏幕
animation.toValue = [ NSValue valueWithCATransform3D:
CATransform3DMakeRotation(M_PI, 0.0, 0.0, 1.0) ];
animation.duration = 0.5;
//旋转效果累计,先转180度,接着再旋转180度,从而实现360旋转
animation.cumulative = YES;
animation.repeatCount = ; [imageView.layer addAnimation:animation forKey:nil];
return imageView;
}
采用CABasicAnimation的动画效果可以达到动画流畅度的完美展示,优点就是增加了旋转性能,缺点就是没有像animateWithDuration那样有动画的回调,这样我们就没有办法动态的去改变label的提示文本,所以细心的读者会发现,博主前面的.h文件中已经申明了一个定时器,那么这个定时器的作用是用来干嘛的呢?我们通过启动定时器,来动态的刷新label的提示文本达到一种动态展示的效果,这种思路在安卓里也同样适用.
完成了我们的图片旋转,基本上这个功能已经完成了百分之八十,剩下就是显示和隐藏了;
三.显示和隐藏
前面介绍.h文件申明的时候,已经把本控件的所有调用方法已经列出来了,其中包含了一系列的.show方法,因为loadding这种控件,我们可能需要对其状态进行判断,而且可能在网络请求中调用多次,为了不浪费内存,我们在这里提倡使用单例模式,并初始化一个Loadding在ViewDidLoad中.后期调用只需要show和dismiss即可,下面我们来看具体的show和dismiss的方法实现:
/**
* 显示loadding.默认文本为 "正在加载"
*/
-(void)showLoaddingView
{
if(isShowLoadding==YES){
return;
}
if(_text==nil||[_text isEqualToString:@""]){
_text=@"正在加载";
}
label.text=_text;
isShowLoadding=YES;
angle=;
self.hidden=NO;
[self addSubview:imageView];
[self addSubview:label];
[view addSubview:self];
[_parentView addSubview:view];
[YPXLoaddingView rotateImageView:imageView];
_timer=[NSTimer scheduledTimerWithTimeInterval:0.5 target:self selector:@selector(UpdateText) userInfo:nil repeats:YES]; } -(void)showLoaddingViewWithStyle:(int)style
{
if(style==){//菊花加载
if(isShowLoadding==YES){
return;
}
if(_text==nil||[_text isEqualToString:@""]){ _text=@"正在加载";
}
label.text=_text;
isShowLoadding=YES;
angle=;
self.hidden=NO;
[self addSubview:_activityView];
[self addSubview:label];
[imageView removeFromSuperview];
[_activityView startAnimating];
[view addSubview:self];
[_parentView addSubview:view];
_timer=[NSTimer scheduledTimerWithTimeInterval:0.5 target:self selector:@selector(UpdateText) userInfo:nil repeats:YES]; }else{//旋转图片加载
[self showLoaddingView];
} } /**
* 显示loadding
*
* @param string 显示的文本
*/
-(void)showLoaddingViewWithText:(NSString *) string
{
_text=string;
[self showLoaddingView];
} -(void)showLoaddingViewWithText:(NSString *)text andStyle:(int)style{
_text=text;
[self showLoaddingViewWithStyle:style];
} /**
* 消失loadding
*/
-(void)dismissLoaddingView
{
self.hidden=YES;
isShowLoadding=NO;
[_timer invalidate];
[imageView.layer removeAllAnimations];
[_activityView stopAnimating];
[view removeFromSuperview];
}
总体来说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
转载请注明出处~谢谢~
ios新手开发——toast提示和旋转图片加载框的更多相关文章
- [iOS微博项目 - 1.8] - 各种尺寸图片加载 & 控件不显示研究
A. 图片的加载: [UIImage imageNamed:@"home"]; 加载png图片 一.非retina屏幕 1.3.5 inch(320 x 480) * ...
- iOS图片加载新框架 - FlyImage
FlyImage 整合了SDWebImage,FastImageCache,AFNetworking的优点,是一个新的性能高效.接口简单的图片加载框架. 特点 高效 可将多张小图解码后存储到同一张大图 ...
- Android常用的图片加载库
Android常用的图片加载库 前言:图片加载涉及到图片的缓存.图片的处理.图片的显示等.四种常用的图片加载框架,分别是Fresco.ImageLoader. Picasso. Glide. Uni ...
- iOS开发——图形编程Swift篇&CAShapeLayer实现圆形图片加载动画
CAShapeLayer实现圆形图片加载动画 几个星期之前,Michael Villar在Motion试验中创建一个非常有趣的加载动画. 下面的GIF图片展示这个加载动画,它将一个圆形进度指示器和圆形 ...
- 自适应文案提示框、无数据图片加载<IOS小组件>
非常感谢,帮助我的朋友们,谢谢你们. 该组件的编写仅仅用来不到4个小时,包括测试与修改bug.为他起名为AdaptivePromptDialogBox(就是自适应文案提示框): 呆毛地址:链接 < ...
- Android开发三种第三方图片加载的框架
最近在项目中用到了大量图片加载,第三方优秀框架还不错,下面介绍三款榜首的框架用法和问题,做一个记录. 现在项目使用的是Android Studio开发的,现在也没有多少人使用Eclipse了吧. 一. ...
- YYWebImage——iOS异步图片加载框架
本文转载至 http://www.mobile-open.com/2015/86582.html YYWebImage 是一个异步图片加载框架 (YYKit 组件之一). 其设计目的是试图替代 S ...
- iOS图片加载框架-SDWebImage解读
在iOS的图片加载框架中,SDWebImage可谓是占据大半壁江山.它支持从网络中下载且缓存图片,并设置图片到对应的UIImageView控件或者UIButton控件.在项目中使用SDWebImage ...
- iOS 图片加载框架- SDWebImage 解读
在iOS的图片加载框架中,SDWebImage可谓是占据大半壁江山.它支持从网络中下载且缓存图片,并设置图片到对应的UIImageView控件或者UIButton控件.在项目中使用SDWebImage ...
随机推荐
- iOS--->微信支付小结
iOS--->微信支付小结 说起支付,除了支付宝支付之外,微信支付也是我们三方支付中最重要的方式之一,承接上面总结的支付宝,接下来把微信支付也总结了一下 ***那么首先还是由公司去创建并申请使用 ...
- 用apt-file解决找不到头文件的问题
在编译C语言的开源项目的时候,经常会出现头文件找不到的问题. 解决这类问题有一个特别好用的工具apt-file 1.在ubuntu下安装 sudo apt install apt-file 2.更新索 ...
- Linux1 在Linux(CentOS)上安装MySql详细记录
前记: 毕业两年了,前两天换了份工作,由以前的传统行业跳到了互联网行业.之前的公司一直在用WinServer2003+Tomcat+SqlServer/Oracle这套部署环境.对于Linux+To ...
- WebEssentials 在vs2013 update5安装报错的解决方法.
WebEssentials 最高支持到update4 如果更新到了update5 RC, 则无法直接安装. 解决方法是 1,下载WebEssentials2013.vsix 文件. 2, 安装7zip ...
- 内网穿透神器ngrok
相信做Web开发的同学们,经常会遇到需要将本地部署的Web应用能够让公网环境直接访问到的情况,例如微信应用调试.支付宝接口调试等.这个时候,一个叫ngrok的神器可能会帮到你,它提供了一个能够在公网安 ...
- ABP源码分析二十:ApplicationService
IApplicationService : 空接口,起标识作用.所有实现了IApplicationService 的类都会被自动注入到容器中.同时所有IApplicationService对象都会被注 ...
- ArtifactTransferException: Failure to transfer org.apache.openejb:javaee-api:jar:5.0-1
最近在myeclipse上创建maven类型的web项目的时候,出现了一个错误. ArtifactTransferException: Failure to transfer org.apache.o ...
- android-解决全屏-webview-输入框被输入法挡住-FullScreen-adjustResize失效问题
由于公司开发的 App 中,Html 的页面嵌入的有点多,坑爹的是,还有很多输入框,这就算了,还要求全屏.然后就出现了这个情况. 下面来唠叨唠叨具体的来龙去脉. 起初是这样的,整个项目基本完工了.测试 ...
- HTML5知识点总结
HTML5知识点总结(一) 一.HTML新增元素 1.IE9版本以下支持HTML5的方法 <!--[if lt IE9]> <script src="http://cdn. ...
- 8.SVM用于多分类
从前面SVM学习中可以看出来,SVM是一种典型的两类分类器.而现实中要解决的问题,往往是多类的问题.如何由两类分类器得到多类分类器,就是一个值得研究的问题. 以文本分类为例,现成的方法有很多,其中一劳 ...