Как бы вы построили и взаимодействовали с сеткой, как доска Судоку? - PullRequest
7 голосов
/ 20 ноября 2008

Какой, по вашему мнению, лучший способ реализовать интерактивную сетку, аналогичную плате Судоку, для родного приложения для iPhone? Я не видел объекта, который бы удовлетворял эту потребность в SDK.

Должен ли я создать пользовательский элемент управления для отдельной ячейки, а затем инициализировать столько их, сколько мне нужно в форме сетки?

Sudoku grid
(источник: 4thewww.com )

Любые комментарии приветствуются. Спасибо!

Ответы [ 7 ]

3 голосов
/ 20 ноября 2008

Для такой полностью однородной сетки я бы создал подкласс UIView и дал бы ему определить, к какой строке и столбцу пользователь прикоснулся, используя простой расчет:

int touchedRow = 9 * touch.x / [self bounds].width;
int touchedCol = 9 * touch.y / [self bounds].width;

Я не вижу большой пользы в создании 81 отдельного объекта в памяти, когда достаточно одного объекта.

1 голос
/ 10 октября 2012

Это очень просто. Я использую gridView в качестве класса UiViewController и добавляю следующий код в gridView.m

#import "SudokuClass.h"
#import "GridView.h"

@interface GridView ()

@end

@implementation GridView


-(void)createNumberButton {

    int cellWidth = 34;
    int cellHeight = 34;
    int xSta = 7 - cellWidth;
    int ySta = 50 - cellHeight;
    //NSMutableDictionary *buttonTable = [[NSMutableDictionary alloc] initWithCapacity:81];
    for (int i = 1; i < 10; i++) {
        xSta = xSta + cellWidth;
        for (int j = 1 ; j < 10; j++) {
            ySta = ySta + cellHeight;
            CGRect pos = CGRectMake(xSta, ySta, cellWidth, cellHeight);
            UIButton *b = [SudokuClass createSudokuButtonForView:self atPos:pos 
                                                           withTag:j*10+i forAction:@selector(numButtonPressed:)];
            NSString *picName = @"ButtonPic.jpg";
            [b setBackgroundImage:[[UIImage imageNamed:picName] stretchableImageWithLeftCapWidth:0 topCapHeight:0]  forState:0];
            [self.view addSubview:b];
            //[numButtons addObject:b];
        }
        ySta = 50 - cellHeight;
    }}
-(void)viewDidLoad
{

    [self createNumberButton];
    [super viewDidLoad];
}
@end

здесь класс sudoku - это мой класс nsobject с методом

+(UIButton *)createSudokuButtonForView:(UIViewController *)view atPos:(CGRect)position withTag:(int)tag forAction:(SEL)action {
UIButton *b = [UIButton buttonWithType:UIButtonTypeCustom];
[b setFrame:position];
[b.titleLabel setFont:[UIFont boldSystemFontOfSize:15]];
[b setTag:tag];
[b addTarget:view action:action forControlEvents:UIControlEventTouchDown];
[b setTitle:@"" forState:0];
[b setTitleColor:[UIColor blackColor] forState:0];
//b.layer.frame = CGRectMake(xSta-1, ySta-1, 31, 31);
//[b.layer setBorderWidth:borderWidth];


b.userInteractionEnabled = YES;
return b;}

надеюсь, кто-нибудь найдет это полезным ..:)

1 голос
/ 30 июня 2012

Я использую этот код (источник: этот блог) ВСЕ время. Это отличный «вход» в веселье и злоключения создания решеток. Я соединяю это с алгоритмом, который смотрит на количество «желаемых» объектов и доступный «кадр», и подскажет мне лучшее количество столбцов / строк. Думай по модулю .. int % int

