Как я могу «поймать» подпредставление во время жеста смахивания на устройстве iOS? - PullRequest
1 голос
/ 13 декабря 2010

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

У меня есть две идеи, как я могу это исправить ...

  1. Если плитка не трогается, когда пользователь касается экрана, я могу использовать местоположение касания родительского вида, чтобы найти ближайшую плитку к месту касания и каким-то образом перенаправить событие касания в вид этой плитки.
  2. Если при прикосновении к экрану к плитке не прикасается, я могу каким-то образом «поймать» плитку, когда пользователь проводит пальцем по ней, пытаясь переместить ее.

Я бы предпочел реализовать решение № 2, поскольку решение № 1 имеет слишком много проблем, не говоря уже о том, что решение № 2 является более реалистичным. Тем не менее, как я могу «поймать» плитку, когда пользователь проводит пальцем по ней, и отправлять события касания, чтобы переместить ее туда, где находится палец?

В настоящее время мои плитки реализованы как подклассы UIView, и они обрабатывают события касания (touchesBegain, touchesMoved и touchesEnded) напрямую. Поэтому, если пользователь почти не касается внешнего вида и проводит пальцем по виду, он не получает никаких событий касания, поскольку не получил первоначальное событие touchesBegan.

Заранее благодарим за всю вашу мудрость!

Ответы [ 2 ]

4 голосов
/ 13 декабря 2010

Может быть, вы должны иметь представление "доска" обрабатывать все перетаскивания.Когда начинается касание и в этой точке появляется плитка, начинайте ее перетаскивать.В противном случае проверяйте всякий раз, когда касание перемещается, и как только вы найдете плитку, начинайте ее перетаскивать.

Вы можете переопределить hitTest:withEvent: в виде доски, чтобы он все еще мог определять, когда касание касается плитки, новсегда возвращайте себя, чтобы сенсорные события переходили в представление доски (например, запишите подпредставление, которое было обработано в отдельной переменной-члене, чтобы вы знали, что нужно перетаскивать позже, когда сенсорные события начинают поступать).

Подробнее

При обработке касаний UIView будет использовать hitTest, чтобы найти представление, которое должно получать события касания.Реализация по умолчанию проверяет каждое подпредставление, так что самое глубокое подпредставление в иерархии получает прикосновения.Чтобы представление на доске получало прикосновения, вам нужно отключить userInteraction на всех видах плиток.Но это означает, что вы не можете использовать hitTest, чтобы найти плитку, к которой прикоснулись, так как она игнорирует представления, у которых отключено userInteraction.

Так что я говорю, что оставьте userInteraction включенным на сенсорных представлениях.Но переопределите hitTest в представлении доски так, чтобы он сначала вызывал супер реализацию, чтобы найти плитку (если результат self, сама доска была поражена).Не нужно реализовывать свой собственный поиск плитки.Примерно так:

- (UIView*)hitTest:(CGPoint)point withEvent:(UIEvent*)event
{
  UIView *hitView = [super hitTest:point withEvent:event];
  if ( hitView != self )
    self.draggingTile = hitView;
  return self;
}

Теперь вы знаете, какую плитку перемещать в touchesMoved.Однако я не думаю, что hitTest вызывается при перемещении касания, поэтому, если плитка еще не была подобрана, вам, возможно, придется вызывать ее вручную (вы можете получить point и event от касания, переданногоtouchesMoved.

1 голос
/ 13 декабря 2010

Вы смотрели на UIGestureRecognizer API ?Я думаю, что вашим лучшим вариантом будет добавить распознаватель UIPanGestureRecognizer к представлению вашей доски, который затем запустит селектор в ваш UIViewController.

Настройка в ViewDidLoad:

UIPanGestureRecognizer *panGestureRecognizer = [[UIPanGestureRecognizer alloc]
                                                      initWithTarget:self action:@selector(handlePan:)];

[[self view] addGestureRecognizer:panGestureRecognizer];

А затем реализовалселектор:

    - (void)handlePan:(UIPanGestureRecognizer *)gestureRecognizer{
          CGPoint currentPoint = [gesture locationInView:[self view]];
    }

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

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