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.
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
Post a Comment