IOS开发之——自定义的Activity Indicator View

引用:

      苹果无敌风火轮如果不是那么酷的话,我们就不需要定制它了。可惜的是,UIActivityIndicator只有一个初始化方法 initWithActivityIndicatorStyle。

      一,不能任意改变它的大小——有时候我们需要一个比 UIActivityIndicatorViewStyleWhiteLarge还要更大的无敌风火轮;

      二,它不够友好——我们需要在风火轮的下面显示一些友好的提示信息。


为此,我们不惜代价,自己用一个UIActivityIndicator控件和用Quartz绘图的手段,定制了一个自己的无敌风火轮。


实现自己的无敌风火轮主要思想如下:

1. 首先建一个MyProgressView类继承UIView,因为我们打算新建一个UIView,在上面添加Indicator和文字并且绘制背景,然后把这个View放到当前界面中

2. 然后就是对这个MyprogressView进行操作了,重写initWithFrame,根据传进来的坐标和大小绘制,固定Indicator和Lable的位置和大小,并且添加到我们定义的外部框架viewHud 中

3. 重写drawRect,判断自定义的view是否可见,可见就绘制圆角矩形,主要根据CGRect绘制路线并根据CGContextFillPath将路线进行颜色填充,这个函数是在自定义view显示之后执行的,所以我们可以在里面进行view移位操作,通过CGRectOffset函数将CGRect进行移位,也可以调用alignToCenter将其居中

4. show,hide,setMessage主要是用来对我们定义的view进行进一步的操作

5. alignToCenter主要是将当前的自定义view进行移位操作


请看源码:

MyProgressView.h文件

//
//  MyProgressView.h
//  FourthIOSProject
//
//  Created by Mac on 14-4-16.
//  Copyright (c) 2014年 Mac. All rights reserved.
//

#import 
#import 

@interface MyProgressView : UIView{
    
    UIActivityIndicatorView* indicator;
    
    UILabel* label;
    
    BOOL visible,blocked;
    
    UIView* maskView;
    
    CGRect rectHud,rectSuper,rectOrigin;//外壳区域、父视图区域
    
    UIView* viewHud;//外壳
    
}

@property (assign) BOOL visible;

-(id)initWithFrame:(CGRect)frame superView:(UIView*)superView;

-(void)show:(BOOL)block;// block:是否阻塞父视图

-(void)hide;

-(void)setMessage:(NSString*)newMsg;

-(void)alignToCenter;

@end


MyProgressView.m 文件

//
//  MyProgressView.m
//  FourthIOSProject
//
//  Created by Mac on 14-4-16.
//  Copyright (c) 2014年 Mac. All rights reserved.
//

#import "MyProgressView.h"

@implementation MyProgressView

@synthesize visible;

-(id)initWithFrame:(CGRect)frame superView:(UIView*)superView{
    
    rectOrigin=frame;
    
    rectSuper=[superView bounds];
    
    //保持正方形比例
    
    rectHud=CGRectMake(frame.origin.x,frame.origin.y, frame.size.width, frame.size.width);
    
    self = [super initWithFrame:rectHud];
    
    if (self) {
        
        self.backgroundColor =[UIColor clearColor];
        
        self.opaque = NO;
        
        viewHud=[[UIView alloc]initWithFrame:rectHud];
        
        [self addSubview:viewHud];
        
        indicator=[[UIActivityIndicatorView alloc]
                   
                   initWithActivityIndicatorStyle:
                   
                   UIActivityIndicatorViewStyleWhiteLarge];
        
        double gridUnit=round(rectHud.size.width/12);
        
        float ind_width=6*gridUnit;
        
        indicator.frame=CGRectMake(
                                   
                                   3*gridUnit,
                                   
                                   2*gridUnit,
                                   
                                   ind_width,
                                   
                                   ind_width);
        
        [viewHud addSubview:indicator];
        
        CGRect rectLabel=CGRectMake(1*gridUnit,
                                    
                                    9*gridUnit,
                                    
                                    10*gridUnit, 2*gridUnit);
        
        label=[[UILabel alloc]initWithFrame:rectLabel];
        
        label.backgroundColor=[UIColor clearColor];
        
        label.font=[UIFont fontWithName:@"Arial" size:14];
        
        label.textAlignment=UITextAlignmentCenter;
        
        label.textColor=[UIColor whiteColor];
        
        label.text=@"请等待...";
        
        label.adjustsFontSizeToFitWidth=YES;
        
        [viewHud addSubview:label];
        
        visible=NO;
        
        [self setHidden:YES];
        
        [superView addSubview:self];
        
    }
    
    return self;
    
}

#pragma mark Drawing

