2010-12-13 2 views
1

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

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

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

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

В настоящее время мои плитки реализованы в виде подклассов UIView, и они обрабатывают события касания (касаютсяBegain, touchhesMoved и touchesEnded) напрямую. Так что, если пользователь касается едва только за пределами представления и перетаскивает свой палец над представлением, он не получает никаких событий касания, так как он не получил начальное событие touchsBegan.

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

ответ

4

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

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

Подробнее

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

Так что я говорю, это разрешение на включение пользователя на сенсорных экранах. Но переопределите 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 вызывается, когда сенсорный движок перемещается, поэтому, если еще не было выбрано ни одной плитки, вам, возможно, придется называть это вручную (вы можете получить и event с касанием, переданным до touchesMoved.

?
+0

спасибо, Брайан, это звучит как правильный подход здесь. быстрый вопрос, если я переопределяю метод hitTest в виде доски, что именно я хочу делать внутри него? Я хочу, чтобы цикл через все плитки и проверить, попадает ли точка хита на любую из плиток? если да, то в чем смысл переопределять метод hitTest, почему бы мне просто не проверить это в методах события касания платы (т. е. коснутьсяBegan, touchhesMoved и т. д.)? – BeachRunnerFred

+0

Обновленный ответ с более подробной информацией – Brian

+0

спасибо, Брайан, который помогает много. Я сделаю это! Кроме того, поскольку мой вид платы содержит другие типы просмотров, а не только фрагменты, я предполагаю, что мне нужно будет проверить тип объекта, который возвращается из вызова в [super hitTest], и убедиться, что это вид плитки. должен ли я использовать [hitView isKindOfClass: [TileView class]] для этого? – BeachRunnerFred

1

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

установки в ViewDidLoad:.

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

[[self view] addGestureRecognizer:panGestureRecognizer]; 

И затем реализовано t он селектор:

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

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

+0

спасибо, cesarislaw. вопрос, кажется, что ваше решение состоит в том, чтобы: 1) обнаружить жест панорамы и 2) получить свое текущее местоположение, чтобы я мог делать все, что захочу, но так ли? Если нет, я извиняюсь, я все еще относительно новичок в iOS. Если да, почему бы просто не использовать метод touchsMoved для получения этой информации? еще раз спасибо! – BeachRunnerFred

+0

Я обнаружил, что жест сделал больше контроля над обратной связью и сделал для меня много работы на низком уровне, позволяя мне сосредоточиться на логике приложения вместо обнаружения касания (это кран или кастрюля?). Мое приложение было чертежом приложение, которое должно проверять, что пользователь перемещается из одной области в другую в определенном порядке. Жесты новы с iOS4, поэтому, если вам требуется 3,2 или более поздняя совместимость, то это единственный вариант. – cesarislaw

+0

Также я смутно помню, как сталкивался с некоторыми проблемами, которые касаются событий, которые иногда перехватываются другими представлениями и не передаются (UIScrollView, о котором я хочу сказать, был особенно плох об этом). – cesarislaw

Смежные вопросы