Iphone 从一个按钮滑到另一个按钮,无需抬起手指

Iphone 从一个按钮滑到另一个按钮,无需抬起手指,iphone,touchesmoved,sliding,Iphone,Touchesmoved,Sliding,我有两个按钮(按钮1和按钮2),如果我按下按钮1,注释1开始,如果我按下按钮2,注释2开始 所以我试着做的是:按下按钮1(note1开始),滑动到按钮2,然后note2开始。就像在中一样,你不用抬起手指就可以在钢琴键盘上滑动,所有音符都是从c音到h音 我用UIImageViews和UIButtons实现了这一点 如果我按c1pianoview,它听起来是一个“c”。如果我按d1pianoview它听起来是一个“d” 但是,如果我不抬起手指从c1pianoview滑动到d1pianoview时,它

我有两个按钮(按钮1和按钮2),如果我按下按钮1,注释1开始,如果我按下按钮2,注释2开始

所以我试着做的是:按下按钮1(note1开始),滑动到按钮2,然后note2开始。就像在中一样,你不用抬起手指就可以在钢琴键盘上滑动,所有音符都是从c音到h音

我用
UIImageViews
UIButtons
实现了这一点

如果我按c1pianoview,它听起来是一个“c”。如果我按
d1pianoview
它听起来是一个“d”

但是,如果我不抬起手指从
c1pianoview
滑动到
d1pianoview
时,它只会发出“c”的声音。我做错了什么?我是否也可以使用
ui按钮执行此操作

触地有效,但滑动无效

谁能帮帮我吗?这是我的代码:

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

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

如何防止这种情况发生?

您不需要:

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

通过使用UIButton的“触碰向下”和“触碰拖动内部”事件,您可能很容易实现这一点

如果要使用
-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];
}

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

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

下面的示例代码截取了
hitTest:withEvent:
中的触摸。然后,在toucks*方法中,它使用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

好吧,我是用TouchsMoved做的。。但现在每次我在图像视图中滑动时,音符都会发出声音。但我想让音符只响一次。我做错了什么?谢谢你的帮助@franhu-Dimitris打败我说itOk它和TouchDragInside不起作用。。。你能帮我触摸一下吗。。哪种食物容易腐烂?很抱歉,但它仍然不起作用。如果我在c1pianoview或d1pianoview中移动,每个小动作都会发出音符。所以,如果我从c1pianoview滑到d1pianoview,会听到大约10个c音和10个d音但我只想听一个c音和一个d音!你知道我为什么不工作吗?谢谢你的帮助!贪婪的马安。。。谢谢。。它起作用了。。我做错了。。是的,你太棒了。。太好了,谢谢!好的,滑动工作。但还有一个小问题。如果我点击c1按钮五次,它会发出五次“C”的声音,所以我用touchesbeent方法做了。这是可行的,但我知道另一个问题是,如果我点击c1按钮,然后在音符内滑动两次。我不知道你是否理解我的问题,但如果你能帮助我,谢谢你!格里齐在我的回答中又增加了一些方法。只要抬起手指,它们就会重置
lastButton
变量。看一看,回答得好。看起来不错,不过还没有测试。似乎没有其他关于Stackoverflow的答案是正确的,除了这一个。在
TouchsMoved
中发现了导致崩溃的错误。第二个
[(UIControl*)oldKey设置高亮显示:是]应为
[(UIControl*)视图集高亮显示:是]。除此之外,这似乎确实有效。