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