Semi-piano app touch troubles with UIButtons

563 Views Asked by At

I am working on a semi-piano app with a diffrent keyboard-layout then a usual one.

I created the view manually with UIButtons, My problem was I that I didn't know how to slide from a UIButton to another, I figured that out with addTarget with the option of withEvent, which gave me the access to the touches.

Now, after I added the target like this:

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

(also for all of the other keys),

I maneged to make them slideable,

outsideOfKey:forEvent: is as follows:

-(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;
            }

(Done for all the other keys as well) I can slide from and into other keys, and when I leave them in keyGetsLeft:forEvent: I have just used the same syntx without the else, and the highlighted became NO.

Up to here it's easy, But then when I try to do multi-touch, I can slide only one of the touches all around and the others must stay in the same position.

And even more, If I take one of the fingers away all of them are becoming non-highlighted, I know the reasons to all of that, but I don't know how to fix it and make it to work.

4

There are 4 best solutions below

6
On BEST ANSWER

I am afraid, bensnider is right. But I'd implement it via GestureRecognizer:

Each key has one TapRecognizer, while a parent view has a SwipeRecognizer to detect slides form one key to another.

Very useful, on Apple Developer Video Archivelogin with development account required:

  • WWDC2010: Session 120 — Simplifying Touch Event Handling with Gesture Recognizers
  • WWDC2010: Session 121 — Advanced Gesture Recognition
0
On

Heres a link to an open source iOS piano app I made https://github.com/meech-ward/iOSPiano

I used CALayers for the piano keys and I used - (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event; - (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event;

to detect if the user is currently touching a piano key. It works really well even with multiple touches.

1
On

I would probably move away from UIButtons altogether and implement my own custom touch tracking code. See Handling Multitouch Events in the docs. Namely, you will be implementing the following methods:

- (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

I would probably just implement hit areas, which you could setup in IB, with perhaps a custom UIView touch overlay (just a UIView with a custom subclass). This would let you setup the view in IB with images, titles, etc., but do all of your touch tracking in your custom subclass.

0
On

I'd use one view for all buttons and manually implement touch tracking as bensnider said. Manually drawing backgrounds/titles also is not so difficult.