欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

iOS实现轮盘动态效果

程序员文章站 2022-06-30 10:14:08
本文实例为大家分享了ios实现轮盘动态效果的具体代码,供大家参考,具体内容如下一个常用的绘图,主要用来打分之类的动画,效果如下。主要是ios的绘图和动画,本来想用系统自带动画实现呢,发现实现不了,用了...

本文实例为大家分享了ios实现轮盘动态效果的具体代码,供大家参考,具体内容如下

一个常用的绘图,主要用来打分之类的动画,效果如下。

iOS实现轮盘动态效果

主要是ios的绘图和动画,本来想用系统自带动画实现呢,发现实现不了,用了其他办法延时并重绘视图没有成功,用了gcd延时,nsthread休眠,performselector delay 都不行。最后用了一个定时器实现类似效果,总感觉不太明智,以后应该考虑下对calayer和

隐式动画的角度考虑下

#import <uikit/uikit.h>
 
/**
 *  自定义变量里面以s结尾的表示具体的数值,否则表示的是表示显示具体内容的标签,以lbe的表示对内容的说明
 
   比如comments 表示的具体评价内容,comment 表示评价的具体内容,lbecomment 是一个显示 "评价:"的标签
 */
 
@interface scoreplateview : uiview
 
/*速度满意度*/
@property (nonatomic,assign) cgfloat speedvalues;
 
/*态度满意度*/
@property (nonatomic,assign) cgfloat altitudevalues;
 
/*把半圆分割的份数*/
@property (nonatomic,assign) int precision;
/**
 * 整体评价
 */
@property (nonatomic,strong) nsstring * comments;
/**
 * 满分是多少分
 */
@property (nonatomic,assign) cgfloat fullvalues;
/**
 * 综合评分
 */
@property (nonatomic,assign) cgfloat comprevalues;
/**
 * 开始角度
 */
 
@property (nonatomic,assign) cgfloat startangle;
/**
 * 终止角度
 */
@property (nonatomic,assign) cgfloat endangle;
 
//-(void)startanimation;
@end
#import "scoreplateview.h"
 
@interface scoreplateview()
{
  cgfloat d_speed;//执行动画时候每个的增量
  cgfloat d_altitude;
  cgfloat d_comp;
}
 
@property (nonatomic,strong) uilabel*lbecomprevalue;//综合分数的标签
 
@property (nonatomic,strong) uilabel *comprevalue;//综合分数的具体数值
 
@property (nonatomic,strong) uilabel * comment;//评价
 
@property (nonatomic,assign) cgfloat cur_speedv;//当前的值
 
@property (nonatomic,assign) cgfloat cur_altitudev;//当前的态度;
 
@property (nonatomic,assign) cgfloat cur_compv;//当前的综合分数
@property (nonatomic,assign) nstimer * timer;
 
@end
 
@implementation scoreplateview
 
