天天看點

iOS-資料模型動畫效果

 主要是展示一個資料資訊的UI動畫,提供一組資料,把資料按比例,顔色,分布在一個圓裡,可以點選每一塊小扇形,扇形點選區域方法。添加開場畫圖效果。

iOS-資料模型動畫效果

  1.首先建立 RLCButton.h 的代碼 繼承UIButton 。 因為要擷取到每一塊扇形的點選。

  2.根據提供的顔色數組,和比例數組建立RLCButton,并設定代理.

這是畫整個圓的效果。

下面是 RLCButton.h 的代碼

@class RLCButton;
@protocol RLCButtonDelegate <NSObject>
@optional

-(void)didbutton:(RLCButton *)btn index:(int)index toindex:(int)toindex;
@end

@interface RLCButton : UIButton

@property(nonatomic,assign)id < RLCButtonDelegate >delegate;

-(instancetype)initWithFrame:(CGRect)frame colors:(NSArray <UIColor *>*)colors  sizes:(NSArray <NSNumber *> *)sizes;
           

這裡是RLCButton.m 的代碼

@interface RLCButton ()

@property(nonatomic,retain)NSArray *colors;

@property(nonatomic,retain)NSArray *sizes;

@property(nonatomic,assign)CGFloat www;

@property(nonatomic,assign)BOOL isClick;
//儲存上一次的點選扇形
@property(nonatomic,assign)int  index;

@end

@implementation RLCButton
-(instancetype)initWithFrame:(CGRect)frame colors:(NSArray <UIColor *>*)colors  sizes:(NSArray <NSNumber *> *)sizes{
    if (self=[super initWithFrame:CGRectMake(frame.origin.x, frame.origin.y, frame.size.width, frame.size.width)]) {
        _colors=colors;
        _sizes=sizes;
        _www=frame.size.width;
        self.layer.cornerRadius=_www/2;
        _isClick=YES;
        _index=-1;
    }
    return self;
}
//重寫了按鈕的點選事件
-(BOOL)pointInside:(CGPoint)point withEvent:(UIEvent *)event{
    if (_isClick) {
        _isClick=NO;
        return _isClick;
    }else{
        _isClick=YES;
    }
    CGFloat X=point.x;
    CGFloat Y=point.y;
    double val=sqrt(pow((X-_www/2.0),2)+pow((Y-_www/2.0),2));
           
//計算使用者點選的點到原點中心的位子 
           
if (val>_www/2||val<_www/4.0-15) {
        return NO;
    }else{
        CGFloat a = X - _www/2.0;
        CGFloat b = Y - _www/2.0;
        CGFloat c = _www - _www/2.0;
        CGFloat d = _www/2.0 - _www/2.0;
           
//計算使用者在扇形點選面中與水準線的角度來判斷在哪個扇形中
        CGFloat rads = acos(((a*c) + (b*d)) / ((sqrt(a*a + b*b)) * (sqrt(c*c + d*d))));
        float jiaodu =rads*180/M_PI;
        b>0?(jiaodu=jiaodu):(jiaodu=360-jiaodu);
        for (int i=0; i<_sizes.count; i++) {
            if (jiaodu<[_sizes[i] floatValue]) {
                if ([self.delegate respondsToSelector:@selector(didbutton:index:toindex:)]) {
                    [self.delegate didbutton:self index:_index toindex:i];
                    _index=i;
                    i=100000;
                }
            }
        }
    };
    return NO;
}
           
//重寫繪制
-(void)drawRect:(CGRect)rect{
    CGContextRef context = UIGraphicsGetCurrentContext();
    CGContextSetLineWidth(context, 0);
    for (int i=0; i<_colors.count; i++) {
        UIColor * aColor = _colors[i];
        CGContextSetFillColorWithColor(context, aColor.CGColor);
        CGContextMoveToPoint(context, _www/2, _www/2);
           
//根據比例畫扇形
        if (i==0) {
            CGContextAddArc(context, _www/2, _www/2, _www/2,  0, [_sizes[i] floatValue] * M_PI / 180, 0);
        }else{
            CGContextAddArc(context, _www/2, _www/2, _www/2,  [_sizes[i-1] floatValue] * M_PI / 180, [_sizes[i] floatValue]* M_PI / 180, 0);
        }
        self.clipsToBounds=NO;
        CGContextClosePath(context);
        CGContextDrawPath(context, kCGPathFillStroke);
    }
           
//畫中心的圓。
    UIColor *color = [UIColor whiteColor];
    CGContextSetFillColorWithColor(context, color.CGColor);
    CGContextAddArc(context, _www/2, _www/2, _www/4-15,  0, 2*M_PI ,0);
    CGContextDrawPath(context, kCGPathFillStroke);
}
           

