Skip to content

Commit

Permalink
- refactor - add examples
Browse files Browse the repository at this point in the history
Change structure of PieLayer. Optimize performance.
  • Loading branch information
AlexandrGraschenkov committed Dec 30, 2013
1 parent 99f6a52 commit f835232
Show file tree
Hide file tree
Showing 28 changed files with 1,160 additions and 638 deletions.
108 changes: 90 additions & 18 deletions MagicPie.xcodeproj/project.pbxproj

Large diffs are not rendered by default.

13 changes: 13 additions & 0 deletions MagicPie/Example1Controller.h
@@ -0,0 +1,13 @@
//
// ViewController.h
// MagicPie
//
// Created by Alexandr on 30.09.13.
// Copyright (c) 2013 Alexandr Corporation. All rights reserved.
//

#import <UIKit/UIKit.h>

@interface Example1Controller : UIViewController

@end
141 changes: 141 additions & 0 deletions MagicPie/Example1Controller.m
@@ -0,0 +1,141 @@
//
// ViewController.m
// MagicPie
//
// Created by Alexandr on 30.09.13.
// Copyright (c) 2013 Alexandr Corporation. All rights reserved.
//

#import "Example1Controller.h"
#import "MagicPieLayer.h"
#import "TestPieLayer.h"
#import "Example1PieView.h"
#import "NSMutableArray+pieEx.h"

#define LOG_ACTION

@interface Example1Controller()
@property (nonatomic, weak) IBOutlet Example1PieView* pieView;
@end

@implementation Example1Controller
@synthesize pieView;

- (void)viewDidLoad
{
[super viewDidLoad];

pieView.elemTapped = ^(PieElement* elem){
[PieElement animateChanges:^{
elem.color = [self randomColor];
}];
};
}

- (UIColor*)randomColor
{
CGFloat hue = ( arc4random() % 256 / 256.0 ); // 0.0 to 1.0
CGFloat saturation = ( arc4random() % 128 / 256.0 ) + 0.5; // 0.5 to 1.0, away from white
CGFloat brightness = ( arc4random() % 128 / 256.0 ) + 0.5; // 0.5 to 1.0, away from black
return [UIColor colorWithHue:hue saturation:saturation brightness:brightness alpha:1];
}

- (IBAction)backPressed:(id)sender
{
[self dismissModalViewControllerAnimated:YES];
}

- (IBAction)addPressed:(id)sender
{
PieElement* newElem = [PieElement pieElementWithValue:(5 + arc4random() % 10) color:[self randomColor]];
// newElem.showTitle = YES;
int insertIndex = arc4random() % (self.pieView.layer.values.count + 1);
[self.pieView.layer insertValues:@[newElem] atIndexes:@[@(insertIndex)] animated:YES];
#ifdef LOG_ACTION
NSLog(@"Insert values %@ to indixes %@", [self arrDesc:@[newElem]], [self arrDesc:@[@(insertIndex)]]);
#endif
}

- (IBAction)deletePressed:(id)sender
{
if(self.pieView.layer.values.count <= 0)
return;

int deleteIndex = arc4random() % self.pieView.layer.values.count;
[self.pieView.layer deleteValues:@[self.pieView.layer.values[deleteIndex]] animated:YES];
#ifdef LOG_ACTION
NSLog(@"Delete values at indixes %@", [self arrDesc:@[@(deleteIndex)]]);
#endif
}

- (IBAction)animateChangeVal:(id)sender
{
if(self.pieView.layer.values.count == 0)return;
int randCount = MAX(MIN(self.pieView.layer.values.count, 2), arc4random() % self.pieView.layer.values.count);
NSMutableArray* randIndexes = [NSMutableArray new];
NSMutableArray* changeValArr = [NSMutableArray new];
[PieElement animateChanges:^{
for(int i = 0; i < randCount; i++){
int randIndx = arc4random() % self.pieView.layer.values.count;
while ([randIndexes containsObject:@(randIndx)]) {
randIndx = arc4random() % self.pieView.layer.values.count;
}
[randIndexes addObject:@(randIndx)];
int randVal = (5 + arc4random() % 10);
int prevVal = [(PieElement*)self.pieView.layer.values[randIndx] val];
[self.pieView.layer.values[randIndx] setVal:randVal];
[changeValArr addObject:[NSString stringWithFormat:@"%d -> %d", prevVal, randVal]];
}
}];
#ifdef LOG_ACTION
NSMutableString* logStr = [[NSMutableString alloc] initWithString:@"Update elements:\n"];
for(int i = 0; i < randIndexes.count; i++){
[logStr appendFormat:@"%@ element: %@\n", randIndexes[i], changeValArr[i]];
}
NSLog(@"%@", logStr);
#endif
}