- (instancetype)initwithframe:(cgrect)frame
{
  if (self = [super initwithframe:frame]) {
    
    self.precision= 50;//这里设置默认值;
    self.fullvalues =5;
    self.altitudevalues=3.0;
    self.speedvalues=4.0;
    self.backgroundcolor = [uicolor clearcolor];
    self.startangle=0.1*m_pi;
    self.endangle = 0.9*m_pi;
    self.comments =@"真是太不可思议了";
    self.backgroundcolor = [uicolor greencolor];
    _cur_compv=0;
    _cur_speedv=0;
    _cur_altitudev=0;
  }
  return self;
}
- (void)drawrect:(cgrect)rect {
  
  //1. 画圆
  
  cgfloat circlemargin = 0; //上下两个半圆的间距
  cgfloat topbottommargin =20;//这个间距用来显示服务态度和服务速度那样标签内容
  
  cgfloat radius = (self.frame.size.height-circlemargin-2*topbottommargin)/2;//半径
  //上边圆的圆心
  cgpoint centertop = cgpointmake(self.frame.size.width/2,self.frame.size.height/2-circlemargin/2);
  [self drawhalfcircle:centertop andwithradius:radius istop:yes];
  //下面圆的圆心
  cgpoint centerbottom = cgpointmake(self.frame.size.width/2, self.frame.size.height/2+circlemargin/2);
  [self drawhalfcircle:centerbottom andwithradius:radius istop:no];
  
  //2. 创建需要的标签,并在合适的位置绘制内容
  uilabel * lbealtitude = [[uilabel alloc]initwithframe:cgrectmake(0, 0, self.frame.size.width, topbottommargin)];
  lbealtitude.text = @"服务速度";
  lbealtitude.textcolor = [uicolor whitecolor];
  lbealtitude.textalignment = nstextalignmentcenter;
  lbealtitude.font = [uifont systemfontofsize:12];
  [lbealtitude drawtextinrect:lbealtitude.frame];
  
  //服务态度评分
  uilabel * lbespeed = [[uilabel alloc]initwithframe:cgrectmake(0, self.frame.size.height-topbottommargin, self.frame.size.width, topbottommargin)];
  lbespeed.text = @"服务态度";
  lbespeed.textcolor = [uicolor whitecolor];
  lbespeed.textalignment = nstextalignmentcenter;
  lbespeed.font = [uifont systemfontofsize:12];
  [lbespeed drawtextinrect:lbespeed.frame];
  
  //绘制综合评分
  nsstring *attitudescore = [nsstring stringwithformat:@"%.2f/%.2f",_cur_altitudev,self.fullvalues];
  nsmutableattributedstring* attributestring = [[nsmutableattributedstring alloc]initwithstring:attitudescore];
  [attributestring addattribute:nsfontattributename value:[uifont systemfontofsize:26] range:nsmakerange(0, 4)];
  [attributestring addattribute:nsfontattributename value:[uifont systemfontofsize:16] range:nsmakerange(4, 3)];
  self.comprevalue = [[uilabel alloc]initwithframe:cgrectmake(0, radius-topbottommargin,self.frame.size.width, 2*topbottommargin)];
  self.comprevalue.attributedtext = attributestring;
  self.comprevalue.textalignment = nstextalignmentcenter;
  self.comprevalue.textcolor = [uicolor whitecolor];
  self.comprevalue.frame = cgrectmake(0, centertop.y-topbottommargin+circlemargin/2, self.frame.size.width, topbottommargin*2);
  [self.comprevalue drawtextinrect:self.comprevalue.frame];
  
  self.lbecomprevalue = [[uilabel alloc]initwithframe:cgrectmake(0, centertop.y-radius*0.5, self.frame.size.width, topbottommargin*2)];
  self.lbecomprevalue.text =@"综合评分";
  self.lbecomprevalue.textalignment = nstextalignmentcenter;
  self.lbecomprevalue.textcolor = [uicolor whitecolor];
  self.lbecomprevalue.font = [uifont systemfontofsize:14];
  [self.lbecomprevalue drawtextinrect:self.lbecomprevalue.frame];
  //评价内容
  self.comment = [[uilabel alloc]initwithframe:cgrectmake(topbottommargin+circlemargin+radius/2, cgrectgetmaxy(self.comprevalue.frame), radius, topbottommargin*2)];
  self.comment.text =self.comments;
  self.comment.numberoflines=0;
  self.comment.textalignment = nstextalignmentcenter;
  self.comment.textcolor = [uicolor whitecolor];
  self.comment.font = [uifont systemfontofsize:14];
  [self.comment drawtextinrect:self.comment.frame];
  
}
/**
 * 画半圆 绘制刻度的时候可以先绘制从圆心的线,最后用一个内圆裁剪的方式,但是如果要求背景随时变化就局限了,特别是父视图背景是渐变的,要么重新定义该类,要么把这个类视图定义为透明,从而透过父视图背景颜色
  透明的背景无法掩盖从圆心出发的线,
 *
 * @param center 圆心坐标
 * @param radius 半径
 * @param top  是不是画上面的圆
 */
