UILabel文字列を円周上に配置し動かしてみる。
(XcodeのiOS6 iPhone Simulatorを使って動かしています。)

概要

大きな円を一つ、真ん中に小さい円を一つ、
大きな円と、真ん中の円の隙間に、3つの円に文字を配置
計5個の円を魔方陣のように回しておいて、
画面をタッチしたら、文字がぱらぱらと下に落ちる
と行った動きにしてみた。

ポイント

テキストにグラデーションを付けたかったので、
GradientLabelというインタフェースを作り、
そのdrawTextInRectの中で、CGContextDrawLinearGradient
を利用した。


サンプルコード

@interface GradientLabel : UILabel

@end

@implementation GradientLabel

– (void)drawTextInRect:(CGRect)rect

{

    CGContextRef context = UIGraphicsGetCurrentContext();

    CGContextSaveGState(context);

    

    CGContextTranslateCTM(context, 0.0f, self.bounds.size.height);

    CGContextScaleCTM(context, 1.0f, –1.0f);

    

    CGContextSelectFont(context, “Chalkduster”, 10, kCGEncodingMacRoman);

    CGContextSetTextDrawingMode(context, kCGTextClip);

    CGContextSetTextPosition(context, 0.0f, round(10.0f / 4.0f));

    CGContextShowText(context, [self.text UTF8String], strlen([self.text UTF8String]));

        

    CGGradientRef gradient;

    CGColorSpaceRef rgbColorspace;

    size_t num_locations = 3;

    CGFloat locations[3] = { 0.0, 0.5, 1.0 };

    CGFloat components[12] = { 1.0, 0, 0, 1.0,  // Start color

        1.0, 1.0, 1.0, 1.0,  // Middle color

        1.0, 0, 0, 1.0 }; // End color

    

    rgbColorspace = CGColorSpaceCreateDeviceRGB();

    gradient = CGGradientCreateWithColorComponents(rgbColorspace, components, locations, num_locations);

    

    CGRect currentBounds = self.bounds;

    CGPoint topCenter = CGPointMake(CGRectGetMidX(currentBounds), 0.0f);

    CGPoint midCenter = CGPointMake(CGRectGetMidX(currentBounds), CGRectGetMidY(currentBounds));

    CGContextDrawLinearGradient(context, gradient, topCenter, midCenter, 0);

    

    CGGradientRelease(gradient);

    CGColorSpaceRelease(rgbColorspace);         

    

    CGContextRestoreGState(context);

}

@end

#import “ViewController.h”

#import <QuartzCore/QuartzCore.h>

@interface ViewController () {

    CADisplayLink *link;

    // big

    NSMutableArray *labelArray1;

    // middle

    NSMutableArray *labelArray2, *labelArray3, *labelArray4;

    // small

    NSMutableArray *labelArray5;

}

@end

@implementation ViewController

– (void)viewDidLoad

{

    [super viewDidLoad];

    

    self.view.backgroundColor = [UIColor blackColor];

        

    [self createLabel1];

    labelArray2 = [self createLabelMid];

    labelArray3 = [self createLabelMid];

    labelArray4 = [self createLabelMid];

    

    labelArray5 = [self createLabelSmall];

    

    [self startTimer];

}

– (void)createLabel1

{

    NSString *stringA = @”ABCDEFGHIJKLMNOPQRSTU”;

    labelArray1 = [[NSMutableArray alloc] init];

    

    for (int i=0; i<[stringA length]; i++) {

        NSRange range = NSMakeRange(i, 1);

        UILabel *l = [[GradientLabel alloc] initWithFrame:CGRectMake(0, 0, 50, 50)];

        l.text = [stringA substringWithRange:range];

        l.textColor = [UIColor redColor];

        l.backgroundColor = [UIColor clearColor];

        

        l.layer.shadowColor = [UIColor whiteColor].CGColor;

        l.layer.shadowOffset = CGSizeMake(2, 2);

        l.layer.shadowRadius = 3;

        l.layer.shadowOpacity = 1.0;

        l.layer.masksToBounds = NO;

        

        [labelArray1 addObject:l];

        [self.view addSubview:l];

    }

}

– (NSMutableArray*)createLabelMid

{

    NSString *stringA = @”1234567890″;

    NSMutableArray *target = [[NSMutableArray alloc] init];

    

    for (int i=0; i<[stringA length]; i++) {

        NSRange range = NSMakeRange(i, 1);

        UILabel *l = [[GradientLabel alloc] initWithFrame:CGRectMake(0, 0, 40, 40)];

        l.text = [stringA substringWithRange:range];

        l.textColor = [UIColor redColor];

        l.backgroundColor = [UIColor clearColor];

        

        l.layer.shadowColor = [UIColor whiteColor].CGColor;

        l.layer.shadowOffset = CGSizeMake(2, 2);

        l.layer.shadowRadius = 3;

        l.layer.shadowOpacity = 1.0;

        l.layer.masksToBounds = NO;

        

        [target addObject:l];

        [self.view addSubview:l];

    }

    return target;

}