- (IBAction)refreshData:(id)sender
{
[self.pieView.layer setNeedsDisplay];
}

- (IBAction)performRandomActions:(id)sender
{
while (arc4random() % 100 < 90) {
switch (arc4random() % 3) {
case 0:
[self addPressed:nil];
break;
case 1:
[self deletePressed:nil];
break;
case 2:
[self animateChangeVal:nil];
break;


default:
break;
}
}
}

- (IBAction)animateStartEnd
{
float startAngle = arc4random() % 360;
float endAngle = arc4random() % 300 + 60 + startAngle;
[self.pieView.layer setStartAngle:startAngle endAngle:endAngle animated:YES];
}

- (NSString*)arrDesc:(NSArray*)arr
{
NSString* str = arr.description;
str = [str stringByReplacingOccurrencesOfString:@" " withString:@""];
str = [str stringByReplacingOccurrencesOfString:@"\n" withString:@""];
return str;
}


@end
121 changes: 121 additions & 0 deletions MagicPie/Example1Controller.xib
@@ -0,0 +1,121 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="4514" systemVersion="13B42" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none">
<dependencies>
<deployment defaultVersion="1280" identifier="iOS"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="3747"/>
</dependencies>
<objects>
<placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner" customClass="Example1Controller">
<connections>
<outlet property="pieView" destination="Oe7-S8-YBE" id="ftR-Nn-cT2"/>
<outlet property="view" destination="QNm-Ab-La5" id="Lc4-L5-oXR"/>
</connections>
</placeholder>
<placeholder placeholderIdentifier="IBFirstResponder" id="-2" customClass="UIResponder"/>
<view contentMode="scaleToFill" id="QNm-Ab-La5">
<rect key="frame" x="0.0" y="0.0" width="320" height="480"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
<subviews>
<view contentMode="scaleToFill" id="Oe7-S8-YBE" customClass="Example1PieView">
<rect key="frame" x="0.0" y="50" width="320" height="270"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMinY="YES"/>
<color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="calibratedWhite"/>
<inset key="insetFor6xAndEarlier" minX="0.0" minY="20" maxX="0.0" maxY="-20"/>
</view>
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" id="EtW-aq-lcK">
<rect key="frame" x="10" y="379" width="140" height="40"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
<color key="backgroundColor" red="1" green="0.8722342609489051" blue="0.64595688868613144" alpha="1" colorSpace="deviceRGB"/>
<inset key="insetFor6xAndEarlier" minX="0.0" minY="20" maxX="0.0" maxY="-20"/>
<fontDescription key="fontDescription" type="system" pointSize="17"/>
<state key="normal" title="Add">
<color key="titleShadowColor" white="0.0" alpha="0.0" colorSpace="calibratedWhite"/>
</state>
<connections>
<action selector="addPressed:" destination="-1" eventType="touchUpInside" id="rtA-bB-KpO"/>
</connections>
</button>
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" id="yli-Pq-K4Q">
<rect key="frame" x="10" y="329" width="140" height="40"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
<color key="backgroundColor" red="0.99670493602752686" green="0.44366491050920281" blue="0.43026072876544591" alpha="1" colorSpace="calibratedRGB"/>
<inset key="insetFor6xAndEarlier" minX="0.0" minY="20" maxX="0.0" maxY="-20"/>
<fontDescription key="fontDescription" type="system" pointSize="17"/>
<state key="normal" title="Refresh">
<color key="titleShadowColor" white="0.0" alpha="0.0" colorSpace="calibratedWhite"/>
</state>
<connections>
<action selector="refreshData:" destination="-1" eventType="touchUpInside" id="mEh-A8-iyw"/>
</connections>
</button>
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" id="qi8-YP-6Gb">
<rect key="frame" x="170" y="329" width="140" height="40"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
<color key="backgroundColor" red="0.99670493599999999" green="0.44366491050000001" blue="0.43026072879999999" alpha="1" colorSpace="calibratedRGB"/>
<inset key="insetFor6xAndEarlier" minX="0.0" minY="20" maxX="0.0" maxY="-20"/>
<fontDescription key="fontDescription" type="system" pointSize="17"/>
<state key="normal" title="Bunch actions">
<color key="titleShadowColor" white="0.0" alpha="0.0" colorSpace="calibratedWhite"/>
</state>
<connections>
<action selector="performRandomActions:" destination="-1" eventType="touchUpInside" id="xc6-cn-pbb"/>
</connections>
</button>
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" id="N4z-lO-FaA">
<rect key="frame" x="170" y="379" width="140" height="40"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
<color key="backgroundColor" red="0.72549021244049072" green="0.5215686559677124" blue="0.96862751245498657" alpha="1" colorSpace="deviceRGB"/>
<inset key="insetFor6xAndEarlier" minX="0.0" minY="20" maxX="0.0" maxY="-20"/>
<fontDescription key="fontDescription" type="system" pointSize="17"/>
<state key="normal" title="Change val">
<color key="titleShadowColor" white="0.0" alpha="0.0" colorSpace="calibratedWhite"/>
</state>
<connections>
<action selector="animateChangeVal:" destination="-1" eventType="touchUpInside" id="a8Z-2Q-FQJ"/>
</connections>
</button>
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" id="qmS-S5-y2X">
<rect key="frame" x="10" y="429" width="140" height="40"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
<color key="backgroundColor" red="0.62352943420410156" green="0.90196084976196289" blue="0.64705884456634521" alpha="1" colorSpace="deviceRGB"/>
<inset key="insetFor6xAndEarlier" minX="0.0" minY="20" maxX="0.0" maxY="-20"/>
<fontDescription key="fontDescription" type="system" pointSize="17"/>
<state key="normal" title="Delete">
<color key="titleShadowColor" white="0.0" alpha="0.0" colorSpace="calibratedWhite"/>
</state>
<connections>
<action selector="deletePressed:" destination="-1" eventType="touchUpInside" id="Dxc-1b-nX2"/>
</connections>
</button>
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" id="wpS-cX-qAc">
<rect key="frame" x="170" y="429" width="140" height="40"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
<color key="backgroundColor" red="0.66274511814117432" green="0.77647066116333008" blue="0.9803922176361084" alpha="1" colorSpace="deviceRGB"/>
<inset key="insetFor6xAndEarlier" minX="0.0" minY="20" maxX="0.0" maxY="-20"/>
<fontDescription key="fontDescription" type="system" pointSize="17"/>
<state key="normal" title="Start-end angle">
<color key="titleShadowColor" white="0.0" alpha="0.0" colorSpace="calibratedWhite"/>
</state>
<connections>
<action selector="animateStartEnd" destination="-1" eventType="touchUpInside" id="auE-9a-bvy"/>
</connections>
</button>
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" id="xEL-R7-OOZ">
<rect key="frame" x="10" y="20" width="89" height="30"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
<color key="backgroundColor" red="0.0" green="0.0" blue="0.0" alpha="1" colorSpace="calibratedRGB"/>
<inset key="insetFor6xAndEarlier" minX="0.0" minY="20" maxX="0.0" maxY="-20"/>
<fontDescription key="fontDescription" type="system" pointSize="15"/>
<state key="normal" title="&lt;= Back">
<color key="titleShadowColor" white="0.5" alpha="1" colorSpace="calibratedWhite"/>
</state>
<connections>
<action selector="backPressed:" destination="-1" eventType="touchUpInside" id="bWN-f6-Q5r"/>
</connections>
</button>
</subviews>
<color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="calibratedWhite"/>
<simulatedScreenMetrics key="simulatedDestinationMetrics"/>
</view>
</objects>
</document>
19 changes: 19 additions & 0 deletions MagicPie/Example1PieView.h
@@ -0,0 +1,19 @@
//
// ExamplePieView.h
// MagicPie
//
// Created by Alexandr on 10.10.13.
// Copyright (c) 2013 Alexandr Corporation. All rights reserved.
//

