Можно ли решить, к какому виду будет привязан UITouch?

У меня есть несколько UIView, которые имеют несколько сложные формы, которые я нарисовал с помощью каждого метода drawRect :. Я сохранил ссылку на путь (через свойство CGPath) и использую ее в своих методах касаний, чтобы определить, действительно ли касание находится внутри контура или формы (CGPathContainsPoint). Из-за форм есть области представления, которые являются прозрачными (очевидно, все, что не является квадратным / прямоугольным, будет иметь области прозрачности, если для свойства backgroundColor представления установлено значение clearColor или что-то подобное).

Для ситуаций (которые случаются часто), когда представления оказываются сверху или перекрывают друг друга, я тестирую методы касаний (touchesBegan и т. Д.), Чтобы увидеть, действительно ли касание находится в пределах CGPath или формы. Если касание выходит за пределы формы, я перенаправляю касание на следующий вид внизу, чтобы проверить, соответствует ли оно, в свою очередь, этому требованию.

К сожалению (и к моему большому разочарованию), это не ведет себя так же, как прикосновение, фактически привязанное к виду. Я работал над этой проблемой всеми способами, кроме одного, в частности. Каждое представление использует UIRotationGestureRecognizer. Но если прикосновение происходит в прозрачной области другого представления, и это представление пересылает это касание на представление под ним, UIGestureRecognizer никогда не запускается.

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

Интересно, можете ли вы сделать что-то таким образом, создав подкласс UIApplication или UIWindow и переопределив метод sendEvent: ". Я не совсем уверен, какой контроль Apple может дать вам в этом. Я не могу позволить себе делать что-либо, что могло бы иметь доступ к частным API. Мне просто нужен способ переназначить прикосновение, чтобы представление считало, что прикосновение принадлежит ему.

Любые идеи?'


person daveMac    schedule 11.05.2012    source источник


Ответы (1)


Вы можете сделать это, создав подкласс UIView или подкласс UIGestureRecognizer.

Создание подкласса UIView

Создав подкласс UIView (или любой из его подклассов) и переопределив

- (BOOL)pointInside:(CGPoint)point withEvent:(UIEvent *)event

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

Создание подкласса UIGestureRecognizer

Создав подкласс UIGestureRecognizer (или любой из его подклассов) и переопределив

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event

вы можете решить, какие прикосновения распознает распознаватель жестов. Для всех касаний вне пути вы должны вызывать (но не подкласс)

- (void)ignoreTouch:(UITouch *)touch forEvent:(UIEvent *)event

на себя.


Точка внутри пути?

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

Если пути уже сохранены как UIBezierPaths, вы можете просто вызвать

- (BOOL)containsPoint:(CGPoint)point

По пути Безье. Точку или касание может потребоваться преобразовать в те же координаты вида, что и путь, вызвав

- (CGPoint)convertPoint:(CGPoint)point toView:(UIView *)view

or

- (CGPoint)convertPoint:(CGPoint)point fromView:(UIView *)view

На ваш взгляд.

Если путь хранится как CGPath, вы можете создать из него UIBezierPath, используя

[UIBezierPath bezierPathWithCGPath:CGPath]; 
person David Rönnqvist    schedule 11.05.2012
comment
Хотя это не полностью ответило на вопрос, но поставило меня на верный путь. Изучив его еще немного, я нашел это сообщение в блоге, которое полностью отвечает на вопрос: bynomial.com/blog /? p = 74 Я принял ответ, потому что это было хорошее усилие и помогло мне понять, что мне нужно знать. - person daveMac; 15.05.2012
comment
Есть кое-что, что я могу уточнить? - person David Rönnqvist; 15.05.2012
comment
Поскольку каждое представление перехватывает касания путем переопределения методов касаний (touchesBegan, move и т. Д.), Событие - (BOOL) pointInside: (CGPoint) point withEvent: (UIEvent *) никогда не вызывалось, если я не касался за пределами представления. Но, перейдя по ссылке, которую я предоставил выше, я смог переопределить метод hitTest: базового подпредставления, а затем использовать pointInside:, чтобы определить, было ли это действительным касанием. Кроме того, хотя я уверен, что вы имели в виду, что точка внутри пути? в разделе, это не имело значения, поскольку я заявил, что уже делаю это. Хотя еще раз спасибо - person daveMac; 15.05.2012