ios - How to make a custom controller like the app "Figure" by properllerhead? -


i'm playing music producing app "figure". has wonderful ui , ux. there 4 disks in first screen, can tap , drag change values.

does know how made function? achieved uigesturerecognizer or uislider? better if can provide sample code here.

enter image description here

here simple example of demonstrates how can achieved cashapelayer.

@interface mydraggableslider ()  @property (nonatomic) cashapelayer *outerpathshape; @property (nonatomic) nsuinteger currentavailableoptions;  @property (nonatomic) catextlayer *textlayer;  @end   @implementation mydraggableslider  static const cgfloat kdefaultlinewidth = 20; static const cgfloat kdefaultangleseparationbetweenstripes = 10;  - (instancetype)initwithframe:(cgrect)frame {     if (self = [super initwithframe:frame]) {         _maximumoptionsavailable = 8;         _currentavailableoptions = 0;         [self createshape];         [self createpath];      }     return self; }  - (void)createshape {     cashapelayer *shapelayer = [cashapelayer layer];     shapelayer.fillcolor = nil;     shapelayer.strokecolor = [[uicolor redcolor] cgcolor];     shapelayer.linewidth = kdefaultlinewidth;     shapelayer.frame = self.bounds;      cgrect textframe = cgrectinset(shapelayer.bounds, shapelayer.linewidth, shapelayer.linewidth);     textframe.size.height = 40;     textframe.origin.y = (self.bounds.size.height - textframe.size.height ) * 0.5;      self.textlayer = [catextlayer layer];     self.textlayer.foregroundcolor = [uicolor redcolor].cgcolor;     self.textlayer.backgroundcolor = nil;     self.textlayer.frame = textframe;     self.textlayer.alignmentmode = kcaalignmentcenter;      [self.layer addsublayer:shapelayer];     [self.layer addsublayer:self.textlayer];     self.outerpathshape = shapelayer; }  - (void)createpath {     cgrect rect = cgrectinset(self.bounds, self.outerpathshape.linewidth * 0.5, self.outerpathshape.linewidth * 0.5);     cgfloat gapangle = [self radianfromdegree:kdefaultangleseparationbetweenstripes];      cgfloat angleforeachstripe = (2 * m_pi - gapangle * self.currentavailableoptions)/ self.currentavailableoptions;     cgpoint center = cgpointmake(cgrectgetmidx(self.bounds), cgrectgetmidy(self.bounds));     cgfloat radius = cgrectgetwidth(rect) * 0.5;       cgfloat currentangleoffset = gapangle;     uibezierpath *path = [uibezierpath bezierpath];      if (self.currentavailableoptions == 0) {         path = [uibezierpath bezierpathwithovalinrect:rect];     }      (int = 0; < self.currentavailableoptions; ++) {         cgfloat startangle = currentangleoffset;         cgfloat endangle = currentangleoffset + angleforeachstripe ;          uibezierpath *stripepath = [uibezierpath bezierpathwitharccenter:center                                                                   radius:radius                                                               startangle:startangle                                                                 endangle:endangle                                                                clockwise:yes];         [path appendpath:stripepath];         currentangleoffset = endangle + gapangle;     }      self.outerpathshape.path = path.cgpath;      if (self.currentavailableoptions == 0) {         self.textlayer.string = @"";     } else {         self.textlayer.string = [nsstring stringwithformat:@"%ld", self.currentavailableoptions];     } }  - (void)touchesbegan:(nsset *)touches withevent:(uievent *)event {  }  - (void)touchesmoved:(nsset *)touches withevent:(uievent *)event {     cgpoint center = cgpointmake(cgrectgetmidx(self.bounds), cgrectgetmidy(self.bounds));       cgpoint touchpoint = [touches.anyobject locationinview:self];      cgpoint vectorfromcenter = cgpointmake(touchpoint.x - center.x, touchpoint.y - center.y);     cgfloat normalizedvalue = sqrt(vectorfromcenter.x * vectorfromcenter.x + vectorfromcenter.y + vectorfromcenter.y);     cgpoint normalizedvector = cgpointmake(vectorfromcenter.x / normalizedvalue, vectorfromcenter.y / normalizedvalue);      cgfloat angle = atan2(normalizedvector.y, normalizedvector.x);     cgfloat currentrotationoffset = angle + m_pi;     if(isnan(currentrotationoffset)) {         self.currentavailableoptions = 0;     } else {         self.currentavailableoptions = currentrotationoffset / (2 * m_pi / self.maximumoptionsavailable) ;     }     [self createpath]; }  - (void)touchesended:(nsset *)touches withevent:(uievent *)event {  }  - (cgfloat)degreefromradian:(cgfloat)radian {     return 180 / m_pi * radian; }  - (cgfloat)radianfromdegree:(cgfloat)degree {     return m_pi / 180 * degree; }  @end  @interface viewcontroller ()  @property (nonatomic, strong) mydraggableslider *slider;  @end   @implementation viewcontroller  - (void)viewdidload {     [super viewdidload];     cgrect rect = cgrectmake((self.view.bounds.size.width - 200) * 0.5, (self.view.bounds.size.height - 200) * 0.5, 200, 200);     self.slider = [[mydraggableslider alloc] initwithframe:rect];     [self.view addsubview:self.slider]; }  @end 

Comments

Popular posts from this blog

Magento/PHP - Get phones on all members in a customer group -

php - .htaccess mod_rewrite for dynamic url which has domain names -

Website Login Issue developed in magento -