#import <UIKit/UIKit.h>

@class PieLayer, PieElement;

@interface Example1PieView : UIView
@property (nonatomic, copy) void(^elemTapped)(PieElement*);
@end

@interface Example1PieView (ex)
@property(nonatomic,readonly,retain) PieLayer *layer;
@end
22 changes: 6 additions & 16 deletions MagicPie/ExamplePieView.m → MagicPie/Example1PieView.m
Expand Up @@ -6,10 +6,10 @@
// Copyright (c) 2013 Alexandr Corporation. All rights reserved.
//

#import "ExamplePieView.h"
#import "Example1PieView.h"
#import "MagicPieLayer.h"

@interface ExamplePieView ()
@interface Example1PieView ()
{
CGPoint panNormalizedVector;
PieElement* panPieElem;
Expand All @@ -18,7 +18,7 @@ @interface ExamplePieView ()
}
@end

@implementation ExamplePieView
@implementation Example1PieView

+ (Class)layerClass
{
Expand Down Expand Up @@ -57,7 +57,7 @@ - (void)setup
self.layer.maxRadius = 120;
self.layer.minRadius = 30;
self.layer.animationDuration = 0.6;
self.layer.showTitles = ShowTitlesIfEnable;
self.layer.showTitles = ShowTitlesNever;
if ([self.layer.self respondsToSelector:@selector(setContentsScale:)])
{
self.layer.contentsScale = [[UIScreen mainScreen] scale];
Expand All @@ -74,23 +74,15 @@ - (void)setup
[self addGestureRecognizer:pan];
}

- (UIColor*)randomColor
{
CGFloat hue = ( arc4random() % 256 / 256.0 ); // 0.0 to 1.0
CGFloat saturation = ( arc4random() % 128 / 256.0 ) + 0.5; // 0.5 to 1.0, away from white
CGFloat brightness = ( arc4random() % 128 / 256.0 ) + 0.5; // 0.5 to 1.0, away from black
UIColor *color = [UIColor colorWithHue:hue saturation:saturation brightness:brightness alpha:1];
return color;
}

- (void)handleTap:(UITapGestureRecognizer*)tap
{
if(tap.state != UIGestureRecognizerStateEnded)
return;

CGPoint pos = [tap locationInView:tap.view];
PieElement* elem = [self.layer pieElemInPoint:pos];
elem.color = [self randomColor];
if(elem && _elemTapped)
_elemTapped(elem);
}

- (void)handlePan:(UIPanGestureRecognizer*)pan
Expand All @@ -100,7 +92,6 @@ - (void)handlePan:(UIPanGestureRecognizer*)pan
if(pan.state == UIGestureRecognizerStateBegan){
panPieElem = [self.layer pieElemInPoint:pos];
panStartCenterOffsetElem = panPieElem.centrOffset;
panPieElem.animateChanges = NO;

CGPoint vec = CGPointMake(pos.x - center.x, pos.y - center.y);
float distance = sqrtf(pow(vec.x, 2.0) + pow(vec.y, 2.0));
Expand All @@ -111,7 +102,6 @@ - (void)handlePan:(UIPanGestureRecognizer*)pan
float dotProduct = currPoint.x * panNormalizedVector.x + currPoint.y * panNormalizedVector.y;
panPieElem.centrOffset = MAX(0.0, dotProduct - panStartDotProduct + panStartCenterOffsetElem);
} else if(pan.state == UIGestureRecognizerStateEnded){
panPieElem.animateChanges = YES;
panPieElem = nil;
}
}
Expand Down
13 changes: 13 additions & 0 deletions MagicPie/Example2Controller.h
@@ -0,0 +1,13 @@
//
// Example2Controller.h
// MagicPie
//
// Created by Alexander on 30.12.13.
// Copyright (c) 2013 Alexandr Corporation. All rights reserved.
//

#import <UIKit/UIKit.h>

@interface Example2Controller : UIViewController

@end

0 comments on commit f835232

Please sign in to comment.