ios新手开发——toast提示和旋转图片加载框
不知不覺自學(xué)ios已經(jīng)四個(gè)月了,從OC語法到app開發(fā),過程雖然枯燥無味,但是結(jié)果還是挺有成就感的,在此分享我的ios開發(fā)之路中的小小心得~廢話不多說,先上我們今天要實(shí)現(xiàn)的效果圖:
?
?
有過一點(diǎn)做APP經(jīng)驗(yàn)的都知道,提示框和等待加載框一直是APP首當(dāng)其中的效果,ios不像android一樣,自帶toast和progressbarDialog,所以在做ios開發(fā)的時(shí)候,我首先想到了先封裝這兩個(gè)基礎(chǔ)控件~當(dāng)然網(wǎng)上的資源數(shù)不勝數(shù),但是博主抱著一顆自主研究的精神,做出的效果也不錯(cuò),也已適配了所有iphone型號和版本.望大家多多支持~
YPXToastView實(shí)現(xiàn)
接觸過安卓開發(fā)的ios開發(fā)者可能對待toast這么個(gè)東西很不陌生,它主要是一種輕量級的提示,代替了復(fù)雜的對話框,有的顯示在中間,有的顯示在屏幕下方,當(dāng)然,這些都是根據(jù)需求而來的.廢話不多說,首先清理一下我們實(shí)現(xiàn)這個(gè)toast的一些必要思路:
1.實(shí)現(xiàn)的基礎(chǔ)控件------UILabel封裝
2.彈出的時(shí)間和透明度變化設(shè)置
3.顯示的位置調(diào)整
?一.UILabel的封裝
首先我們想要實(shí)現(xiàn)一下這個(gè)效果,首當(dāng)其沖的肯定想到UILabel,那么接下來就是對UILabel的封裝了,首先我們創(chuàng)建一文件繼承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定義了四個(gè)全局變量,兩個(gè)屬性,分別制定了提示框的圓角和時(shí)間.方法中定義了三個(gè)類方法,和四個(gè)實(shí)例方法,主要是因?yàn)槲覀冊谑褂脮r(shí)并不想實(shí)例化一次我們的提示框,所有的實(shí)例方法中抽出了三個(gè)類方法方便用戶調(diào)用.
下面我們來看內(nèi)部主要方法實(shí)現(xiàn):
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 * 初始化測量數(shù)據(jù) 30 */ 31 -(void)caculateSize{ 32 screenWidth=[UIScreen mainScreen].bounds.size.width; 33 screenHeight=[UIScreen mainScreen].bounds.size.height; 34 }方法一目了然,指定了UILabel的居中方式和背景,并設(shè)置屬性讓其寬度自適應(yīng),涉及到一些簡單的frame計(jì)算,主要是定位于屏幕中間,寬度設(shè)為文本寬度的1.7倍,看起來比較適中.y點(diǎn)主要就是屏幕高度的一半,理應(yīng)減去文本的高度的一半,但是博主在這偷個(gè)懶,并沒有計(jì)算label的高度,所以就不贅述了~~
?二.彈出的時(shí)間和透明度變化設(shè)置
原理很簡單,就是設(shè)定了一個(gè)animateWithDuration的block回調(diào),然后設(shè)置label的透明度和時(shí)間,具體實(shí)現(xiàn)如下:
/*** 顯示toast** @param parentView <#parentView description#>*/ -(void)showToastByParentView:(UIView *)parentView{[parentView addSubview:self];//animateWithDuration可以控制label顯示持續(xù)時(shí)間[UIView animateWithDuration:_duration animations:^{self.alpha = 1.0;} completion:^(BOOL finished){[self removeFromSuperview];}]; }默認(rèn)時(shí)間為1秒,思路很清晰,先添加進(jìn)我們的parentView中,然后指定時(shí)間后移除.
到此,我們的YPXToastView已經(jīng)全部完成,其實(shí)內(nèi)部邏輯主要是對UILabel的定制,思路簡單,但是對于ios開發(fā)之路的封裝思想有很大的幫助.調(diào)用時(shí)只需要一行代碼:
[YPXToastView showToastViewWithText:@"已開啟" andDuration:3 andCorner:5 andParentView:self.view];調(diào)用方便簡潔,以后測試就不需要用NSLog了嘿嘿~
YPXLoddingView實(shí)現(xiàn)
相信在ios的開發(fā)中少不了加載等待框的開發(fā),畢竟原生系統(tǒng)中貌似沒有這樣的對話框,我們在訪問網(wǎng)絡(luò)或者讀取數(shù)據(jù)時(shí)可能需要給用戶一個(gè)等待回饋,這里就用到了我們的等待加載.上面的gif中提供了兩種等待加載框的樣式,一種是自定義圖片的旋轉(zhuǎn),順時(shí)針或者逆時(shí)針,另一種是使用系統(tǒng)的UIActivityIndicatorView,使用大的加載Loadding.具體開發(fā)思路如下:
1.繼承UIView通過添加UIImageView和UILabel來組合實(shí)現(xiàn)
2.控制UIImageView的旋轉(zhuǎn)以及UIlabel的三個(gè)點(diǎn)的動(dòng)態(tài)效果
3.顯示和隱藏
一.UIView的封裝
通過效果我們可以一目了然的知道,實(shí)現(xiàn)這個(gè)控件至少需要一個(gè)UIImageView(或者UIActivityIndicatorView)和UILabel,一個(gè)提供加載圖片,一個(gè)提供加載文本,組合方式為豎直方向,然后設(shè)置背景的透明度.具體.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定義了一些必要的屬性,包括計(jì)時(shí)器和顯示文本等,主要功能為show開頭的方法,style應(yīng)該是個(gè)枚舉類型,但是博主目前還沒有寫過枚舉類,所以直接引用0和1來指定使用圖片還是系統(tǒng)的菊花加載.看完.h我們來看看具體的UIView代碼實(shí)現(xiàn):
1 2 3 /** 4 * 計(jì)算一些必要尺寸 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 * 創(chuàng)建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 }手動(dòng)布局,我們指定了imageview和label的frame,通過一系列計(jì)算,把imageview設(shè)為UIView中上部,并留出四周的邊距,看起來更親切自然一點(diǎn).label的位置根據(jù)imageview的frame來指定,這樣就可以完成適配避免在不同屏幕上顯示不同的問題.完場上述代碼,一個(gè)初步的靜態(tài)效果已經(jīng)生成,剩下的就是添加動(dòng)畫;
二.UIImageView旋轉(zhuǎn)動(dòng)畫以及UILabel點(diǎn)點(diǎn)動(dòng)態(tài)展示
imageview的動(dòng)畫添加很簡單,因?yàn)槲覀冎皇巧婕耙稽c(diǎn)點(diǎn)的旋轉(zhuǎn)動(dòng)畫,其中并沒有加速度變化,讀者若是想要添加,可以自己嘗試一下.旋轉(zhuǎn)動(dòng)畫的實(shí)現(xiàn)方式有兩種:
一種是用animateWithDuration來動(dòng)態(tài)的旋轉(zhuǎn)一定角度,然后通過延時(shí)來改變旋轉(zhuǎn)的速率,好處是簡單,但是缺點(diǎn)也很明顯,在5s中動(dòng)畫顯得僵硬,并伴隨著一點(diǎn)點(diǎn)的卡頓,如下是第一種動(dòng)畫方案的代碼:
1 /** 2 * 開啟loadding動(dòng)畫 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的角度來旋轉(zhuǎn)圖片的方式,使用block回調(diào)中的角度關(guān)系,我們可以動(dòng)態(tài)的設(shè)置提示文本省略號的動(dòng)態(tài)展示.因?yàn)閷?shí)現(xiàn)效果有點(diǎn)卡頓,所以博主采用了第二種實(shí)現(xiàn)方式,代碼如下:
1 /** 2 * 啟動(dòng)計(jì)數(shù)定時(shí)器 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添加動(dòng)畫 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軸旋轉(zhuǎn),垂直與屏幕 36 animation.toValue = [ NSValue valueWithCATransform3D: 37 CATransform3DMakeRotation(M_PI, 0.0, 0.0, 1.0) ]; 38 animation.duration = 0.5; 39 //旋轉(zhuǎn)效果累計(jì),先轉(zhuǎn)180度,接著再旋轉(zhuǎn)180度,從而實(shí)現(xiàn)360旋轉(zhuǎn) 40 animation.cumulative = YES; 41 animation.repeatCount = 10000; 42 43 [imageView.layer addAnimation:animation forKey:nil]; 44 return imageView; 45 }采用CABasicAnimation的動(dòng)畫效果可以達(dá)到動(dòng)畫流暢度的完美展示,優(yōu)點(diǎn)就是增加了旋轉(zhuǎn)性能,缺點(diǎn)就是沒有像animateWithDuration那樣有動(dòng)畫的回調(diào),這樣我們就沒有辦法動(dòng)態(tài)的去改變label的提示文本,所以細(xì)心的讀者會(huì)發(fā)現(xiàn),博主前面的.h文件中已經(jīng)申明了一個(gè)定時(shí)器,那么這個(gè)定時(shí)器的作用是用來干嘛的呢?我們通過啟動(dòng)定時(shí)器,來動(dòng)態(tài)的刷新label的提示文本達(dá)到一種動(dòng)態(tài)展示的效果,這種思路在安卓里也同樣適用.
完成了我們的圖片旋轉(zhuǎn),基本上這個(gè)功能已經(jīng)完成了百分之八十,剩下就是顯示和隱藏了;
三.顯示和隱藏
前面介紹.h文件申明的時(shí)候,已經(jīng)把本控件的所有調(diào)用方法已經(jīng)列出來了,其中包含了一系列的.show方法,因?yàn)閘oadding這種控件,我們可能需要對其狀態(tài)進(jìn)行判斷,而且可能在網(wǎng)絡(luò)請求中調(diào)用多次,為了不浪費(fèi)內(nèi)存,我們在這里提倡使用單例模式,并初始化一個(gè)Loadding在ViewDidLoad中.后期調(diào)用只需要show和dismiss即可,下面我們來看具體的show和dismiss的方法實(shí)現(xiàn):
1 /** 2 * 顯示loadding.默認(rèn)文本為 "正在加載" 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{//旋轉(zhuǎn)圖片加載 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就好,非常簡單,同時(shí)不要忘記stop我們的_activityView以及關(guān)閉定時(shí)器就好.
致此,所有的代碼實(shí)現(xiàn)已經(jīng)完成,我們在需要調(diào)用的地方首先實(shí)例化一次,然后使用show和dismiss即可.
總結(jié)
ios開發(fā)總體來說還算順風(fēng)順?biāo)?因?yàn)閷Π沧坑幸欢ǖ幕A(chǔ),學(xué)習(xí)oc等面向?qū)ο蟮恼Z法不免要快一點(diǎn),但是ios中對于控件的方法并不是很多,甚至某些安卓一行代碼就能實(shí)現(xiàn)的功能,ios需要好多行,這就是一個(gè)語言的魅力所在,當(dāng)然,在自學(xué)ios的過程中我會(huì)不斷的通過寫博客的方式來提升自己的水平,在新手開發(fā)道路中,希望我能雨你們同行,謝謝讀者的支持~~?
下載地址:http://download.csdn.net/detail/qq_16674697/9622230
作者:yangpeixing
QQ:313930500
CSND地址:http://blog.csdn.net/qq_16674697/article/details/53172388
轉(zhuǎn)載請注明出處~謝謝~
?
轉(zhuǎn)載于:https://www.cnblogs.com/teamblog/p/yangpeixing.html
總結(jié)
以上是生活随笔為你收集整理的ios新手开发——toast提示和旋转图片加载框的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: JWT 简介
- 下一篇: Word -- 列表重新编号