【问题标题】:can't click UIButton inside a cell in UITableview无法在 UITableview 中的单元格内单击 UIButton
【发布时间】:2013-09-22 20:52:30
【问题描述】:

已经搜索了一些可能的修复方法,但都没有解决我的问题。

我一直点击 uitableview 中的单元格而不是其中的按钮。

这是我的代码:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:  (NSIndexPath *)indexPath{

    static NSString *CellIdentifier = @"Cell";

    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
    if (cell == nil) {
        cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
    }

    cell.backgroundColor = [UIColor blackColor];

    UIView *v  = nil;
    NSArray *array = [cell subviews];

    for (v in array) {
        NSLog(@"%@",[v class]);
        if( [v isKindOfClass:[UIView class]] ){
           [v removeFromSuperview];
        }
    }

    //tb
    if (tableView == self.tb) {

        v = [[UIView alloc] initWithFrame: CGRectMake(0, 0, self.tb.bounds.size.width, 120.0)];

        if([feeds count]>0){
            UIImageView *box=[[UIImageView alloc] initWithImage:[UIImage imageNamed:@"statusBox.png"]];

            box.userInteractionEnabled = YES;
            [v addSubview:box];

            AsyncImageView *imageView1 = [[AsyncImageView alloc] initWithFrame:CGRectMake(10, 20.0f, 34.0f, 34.0f)];
            imageView1.contentMode = UIViewContentModeScaleAspectFill;
            imageView1.clipsToBounds = YES;

            //cancel loading previous image for cell
            [[AsyncImageLoader sharedLoader] cancelLoadingImagesForTarget:imageView1];
            if (users1 != nil && users1.imagelink != nil && (id) users1.imagelink !=   [NSNull null]){
               imageView1.imageURL = [NSURL URLWithString:users1.imagelink];
            }
            else{
                imageView1.image=[UIImage imageNamed:@"default_ProfilePic.png"];
            }

            UITapGestureRecognizer *tapped = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(myFunction:)];
            tapped.numberOfTapsRequired = 1;
            [imageView1 addGestureRecognizer:tapped];
            [tapped release];

            imageView1.userInteractionEnabled = NO;
            [v addSubview:imageView1];


            UIFont *font     = [UIFont fontWithName:@"TrebuchetMS-Bold" size:11];
            UILabel *descLabel1 = [[UILabel alloc] initWithFrame: CGRectMake(52, 23, 160, 48)];
            descLabel1.text                 = [NSString stringWithFormat:@"%@ %@",users1.userfirstn,users1.userlastn];
            descLabel1.textColor            = [UIColor blackColor];
            descLabel1.font                 = font;
            descLabel1.adjustsFontSizeToFitWidth=YES;
            descLabel1.numberOfLines = 0;
            CGSize expectedLabelSize = [descLabel1.text sizeWithFont:descLabel1.font
                                               constrainedToSize:descLabel1.frame.size
                                                   lineBreakMode:UILineBreakModeWordWrap];

            CGRect newFrame = descLabel1.frame;
            newFrame.size.height = expectedLabelSize.height;
            descLabel1.frame = newFrame;
            descLabel1.numberOfLines = 0;

            descLabel1.userInteractionEnabled = NO;
            [v addSubview:descLabel1];


            UILabel *descLabel2= [[UILabel alloc] initWithFrame: CGRectMake(52, 43, 200, 48)];
            StatusClass *stat1=[feeds objectAtIndex:indexPath.row];
            descLabel2.text                 = [stat1 statcreate];
            descLabel2.textColor            = [UIColor blackColor];
            descLabel2.font                 = font;
            descLabel2.adjustsFontSizeToFitWidth=YES;
            descLabel2.numberOfLines = 0;
            CGSize expectedLabelSize2 = [descLabel2.text sizeWithFont:descLabel2.font
                                                constrainedToSize:descLabel2.frame.size
                                                    lineBreakMode:UILineBreakModeWordWrap];

            CGRect newFrame2 = descLabel2.frame;
            newFrame2.size.height = expectedLabelSize2.height;
            descLabel2.frame = newFrame2;
            descLabel2.numberOfLines = 0;

            descLabel2.userInteractionEnabled = NO;
            [v addSubview:descLabel2];

            UILabel *descLabel3= [[UILabel alloc] initWithFrame: CGRectMake(10, 63, 280, 80)];
            StatusClass *stat=[feeds objectAtIndex:indexPath.row];
            descLabel3.text                 = [stat stattext];
            descLabel3.textColor            = [UIColor blackColor];
            descLabel3.font                 = font;
            descLabel3.adjustsFontSizeToFitWidth=YES;
            descLabel3.numberOfLines = 0;

            descLabel3.userInteractionEnabled = NO;
            [v addSubview:descLabel3];

            //comment button
            UIButton *buttonC = [UIButton buttonWithType:UIButtonTypeRoundedRect];
            [buttonC addTarget:self action:@selector(sendComment:) forControlEvents:UIControlEventTouchUpInside];
            [buttonC setImage:[UIImage imageNamed:@"comment.png"] forState:UIControlStateNormal];
            buttonC.frame = CGRectMake(2, 160, 145, 35);

            buttonC.userInteractionEnabled = YES;
            [v addSubview:buttonC];

            //share button
            UIButton *buttonS = [UIButton buttonWithType:UIButtonTypeRoundedRect];
            buttonS.tag = indexPath.row;
            [buttonS addTarget:self action:@selector(sendShare:) forControlEvents:UIControlEventTouchUpInside];
            [buttonS setImage:[UIImage imageNamed:@"share.png"] forState:UIControlStateNormal];
            buttonS.frame = CGRectMake(150, 160, 140, 35);

            buttonS.userInteractionEnabled = YES;
            [v addSubview:buttonS];

        }
        v.userInteractionEnabled = YES;
        [cell addSubview:v];
    }
    return cell; 
}