– (NSMutableArray*)createLabelSmall

{

    NSString *stringA = @”iPhone Apple develop”;

    NSMutableArray *target = [[NSMutableArray alloc] init];

    

    for (int i=0; i<[stringA length]; i++) {

        NSRange range = NSMakeRange(i, 1);

        UILabel *l = [[GradientLabel alloc] init];

        l.text = [stringA substringWithRange:range];

        l.textColor = [UIColor redColor];

        l.backgroundColor = [UIColor clearColor];

        [l sizeToFit];

        

        l.layer.shadowColor = [UIColor whiteColor].CGColor;

        l.layer.shadowOffset = CGSizeMake(2, 2);

        l.layer.shadowRadius = 3;

        l.layer.shadowOpacity = 1.0;

        l.layer.masksToBounds = NO;

        

        [target addObject:l];

        [self.view addSubview:l];

    }

    return target;

}

– (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event

{

    NSArray *arr = [NSArray arrayWithObjects:labelArray1, labelArray2, labelArray3, labelArray4, labelArray5, nil];

    for (int j=0; j<[arr count]; j++) {

        NSMutableArray *a = [arr objectAtIndex:j];

        int count = [a count];

        for (int i=0; i<count; i++) {

            [self performSelector:@selector(fallFrom:) withObject:a afterDelay:i*0.2 + j*2];

        }

    }

}

– (void)fallFrom:(NSMutableArray*)a

{

    UIView *v = [a lastObject];

    [a removeLastObject];

    [UIView animateWithDuration:2.0 animations:^{

        int w = arc4random() % 100;

        v.center = CGPointMake(100 + w, 300);

    } completion:^(BOOL finished) {

        [v removeFromSuperview];

    }];

}

– (void)startTimer

{

    link = [CADisplayLink displayLinkWithTarget:self selector:@selector(tick:)];

    [link addToRunLoop:[NSRunLoop currentRunLoop] forMode:NSRunLoopCommonModes];

}

– (void)tick:(CADisplayLink*)sender

{

    static float lastTime;

    lastTime += sender.duration;

    float angle = 0.5 * M_PI * fmodf(lastTime, 4.0f);

    

    // big circle    

    for (int i=0; i< [labelArray1 count]; i++) {

        UIView *v = [labelArray1 objectAtIndex:i];

        

        float x = 100 * cos(angle + M_PI * 0.1 *i) + 150;

        float y = 100 * sin(angle + M_PI * 0.1 *i) + 150;

        

        v.center = CGPointMake(x, y);

        v.transform = CGAffineTransformMakeRotation(angle + M_PI * 0.1 *i + M_PI * 0.5);

    }

    

    // middle circle

    angle = -angle;

    

    

    NSMutableArray *mids = [NSMutableArray arrayWithObjects:labelArray2, labelArray3, labelArray4, nil];

    

    for (int i=0; i<3; i++) {

        angle = angle + 2.0 * (M_PI/3.0);

        NSMutableArray *labelArray = [mids objectAtIndex:i];

        

        CGPoint center = CGPointMake(50 * cos(angle) + 150, 50 * sin(angle) + 150);

        for (int i=0; i< [labelArray count]; i++) {

            UIView *v = [labelArray objectAtIndex:i];

            

            float x = 20 * cos(2*angle + (M_PI/5.0) *i) + center.x;

            float y = 20 * sin(2*angle + (M_PI/5.0) *i) + center.y;

            v.transform = CGAffineTransformMakeRotation(2*angle + (M_PI/5.0) *i + M_PI * 0.5);

            v.center = CGPointMake(x, y);

        }

    }

    

    // small circle

    angle = – 2 * angle;

    for (int i=0; i< [labelArray5 count]; i++) {

        UIView *v = [labelArray5 objectAtIndex:i];        

        float x = 30 * cos(angle + M_PI * 0.1 *i) + 150;

        float y = 30 * sin(angle + M_PI * 0.1 *i) + 150;

        v.center = CGPointMake(x, y);

        v.transform = CGAffineTransformMakeRotation(angle + M_PI * 0.1 *i + M_PI * 0.5);

    }

    

    

}

– (void)didReceiveMemoryWarning

{

    [super didReceiveMemoryWarning];

    

    [link invalidate];

    link = nil;

    

    labelArray1 = nil;

}

@end