3

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.

vikingosegundo
  • 52,040
  • 14
  • 137
  • 178

4 Answers4

2

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.

bensnider
  • 3,742
  • 1
  • 24
  • 25
  • the problem is the I need the title and background image features that are in the UIButton, and I'm afraid I'll lose my hands and feet in a new class. –  Nov 25 '11 at 17:03
0

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.

Sam
  • 864
  • 7
  • 15
0

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
Cœur
  • 37,241
  • 25
  • 195
  • 267
vikingosegundo
  • 52,040
  • 14
  • 137
  • 178
  • Do you think that I will be able to create a piano-like app with the GestureRecognizer? My main actions are going to be dragging the touch, staying at one point(or with slight movments), and tracking if a finger is moving rapidly from side to side on the same view(or key), I don't think I'd have the access to all that with only the GestureRecognizer. Thanks! –  Nov 25 '11 at 17:17
  • Yes, that is possible. Also you can define custom Recognizers with similar amount of work as using custom views, but with less inheritance hassle resulting in cleaner code. – vikingosegundo Nov 25 '11 at 17:21
  • see http://developer.apple.com/library/ios/documentation/EventHandling/Conceptual/EventHandlingiPhoneOS/GestureRecognizers/GestureRecognizers.html#//apple_ref/doc/uid/TP40009541-CH6-SW2 for custom recognizers. Actually most of the work is done in method with same signatures as those touches… methods from UIResponder. – vikingosegundo Nov 25 '11 at 17:24
  • karen view? excuse me, I'm very new to all of this. –  Nov 25 '11 at 17:25
  • karen view? do u mean custom view? a custom UIView subclass. – vikingosegundo Nov 25 '11 at 17:27
  • I meant parent view. or superview. – vikingosegundo Nov 25 '11 at 17:30
0

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.

pronvit
  • 4,169
  • 1
  • 18
  • 27