按钮的 UITapGestureRecognizer 问题

Posted

技术标签:

【中文标题】按钮的 UITapGestureRecognizer 问题【英文标题】:issue with UITapGestureRecognizer for a button 【发布时间】:2011-11-08 13:20:39 【问题描述】:

我做了以下事情:

 buttonPlaylistView = [[UIButton alloc] initWithFrame:CGRectMake(self.view.frame.size.width *(urlList.count+1), 0, self.view.frame.size.width, self.view.frame.size.height)];
            buttonPlaylistView.tag = 0;

 UITapGestureRecognizer *doubleTap3 = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(handleDoubleTap:)];
            [doubleTap3 setNumberOfTapsRequired:2];
            [buttonPlaylistView addGestureRecognizer:doubleTap3];
            [doubleTap3 release];

-(void) handleDoubleTap:(UITapGestureRecognizer *)sender
    if(sender.state == UIGestureRecognizerStateEnded)

    int x = [sender tag];
    return;

但我在这一行得到SIGAGRTint x = [sender tag]; 说:

[UITapGestureRecognizer tag]: unrecognized selector sent to instance 0x61280b0
*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[UITapGestureRecognizer tag]: unrecognized selector sent to instance 0x61280b0'

现在:这是什么问题以及解决方案是什么?谢谢

【问题讨论】:

【参考方案1】:
-(void) handleDoubleTap:(UITapGestureRecognizer *)sender

    if(sender.state == UIGestureRecognizerStateEnded)
    
      int x = [sender.view tag];
    

将解决问题。

【讨论】:

【参考方案2】:

UITapGestureRecognizer 没有名为 tag 的属性 - 如您所见,您获得的发送者是 NOT 按钮。您必须直接访问 buttonPlayListView,例如

int x = [buttonPlayListView tag];

或以其他方式记住您要访问的按钮。

【讨论】:

如果我创建了 100 个按钮,我怎么能记得。我记得使用 TAG。这就是为什么我使用标签...来记住按钮:) 您可以继承 UIGestureRecognizer,为其添加属性 myButton 并在将手势识别器分配给按钮时对其进行设置。然后,您可以将作为发件人获得的 UIGestureRecognizer 转换为 MyGestureRecognizer 并获取 myButton 属性。或者您创建一个 NSMutableDictionary 类变量并将按钮设置为手势识别器的值作为键,例如[allMyGestureRecognizerButtons setObject:buttonPlaylistView forKey:doubleTap3] - 然后你通过使用发送者作为字典的键来获取按钮。 您可能还会单击按钮(不确定,但您可以检查)并记住上次单击的是哪个按钮... 实际上,UIGestureRecognizer 知道它附加到哪个视图(参见它的视图属性)。 @till 确实,这是一个不错的解决方案 :-)。我也在文档中查找过,但我总是忘记检查父类......我希望 Apple 也能在子类的文档中包含超类属性和函数......【参考方案3】:

即使我很确定您的做法是错误的,将双击手势识别器添加到 UIButton,您仍然可以执行不应该太多的任务为你工作。 你发表了评论

如果我创建了 100 个按钮,我怎么能记得

对于其中一个答案,该答案突出了导致您的 SIGBART 的问题。 UIGestureRecognizer 没有标签属性。

您可以这样做,遍历 [self view] 的所有子视图并找到具有相同 UIGestureRecognizer 的子视图,这不是最漂亮的解决方案,您拥有的子视图越多,循环所需的时间就越长.但它会做你似乎正在寻找的东西,所以如果你要添加。

在您的 handleDoubleTap 函数中,您可以执行以下操作

-(void) handleDoubleTap:(UITapGestureRecognizer *)sender

    if(sender.state == UIGestureRecognizerStateEnded)
    
        int iButtonTag = -1 //This is important later to escape the below for loop as we don't need to needlessly go around in circles
        for(UIView* psubView in [[self view] subviews])
        
            if( [psubView isKindOfClass:[UIButton class]] )
            
                UIButton* pButton = (UIButton*)psubView;
                for(UIGestureRecognizer* pGesture in [pButton gestureRecognizers] )
                
                     if( pGesture == sender )//this is the button we're after
                     
                         iButtonTag = [pButton tag];
                         break;
                     
                
                if( iButton != -1 )//found what we came for
                
                    break;
                
             
        
        //do what ever it was you needed to do now that you have the views tag, or you could have kept a reference to the button etc.
    
 

这应该可以解决您的问题。或者,如果您要向子视图的子视图添加按钮,最好在 NSMutableArray 中跟踪您的 UIButtons,您可以通过创建类属性(或成员变量)并使用'addObject:' NSMutableArray 的函数。然后代替行

for(UIView* psubView in [[self view] subviews])

以上可以换成

for( UIButton* pButton in m_pMutableButtonArray )

其中“m_pMutableButtonArray”是您为存储 UIButtons 的 NSMutableArray 提供的变量名称。这也意味着您将取消以下 if isKindOfClass 测试在下一行。

这应该可以解决您的问题。

【讨论】:

UIGestureRecognizer 没有标签属性。对,但 UIGestureRecognizer.view 有标签属性;)。问题已通过@Till方式解决。谢谢【参考方案4】:

为什么要在按钮中放置 UITapGestureRecognizer?该按钮已经为您处理了,并将向您发送回调,您可以使用此 UIControl 方法将目标添加到按钮

- (void)addTarget:(id)target action:(SEL)action forControlEvents:(UIControlEvents)controlEvents

【讨论】:

因为当我双击时我想做某事。明白吗?按钮处理简单的点击 在这种情况下,你根本不应该有一个按钮,只有一个带有 2 个手势识别器的视图,一个用于单击,一个用于双击。了解。 然后要求双击失败,单击失败,按钮不会这样做。

以上是关于按钮的 UITapGestureRecognizer 问题的主要内容,如果未能解决你的问题,请参考以下文章

HTMLHTML 表单 ② ( 按钮表单 | 普通按钮 | 提交按钮 | 重置按钮 | 图片按钮 | 文件域 )

选择一个按钮时如何更改多个按钮的按钮图像?

labview中,怎么将按钮机械动作释放时候触发,传递给其他按钮,就是按了一个按钮,其他的按钮也会

按钮角色 role="button"

如何在winform中实现,一个按钮停止另一个按钮的事件

简述在按钮制作窗口中,按钮的4种状态分别代表的意义。