-(void)drawhalfcircle:(cgpoint) center andwithradius:(cgfloat)radius istop:(bool) top
{
  
  //画上面圆的边框
  cgcontextref ctx = uigraphicsgetcurrentcontext();
  cgcontextsetstrokecolorwithcolor(ctx, [uicolor whitecolor].cgcolor);
  if (top) {
    cgcontextaddarc(ctx, center.x, center.y, radius, -self.startangle, -self.endangle, 1);
  }
  else
  {
    cgcontextaddarc(ctx, center.x, center.y, radius,self.startangle,self.endangle, 0);
  }
  //设置线的宽度
  cgcontextsetlinewidth(ctx, 1);
  cgcontextsetstrokecolorwithcolor(ctx, [uicolor whitecolor].cgcolor);
  cgcontextstrokepath(ctx);
  //绘制上下圆的分割线
  cgcontextsetlinewidth(ctx, 2);//设置线宽
  cgfloat bordervalue;
  if (top) {
    bordervalue=_cur_altitudev/self.fullvalues;//设置边界值
  }
  else
  {
    bordervalue =_cur_speedv/self.fullvalues;
  }
  //实现动画效果,只能先画刻度,再画具体值
  for (int i=1; i<self.precision; i++)//画刻度
  {
    
    cgcontextsetrgbstrokecolor(ctx, 1.0, 1.0, 1.0, 0.5);//设置白色 透明
    cgfloat endx,endy,startx,starty;//刻度的长度是这里 7 -2 =5;
    if (top) {
      startx = center.x -(radius-10)*cos((double)i/self.precision*(self.endangle-self.startangle)+self.startangle);
      starty = center.y - (radius-10)*sin((double)i/self.precision*(self.endangle-self.startangle)+self.startangle);
      endx = center.x - (radius-2)*cos((double)i/self.precision*(self.endangle-self.startangle)+self.startangle);//圆上的点的x坐标
      endy = center.y - (radius-2)*sin((double)i/self.precision*(self.endangle-self.startangle)+self.startangle);//圆上的点的y坐标
    }
    else
    {
      startx = center.x +(radius-10)*cos((double)i/self.precision*(self.endangle-self.startangle)+self.startangle);
      starty = center.y + (radius-10)*sin((double)i/self.precision*(self.endangle-self.startangle)+self.startangle);
      endx = center.x + (radius-2)*cos((double)i/self.precision*(self.endangle-self.startangle)+self.startangle);//圆上的点的x坐标
      endy = center.y + (radius-2)*sin((double)i/self.precision*(self.endangle-self.startangle)+self.startangle);//圆上的点的y坐标
    }
    cgcontextmovetopoint(ctx, startx, starty);
    cgcontextaddlinetopoint(ctx, endx, endy);
    cgcontextstrokepath(ctx);
  }
  for (int i=1; i<self.precision; i++)
  {
    
    cgfloat curangle =(double)i/self.precision*(self.endangle-self.startangle)+self.startangle;
    if ((double)i/(double)self.precision<bordervalue)
    {
      cgcontextsetrgbstrokecolor(ctx, 1.0, 1.0, 1.0, 1);//设置白色 不透明
      cgfloat endx,endy,startx,starty;//刻度的长度是这里 7 -2 =5;
      if (top) {
        startx = center.x -(radius-10)*cos(curangle);
        starty = center.y - (radius-10)*sin(curangle);
        endx = center.x - (radius-2)*cos(curangle);//圆上的点的x坐标
        endy = center.y - (radius-2)*sin(curangle);//圆上的点的y坐标
      }
      else
      {
        startx = center.x +(radius-10)*cos(curangle);
        starty = center.y + (radius-10)*sin(curangle);
        endx = center.x + (radius-2)*cos(curangle);//圆上的点的x坐标
        endy = center.y + (radius-2)*sin(curangle);//圆上的点的y坐标
      }
      cgcontextmovetopoint(ctx, startx, starty);
      cgcontextaddlinetopoint(ctx, endx, endy);
      cgcontextstrokepath(ctx);
    }
  }
}
- (void)didmovetosuperview
{
  self.timer = [nstimer scheduledtimerwithtimeinterval:0.1 target:self selector:@selector(update) userinfo:nil repeats:yes];
  d_comp = self.comprevalues/20;
  d_speed= self.speedvalues/20;
  d_altitude=self.speedvalues/20;
}
-(void)update
{
  _cur_altitudev+=d_altitude;
  _cur_speedv+=d_speed;
  _cur_compv+=d_comp;
  if (_cur_altitudev>self.altitudevalues) {
    _cur_altitudev =self.altitudevalues;
  }
  if (_cur_speedv > self.speedvalues) {
    _cur_speedv=self.speedvalues;
  }
  if (_cur_compv>self.comprevalues) {
    _cur_compv=self.comprevalues;
  }
  if ( _cur_compv==self.comprevalues&&_cur_speedv==self.speedvalues&&_cur_altitudev ==self.altitudevalues) {
    
    [self.timer invalidate];
    self.timer = nil;
  }
  //self.backgroundcolor = [uicolor colorwithred:arc4random()%255/255.0 green:arc4random()%255/255.0 blue:arc4random()%255/255.0 alpha:1];
  [self setneedsdisplay];
 
}
 
@end

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。

相关标签: iOS 轮盘