检测节点是不是被任何手指触摸

Posted

技术标签:

【中文标题】检测节点是不是被任何手指触摸【英文标题】:Detect if node is being touched by any finger检测节点是否被任何手指触摸 【发布时间】:2015-02-19 23:17:32 【问题描述】:

所以我想在我的应用程序中调用一个方法,只要有一个 touchesEnd 并且节点 buttonX 没有被触摸。本来我只是打算用这段代码:

- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event    
    NSArray *touchesArray = [touches allObjects];
    UITouch *touch = (UITouch *)[touchesArray objectAtIndex:0];

    CGPoint pointTouched = [touch locationInNode:self];
    SKNode *nodeAtTouchPoint = [self nodeAtPoint:pointTouched];

    if ([nodeAtPointTouched.name isEqualToString:buttonX.name]) 
        // Call the method I want to call
    

问题在于,仅检测“当前手指”的touchesEnded 和“当前手指”是否未接触buttonX。如果fingerA 触摸按钮,然后fingerB touchesStartedtouchesEnded(屏幕上的任何其他位置),即使fingerA 仍在触摸buttonX,我想调用的方法也会被调用。

我真正的问题:如何在 touchesEnded 上为最初按下 buttonX 的手指调用我的方法,但在其他地方为手指调用 touchesEnded 时不调用该方法?

编辑:如果我可以创建一个 BOOL 方法来返回节点是否被触摸,并且它在对象中的“任何地方”都可以工作(不需要来自 touchesBegantouchesEnd 的数据),我想这将帮助我解决问题。

【问题讨论】:

你的问题让我想起了数学课。如果所有 Gimp 都是 Gomp,但只有一些 Gomp 是 Gimp……您已经检查了节点的名称以进行触摸,因此您拥有正确的代码。你到底遇到了什么问题? 现在我已经设置为在 buttonX 上启动操作 touchesBegin,然后在 buttonX 上 touchesEnd 时停止操作。任何触摸都会调用touchesEnd。问题是,如果 buttonX 上的 fingerA touchesBegin,然后是其他地方的 fingerB touchesEnd(有或没有第一个 touchesBegin),即使在 buttonX 上的 fingerA 没有 touchesEnd,它也会调用停止动作。我希望在 fingerA 按下 buttonX 时开始动作,并且仅在 fingerA 不再触摸 buttonX 时停止动作(通过touchesMovedtouchesEnd),而不管其他手指同时做什么。 【参考方案1】:

不要使用 -nodeAtPoint:,而是尝试使用 -containsPoint:

if ([buttonX containtsPoint:pointTouched]) 
    // Code here

【讨论】:

这不是问题的答案,这只是一种更有效的方法来检测是否点击了节点。 @Johny973 它应该可以解决代码存在的问题。 if 语句的内部在 touchesEnded 被调用时发生,但前提是所讨论的触摸在 buttonX 的框架内 - 它会忽略其他触摸。【参考方案2】:

您需要跟踪按钮内的手指。每次从touchesBegantouchesEnded 都会为每个手指返回一个唯一的对象。所以跟踪它非常简单。

首先初始化buttonXuserData

buttonX.userData = [[NSMutableDictionary alloc] init];

然后使用以下touchesBegan and touchesMoved 函数。

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

    NSArray *touchesArray = [touches allObjects];
    for (UITouch *touch in touchesArray)
    
        CGPoint pointTouched = [touch locationInNode:self];
        SKNode *nodeAtTouchPoint = [self nodeAtPoint:pointTouched];

        if ([nodeAtTouchPoint.name isEqualToString:buttonX.name]) 
            buttonX.userData[@"touchPoint"] = touch;
        
    


- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event 
    NSArray *touchesArray = [touches allObjects];
    for (UITouch *touch in touchesArray)
    

        CGPoint pointTouched = [touch locationInNode:self];
        SKNode *nodeAtTouchPoint = [self nodeAtPoint:pointTouched];

        if (buttonX.userData[@"touchPoint"] == touch)
        
            if ([buttonX.name isEqualToString:nodeAtTouchPoint.name])
            
                NSLog(@"clicked");
            
            [buttonX.userData removeObjectForKey:@"touchPoint"];
        
    


【讨论】:

【参考方案3】:

我可以通过两种方式了解您的情况。

第一个无需对代码进行太多更改的方法是在您的类中创建一个属性。

@property (nonatomic, strong)UITouch *buttonTouch;

并在您像示例一样遍历所有触摸时跟踪它

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

    for (UITouch *touch in [touches allObjects])
    
        CGPoint pointTouched = [touch locationInNode:self];
        SKNode *nodeAtTouchPoint = [self nodeAtPoint:pointTouched];

        if ([nodeAtTouchPoint.name isEqualToString:buttonX.name] && !self.buttonTouch)
        
            self.buttonTouch = touch;
        
    


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

    for (UITouch *touch in [touches allObjects])
    
        CGPoint pointTouched = [touch locationInNode:self];
        SKNode *nodeAtTouchPoint = [self nodeAtPoint:pointTouched];

        if ([nodeAtTouchPoint.name isEqualToString:buttonX.name] && touch == self.buttonTouch)
        
            self.buttonTouch = nil;
            // Call the method I want to call
        
    

另一个选项更复杂一点是为您的按钮子类化 SKSpriteNode 并在其中处理触摸并使用委托。这就是我在项目中处理按钮的方式。

编辑

我将我的 ButtonSprite 类添加到 GitHub,以防您发现它有用。

https://github.com/Urthstripe29/ButtonSprite

【讨论】:

以上是关于检测节点是不是被任何手指触摸的主要内容,如果未能解决你的问题,请参考以下文章

目标c:从视图/图像/按钮外部开始触摸时检测触摸开始/向下

苹果手机。在一个手指触摸屏幕时检测另一个手指触摸

检测 Sprite Kit 中的长触摸

检测 SpriteKit 中节点特定区域的触摸

颤动悬停式触摸处理 - 无需抬起手指即可检测来自不同小部件的触摸

Godot:检测按下的鼠标是不是在按钮上方