iOS Swift 4 Экран игровой салфетки - PullRequest
0 голосов
/ 07 марта 2019

Я создаю приложение, чтобы пользователю приходилось смахивать все поля с экрана.Цель состоит в том, чтобы сильно ударить все ящики, пока все ящики не будут считаны, как показано ниже.

Example that is made with buttons and UIStackView Поэтому мой вопрос:

  1. Лучше лисоздавать поля с использованием стека или точнее рисовать вручную по координатам на экране?
  2. Как определить, прошел ли пользователь по полям (используя UIGestureRecognizer)?

Примечание. Когда пользовательпроведя пальцами по коробкам, салфетки превратятся в другой цвет.

1 Ответ

0 голосов
/ 07 марта 2019

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

Распознаватель жестов должен быть довольно простым.Вы просто добавляете его в суперпредставление этих ячеек и проверяете местоположение, когда оно перемещается или когда оно начинается.Жест панорамирования кажется наиболее подходящим, но он не обнаружит, если пользователь просто нажимает на экран.Это может быть функция, но если вы хотите обрабатывать все касания, вы должны либо использовать длинный жест нажатия с нулевой продолжительностью нажатия (это не имеет особого смысла, я знаю, но это работает), либо вы можете просто переопределить методы касания:

override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
    if let touch = touches.first {
        handleDrag(at: touch.location(in: viewWhereAllMiniViewsAre))
    }
}
override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?) {
    if let touch = touches.first {
        handleDrag(at: touch.location(in: viewWhereAllMiniViewsAre))
    }
}

func handleDrag(at location: CGPoint) {
    // TODO: handle the nodes
}

Процедура распознавания жестов будет выглядеть примерно так:

func onDrag(_ sender: UIGestureRecognizer) {
    switch sender.state {
    case .began, .changed, .ended, .cancelled: handleDrag(at: sender.location(in: viewWhereAllMiniViewsAre))
    case .possible, .failed: break
    }
}

Теперь все, что вам нужно, это ваш источник данных.Массив всех ваших предметов должно быть достаточно.Как:

static let rows: Int = 10
static let columns: Int =  10

var nodes: [Node] = {
    return Array<Node>(repeating: Node(), count: LoginViewController.rows * LoginViewController.columns)
}()

И список всех ваших мини-представлений:

var nodeViews: [UIView] = { ... position them or get them from stack view or from collection view }

Теперь реализация на сенсорной ручке:

func handleDrag(at location: CGPoint) {
    nodeViews.enumerated().forEach { index, view in
        if view.frame.contains(location) {
            view.backgroundColor = UIColor.green
            nodes[index].selected = true
        }
    }
}

Это всего лишьпример.Легкий и довольно плохой с точки зрения обслуживания, по крайней мере.В общем, я бы предпочел иметь представление узла пользовательского подкласса UIView со ссылкой на узел.Кроме того, он должен подключиться с использованием делегата к экземпляру Node, чтобы узел сообщал об изменении состояния выбора.

Таким образом, при обработке касаний у вас есть более чистое решение:

func handleDrag(at location: CGPoint) {
    nodeViews.first(where: { $0.frame.contains(location) }).node.selected = true
}

Проверкаесли все зеленые, то просто

var allGreen: Bool {
    return !nodes.contains(where: { $0.selected == false })
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...