【问题标题】:How to create a long press button in TableView Cell to segue如何在 TableView Cell 中创建长按按钮以进行 segue
【发布时间】:2020-08-25 15:07:22
【问题描述】:

我只能从 ViewController 创建我的 segue 函数,并且我的 TableViewCell 中必须有 longPress 函数。没有办法在不出错的情况下引用 segue 函数。当按钮保持在 TableView 单元中时,我将如何在 cellForRow 中实现此代码以继续?顺便说一句,我正在使用故事板。

@objc func longPress(gesture: UILongPressGestureRecognizer) {
        if gesture.state == UIGestureRecognizer.State.began {
            print("Long Press")
            //performSegue(withIdentifier: "toProfile", sender: self)
        }
      }

    func addLongPressGesture(){
        let longPress = UILongPressGestureRecognizer(target: self, action: #selector(longPress(gesture:)))
            longPress.minimumPressDuration = 0.75
            self.expandButton.addGestureRecognizer(longPress)

【问题讨论】:

    标签: ios swift uitableview button storyboard


    【解决方案1】:

    我找到了一个简单但非正统的解决方案,但效果很好:

    在您的 TableView Cell 中放置第二个按钮,连接您的 segue,并将其设置为隐藏。然后为它创建您的 IBOutlet,我将其命名为 SegueButton:

    @IBOutlet weak var LongPressButton: UIButton!
    @IBOutlet weak var SegueButton: UIButton!
    

    现在添加到您的 awakeFromNib:

    override func awakeFromNib() {
    addLongPressGesture()
    }
    

    最后,添加长按按钮代码:

    @objc func longPress(gesture: UILongPressGestureRecognizer) {
                if gesture.state == UIGestureRecognizer.State.began {
                    print("Segue was Successful")
                    SegueButton.sendActions(for: .touchUpInside)
                    }
                }
    
        func addLongPressGesture(){
        let longPress = UILongPressGestureRecognizer(target: self, action: #selector(longPress(gesture:)))
            longPress.minimumPressDuration = 0.75
            self.LongPressButton.addGestureRecognizer(longPress)
        }
    }
    

    【讨论】:

      【解决方案2】:

      您需要一种从按钮/单元格返回到视图控制器的方法。我建议使用闭包。它看起来像这样(我没有测试过这段代码)......

      class SomeCell: UITableViewCell {
      
          var didLongPress: (()->Void)? = nil
      
          @objc func longPress(gesture: UILongPressGestureRecognizer) {
              if gesture.state == UIGestureRecognizer.State.began {
                  didLongPress?() 
              }
          }
      
          override func prepareForReuse() {
              didLongPress = nil
          }
      }
      
      class TableViewController: UITableViewController {
      
          override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
              let cell = tableView.dequeueReusableCell(withIdentifier: "CellId") as! SomeCell
              cell.didLongPress = { [weak self] in 
                  self?.performSegue(withIdentifier: "showDetail", sender: nil)
              }
              return cell
          }
      
      }
      

      【讨论】:

      • 这实际上非常接近我的需要!当我按住按钮时它可以工作,但是当我太不幸地点击它时它会继续
      • 它在手势开始的那一刻触发了segue,因此gesture.state == UIGestureRecognizer.State.began。将其更改为ended
      • 好吧,我在这个按钮上已经有一个点击动作,但我切换到“结束”,现在它只在点击时触发
      • 你的措辞让我很困惑。如果有按钮,为什么要添加手势识别器?如果您有一个想要触发 segue 的按钮,我会将关闭称为按钮操作的一部分。
      • 我希望我的按钮在点击时执行特定操作,在按住时执行不同操作。但是,我在一个全新的项目中尝试了您的示例,并以相同的结果结束
      【解决方案3】:

      我在 tableview 单元格内设置了按钮,以便在点击时连接到一个视图控制器,在长按时连接到另一个视图控制器。

      1) 创建一个委托协议。您可以将其放在自定义 TableViewCell 类文件中,但不能放在类本身中。

      protocol MyTableViewCellDelegate : class {
         func didTapButton ()
         func didLongPressButton ()
      }
      

      2) 在实际的 TableViewCell 类中,放入以下内容:

      weak var delegate: MyTableViewCellDelegate?
      

      // 样板代码

      @objc func didLongPress(sender: UILongPressGestureRecognizer) {
          if sender.state == UIGestureRecognizer.State.began {
              delegate?.didLongPressButton()
          }
      }
      

      控件将您的按钮从您的表格视图单元格拖到此文件中。然后添加附加逻辑。

      @IBAction func expandButton(_ sender: Any) {
          let longPress = UILongPressGestureRecognizer(target: self, action: #selector(didLongPress))
          self.addGestureRecognizer(longPress)
          delegate?.didTapButton()        
      }
      

      在您的主 ViewController 文件中,在 cellForRowAt 内:

      cell.delegate = self
      

      然后在 ViewController 的类逻辑之外的某个地方,添加以下内容以符合您的委托协议并执行您的转场:

      extension ViewController: MyTableViewCellDelegate {
          func didTapButton() {
              performSegue(withIdentifier: "toInfoSegue", sender: self)
      }
          @objc func didLongPressButton() {
              performSegue(withIdentifier: "toProfileSegue", sender: self)
          }
      }
      

      【讨论】:

      • 我不确定这是否与 segue 能够访问情节提要上的水龙头有关,但不幸的是它仍然无法正常工作
      • 我在一个项目中测试了它并且它正在工作。你是如何创造你的segues的?我从主视图控制器(带有 tableview)到另外两个视图控制器做了一个 ctrl-drag。另外,您收到了哪些错误消息或您看到了哪些行为?
      • 好吧,我也做了一个 ctrl-drag,但我的 cellForRow 中已经有了我需要的点击功能。尽管您的示例在我按住按钮时有效,但在我点击时也有效。但我很高兴地说,我找到了一个简单的解决方案并在这里发布了答案!
      • 澄清一下:您是否正在寻找对 tableview 单元格的三种可能的操作? 1)当您选择行时发生了一些事情。 2)当您点击行内的按钮时会发生其他事情吗? 3)当您长按行中的同一个按钮时会发生其他事情吗?不确定“点击功能”是什么意思(在行还是按钮上?)你可以同时拥有这三个;只需要知道你在寻找什么。
      • 如果有帮助,我创建了一个 Github 存储库以在上下文中显示上面的代码。 github.com/IosStever/Stackoverflow05112020
      猜你喜欢
      • 2020-08-25
      • 2013-07-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-07-19
      • 1970-01-01
      相关资源
      最近更新 更多