iPhone木探索

ツリー上のラベルを上から探索するアプリのサンプルコードを描いてみます。

#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.x100, o.y + 100)];

    [self nodeLabelWithNumber:self.rootNode.left.left.number atPoint:CGPointMake(o.x150, o.y + 200)];

    [self nodeLabelWithNumber:self.rootNode.left.right.number atPoint:CGPointMake(o.x50, 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