3 我們還要畫每個小扇形的的視圖,因為放大,縮小,要保證在單一的視圖上,我們重新建立一個 RLCMyButton 讓他完成單個的扇形建立,并加入定時器來完成開場的轉動效果

這裡是.h的方法  提供了2個建立方法一個是否添加定時器,一個是根據比例 顔色建立扇形

@interface RLCMyButton : UIButton
//建立扇形 
-(instancetype)initWithFrame:(CGRect)frame color:(UIColor *)color  start:(CGFloat)startindex stop:(CGFloat)stopindex;
//建立有定時器的圓 完成開場動畫
-(instancetype)initWithFrame:(CGRect)frame islink:(BOOL)link;
           

這裡是.m方法

@interface RLCMyButton ()

@property(nonatomic,retain)UIColor *bgColor;

@property(nonatomic,assign)CGFloat startindex;

@property(nonatomic,assign)CGFloat stopindex;

@property(nonatomic,assign)CGFloat www;

@property(nonatomic,assign)BOOL isClick;

@property (nonatomic, strong) CADisplayLink *link;
@end

@implementation RLCMyButton
-(instancetype)initWithFrame:(CGRect)frame color:(UIColor *)color  start:(CGFloat)startindex stop:(CGFloat)stopindex{
    if (self=[super initWithFrame:CGRectMake(frame.origin.x, frame.origin.y, frame.size.width, frame.size.width)]) {
        _bgColor=color;
        _startindex=startindex;
        _stopindex=stopindex;
        _www=frame.size.width;
        _isClick=NO;
        //self.layer.cornerRadius=_www/2;
    }
    return self;
}
-(instancetype)initWithFrame:(CGRect)frame islink:(BOOL)link{
    if (self=[super initWithFrame:frame]) {
        _bgColor=[UIColor whiteColor];
           
//設定介紹角度為360
        _stopindex=360;
           
//設定初始角度為1
        _startindex=1;
        _www=frame.size.width;
        _isClick=YES;
           
//開啟定時器
        self.link.paused = NO;
    }
    return self;
}
           
//懶加載定時器
- (CADisplayLink *)link
{
    if (_link == nil) {
        
        _link = [CADisplayLink displayLinkWithTarget:self selector:@selector(angleChange)];
        
        [_link addToRunLoop:[NSRunLoop mainRunLoop] forMode:NSDefaultRunLoopMode];
    }
    return _link;
}
-(void)drawRect:(CGRect)rect{
        CGContextRef context = UIGraphicsGetCurrentContext();
        CGContextSetLineWidth(context, 0);
       CGContextSetFillColorWithColor(context, _bgColor.CGColor);
       CGContextMoveToPoint(context, _www/2, _www/2);
    if (_isClick==NO) {
           
//定時器關閉的情況下
           
CGContextAddArc(context, _www/2, _www/2, _www/2,  _startindex* M_PI / 180, _stopindex* M_PI / 180, 0);
        self.clipsToBounds=NO;
    }else {
           
<pre name="code" class="objc" style="font-size: 11px;">//定時器開啟的情況下  畫扇形
           

CGContextAddArc(context, _www/2, _www/2, _www/2, _startindex* M_PI / 180,2*M_PI , 0); } CGContextClosePath(context); CGContextDrawPath(context, kCGPathFillStroke);}//定時器開啟-(void)angleChange{

//每一次讓視圖重畫一個角度 來欺騙眼睛  達到動畫效果
        _startindex+=3;
           
if (_startindex>=360) {
            self.link.paused = YES;
            self.alpha=0;
        }
           
//重畫視圖
     [self setNeedsDisplay];
}
           

4.由于這裡我們建立的2的檔案 我們在把這個檔案封裝結合在一起。建立整個的模型視圖

我們建立一個視圖繼承UIView  提供給他3個方法,一個是建立,重新整理,停止

這裡是.h的代碼

@interface RLCView : UIView

-(instancetype)initWithFrame:(CGRect)frame colors:(NSArray <UIColor *>*)colors  sizes:(NSArray <NSNumber *> *)sizes;
//建立View
-(void)createView;
//重新整理 保證每次視圖一進入螢幕 就開啟動畫
-(void)shuaxin;
//停止 保證視圖退出螢幕 把點選上面的扇形還原下去
-(void)stop;
           

這裡是.m的代碼

@interface RLCView ()<RLCButtonDelegate>

@property(nonatomic,retain)NSArray *colors;

@property(nonatomic,retain)NSArray *sizes;

@property(nonatomic,assign)CGFloat index;

