SHARE
TWEET

Untitled

a guest Apr 21st, 2017 57 Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. //
  2. //  LSCircleView.m
  3. //  LEE Stopper App
  4. //
  5. //  Created by admin on 10.02.16.
  6. //  Copyright © 2016 1. All rights reserved.
  7. //
  8.  
  9. #import "LSCircleView.h"
  10. #import "LSTouchGestureRecognizer.h"
  11.  
  12. @implementation LSCircleView
  13.  
  14. /*
  15. // Only override drawRect: if you perform custom drawing.
  16. // An empty implementation adversely affects performance during animation.
  17.  */
  18.  
  19. static double distanceAngleRatio=0.0035;
  20.  
  21.  
  22. -(id) initWithFrame:(CGRect)frame
  23. {
  24.     if (self = [super initWithFrame:frame])
  25.     {
  26.        
  27.         NSString *clickSoundPath = [[NSBundle mainBundle] pathForResource:@"click_soft_tap" ofType:@"aif"];
  28.         AudioServicesCreateSystemSoundID((__bridge CFURLRef)[NSURL fileURLWithPath: clickSoundPath], &_clickSoundID);
  29.        
  30.     }
  31.    
  32.     return self;
  33. }
  34.  
  35. -(void) initWith:(UIColor*) dividersColor labelTexts:(NSArray*)labelTexts
  36. {
  37.    
  38.     _activeDividerIndex=-1;
  39.    
  40.     //if(_radius == 0)
  41.     [self calculateRadiusAndCenter];
  42.    
  43.     _dividersArray=[NSMutableArray array];
  44.     _dividersView = [[UIView alloc] init];
  45.     _dividersView.layer.anchorPoint=CGPointMake(0.5, 0.5);
  46.     _dividersView.frame=CGRectMake(0,0, 2*_radius,2*_radius);
  47.     _dividersView.center = CGPointMake(_center.x, _center.y);
  48.    
  49.     //_dividersView.backgroundColor=[UIColor redColor];
  50.     [self addSubview:_dividersView];
  51.    
  52.     int dividersCount = 19;
  53.     int partsPerDivider = 3;
  54.    
  55.     float angleStep = 2*M_PI/dividersCount;
  56.     _rotationStep = angleStep / partsPerDivider;
  57.     float startAngle = self.mirrored ? M_PI : 0;
  58.     float direction = self.mirrored ? -1 : 1;
  59.    
  60.     float bigDividerLength = 19;
  61.     float smallDividerLength = 10;
  62.     CGPoint localCelnter = CGPointMake(_radius,_radius);
  63.     for(int i=0;i<dividersCount;i++)
  64.     {
  65.         float angle = startAngle + direction * angleStep * i;
  66.         float x = localCelnter.x + (_radius - bigDividerLength/2) * cos(angle);
  67.         float y = localCelnter.y + (_radius - bigDividerLength/2) * sin(angle);
  68.        
  69.        
  70.         UIView * divider = [[UIView alloc] initWithFrame:CGRectMake(0, 0, bigDividerLength, 0)];
  71.         [UIView animateWithDuration:0.2 animations:^{
  72.             divider.frame=CGRectMake(0, 0, bigDividerLength, 2);
  73.         }];
  74.        
  75.         divider.backgroundColor=dividersColor;
  76.         divider.alpha=0.3;
  77.         divider.center = CGPointMake(x, y);
  78.         divider.transform = CGAffineTransformMakeRotation(angle);
  79.         [_dividersView addSubview:divider];
  80.         [_dividersArray addObject:divider];
  81.        
  82.         UILabel * label = [[UILabel alloc] init];
  83.         label.font=[UIFont fontWithName:@"Roboto Condensed" size:25];
  84.         label.textColor=dividersColor;
  85.         //label.backgroundColor=[UIColor redColor];
  86.         label.text=labelTexts[i*3];//[NSString stringWithFormat:@"%d",i]; ////
  87.         label.numberOfLines=0;
  88.         [label sizeToFit];
  89.         //label.layer.anchorPoint=CGPointMake(0.5, 0.5);
  90.  
  91.         [_dividersView addSubview:label];
  92.                 //label.center = CGPointMake(x - label.frame.size.width/2, y);
  93.        
  94.         float labelX = localCelnter.x + (_radius - label.frame.size.width/2 - bigDividerLength -5) * cos(angle);
  95.         float labelY = localCelnter.y + (_radius - label.frame.size.width/2 - bigDividerLength -5) * sin(angle);
  96.        
  97.         label.frame=CGRectMake(labelX,labelY, label.frame.size.width, label.frame.size.height);
  98.         label.center=CGPointMake(labelX, labelY);
  99.        
  100.         label.transform= CGAffineTransformMakeRotation(angle);
  101.         label.alpha=0;
  102.        
  103.         if(self.mirrored)
  104.             label.transform= CGAffineTransformMakeRotation(angle - M_PI );
  105.  
  106.        
  107.         [UIView animateWithDuration:0.2 animations:^{
  108.             label.alpha=1;
  109.         }];
  110.  
  111.        
  112.         // Add small dividers
  113.        
  114.         if(i != dividersCount-1)
  115.         for (int j=0;j<2;j++)
  116.         {
  117.             float smallAngle = angle + direction * (j+1)*angleStep/partsPerDivider;
  118.            
  119.             x = localCelnter.x + (_radius - smallDividerLength/2) * cos(smallAngle);
  120.             y = localCelnter.y + (_radius - smallDividerLength/2) * sin(smallAngle);
  121.            
  122.             UIView * smallDivider = [[UIView alloc] initWithFrame:CGRectMake(0, 0, smallDividerLength, 0)];
  123.             [UIView animateWithDuration:0.2 animations:^{
  124.                 smallDivider.frame=CGRectMake(0, 0, smallDividerLength, 1);
  125.             }];
  126.            
  127.             smallDivider.backgroundColor=dividersColor;
  128.             smallDivider.alpha=0.3;
  129.             smallDivider.center = CGPointMake(x, y);
  130.             smallDivider.transform = CGAffineTransformMakeRotation(smallAngle);
  131.             [_dividersView addSubview:smallDivider];
  132.             [_dividersArray addObject:smallDivider];
  133.         }
  134.        
  135.     }
  136.    
  137.    
  138.     // Gesture recognition
  139.    
  140. /*
  141.    
  142.    
  143.     LSTouchGestureRecognizer *touchDown = [[LSTouchGestureRecognizer alloc] initWithTarget:self action:@selector(handleTouchDown:)];
  144.     touchDown.delegate=self;
  145.     touchDown.cancelsTouchesInView=NO;
  146.     touchDown.delaysTouchesBegan=NO;
  147.     touchDown.delaysTouchesEnded=NO;
  148.     [self addGestureRecognizer:touchDown];
  149.   */
  150.    
  151.     self.userInteractionEnabled=YES;
  152.    
  153.     UIPanGestureRecognizer * pan = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(panHandler:)];
  154.     pan.delegate=self;
  155.     pan.cancelsTouchesInView=YES;
  156.     pan.delaysTouchesBegan=NO;
  157.     pan.delaysTouchesEnded=NO;
  158.     [self addGestureRecognizer:pan];
  159.    
  160.    
  161.     [NSTimer scheduledTimerWithTimeInterval:1/30.0 target:self selector:@selector(updateMethod) userInfo:nil repeats:YES];
  162. }
  163.  
  164. -(void) deativatePanIfNeeded
  165. {
  166.     _shouldSendDelegateUpdates=NO;
  167.    
  168.     _dividersView.layer.transform = [(CALayer*)_dividersView.layer.presentationLayer transform];
  169.    
  170.    
  171.     [CATransaction begin];
  172.     [_dividersView.layer removeAllAnimations];
  173.     [CATransaction commit];
  174. }
  175.  
  176. -(void) hideDividers
  177. {
  178.     _dividersView.alpha=0;
  179. }
  180.  
  181. -(void) showDividers
  182. {
  183.     _dividersView.alpha=1;
  184. }
  185.  
  186. -(void) rotateManuallyTo:(double)rotation
  187. {
  188.     _changedRotation=YES;
  189.     _dividersView.transform=CGAffineTransformMakeRotation(rotation);
  190. }
  191.  
  192. -(void) updateMethod
  193. {
  194.    
  195.     [self updateDividersIfNeeded];
  196.     //NSLog(@"_shouldSendDelegateUpdates = %d",_shouldSendDelegateUpdates);
  197.    
  198.     /*
  199.     if(!_shouldSendDelegateUpdates)
  200.         return;
  201.    
  202.    
  203.    
  204.     float curAngle = [(NSNumber *)[_dividersView.layer.presentationLayer valueForKeyPath:@"transform.rotation.z"] floatValue];
  205. ;
  206.     [self.delegate circleView:self didRotateTo:curAngle];
  207.      */
  208.    
  209. }
  210.  
  211. #pragma mark - Gesture Recognition
  212.  
  213.  
  214. -(void) touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
  215. {
  216.    
  217.     //float startAngle = atan2(_dividersView.transform.b, _dividersView.transform.a);
  218.    
  219.     //_dividersView.layer.speed = 0;
  220.    
  221.     [self.delegate circleViewDidTouchBegan:self];
  222.    
  223.     [self stopAnimation];
  224.    
  225. }
  226.  
  227. -(void) touchesEnded:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
  228. {
  229.     if(_isPanning)
  230.         return;
  231.    
  232.     [self rotateAnimatedWithVelocity:0];
  233. }
  234.  
  235. -(void) touchesCancelled:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
  236. {
  237.     [self touchesEnded:touches withEvent:event];
  238. }
  239.  
  240.  
  241. -(void) stopAnimation
  242. {
  243.     _dividersView.layer.transform = [(CALayer*)_dividersView.layer.presentationLayer transform];
  244.    
  245.    
  246.     [CATransaction begin];
  247.     [_dividersView.layer removeAllAnimations];
  248.     [CATransaction commit];
  249.    
  250. }
  251.  
  252. -(void) panHandler:(UIPanGestureRecognizer*)sender
  253. {
  254.     _changedRotation=YES;
  255.    
  256.     static double startAngle;
  257.     static double lastChange=0;
  258.    
  259.     CGPoint translatedPoint = [sender translationInView:sender.view];
  260.     CGPoint velocity=[sender velocityInView:sender.view];
  261.    
  262.    
  263.     if ( sender.state == UIGestureRecognizerStateChanged )
  264.           lastChange = CFAbsoluteTimeGetCurrent();
  265.    
  266.     /*
  267.     if(previousDate)
  268.     {
  269.         float seconds = [curDate timeIntervalSinceDate:previousDate];
  270.         float yDelta =  translatedPoint.y - previousLocation.y;
  271.         velocity =CGPointMake(0, yDelta/seconds);
  272.        
  273.         NSLog(@"vel %f actual %f",velocity.y,[sender velocityInView:sender.view].y);
  274.     }
  275.    
  276.     if(sender.state == UIGestureRecognizerStateEnded)
  277.         velocity = previousVelocity;
  278.    
  279.     previousDate=curDate;
  280.     previousLocation=translatedPoint;
  281.     previousVelocity = velocity;
  282.     */
  283.    
  284.     if(sender.state == UIGestureRecognizerStateBegan)
  285.     {
  286.         startAngle = atan2(_dividersView.transform.b, _dividersView.transform.a);
  287.        
  288.         // Hack to prefent floating error
  289.         //int steps = startAngle / _rotationStep;
  290.         //startAngle = steps * _rotationStep;
  291.        
  292.         _isPanning = YES;
  293.     }
  294.  
  295.    
  296.     if(sender.state == UIGestureRecognizerStateEnded)
  297.     {
  298.        
  299.         //_dividersView.layer.speed=1;
  300.        
  301.         //NSLog(@"\n\n\n\n\n\n\n\n\n\n");
  302.        
  303.         //if(curAngle<0)
  304.         //    curAngle = + 2*M_PI;
  305.        
  306.         float vY = velocity.y;
  307.  
  308.         double curTime = CFAbsoluteTimeGetCurrent();
  309.         double timeElapsed = curTime - lastChange;
  310.         if ( timeElapsed > 0.02 )
  311.             vY = 0;
  312.        
  313.         //NSLog(@"TIME %f %f",timeElapsed,vY);
  314.        
  315.         if(fabs(vY)<200)
  316.             vY=0;
  317.        
  318.         [self rotateAnimatedWithVelocity:vY];
  319.        
  320.         //NSLog(@"delta %f", delta);
  321.        
  322.         //NSLog(@"%f === %f", (curAngle -  delta) / _rotationStep , atan2(_dividersView.transform.b, _dividersView.transform.a)/ _rotationStep );
  323.        
  324.  
  325.         _isPanning = NO;
  326.        
  327.         return;
  328.     }
  329.    
  330.     int direction = self.mirrored? -1:1;
  331.     float newRotation = startAngle + direction * translatedPoint.y * distanceAngleRatio;
  332.     _dividersView.transform=CGAffineTransformMakeRotation(newRotation);
  333.    
  334.     [self.delegate circleView:self didRotateTo:newRotation];
  335.     [self updateDividersIfNeeded];
  336.    
  337. }
  338.  
  339. -(void) rotateAnimatedWithVelocity:(float) vY
  340. {
  341.     int velDirection = vY/fabs(vY);
  342.     if(vY ==0)
  343.         velDirection=0;
  344.    
  345.     if(!self.mirrored)
  346.         velDirection = - velDirection;
  347.    
  348.     float curAngle = atan2(_dividersView.transform.b, _dividersView.transform.a);
  349.     int angleSign = curAngle / fabs(curAngle);
  350.    
  351.     double delta = fabs(vY);//MIN(fabs(vY),3600);
  352.     float distanceAngleRatio_ = 0.03;
  353.     delta = delta * (distanceAngleRatio_ * 20);
  354.     delta = delta / 180;
  355.     //delta = delta;
  356.    
  357.     double stepsF = (curAngle - velDirection * delta) / _rotationStep;
  358.    
  359.    
  360.     int steps = (int)(stepsF + angleSign * 0.5);
  361.    
  362.     //NSLog(@"stepsF = %f, steps = %d,  vY = %f",stepsF,steps,vY);
  363.    
  364.     //NSLog(@"velDirection %d",velDirection);
  365.    
  366.     float duration=2.0;
  367.     if(velDirection == 0)
  368.     {
  369.         velDirection=angleSign;
  370.         duration=0.3;
  371.     }
  372.    
  373.    
  374.     if(angleSign >0)
  375.     {
  376.         delta = -velDirection * (steps*_rotationStep - curAngle);
  377.     }
  378.     else
  379.     {
  380.         delta = -velDirection * (-steps*_rotationStep + curAngle);
  381.     }
  382.    
  383.    
  384.  
  385. //    float durationStep=duration / (delta / M_PI_2);
  386.    
  387.     int animateDirection = - angleSign * velDirection;
  388.    
  389.     [self.delegate circleView:self didAnimateByAngle:delta inDirection:animateDirection withDuration:duration];
  390.     [self animateRotationDividersViewByAngle:delta inDirection:animateDirection duration:duration];
  391. }
  392.  
  393.  
  394. -(void)animateRotationDividersViewByAngle:(double)angle inDirection:(int)direction duration:(float)duration
  395. {
  396.     /*
  397.     double restOfTheRotation = angle - M_PI_2;
  398.     double angleToRotate = M_PI_2;
  399.  
  400.     NSInteger easing = UIViewAnimationOptionCurveLinear;
  401.    
  402.     if(restOfTheRotation<=0)
  403.     {
  404.         easing = UIViewAnimationOptionCurveEaseOut;
  405.         angleToRotate=angle;
  406.     }
  407.    
  408.     float duration = durationStep * angleToRotate / M_PI_2;
  409.    
  410.     [UIView animateWithDuration:duration delay:0 options:UIViewAnimationOptionAllowUserInteraction|easing animations:^{
  411.        
  412.         [_dividersView setTransform:CGAffineTransformRotate(_dividersView.transform, direction * angleToRotate)];
  413.     }completion:^(BOOL finished){
  414.         if (finished) {
  415.  
  416.             if(restOfTheRotation>0)
  417.                 [self animateRotationDividersViewByAngle:restOfTheRotation inDirection:direction durationStep:durationStep];
  418.             else
  419.             {
  420.                 //_shouldSendDelegateUpdates=NO;
  421.             }
  422.         }
  423.        
  424.         //NSLog(@"finished %f",atan2(_dividersView.transform.b, _dividersView.transform.a));
  425.     }];
  426.      */
  427.    
  428.    
  429.     /*
  430.     CABasicAnimation *rotationAnimation = [CABasicAnimation animationWithKeyPath:@"transform.rotation.z"];
  431.    
  432.     rotationAnimation.fromValue=[_dividersView.layer valueForKeyPath:@"transform.rotation.z"];
  433.     rotationAnimation.toValue = @(direction == 1 ? angle : -angle);
  434.     rotationAnimation.duration = 2.0;
  435.     rotationAnimation.autoreverses = NO;
  436. //    rotationAnimation.repeatCount = repeatCount;
  437.     rotationAnimation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
  438.    
  439.     [_dividersView.layer addAnimation:rotationAnimation
  440.                       forKey:@"transform.rotation.z"];
  441.      
  442.      */
  443.    
  444.  
  445.     _prevRotationDuration=duration;
  446.     _prevRotationDirection=direction;
  447.     _prevRotationAngle=angle;
  448.    
  449.     double deltaAngle = direction * angle;
  450.     _backRotationAngle = deltaAngle / 20.0;
  451.     int backAngleSign = _backRotationAngle/ fabs(_backRotationAngle);
  452.     _backRotationAngle = backAngleSign * MIN(0.1, fabs(_backRotationAngle));
  453.    
  454.    
  455.     //NSLog(@"back %f",_backRotationAngle);
  456.    
  457.     CALayer * myLayer = _dividersView.layer;
  458.     NSNumber *rotationAtStart = [myLayer valueForKeyPath:@"transform.rotation.z"];
  459.     CATransform3D myRotationTransform = CATransform3DRotate(myLayer.transform, deltaAngle + _backRotationAngle, 0.0, 0.0, 1.0);
  460.     myLayer.transform = myRotationTransform;
  461.     CABasicAnimation *myAnimation = [CABasicAnimation animationWithKeyPath:@"transform.rotation.z"];
  462.     myAnimation.duration = duration;
  463.     myAnimation.fromValue = rotationAtStart;
  464.     myAnimation.toValue = [NSNumber numberWithFloat:([rotationAtStart floatValue] + deltaAngle + _backRotationAngle)];
  465.     myAnimation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseOut];
  466.     //myAnimation.timingFunction=[CAMediaTimingFunction functionWithControlPoints:.0 :1.2 :1 :1];
  467.     myAnimation.delegate=self;
  468.     [myLayer addAnimation:myAnimation forKey:@"transform.rotation.z"];
  469. }
  470.  
  471.  
  472.  
  473.  
  474. - (void)animationDidStop:(CAAnimation *)theAnimation finished:(BOOL)flag
  475. {
  476.     if(!flag)
  477.         return;
  478.    
  479.     //NSLog(@"Angele = %f",_prevRotationAngle/20.0);
  480.    
  481.     CALayer * myLayer = _dividersView.layer;
  482.     NSNumber *rotationAtStart = [myLayer.presentationLayer valueForKeyPath:@"transform.rotation.z"];
  483.     CATransform3D myRotationTransform = CATransform3DRotate(myLayer.transform,-_backRotationAngle, 0.0, 0.0, 1.0);
  484.     myLayer.transform = myRotationTransform;
  485.     CABasicAnimation *myAnimation = [CABasicAnimation animationWithKeyPath:@"transform.rotation.z"];
  486.     myAnimation.duration = _prevRotationDuration/5.0;
  487.     myAnimation.fromValue = rotationAtStart;
  488.     myAnimation.toValue = [NSNumber numberWithFloat:([rotationAtStart floatValue] - _backRotationAngle)];
  489.       myAnimation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseIn];
  490. //    myAnimation.timingFunction=[CAMediaTimingFunction functionWithControlPoints:.0 :1.2 :1 :1];
  491.     [myLayer addAnimation:myAnimation forKey:@"transform.rotation.z"];
  492. }
  493.  
  494. /*
  495. -(void) panHandler:(UIPanGestureRecognizer*)sender
  496. {
  497.     static CGPoint startPos;
  498.     static double startAngle;
  499.     static double distanceAngleRatio=0.007;
  500.     static int draggedStepsCount;
  501.    
  502.     CGPoint translatedPoint = [sender locationInView:sender.view];
  503.     CGPoint velocity = [sender velocityInView:sender.view];
  504.    
  505.     if(sender.state == UIGestureRecognizerStateBegan)
  506.     {
  507.         startPos = translatedPoint;
  508.         startAngle = atan2(_dividersView.transform.b, _dividersView.transform.a);
  509.        
  510.         // Hack to prefent floating error
  511.         int steps = startAngle / _rotationStep;
  512.         startAngle = steps * _rotationStep;
  513.        
  514.         draggedStepsCount = 0;
  515.     }
  516.    
  517.    
  518.     int direction = self.mirrored? -1 : 1;
  519.     double dist = translatedPoint.y - startPos.y;
  520.     dist = dist * distanceAngleRatio;
  521.    
  522.     int steps= dist/_rotationStep;
  523.    
  524.     double newRotatation=startAngle + direction * steps * _rotationStep;
  525.    
  526.     if(sender.state == UIGestureRecognizerStateEnded)
  527.     {
  528.         float vY = velocity.y;
  529.         int velDirection = -velocity.y/fabs(velocity.y);
  530.  
  531.         float delta = MIN(fabs(vY),1790);
  532.         delta = delta/10;
  533.         delta = delta / 180;
  534.         delta = delta * velDirection;
  535.        
  536.         NSLog(@"%f %f",delta,vY);
  537.        
  538.         [UIView animateWithDuration:0.5 delay:0 options:UIViewAnimationOptionCurveEaseOut animations:^{
  539.             _dividersView.transform=CGAffineTransformMakeRotation(newRotatation + delta);
  540.         } completion:nil];
  541.        
  542.     }
  543.    
  544.    
  545.    
  546.     if(steps != draggedStepsCount)
  547.     {
  548.         NSInteger activeDividerNumber = [self calculateDividerIndexBasedOnRotation:newRotatation];
  549.  
  550.        
  551.         ///////////////////
  552.    
  553.         _dividersView.transform=CGAffineTransformMakeRotation(newRotatation);
  554.         draggedStepsCount = steps;
  555.            
  556.        
  557.         [self updateDividers:newRotatation];
  558.         [self.delegate circleView:self didRotateTo:newRotatation];
  559.     }
  560. }
  561. */
  562.  
  563. -(NSInteger) calculateDividerIndexBasedOnRotation:(double) testRotation
  564. {
  565.     double direction = self.mirrored ? 1 : -1;
  566.     testRotation = direction * testRotation;
  567.    
  568.     if(testRotation<0)
  569.         testRotation=testRotation + 2 * M_PI;
  570.    
  571.     int activeDividerNumber = testRotation / _rotationStep;
  572.    
  573.     return activeDividerNumber;
  574. }
  575.  
  576. -(void) updateDividersIfNeeded
  577. {
  578.     double newRotatation = [[_dividersView.layer.presentationLayer valueForKeyPath:@"transform.rotation.z"] doubleValue];
  579.    
  580.     //float newRotatation = atan2(_dividersView.transform.b, _dividersView.transform.a);
  581.     //float newRotatation = atan2(_dividersView.transform.b, _dividersView.transform.a);
  582.    
  583.     double direction = self.mirrored ? 1.0 : -1.0;
  584.     newRotatation = direction * newRotatation;
  585.     newRotatation = roundf(newRotatation * 1000) / 1000;
  586.    
  587.     if(newRotatation<0)
  588.         newRotatation=newRotatation + 2 * M_PI;
  589.    
  590.     int activeDividerNumber = (int)((newRotatation / _rotationStep) + 0.5);
  591.    
  592.     if (activeDividerNumber != _activeDividerIndex)
  593.     {
  594.  
  595.         if(self.playSound)
  596.         {
  597.             //NSString *clickSoundPath = [[NSBundle mainBundle] pathForResource:@"click_soft_tap" ofType:@"aif"];
  598.             //AudioServicesCreateSystemSoundID((__bridge CFURLRef)[NSURL fileURLWithPath: clickSoundPath], &_clickSoundID);
  599.            
  600.             NSUserDefaults * def= [NSUserDefaults standardUserDefaults];
  601.             BOOL fxMuted = [def boolForKey:@"fxMuted"];
  602.            
  603.             if(_changedRotation && !fxMuted)
  604.                 AudioServicesPlaySystemSound (_clickSoundID);
  605.         }
  606.        
  607.         if(_activeDividerIndex>=0 && _activeDividerIndex < _dividersArray.count)
  608.             _dividersArray[_activeDividerIndex].alpha=0.3;
  609.        
  610.         _activeDividerIndex = activeDividerNumber;
  611.        
  612.         /*
  613.         for (UIView * divider in _dividersArray)
  614.         {
  615.             divider.alpha=0.3;
  616.         }
  617.          */
  618.        
  619.        
  620.         if(activeDividerNumber < _dividersArray.count)
  621.         {
  622.             [_dividersArray[activeDividerNumber] setAlpha:1.0];
  623.             [self.delegate circleViewDidChangeDivider:self];            
  624.         }
  625.     }
  626.    
  627. }
  628.  
  629.  
  630. #pragma mark - Properties
  631.  
  632. -(int) activeDividerIndex
  633. {
  634.     return _activeDividerIndex;
  635. }
  636.  
  637. -(void) setFillColor:(UIColor *)fillColor
  638. {
  639.     _fillColor=fillColor;
  640.     [self setNeedsDisplay];
  641. }
  642.  
  643. -(void) setMirrored:(BOOL)mirrored
  644. {
  645.     _mirrored = mirrored;
  646.     [self setNeedsDisplay];
  647. }
  648.  
  649. -(NSInteger) stopsCount
  650. {
  651.     return [_dividersArray count];
  652. }
  653.  
  654. -(void) setActiveDivider:(int)dividerIndex
  655. {
  656.     _activeDividerIndex=dividerIndex;
  657.     double angle = -(dividerIndex) * _rotationStep;
  658.     _dividersView.transform=CGAffineTransformMakeRotation(angle);
  659.     //[_dividersView.layer.presentationLayer setValue:[NSNumber numberWithDouble:angle] forKeyPath:@"transform.rotation.z"];
  660.     [self.delegate circleView:self didRotateTo:angle];
  661. }
  662.  
  663. #pragma mark - Animating color
  664.  
  665. - (void)setColorAnimated:(UIColor *)color {
  666.     _sourceColor = self.fillColor; // set start to current color
  667.     _targetColor = color; // destination color
  668.     _startDate = [NSDate date]; // begins currently, you could add some delay if you wish
  669.     _endDate = [_startDate dateByAddingTimeInterval:.3]; // will define animation duration
  670.    
  671.     [_displayLink invalidate]; // if one already exists
  672.     _displayLink = [CADisplayLink displayLinkWithTarget:self selector:@selector(onFrame)]; // create the display link
  673.     [_displayLink addToRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
  674.  
  675. }
  676.  
  677. - (UIColor *)interpolatedColor:(UIColor *)sourceColor withColor:(UIColor *)targetColor forScale:(CGFloat)scale {
  678.     // this will interpolate between two colors
  679.     CGFloat r1, g1, b1, a1;
  680.     CGFloat r2, g2, b2, a2;
  681.     [sourceColor getRed:&r1 green:&g1 blue:&b1 alpha:&a1];
  682.     [targetColor getRed:&r2 green:&g2 blue:&b2 alpha:&a2];
  683.    
  684.     // do a linear interpolation on RGBA. You can use other
  685.     return [UIColor colorWithRed:r1+(r2-r1)*scale
  686.                            green:g1+(g2-g1)*scale
  687.                             blue:b1+(b2-b1)*scale
  688.                            alpha:a1+(a2-a1)*scale];
  689. }
  690. - (void)onFrame {
  691.     // scale is valid between 0 and 1
  692.     CGFloat scale = [[NSDate date] timeIntervalSinceDate:_startDate] / [_endDate timeIntervalSinceDate:_startDate];
  693.     if(scale < .0f) {
  694.         // this can happen if delay is used
  695.         scale = .0f;
  696.     }
  697.     else if(scale > 1.0f)
  698.     {
  699.         // end animation
  700.         scale = 1.0f;
  701.         [_displayLink invalidate];
  702.         _displayLink = nil;
  703.     }
  704.     [self setFillColor:[self interpolatedColor:_sourceColor withColor:_targetColor forScale:scale]];
  705. }
  706.  
  707. #pragma mark - Draw Rect
  708.  
  709. - (void)drawRect:(CGRect)rect
  710. {
  711.    
  712.     [self calculateRadiusAndCenter];
  713.    
  714.     CGRect borderRect = CGRectMake(_center.x-_radius, _center.y - _radius, 2*_radius,2*_radius);
  715.    
  716.     CGContextRef context = UIGraphicsGetCurrentContext();
  717.    
  718.     if(_fillColor)
  719.     {
  720.         const CGFloat *components = CGColorGetComponents(_fillColor.CGColor);
  721.         CGContextSetRGBFillColor(context, components[0],components[1],components[2], 1.0);
  722.     }
  723.     else
  724.     {
  725.        
  726.     }
  727.    
  728.     CGContextFillEllipseInRect (context, borderRect);
  729.     CGContextFillPath(context);
  730.    
  731. }
  732.  
  733.  
  734. #pragma mark - Calculations
  735.  
  736. -(void) calculateRadiusAndCenter
  737. {
  738.     CGPoint pointA;
  739.     CGPoint pointB;
  740.    
  741.     if(self.mirrored)
  742.     {
  743.         pointA = CGPointMake(0,self.frame.size.height/2);
  744.         pointB = CGPointMake(self.frame.size.width,0);
  745.     }
  746.     else
  747.     {
  748.         pointA = CGPointMake(self.frame.size.width,self.frame.size.height/2);
  749.         pointB = CGPointMake(0,0);
  750.     }
  751.    
  752.     // getting angle
  753.    
  754.     CGPoint originPoint = CGPointMake(pointA.x - pointB.x, pointA.y - pointB.y); // get origin point to origin by subtracting end from start
  755.     float bearingRadians = atan2f(originPoint.y, originPoint.x); // get bearing in radians
  756.     //float bearingDegrees = bearingRadians * (180.0 / M_PI); // convert to degrees
  757.    
  758.     double dx = (pointA.x-pointB.x);
  759.     double dy = (pointA.y-pointB.y);
  760.     double dist = sqrt(dx*dx + dy*dy);
  761.    
  762.     _radius =  fabs(dist / (2 * cos(bearingRadians)));
  763.    
  764.     if (self.mirrored)
  765.     {
  766.         _center = CGPointMake(_radius, self.frame.size.height/2);
  767.     }
  768.     else
  769.     {
  770.         _center = CGPointMake(self.frame.size.width - _radius, self.frame.size.height/2);
  771.     }
  772. }
  773.  
  774. @end
RAW Paste Data
Challenge yourself this year...
Learn something new in 2017
Top