无需松开手指即可从一个按钮滑动到另一个按钮

发布于 2024-08-20 17:22:09 字数 1493 浏览 5 评论 0原文

我有两个按钮(按钮 1 和按钮 2),如果我按按钮 1,则注释 1 启动,如果我按按钮 2,则注释 2 启动。

所以我尝试做的是:按下按钮一(note1 启动)并滑动到按钮2,然后 note2 应该启动。就像这样,您无需在钢琴键盘上抬起手指即可滑动,并且可以滑动从 c 到 h 的所有音符。

我用 UIImageViews 做到了这一点,我也用 UIButtons 做到了这一点。

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

但是,如果我在没有抬起手指的情况下从 c1pianoview 滑动到 d1pianoview,它只会发出“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。一个黑色钢琴键位于两个白色钢琴键之上。如果我按下黑键,它下面的白键也会发出音符。

我该如何防止这种情况?

I have two buttons (Button 1 and button 2) and if I press button 1, note1 starts and if i press button 2, note 2 starts.

So what I try to do is: press button one (note1 starts) and SLIDE to button2 and than should note2 start. As in, you slide without lifting your finger over a piano keyboard and all notes from c to h sound.

I did this with UIImageViews and I did it also with UIButtons.

If i press the c1pianoview it sounds a "c". If I press the d1pianoview it sounds a "d".

But if I slide without lifting my finger from c1pianoview to d1pianoview it only sounds a "c". What did I wrong? Can I also do this with UIButtons?

Touch down works but sliding doesn't work.

Can somebody help me, please? Here my code:

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

Update:

I have a further question. Now I have two UIImageVIews on each other. A black piano key over two white piano keys. If I press on the black key it also sound the note from the white key under it.

How do I prevent this?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

墨落画卷 2024-08-27 17:22:10

你不需要:

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

Don't you need the:

- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
三人与歌 2024-08-27 17:22:10

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

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

更详细地说:

在标头中声明一个 UIView *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];
}

You can probably achieve this easily by using the "Touch Down" and "Touch Drag Inside" events of the UIButton.

If you want to use the -touchesMoved: approach, you can use a variable to keep track of the last button that triggered a sound and only play a sound if the current button is not the one that last played a sound.

In more detail:

Declare a UIView *lastButton; in your header and then:

-(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];
}
内心旳酸楚 2024-08-27 17:22:09

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

下面的示例代码拦截 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

I think a simpler solution is to create a superview that intercepts all the touches and decides what to do. Then in IB, you make your view an instance of PianoView, and make all the keys subviews. Each key would have a tag that identifies which key it is, so PianoView knows what note to play. PianoView has a currentView property which keeps track of the last view in touchesMoved so it doesn't keep trying to play the same key. I have a keyboard with similar but different requirements, and this approach works well.

The sample code below intercepts touches in hitTest:withEvent:. Then, in the touches* methods, it uses UIView's default implementation of hitTest:withEvent: to determine which key is being played. You'll have to modify it a bit if you want to support playing keys simultaneously with multi-touch.

@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
离笑几人歌 2024-08-27 17:22:09

[将进一步的问题合并到原始帖子中]

[Merged further question into original post]

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文