@property(nonatomic,retain)RLCMyButton *btn2;

@property(nonatomic,retain)RLCMyButton *btn3;

@property(nonatomic,retain)RLCMyButton *selButton;

@end


@implementation RLCView

-(instancetype)initWithFrame:(CGRect)frame colors:(NSArray <UIColor *>*)colors  sizes:(NSArray <NSNumber *> *)sizes{
    if (self=[super initWithFrame:frame]) {
        _colors=colors;
        _sizes=sizes;
    }
    return self;
}

-(void)createView{
    _index=10;
    CGRect Farme=CGRectMake(_index, _index, 200-2*_index, 200-2*_index);
    [email protected][[NSNumber numberWithInt:130],[NSNumber numberWithInt:250],[NSNumber numberWithInteger:300],[NSNumber numberWithInt:360]];
    [email protected][[UIColor redColor],[UIColor blueColor],[UIColor yellowColor],[UIColor purpleColor]];
    for (int i=0; i<_sizes.count; i++) {
        RLCMyButton *btn2;
        if (i==0) {
            btn2=[[RLCMyButton alloc]initWithFrame: CGRectMake(75, 75, 50, 50) color: _colors[i] start:0 stop:[ _sizes[i] floatValue]];
        }else{
            btn2=[[RLCMyButton alloc]initWithFrame: CGRectMake(75, 75, 50, 50) color: _colors[i] start:[_sizes[i-1] floatValue] stop:[ _sizes[i]floatValue]];
        }
        btn2.tag=100+i;
        btn2.layer.cornerRadius=100-_index;
        [self addSubview:btn2];
    }
    RLCButton *btn=[[RLCButton alloc]initWithFrame:Farme colors:_colors sizes:_sizes];
    btn.layer.cornerRadius=Farme.size.width/2;
    btn.delegate=self;
    [self addSubview:btn];
    [self shuaxin];
}

-(void)shuaxin{
    RLCMyButton *btn3=[[RLCMyButton alloc]initWithFrame:CGRectMake(0, 0, 200, 200) islink:YES];
    [self addSubview:btn3];
}
-(void)didbutton:(RLCButton *)btn index:(int)index toindex:(int)toindex{
    CGFloat a=1.5;
    RLCMyButton *View1=[self viewWithTag:100+toindex];
    RLCMyButton *View=[self viewWithTag:100+index];
    if (index!=toindex) {
        if (index>=0) {
            [self setView:View frame:CGRectMake(75, 75, 50, 50)];
        }
        [self setView:View1 frame:CGRectMake(a, a, 200-2*a, 200-2*a)];
    }else {
        if (View1.bounds.size.width==50) {
             [self setView:View1 frame:CGRectMake(a, a, 200-2*a, 200-2*a)];
        }else {
           [self setView:View1 frame:CGRectMake(75, 75, 50, 50)];
        }
    }
    _selButton=View1 ;
}
-(void)setView:(RLCMyButton *)RlcMyButton frame:(CGRect)Frame{
    RlcMyButton.layer.cornerRadius=100-_index;
    [UIView animateWithDuration:0 delay:0.3 usingSpringWithDamping:0.3 initialSpringVelocity:0.7 options:UIViewAnimationOptionOverrideInheritedCurve animations:^{
        RlcMyButton.frame=Frame;
    } completion:^(BOOL finished) {
    }];
}
-(void)stop{
    _selButton.frame=CGRectMake(75, 75, 50, 50);
}
           

這裡是全部的代碼了

5.下面我們來個示例建立這個View

@interface UiDonghuaViewController ()

@property(nonatomic,retain)RLCView *RlcView;
@end

@implementation UiDonghuaViewController


-(void)viewWillAppear:(BOOL)animated{
    [super viewWillAppear:animated];
           
//每一次進入螢幕就開啟一次動畫
    [_RlcView shuaxin];
}
-(void)viewDidAppear:(BOOL)animated{
    [super viewDidAppear:animated];
           
//這裡還原螢幕已經點選了儲存方法的扇形 在縮放回來
    [_RlcView stop];
}

- (void)viewDidLoad {
    [super viewDidLoad];
    RLCView *btn4=[[RLCView alloc]initWithFrame:CGRectMake(50, 100, 250, 250) colors:@[[UIColor redColor],[UIColor blueColor],[UIColor yellowColor],[UIColor purpleColor]] sizes:@[[NSNumber numberWithInt:130],[NSNumber numberWithInt:250],[NSNumber numberWithInteger:300],[NSNumber numberWithInt:360]]];
    [self.view addSubview:btn4];
    [btn4 createView];
    _RlcView=btn4;
}
           

繼續閱讀