不知不觉自学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即可.

总结

ios开发总体来说还算顺风顺水,因为对安卓有一定的基础,学习oc等面向对象的语法不免要快一点,但是ios中对于控件的方法并不是很多,甚至某些安卓一行代码就能实现的功能,ios需要好多行,这就是一个语言的魅力所在,当然,在自学ios的过程中我会不断的通过写博客的方式来提升自己的水平,在新手开发道路中,希望我能雨你们同行,谢谢读者的支持~~
 
 

下载地址:http://download.csdn.net/detail/qq_16674697/9622230

作者:yangpeixing

QQ:313930500

CSND地址:http://blog.csdn.net/qq_16674697/article/details/53172388

转载请注明出处~谢谢~

ios新手开发——toast提示和旋转图片加载框的更多相关文章

  1. [iOS微博项目 - 1.8] - 各种尺寸图片加载 & 控件不显示研究

    A. 图片的加载:  [UIImage imageNamed:@"home"];  加载png图片    一.非retina屏幕  1.3.5 inch(320 x 480)  * ...

  2. iOS图片加载新框架 - FlyImage

    FlyImage 整合了SDWebImage,FastImageCache,AFNetworking的优点,是一个新的性能高效.接口简单的图片加载框架. 特点 高效 可将多张小图解码后存储到同一张大图 ...

  3. Android常用的图片加载库

     Android常用的图片加载库 前言:图片加载涉及到图片的缓存.图片的处理.图片的显示等.四种常用的图片加载框架,分别是Fresco.ImageLoader. Picasso. Glide. Uni ...

  4. iOS开发——图形编程Swift篇&CAShapeLayer实现圆形图片加载动画

    CAShapeLayer实现圆形图片加载动画 几个星期之前,Michael Villar在Motion试验中创建一个非常有趣的加载动画. 下面的GIF图片展示这个加载动画,它将一个圆形进度指示器和圆形 ...

  5. 自适应文案提示框、无数据图片加载<IOS小组件>

    非常感谢,帮助我的朋友们,谢谢你们. 该组件的编写仅仅用来不到4个小时,包括测试与修改bug.为他起名为AdaptivePromptDialogBox(就是自适应文案提示框): 呆毛地址:链接 < ...

  6. Android开发三种第三方图片加载的框架

    最近在项目中用到了大量图片加载,第三方优秀框架还不错,下面介绍三款榜首的框架用法和问题,做一个记录. 现在项目使用的是Android Studio开发的,现在也没有多少人使用Eclipse了吧. 一. ...

  7. YYWebImage——iOS异步图片加载框架

    本文转载至 http://www.mobile-open.com/2015/86582.html   YYWebImage 是一个异步图片加载框架 (YYKit 组件之一). 其设计目的是试图替代 S ...

  8. iOS图片加载框架-SDWebImage解读

    在iOS的图片加载框架中,SDWebImage可谓是占据大半壁江山.它支持从网络中下载且缓存图片,并设置图片到对应的UIImageView控件或者UIButton控件.在项目中使用SDWebImage ...

  9. iOS 图片加载框架- SDWebImage 解读

    在iOS的图片加载框架中,SDWebImage可谓是占据大半壁江山.它支持从网络中下载且缓存图片,并设置图片到对应的UIImageView控件或者UIButton控件.在项目中使用SDWebImage ...

随机推荐

  1. Android(安卓)-------CardView

    1.activity_main.xml <android.support.v7.widget.CardView android:id="@+id/cardView" andr ...

  2. 数据库 DML、DDL、DCL区别 .

    总体解释: DML(data manipulation language): 它们是SELECT.UPDATE.INSERT.DELETE,就象它的名字一样,这4条命令是用来对数据库里的数据进行操作的 ...

  3. ORACLE中STATUS为INACTIVE但是SERVER为SHARED状态的会话浅析

    我们知道当ORACLE数据库启用共享服务器模式时,通过共享服务器模式连接到数据库的会话是有一些特征的.在v$session里面,其SERVER的状态一般为SHARED和NONE, 为SHARED时,表 ...

  4. Linux命令【第三篇】

    执行下面命令时发现提示需要输入密码,请问提示输入的密码是哪个用户的密码. [test@oldboy ~]$ sudo su - oldboy 解答: 输入当前执行命令test账户的密码. 相关说明: ...

  5. BZOJ 2119: 股市的预测 [后缀数组 ST表]

    2119: 股市的预测 Time Limit: 10 Sec  Memory Limit: 259 MBSubmit: 331  Solved: 153[Submit][Status][Discuss ...

  6. 我的MYSQL学习心得(十七) 复制

    我的MYSQL学习心得(十七) 复制 我的MYSQL学习心得(一) 简单语法 我的MYSQL学习心得(二) 数据类型宽度 我的MYSQL学习心得(三) 查看字段长度 我的MYSQL学习心得(四) 数据 ...

  7. .NET Core dotnet 命令大全

    dotnet 命令大全,让你理解dotnet 命令. 本文将以一个实例串起 dotnet 所有命令,让你玩转dotnet 命令. 本篇文章编写环境为windows 10 ,dotnet 命令同样适用于 ...

  8. hadoop 笔记(zookeeper)

    1.安装 需要提前安装java环境,本文下载zookeeper-3.3.6.tar.gz包. 1.1 tar -zxvf zookeeper-3.3.6.tar.gz 1.2 修改conf中的zoo_ ...

  9. Mac 词典工具推荐:Youdao Alfred Workflow(可同步单词本)

    想必大家都有用过 Mac 下常见的几款词典工具: 特性 系统 Dictionary 欧路词典 Mac 版 有道词典 Mac 版 在线搜索 ✗ ✔ ✔ 屏幕取词 ☆☆☆ ★★☆ ★☆☆ 划词搜索 ★★★ ...

  10. The Coroutine

    关于Coroutine 说到coroutine就不的不说subroutine,也就是我们常用到的一般函数.调用一个函数开始执行,然后函数执行完成后就退出,再次调用的时候,再从头开始,调用之间是没有保存 ...