我还尝试了UITapGestureRecognizer 的按钮,但仍然无法正常工作。

谢谢。

【问题讨论】:

  • 将选择样式设置为无
  • 我只是想知道按钮的 y 偏移量是 160,而你的视图 v 的高度是 120。那么你怎么能看到按钮呢?
  • 好眼睛....谢谢。没注意到那个。这就是为什么它不可点击的原因是它不在视图中。它现在工作正常
  • 评论添加为答案..
  • 每个项目我都遇到过几次同样的情况。当它没有按预期工作时,每当您将按钮作为子视图添加到任何内容时,1) 父视图必须能够接受触摸操作,isUserInteractionEnabled = true。 2)视图被正确地添加到父视图中,而不仅仅是可见的。单元格很容易发生这种情况,它在屏幕上可见,但视图超出了单元格的范围......它永远无法点击。

标签: iphone ios uitableview uibutton uitapgesturerecognizer


【解决方案1】:

UITableViewCell 默认处理所有手势。 设置cell.selectionStyle = UITableViewCellSelectionStyleNone; 使其禁用默认行为。

【讨论】:

  • 谢谢,但我仍然无法单击 2 个按钮。但图像视图上的 UItapgesture 工作正常。
  • 也可以试试[cell.contentView addSubview:v] 而不是[cell addSubview:v]
  • 如果我使用 contentView 我将看不到单元格。
【解决方案2】:

创建一个自定义 UITableViewCell。参考this link

假设你有一个名为 displayButton 的UIButton,你可以这样做:

在您的- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath 中,创建单元格后,

[cell.dislayButton addTarget: self
                             action: @selector(replyButtonPressed:withEvent:)
                   forControlEvents: UIControlEventTouchUpInside];

然后在你的 ViewController 中创建这样的方法:

- (void) replyButtonPressed: (id) sender withEvent: (UIEvent *) event
{
    UITouch * touch = [[event allTouches] anyObject];
    CGPoint location = [touch locationInView: self.tableView];
    NSIndexPath * indexPath = [self.tableView indexPathForRowAtPoint: location];
}

