Проблемы с прикосновением к полу-фортепианному приложению с UIButtons

Я работаю над приложением для полуфортепиано с раскладкой клавиатуры, отличной от обычной.

Я создал представление вручную с помощью UIButtons. Моя проблема заключалась в том, что я не знал, как перейти от UIButton к другому, я понял это с помощью addTarget с опцией withEvent, которая дала мне доступ к прикосновениям.

Теперь, после того как я добавил цель следующим образом:

[C addTarget:self action:@selector(outsideOfKey: forEvent:) forControlEvents:UIControlEventTouchDragOutside|UIControlEventTouchDragInside];
[C addTarget:self action:@selector(keyGetsLeft: forEvent:) forControlEvents:UIControlEventTouchUpOutside | UIControlEventTouchUpInside];

(также для всех остальных ключей),

Мне удалось сделать их скользящими,

outsideOfKey:forEvent: выглядит следующим образом:

-(void) outsideOfKey:(id)sender forEvent:(UIEvent *)event
{    
    for(UITouch *t in [event allTouches])
    {

            CGPoint touchPoint = [t locationInView:window];
            if(CGRectContainsPoint(C.frame, touchPoint))
             {
                 C.highlighted = YES;
             }
            else{
                C.highlighted = NO;
            }

(Сделано и для всех остальных клавиш) Я могу перемещаться между другими клавишами и в них, и когда я оставляю их в keyGetsLeft:forEvent: я только что использовал тот же синтаксис без else, и выделенное стало НЕТ.

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

И даже больше, если я уберу один из пальцев, все они становятся невыделенными, я знаю причины всего этого, но я не знаю, как это исправить и заставить это работать.


person Community    schedule 25.11.2011    source источник


Ответы (4)


Боюсь, bensnider прав. Но я бы реализовал это через GestureRecognizer:

Каждая клавиша имеет один TapRecognizer, а родительское представление имеет SwipeRecognizer для обнаружения слайдов от одной клавиши к другой.

Очень полезно, в Apple Developer Video Archiveтребуется вход с учетной записью разработчика:

  • WWDC2010: Сессия 120 — Упрощение обработки сенсорных событий с помощью распознавателей жестов
  • WWDC2010: Сессия 121 — Расширенное распознавание жестов
person vikingosegundo    schedule 25.11.2011
comment
Как вы думаете, смогу ли я создать приложение, похожее на фортепиано, с помощью GestureRecognizer? Моими основными действиями будут перетаскивание прикосновения, пребывание в одной точке (или с небольшими движениями) и отслеживание того, быстро ли перемещается палец из стороны в сторону на одном и том же виде (или клавише), я не думаю, что я' d иметь доступ ко всему этому только с помощью GestureRecognizer. Спасибо! - person ; 25.11.2011
comment
Да, это возможно. Также вы можете определить пользовательские распознаватели с тем же объемом работы, что и при использовании пользовательских представлений, но с меньшими проблемами наследования, что приводит к более чистому коду. - person vikingosegundo; 25.11.2011
comment
см. developer.apple.com/library/ios/documentation/EventHandling/ для пользовательских распознавателей. На самом деле большая часть работы выполняется в методе с теми же сигнатурами, что и эти штрихи… методы из UIResponder. - person vikingosegundo; 25.11.2011
comment
Карен Вью? извините меня, я очень новичок во всем этом. - person ; 25.11.2011
comment
Карен Вью? вы имеете в виду пользовательский вид? пользовательский подкласс UIView. - person vikingosegundo; 25.11.2011
comment
Я имел в виду родительский взгляд. или супервью. - person vikingosegundo; 25.11.2011

Я бы, вероятно, вообще отказался от UIButtons и реализовал свой собственный код отслеживания касаний. См. Обработка событий мультитач в документы А именно, вы будете реализовывать следующие методы:

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event;
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event;
- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event;
- (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event

Я бы, вероятно, просто реализовал области попадания, которые вы могли бы настроить в IB, возможно, с пользовательским сенсорным наложением UIView (просто UIView с настраиваемым подклассом). Это позволит вам настроить представление в IB с изображениями, заголовками и т. д., но выполнять все отслеживание касаний в своем пользовательском подклассе.

person bensnider    schedule 25.11.2011
comment
проблема в том, что мне нужны функции заголовка и фонового изображения, которые есть в UIButton, и я боюсь потерять руки и ноги в новом классе. - person ; 25.11.2011

Я бы использовал одно представление для всех кнопок и вручную реализовал отслеживание касаний, как сказал Беннидер. Ручное рисование фона/титров также не так сложно.

person pronvit    schedule 25.11.2011

Вот ссылка на приложение для пианино с открытым исходным кодом для iOS, которое я сделал https://github.com/meech-ward/iOSPiano

Я использовал CALayers для клавиш пианино и использовал - (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event; - (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event;

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

person Sam    schedule 10.12.2014