【问题标题】:How to make UITableView Header selectable?如何使 UITableView Header 可选择?
【发布时间】:2019-08-21 15:26:17
【问题描述】:

我为 UITableView 制作了一个自定义节标题,其中包括一些控件,如分段控件、UIImageView 等。它成功显示,但不可点击,因此我无法与其控件交互。

我需要知道如何使此标题视图可选择?

【问题讨论】:

  • 如果你使用 ImageView 作为基础视图,那么使用 imageView.userInteractionEnabled = YES;

标签: ios uitableview


【解决方案1】:

UITableViewDelegate 无法做到这一点。

你必须添加一个 UITapGestureRecognizer 到 yourHeaderView Like:

UITapGestureRecognizer *singleTapRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(gestureHandler:)];
[singleTapRecognizer setDelegate:self];
singleTapRecognizer.numberOfTouchesRequired = 1;
singleTapRecognizer.numberOfTapsRequired = 1;   
[yourHeaderView addGestureRecognizer:singleTapRecognizer];


-(void) handleGesture:(UIGestureRecognizer *)gestureRecognizer; //do in this method whatever you want

适用于 Swift 3.0

let tapGesture = UITapGestureRecognizer(target: self, action: #selector(YOURVIEWCONTROLLER.TapGestureRecognizer(_:)))
yourHeaderView.addGestureRecognizer(tapGesture)

func TapGestureRecognizer(gestureRecognizer: UIGestureRecognizer) {
    //do your stuff here 
}

斯威夫特 >= 4.0

添加UIGestureRecognizerDelegate类引用继承

let tap = UITapGestureRecognizer(target: self, action:#selector(self.handleTap(_:)))
tap.delegate = self
self.view.addGestureRecognizer(tap)

  @objc func handleTap(_ sender: UITapGestureRecognizer) {
        //Do your work 
    }

也许会有所帮助。

快乐编码。

【讨论】:

  • 如果屏幕中有超过 1 个部分(不需要滚动)点击所有部分的行为相同。
  • 请注意:.numberOfTouchesRequired.numberOfTapsRequired 默认设置为 1,因此您无需手动设置它们,除非它不是 1。
  • Swift >= 5:不再需要为“tap”添加委托属性。
【解决方案2】:

如果你需要知道被抽头部分的索引,你可以使用下面的模式(Swift 4):

func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
    let view = UIView(frame: CGRect(x: 0, y: 0, width: 300, height: 44))

    // Configure your view here
    // ...

    let tapGestureRecognizer = UITapGestureRecognizer(
        target: self,
        action: #selector(headerTapped(_:))
    )
    view.tag = section
    view.addGestureRecognizer(tapGestureRecognizer)
    return view
}

@objc func headerTapped(_ sender: UITapGestureRecognizer?) {
    guard let section = sender?.view?.tag else { return }

    // Use your section index here
    // ...
}

【讨论】:

  • 根据我的经验,这也是最简单的方法.. 谢谢..
【解决方案3】:

这对我有用:

override func tableView(tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {

    let v = UITableViewHeaderFooterView()
    v.textLabel?.text = "Header Text"
    let tapRecognizer = UITapGestureRecognizer(target: self, action: #selector(handleTap))
    tapRecognizer.delegate = self
    tapRecognizer.numberOfTapsRequired = 1
    tapRecognizer.numberOfTouchesRequired = 1
    v.addGestureRecognizer(tapRecognizer)
    return v
}

func handleTap(gestureRecognizer: UIGestureRecognizer)
{
    print("Tapped")
}

【讨论】:

  • 请注意,如果您使用tableView.dequeueReusableHeaderFooterView 回收现有视图而不是每次都创建新视图,则需要确保您不会一遍又一遍地重复添加UITapGestureRecognizer。跨度>
【解决方案4】:

Swift 3.0 的简单解决方案

 func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {

        let v = UITableViewHeaderFooterView()
        let tapRecognizer = UITapGestureRecognizer(target: self, action: #selector(handleTap))
        v.addGestureRecognizer(tapRecognizer)
        return v
    }


    func handleTap(gestureRecognizer: UIGestureRecognizer)
    {
        controller?.view.endEditing(true)
    }

【讨论】:

    【解决方案5】:

    创建一个自定义的section headerView..然后给它添加Tap手势。

    UITapGestureRecognizer * recognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(handleTap:)];
    
    //This method will be called on Tap of section header
    - (void)handleTap:(UITapGestureRecognizer *)sender {
    //Do the action on Tap
    }
    

    【讨论】:

      【解决方案6】:

      您可以简单地将 UIButton 添加到您的标题视图(或者您的标题视图可以是 UIButton 本身)。

      - (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section{
      
              static NSString *cellIdentifier = @"cellIdentifier";
      
          UITableViewCell *cell = (UITableViewCell*)[tableView dequeueReusableCellWithIdentifier:cellIdentifier];
      
          UIButton *cellButton = (UIButton*)[cell viewWithTag:1];
          [cellButton addTarget:self action:@selector(premiumSectionClicked:) forControlEvents:UIControlEventTouchUpInside];
      
          return cell;
      }
      
      -(void)buttonTapped:(id)sender{
      
      }
      

      【讨论】:

      • 最简单的解决方案:)
      【解决方案7】:

      创建一个自定义视图用作截面头视图并实现该方法 - (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event,手指点击就会调用。

      【讨论】:

      • 完美运行!在标题视图上添加触摸事件的最简单方法
      【解决方案8】:

      我在 Swift 中的实现:

      在你的UITableViewController:

      let myView = MyView()
      
      let tapRecognizer = UITapGestureRecognizer(target: myView, action: "handleTap")
      myView.addGestureRecognizer(tapRecognizer)
      
      self.tableView.tableHeaderView = myView
      

      MyView:

      class MyView: UIView {
      
          func handleTap() {
              // Handle touch event here
          }
      }
      

      【讨论】:

        【解决方案9】:

        快速解决方案:

        let tapR : UITapGestureRecognizer = UITapGestureRecognizer(target: self, action: "gotoHeaderArticle")
        tapR.delegate = self
        tapR.numberOfTapsRequired = 1
        tapR.numberOfTouchesRequired = 1
        yourView.addGestureRecognizer(tapR)
        

        然后实施

        func gotoHeaderArticle() {
        
        }
        

        确保您的调用视图控制器遵守 UIGestureRecognizerDelegate

        【讨论】:

          【解决方案10】:

          Swift 3.1 更新

          let tapGesture = UITapGestureRecognizer(target: self, action: #selector(TapGestureRecognizer(gestureRecognizer:)))
          yourView.addGestureRecognizer(tapGesture)
          
          func TapGestureRecognizer(gestureRecognizer: UIGestureRecognizer) {
                  //do your stuff here
                  print("Gesture")
              }
          

          【讨论】:

            【解决方案11】:

            这对我有用

              -(UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section{
                    static NSString *cellIdentifier = @"cellIdentifier";
                YourHeaderTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier];
               cell.imageView.image = [image imageNamed:@"imageName"];
            cell.segmentedControl.tag = section;
            [cell.segmentedControl addTarget:self
                                 action:@selector(action:)
                       forControlEvents:UIControlEventValueChanged];
                return cell;
            }
            
            - (void)action:(id)sender{
                UISegmentedControl *segmentedControl = (UISegmentedControl *) sender;
                NSLog(@"selected section:%ld",(long)segmentedControl.tag);
            
            }
            

            【讨论】:

            • 如果您在运行时对表进行了更新,这将中断。如果例如在表的开头插入一个部分(使用 beginUpdates endUpdates),然后现有的部分标题将不会重新加载,并且标签将包含错误的部分索引。
            【解决方案12】:

            如果有人需要一个在 tableview 有多个部分时可以工作的解决方案,我遇到了同样的问题,我想出的解决方案是根据部分在 viewForHeaderInSection 方法的按钮上创建不同的目标。我正在使用一个按钮,但这应该与 UITapGestureRecognizer 一样工作

            func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
            
                    // ...
            
                    if section == 0 {
                        cell.button.addTarget(self, action: #selector(firstSectionTapped(_:)), for: .touchUpInside)
                    } else if section == 1 {
                        cell.button.addTarget(self, action: #selector(secondSectionTapped(_:)), for: .touchUpInside)
                    }
            
                    // ...
            
            }
            

            然后在 ViewController 中:

            @objc func goalCategoryTapped(_ sender: UITapGestureRecognizer?) {
                print("Section One Tapped")
            }
            
            @objc func ideaCategoryTapped(_ sender: UITapGestureRecognizer?) {
                print("Section Two Tapped")
            }
            

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 1970-01-01
              • 2010-09-16
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2017-04-13
              • 1970-01-01
              • 1970-01-01
              相关资源
              最近更新 更多