【讨论】:

  • 我在 tableview 中有一个以编程方式制作的 UIButton,名为“buttonC”,我尝试了你想让我做的事情。 [cell.buttonC addTarget: self action etc...];但问题是单元格找不到按钮C,所以它给了我一个错误。
  • 而不是 [buttonS addTarget:self action:@selector(sendShare:) forControlEvents:UIControlEventTouchUpInside];添加以下内容: [buttonS addTarget: self action: @selector(replyButtonPressed:withEvent:) forControlEvents: UIControlEventTouchUpInside];
【解决方案3】:

您的UIButton= 的 y 偏移量为 160,UIView's 高度仅为 120。请更改 UIButton's y 偏移量并尝试。

【讨论】:

    【解决方案4】:

    还有另一个可能导致此类问题的原因,那就是UITableViewCells 现在有了contentView。这可以并且将被放置在您的自定义表格视图单元格中的其他视图之前,以便拾取触摸并检测单元格选择。在这样做时,它可能会阻止对其背后的任何视图的触摸。在使用笔尖创建单元格时,我特别注意到了这种烦恼。

    处理此问题的公认方法是确保所有子视图都不是添加到 tableview 单元格本身,而是添加到其contentView。这是一个只读属性,可在某些情况下调整其自身的框架,例如在侧向滑动以显示删除按钮时,或在编辑模式期间。因此,您应该确保您添加到 contentView 的任何项目都经过智能调整大小并具有正确的大小调整行为。

    另外请注意,通过将单元格添加到contentView,您自己可能会阻止对其进行触摸,从而阻止单元格被选中。我个人尽量不允许在包含具有自定义用户启用控件的单元格的表格视图中选择单元格。它只会导致混乱和尴尬的界面。事实上,我正在认真考虑将我未来项目中的所有UITableViews 替换为UICollectionViews,因为它的适应性要强得多。

    -灰

    【讨论】:

    • ¿您仍然可以使用 XIB 文件并将您设计的内容添加到 contentView 而不是视图本身吗?
    • 您可以在 nib 或 storyboard 中创建表格视图单元格,只要您使用 UITableView 创建原型单元格的能力,或者在表格视图单元格对象之上构建并将 nib 注册到表格视图使用 registerNib:forCellWithReuseIdentifier: - 我通常使用原型单元来保持一切整洁。
    【解决方案5】:

    我只是对这个问题感到困惑......

    我设法在一个项目上解决了这个问题:

    func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCellWithIdentifier("RegCell", forIndexPath: indexPath) as! CustomCell
    
        cell.contentView.userInteractionEnabled = false // <<-- the solution
    
        return cell
    }
    

    但同样不适用于不同的项目。我不知道为什么...

    【讨论】:

    • 谢谢!!也许我们做的事情略有不同,真正为我解决了这个问题:cell.contentView.isUserInteractionEnabled = true //
    • @SimonBriggs,你是对的! “true”也为我修复了它:)
    • false 为我工作 - 也许我添加的内容错误并且 contentView 正在点击我。但它自 iOS 8 以来一直在工作,并在 XCode 12.1 上中断。
    【解决方案6】:

    我遇到了这个问题,但在我的情况下,它与表格视图无关,而是因为我在按钮中使用了userInteractionEnabled 为真的子视图,将该值设置为假(否)所有按钮的子视图都为我解决了这个问题。

    【讨论】:

      【解决方案7】:

      适用于 Swift 3 和 Storyboard

      对我来说,我必须在内容视图中启用多点触控,并在所有内容上启用用户交互 - 表格视图、表格视图单元格、内容视图和 UIButton。我正在使用情节提要。

      我还将我的 tableview 单元格设置为子类。

      由于我在探索问题时在这里找不到答案,因此我发布了另一个关于堆栈溢出的问题。你可以在这里查看我的代码并下载一个项目:Can't click button inside UITableViewCell?

      【讨论】:

      • 在自定义单元格 ( cellForRowAt ) 中添加目标确实按照代码中的建议工作。
      • 很奇怪,我以前从未遇到过这种情况,但出于某种原因,在这个 tableview 上就是这种情况。无论如何,谢谢!
      【解决方案8】:

      我也有同样的问题,但不知怎的,我发现了我的错误。
      在我将constraintsself(UITableViewCell) 更改为constraintscontentViewself(UITableViewCell) 之后,我的单元格的按钮又可以点击了。

      【讨论】:

      • 将我的约束从 self(UITableViewCell) 更改为具有单元格内容视图的约束,这会导致我的按钮/文本视图从单元格中消失。这很奇怪。
      • 我只是通过保持 contentView 作为单元格的约束并删除我对 contentView 和 textview 高度的两个约束来修复它,这些约束试图修复初始错误。所有子视图从上到下都受到适当的约束,并且有效!谢谢@wj2061
      【解决方案9】:

      我正在这样做:

      let plusButton: UIButton = {
          let v = UIButton()
          v.setImage(plusImg, for: .normal)
          v.tintColor = .dark
          v.translatesAutoresizingMaskIntoConstraints = false
      
      
          // adding targets here did not work
          v.addTarget(self, action: #selector(plusButtonHandler), for: .touchUpInside)
      
      
          return v
      }()
      

      似乎在闭包内调用addTarget 方法不起作用。

      当我将 addTarget 方法分解出来并将其放入初始化程序时,一切正常!

      【讨论】:

      • 经过很多解决方案后,这对我有用。非常感谢:)
      • 是的,这是一个棘手的问题,很难找到。在对一个小项目进行测试后,我发现如果我将此按钮设置为lazy 它也可以工作,否则将addTarget 放在init() 中。
      【解决方案10】:

      如果在某些UITableViewCell 中按下UIButton 没有其他选择器,则需要关闭按钮的userInteractionEnabled

      cellButton.userInteractionEnabled = false
      

      在这种情况下,任何按钮触摸都会传播到单元格触摸。

      【讨论】:

      • 问题是如何启用按钮触摸。仔细阅读
      【解决方案11】:

      试试这个

      public override void SetSelected(bool selected, bool animated)
          {
             // this.interestsButton.Selected = true;
              if (selected)
              {
                  //  this.TextLabel.TextColor = UIColor.Red;
      
                  //this.interestsButton.ShowsTouchWhenHighlighted = true;
                  this.interestsButton.BackgroundColor = UIColor.Purple;
                  //this.interestsButton.SetTitleColor(UIColor.Red, UIControlState.Highlighted);
              }
              else
              {
      
              }
      
      
             // cell.ContentView.UserInteractionEnabled = false;
              base.SetSelected(selected, animated);
      
      
          }
      

      仅在“Mvvmcross.iOS”上测试

      【讨论】:

        【解决方案12】:

        更新 swift 4.2

        在 func tableView(_tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell

        添加:cell.buttonCheckBox.isUserInteractionEnabled = false

        或者,取消选中启用用户交互的检查器

        现在您可以选择按钮以及单元格。 这对我有用:)

        【讨论】:

          【解决方案13】:

          在我的例子中,我尝试通过self.addSubview(myButton) 将 UIButton 直接添加到单元格中,所以我改为self.contentView.addSubview(myButton) 并且它起作用了

          contentView 似乎在 myButton 前面,所以按钮不会收到点击手势。

          【讨论】:

          • 这个解决方案在更新到 xcode 12 后对我有用
          • 在我的手机从 13 更新到 14 后,此解决方案对我有用。在这两种情况下我都使用 Xcode 12。我的问题是这现在会在 13 日失败吗?
          • 我试过了,它在 iOS 13 上是固定的,现在在 iOS 14 上仍然可以工作
          • 在我的例子中,自定义类中的按钮没有响应添加到 tableview 单元格的点击。将按钮添加到“self.contentview”而不是“self”后,它起作用了。
          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2017-11-14
          • 2019-11-17
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2015-11-04
          相关资源
          最近更新 更多