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