- (void)drawRect:(CGRect)rect {
    
    if(visible){

        CGContextRef context = UIGraphicsGetCurrentContext();
        
        CGRect boxRect = rectHud;
        
        // 绘制圆角矩形
        
        float radius = 10.0f;
        
        // 路径开始
        
        CGContextBeginPath(context);
        
        // 填充色:灰度0.0,透明度:0.1
        
        CGContextSetGrayFillColor(context,0.0f, 0.25);
        
        // 画笔移动到左上角的圆弧处
        
        CGContextMoveToPoint(context,CGRectGetMinX(boxRect) + radius, CGRectGetMinY(boxRect));
        
        // 开始绘制右上角圆弧:圆心x坐标,圆心y坐标,起始角,终止角,方向为顺时针
        
        CGContextAddArc(context,CGRectGetMaxX(boxRect) - radius, CGRectGetMinY(boxRect) + radius, radius, 3 * (float)M_PI / 2, 0, 0);
        
        // 开始绘制右下角圆弧
        
        CGContextAddArc(context,CGRectGetMaxX(boxRect) - radius, CGRectGetMaxY(boxRect) - radius, radius, 0, (float)M_PI / 2, 0);
        
        // 开始绘制左下角圆弧
        
        CGContextAddArc(context,CGRectGetMinX(boxRect) + radius, CGRectGetMaxY(boxRect) - radius, radius, (float)M_PI / 2, (float)M_PI, 0);
        
        // 开始绘制左上角圆弧
        
        CGContextAddArc(context,CGRectGetMinX(boxRect) + radius, CGRectGetMinY(boxRect) + radius, radius, (float)M_PI, 3 * (float)M_PI / 2, 0);
        
//        NSLog(@"MinX is:%f",CGRectGetMinX(boxRect));
//        NSLog(@"MaxX is:%f",CGRectGetMaxX(boxRect));
//        NSLog(@"MinY is:%f",CGRectGetMinY(boxRect));
//        NSLog(@"MaxY is:%f",CGRectGetMaxY(boxRect));
        
        
        //  CGContextClosePath(context);// 关闭路径
        
        CGContextFillPath(context);// 填充路径,该函数自动关闭路径
        
        //将画面按照这个方向平移
        //[self setFrame:CGRectOffset(self.frame, 100, 160)];
        //这行代码是最新添加的,表示绘制结束后,讲画面放到屏幕最中间
        [self alignToCenter];
    }
    
}

#pragma mark Action

-(void)show:(BOOL)block{
    
    if (block && blocked==NO) {
        
        CGPoint offset=self.frame.origin;
        
        // 改变视图大小为父视图大小
        
        self.frame=rectSuper;
        
        viewHud.frame=CGRectOffset(viewHud.frame, offset.x, offset.y);
        
        if (maskView==nil) {
            
            maskView=[[UIView alloc]initWithFrame:rectSuper];
            
        }else{
            
            maskView.frame=rectSuper;
            
        }
        
        maskView.backgroundColor=[UIColor clearColor];
        
        [self addSubview:maskView];
        
        [self bringSubviewToFront:maskView];
        
        blocked=YES;
        
    }
    
    [indicator startAnimating];
    
    [self setHidden:NO];
    
    [self setNeedsLayout];
    
    visible=YES;
    
}

#pragma mark 将这个东东隐藏
-(void)hide{
    
    visible=NO;
    
    [indicator stopAnimating];
    
    [self setHidden:YES];
    
}

#pragma mark 改变里面的文字
-(void)setMessage:(NSString*)newMsg{
    
    label.text=newMsg;
    
}

#pragma mark 将这个东东居中
-(void)alignToCenter{
    
    CGPoint centerSuper={rectSuper.size.width/2,rectSuper.size.height/2};
    
    CGPoint centerSelf={self.frame.origin.x+self.frame.size.width/2,
        
        self.frame.origin.y+self.frame.size.height/2};
    
    CGPoint offset={centerSuper.x-centerSelf.x,centerSuper.y-centerSelf.y};
    
    CGRect newRect=CGRectOffset(self.frame, offset.x, offset.y);
    
    [self setFrame:newRect];
    
    rectHud=newRect;
    
    // NSLog(@"newRect:%f,%f",newRect.origin.x,newRect.origin.y);
    
}
@end

那么如何引用上面的代码产生效果呢?

ViewController.m 里面的引用代码如下:

- (void)viewDidLoad
{
    [super viewDidLoad];
    // Do any additional setup after loading the view.
    
    //在页面中添加一个Activity Indicator View
    //这玩意不用了,太丑,现在换大的了
//    UIActivityIndicatorView *indicator = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleGray];
//    [indicator setCenter:CGPointMake(100, 100)];
//    [self.view addSubview:indicator]; 
//    [indicator startAnimating];
    
    MyProgressView *indicator = [[MyProgressView alloc]initWithFrame:CGRectMake(0, 0, 120, 120) superView:self.view];
    [indicator setMessage:@"正在接受心电数据请稍候..."];
    
    if (indicator.visible==NO) {

        [indicator show:NO];
        
    }else {
        
        [indicator hide];
        
    }
    
}
在页面加载的时候我就想让Indicator出现了,使用
[indicator hide];
将它隐藏就好啦。

show方法有一个BOOL值参数,如果你设置为YES,在无敌风火轮出现的同时,父视图界面会被冻结,用户将不能操作任何控件——我想这是我需要的。当hide方法被调用,风火轮消失,界面冻结被取消。


最后的实现效果图如下:

IOS开发之——自定义的Activity Indicator View_第1张图片


你可能感兴趣的:(IOS)