ツリー上のラベルを上から探索するアプリのサンプルコードを描いてみます。
#import “ViewController.h”
@interface TreeNode : NSObject
@property (nonatomic, weak) TreeNode *p;
@property (nonatomic, strong) TreeNode *left;
@property (nonatomic, strong) TreeNode *right;
@property (nonatomic) NSInteger number;
@end
@implementation TreeNode @end
@interface ViewController ()
@property (nonatomic, strong) TreeNode *rootNode;
@property (nonatomic, strong) NSMutableArray *animationQueue;
@property (nonatomic, weak) NSNotificationCenter *notification;
@property (nonatomic, strong) NSTimer *timer;
@end
@implementation ViewController
#define SearchNumber @“Search Number”
– (void)viewDidAppear:(BOOL)animated
{
[super viewDidAppear:animated];
self.view.backgroundColor = [UIColor colorWithRed:0.9 green:1.0 blue:0.9 alpha:1];
[self createNodeTree];
self.animationQueue = [NSMutableArray array];
NSOperationQueue *mainQueue = [NSOperationQueue mainQueue];
self.notification = [[NSNotificationCenter defaultCenter] addObserverForName:SearchNumber object:nil queue:mainQueue usingBlock:^(NSNotification *note) {
[self.animationQueue addObject:note.userInfo[@”node”]];
}];
self.timer = [NSTimer scheduledTimerWithTimeInterval:0.5 target:self selector:@selector(tick:) userInfo:nil repeats:YES];
}
– (void)viewDidDisappear:(BOOL)animated
{
[super viewDidDisappear:animated];
[[NSNotificationCenter defaultCenter] removeObserver:self.notification];
}
– (void)createNodeTree
{
self.rootNode = [[TreeNode alloc] init];
self.rootNode.number = 6;
TreeNode *n = self.rootNode;
n.left = [[TreeNode alloc] init];
n.left.number = 3;
n.right = [[TreeNode alloc] init];
n.right.number = 8;
n = self.rootNode.left; // 3
n.left = [[TreeNode alloc] init];
n.left.number = 1;
n.right = [[TreeNode alloc] init];
n.right.number = 4;
n = self.rootNode.right; // 8
n.left = [[TreeNode alloc] init];
n.left.number = 7;
n.right = [[TreeNode alloc] init];
n.right.number = 10;
CGPoint o = CGPointMake(CGRectGetMidX(self.view.bounds), 90);
[self nodeLabelWithNumber:self.rootNode.number atPoint:o];
[self nodeLabelWithNumber:self.rootNode.left.number atPoint:CGPointMake(o.x – 100, o.y + 100)];
[self nodeLabelWithNumber:self.rootNode.left.left.number atPoint:CGPointMake(o.x – 150, o.y + 200)];
[self nodeLabelWithNumber:self.rootNode.left.right.number atPoint:CGPointMake(o.x – 50, o.y + 200)];
[self nodeLabelWithNumber:self.rootNode.right.number atPoint:CGPointMake(o.x + 100, o.y + 100)];
[self nodeLabelWithNumber:self.rootNode.right.left.number atPoint:CGPointMake(o.x + 50, o.y + 200)];
[self nodeLabelWithNumber:self.rootNode.right.right.number atPoint:CGPointMake(o.x + 150, o.y + 200)];
}
– (void)nodeLabelWithNumber:(NSInteger)number atPoint:(CGPoint)p
{
UILabel *v = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, 50, 50)];
v.backgroundColor = [UIColor colorWithRed:0.8 green:0.8 blue:1.0 alpha:1];
v.layer.cornerRadius = 25;
v.layer.borderWidth = 0;
v.layer.masksToBounds = YES;
v.textAlignment = NSTextAlignmentCenter;
v.center = p;
v.tag = number;
v.text = [@(number) stringValue];
v.userInteractionEnabled = YES;
[self.view addSubview:v];
}
-(TreeNode *)treeSearch:(TreeNode *)x number:(NSInteger)number
{
[[NSNotificationCenter defaultCenter] postNotificationName:SearchNumber object:nil userInfo:@{@”node”:x}];
if (x == nil || number == x.number)
return x;
else if (number < x.number)
return [self treeSearch:x.left number:number];
else
return [self treeSearch:x.right number:number];
}
– (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
if (self.animationQueue.count == 0) {
UIView *hit = [self.view hitTest:[[touches anyObject] locationInView:self.view] withEvent:nil];
if ([hit isKindOfClass:[UILabel class]]) {
[self treeSearch:self.rootNode number:[((UILabel *)hit).text intValue]];
}
}
}
– (void)tick:(NSTimer *)timer
{
if (self.animationQueue.count) {
TreeNode *n = [self.animationQueue objectAtIndex:0];
[self.animationQueue removeObjectAtIndex:0];
UIView *v = [self.view viewWithTag:n.number];
UIColor *origin = v.backgroundColor;
v.backgroundColor = [UIColor greenColor];
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.5 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
v.backgroundColor = origin;
});
}
}
@end