- (void)awakeFromNib {
    self.wantsLayer = YES;
    CALayer *grid = self.layer;
    grid.backgroundColor = CGColorCreateGenericRGB(0.1, 0.1, 0.4, .8);
    grid.layoutManager = [CAConstraintLayoutManager layoutManager];   
    int rows = 8;    int columns = 8;
    for (int r = 0; r < rows; r++) {
        for (int c = 0; c < columns; c++) {
            CALayer *cell = [CALayer layer];
            cell.borderColor = CGColorCreateGenericGray(0.8, 0.8);
            cell.borderWidth = 1;  cell.cornerRadius = 4;
            cell.name = [NSString stringWithFormat:@"%u@%u", c, r];
            [cell addConstraint:
            [CAConstraint constraintWithAttribute: kCAConstraintWidth
                relativeTo: @"superlayer"
                attribute: kCAConstraintWidth
                scale: 1.0 / columns  offset: 0]];
            [cell addConstraint:
            [CAConstraint constraintWithAttribute: kCAConstraintHeight
                relativeTo: @"superlayer"
                attribute: kCAConstraintHeight
                scale: 1.0 / rows   offset: 0]];
            [cell addConstraint:
            [CAConstraint constraintWithAttribute: kCAConstraintMinX
                relativeTo: @"superlayer"
                attribute: kCAConstraintMaxX
                scale: c / (float)columns   offset: 0]];
            [cell addConstraint:
            [CAConstraint constraintWithAttribute: kCAConstraintMinY
                relativeTo: @"superlayer"
                attribute: kCAConstraintMaxY
                scale: r / (float)rows    offset: 0]];
        [grid addSublayer:cell];
}   }   }

enter image description here

1 голос
/ 20 ноября 2008

Раньше я дурачился с игрой в судоку и рисовал линии сетки и рисование чисел в одном виде. Не из-за ограничений памяти (использование одного элемента управления и многократно используемой памяти ячеек не должно вызывать беспокойства), а потому, что для определения местоположения сетки и чисел требуется всего лишь простая математика, и программирование представления будет быть проще на первый взгляд. Если позже вы начнете чувствовать себя перегруженным количеством кода и кода обработки событий в вашем классе представления, вы можете захотеть создать многократно используемый объект ячейки, который выполняет большую часть работы, аналогично UITableView.

Базовая анимация, безусловно, будет работать и здесь, если вам нужна анимация или нет. У доски Судоку, вероятно, не было бы большой анимации, но если вы это сделаете (возможно, скользящее поле выбора?), То это может быть лучшим выбором.

0 голосов
/ 20 ноября 2008

Где-то была статья о том, как внедрить решатель судоку. Я думаю, что он использовал такую ​​структуру данных:

  • сетка имеет 81 ячейку
  • ячейка имеет три членства в группах: один столбец, один ряд и одно поле
  • группа имеет 9 ячеек (ссылки)

Ячейка имеет еще несколько свойств, в зависимости от того, что вы хотите сделать со структурой:

  • значение
  • a hidden флаг (для игры)
  • набор возможных значений (для решателя)
0 голосов
/ 20 ноября 2008

Вы можете сделать это с помощью UIViews или CALayers в качестве подпредставлений основного суперпредставления. Вам понадобится как минимум 81 из них (по одному на каждое число в сетке судоку). Слои имеют меньший вес и менее ресурсоемкие, но представления имеют немного большую функциональность. То, что вы выберете, зависит от того, что вы пытаетесь сделать.

0 голосов
/ 20 ноября 2008

Сетка - это средство просмотра содержимого, а не хранения представления. В конечном счете, ваша сетка состоит из ячеек, которые имеют содержимое, и поэтому ваш базовый объект модели, возможно, лучше всего воплощается в ячейке. Существует несколько способов спроектировать базовое хранилище для игры Судоку, и более сложная задача, безусловно, будет заключаться в создании головоломок. Тем не менее, совет, который следует принять, заключается в том, чтобы не определять вашу модель на основе того, как она отображается на экране - слой представления полностью отделен, и поэтому делать что-то вроде хранения доски в виде двумерного массива было бы плохой идеей.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...