2

我有两个按钮(按钮 1 和按钮 2),如果我按下按钮 1,note1 启动,如果我按下按钮 2,note 2 启动。

所以我尝试做的是:按下按钮一(note1 启动)并滑动到按钮 2,然后 note2 应该启动。就像在钢琴键盘上滑动而不用抬起手指一样,从 c 到 h 的所有音符都发声。

我这样做了UIImageViews,我也这样做了UIButtons

如果我按下c1pianoview它会发出“c”的声音。如果我按下d1pianoview它会发出“d”的声音。

但是,如果我在没有抬起手指的情况下滑动c1pianoviewd1pianoview只会发出“c”的声音。我做错了什么?我也可以这样做UIButtons吗?

着陆有效,但滑动不起作用。

有人可以帮我吗?这是我的代码:

-(void)touchesBeganNSSet *)touches withEventUIEvent *)event
{
    UITouch *touch = [[event allTouches] anyObject];
    CGPoint location = [touch locationInView:touch.view];

    if(CGRectContainsPoint(c1pianoview.frame, location))
    { 
      NSString *path = [[NSBundle mainBundle]
      pathForResource: @"c1piano" ofType:@"mp3"];
      AVAudioPlayer* theAudio = [[AVAudioPlayer alloc] 
          initWithContentsOfURL:[NSURL fileURLWithPathath] error:NULL];
      [theAudio play];
    }

    if(CGRectContainsPoint(d1pianoview.frame, location))
    { 
      NSString *path = [[NSBundle mainBundle]
      pathForResource: @"d1piano" ofType:@"mp3"];
      AVAudioPlayer* theAudio=[[AVAudioPlayer alloc] 
          initWithContentsOfURL: [NSURL fileURLWithPathath] error:NULL];
      [theAudio play];
    }
}

更新:

我还有一个问题。现在我有两个UIImageVIews彼此。两个白色钢琴键上的黑色钢琴键。如果我按下黑键,它也会从它下面的白键发出音符。

我该如何防止这种情况?

4

4 回答 4

5

我认为一个更简单的解决方案是创建一个超级视图来拦截所有的触摸并决定做什么。然后在 IB 中,您将视图设为 PianoView 的实例,并将所有键子视图设为子视图。每个键都有一个标签来标识它是哪个键,因此 PianoView 知道要演奏什么音符。PianoView 有一个 currentView 属性,它跟踪 touchesMoved 中的最后一个视图,因此它不会一直尝试播放相同的键。我有一个具有相似但不同要求的键盘,这种方法效果很好。

下面的示例代码拦截了hitTest:withEvent:. 然后,在 touches* 方法中,它使用 UIView 的默认实现hitTest:withEvent:来确定正在播放的键。如果您想支持多点触控同时播放按键,则必须对其进行一些修改。

@implementation PianoView

-(UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event {
    // intercept touches
    if ([self pointInside:point withEvent:event]) {
        return self;        
    }
    return nil;
}

-(void) touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
    UIView* view = [super hitTest: [[touches anyObject] locationInView: self] withEvent: nil];
    // highlight subview under touch
    if (view != nil && view != self) {
        if ([view isKindOfClass:[UIButton class]]) {
            [(UIControl *)view setHighlighted:YES];
        }
        [self setCurrentView:view];
        [self playKey:view];
    }
}

-(void) touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event {
    // un-highlight everything
    for (UIView *subview in [self subviews]) {
        if ([subview isKindOfClass:[UIButton class]]) {
            [(UIControl *)subview setHighlighted:NO];
        }
    }
    [self stopPlaying];
    [self setCurrentView:nil];
}

-(void) touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {
    UIView* view = [super hitTest: [[touches anyObject] locationInView: self] withEvent: nil];
    if (view != [self currentView]) {
        UIView *oldKey = [self currentView];
        // un-highlight
        if ([oldKey isKindOfClass:[UIButton class]]) {
            [(UIControl *)oldKey setHighlighted:NO];
        }    
        if ([view isKindOfClass:[UIButton class]]) {
            [(UIControl *)view setHighlighted:YES];
        }    
        [self stopPlaying];
        [self playKey:view];
        [self setCurrentView:view];
    }
}

-(void) touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {
    UIView* view = [super hitTest: [[touches anyObject] locationInView: self] withEvent: nil];
    for (UIView *subview in [self subviews]) {
        if ([subview isKindOfClass:[UIButton class]]) {
            [(UIControl *)subview setHighlighted:NO];
        }
    }
    [self stopPlaying];
    [self setCurrentView:nil];
}

@end
于 2011-04-07T19:45:24.107 回答
1

[Merged further question into original post]

于 2010-02-07T22:15:36.310 回答
0

你不需要:

- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
于 2010-02-07T12:25:10.417 回答
0

您可以通过使用 UIButton 的“Touch Down”和“Touch Drag Inside”事件轻松实现这一点。

如果要使用该-touchesMoved:方法,可以使用变量来跟踪触发声音的最后一个按钮,并且仅在当前按钮不是最后播放声音的按钮时才播放声音。

更详细地说:

在标题中声明 aUIView *lastButton;然后:

-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
UITouch *touch = [[event allTouches] anyObject];
CGPoint location = [touch locationInView:touch.view];

if(CGRectContainsPoint(c1pianoview.frame, location) && lastButton != c1pianoview) {
    //play c1
    lastButton = c1pianoview;
}
else if(CGRectContainsPoint(d1pianoview.frame, location) && lastButton != d1pianoview) {
    //play d1
    lastButton = d1pianoview;
}
}

- (void)touchedEnded:(NSSet *)touches withEvent:(UIEvent *)event {
    lastButton = nil;
}

- (void)touchedCancelled:(NSSet *)touches withEvent:(UIEvent *)event {
    [self touchesEnded:touches withEvent:event];
}
于 2010-02-07T13:04:24.850 回答