iPhone隣接行列

グラフの枝と隣接行列という感じのiPhoneアプリのサンプルコードを描いてみます。

#import “ViewController.h”

#include <array>

using namespace std;

template <class T, size_t R, size_t C>

using Matrix = array<array<T, C>, R>;

Matrix<int, 10, 10> mat;

@interface ViewController ()

@property (nonatomic, strong) NSMutableArray *nodes;

@property (nonatomic, weak) UILabel *selected;

@end

@implementation ViewController

– (void)viewDidLoad {

    [super viewDidLoad];

    self.view.backgroundColor = [UIColor blackColor];

    

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

        for (int j=0; j<10; j++) {

            mat[i][j] = 0;

        }

    }

    

    [self updatePanels];

    [self updateNodes];

}

– (void)updatePanels {

    

    [self.view.subviews enumerateObjectsUsingBlock:^(UIView *v, NSUInteger idx, BOOL *stop) {

        if (v.tag == 1) {

            [v removeFromSuperview];

        }

    }];

    

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

        for (int j=0; j<10; j++) {

            float x = 30 * i + 40;

            float y = 30 * j + 40;

            UILabel *l = [[UILabel alloc] initWithFrame:CGRectMake(x, y, 30, 30)];

            l.tag = 1;

            l.textAlignment = NSTextAlignmentCenter;

            l.backgroundColor = mat[i][j] == 0 ? [UIColor yellowColor] : [UIColor colorWithHue:0.12 saturation:0.5 brightness:1 alpha:1];

            l.text = [NSString stringWithFormat:@”%d”, mat[i][j]];

            [self.view addSubview:l];

    }}

}

– (void)updateNodes {

    

    float dw = M_PI / 5.0;

    CGPoint o = CGPointMake(CGRectGetMidX(self.view.bounds), 480);

    

    if (!self.nodes) {

        self.nodes = [NSMutableArray array];

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

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

            n.userInteractionEnabled = YES;

            n.tag = 2;

            n.font = [UIFont boldSystemFontOfSize:20];

            n.backgroundColor = [UIColor whiteColor];

            n.textAlignment = NSTextAlignmentCenter;

            n.layer.cornerRadius = 20;

            n.layer.masksToBounds = YES;

            n.text = [NSString stringWithFormat:@”%d”, i+1];

            n.center = CGPointMake(o.x + 100 * cos(dw * i – M_PI * 0.5), o.y + 100 * sin(dw * i  M_PI * 0.5));

            [self.view addSubview:n];

        }

    }

    

    for (int i = (int)self.view.layer.sublayers.count1; i>=0; i–) {

        CALayer *l = self.view.layer.sublayers[i];

        if ([l.name isEqual:@”edge”]) {

            [l removeFromSuperlayer];

        }

    };

    

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

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

            if (mat[i][j] == 1) {

                UIBezierPath *path = [UIBezierPath bezierPath];

                [path moveToPoint:CGPointMake(o.x + 100 * cos(dw * i – M_PI * 0.5), o.y + 100 * sin(dw * i  M_PI * 0.5))];

                [path addLineToPoint:CGPointMake(o.x + 100 * cos(dw * j – M_PI * 0.5), o.y + 100 * sin(dw * j  M_PI * 0.5))];

                CAShapeLayer *edge = [CAShapeLayer layer];

                edge.name = @”edge”;

                edge.path = path.CGPath;

                edge.fillColor = [UIColor clearColor].CGColor;

                edge.strokeColor = [[UIColor orangeColor] colorWithAlphaComponent:0.7].CGColor;

                edge.lineWidth = 5;

                [self.view.layer addSublayer:edge];

            }

    }}

}

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

    CGPoint p = [[touches anyObject] locationInView:self.view];

    UIView *v = [self.view hitTest:p withEvent:nil];

    if (v.tag == 2) {

        v.backgroundColor = [UIColor colorWithHue:0.3 saturation:0.1 brightness:1 alpha:1];

        if (self.selected) {

            int s = [self.selected.text intValue] – 1;

            int e = [((UILabel *)v).text intValue] – 1;

            mat[s][e] = 1;

            mat[e][s] = 1;

            

            [self updatePanels];

            [self updateNodes];

            

            self.selected = nil;

        } else {

            self.selected = (UILabel *)v;

        }

    }

}

@end