【问题标题】:UIButton move to storyboard in Custom CellUIButton 移动到自定义单元格中的情节提要
【发布时间】:2017-07-21 14:14:12
【问题描述】:

当在自定义单元格类型中点击按钮时,我正在尝试移动到新的故事板,但自定义类有问题。我目前有这个

class submitCell: UITableViewCell {
    @IBAction func cancelButton(_ sender: Any) {

    }

}

我需要取消按钮来执行此操作

            let storyboard = UIStoryboard(name: "Main", bundle: nil)
            let viewController = storyboard.instantiateViewController(withIdentifier: "TripList") as! TripTableViewController
            self.present(viewController, animated: true , completion: nil) //Move

除了.present不是UITableViewCell的方法,只有UIViewController。我怎样才能实现这个功能?

【问题讨论】:

  • 您真的不应该从 TableViewCell 执行此操作,因为它会破坏 MVC。您应该真正将操作委托给 tableViewController(或它的父视图控制器)。

标签: ios swift uitableview uibutton


【解决方案1】:

与其尝试在您的自定义单元格中调用该函数,不如在您的视图控制器中执行此操作。这就是你需要的

class submitCell: UITableViewCell {

    var tapAction: ((UITableViewCell) -> Void)?

    @IBAction func cancelButton(_ sender: Any) {
        tapAction?(self)
    }
}

然后在你的视图控制器中

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {

    cell.tapAction = { [weak self] cell in self?.move()}
}

func move() {
    let storyboard = UIStoryboard(name: "Main", bundle: nil)
    let viewController = storyboard.instantiateViewController(withIdentifier: "TripList") as! TripTableViewController
    self.present(viewController, animated: true , completion: nil) //Move
}

注意:您应该将班级名称的第一个字母大写。查看Swift name conventions了解更多信息。

【讨论】:

    【解决方案2】:

    首先在自定义单元格中,将按钮放入其中并连接。

    class submitCell: UITableViewCell {
        @IBOutlet weak var cancelButton: UIButton!
    }
    

    现在让我们在使用按钮的类中做你想做的事。 在创建单元格的类中,执行

    cell.delegate = self
    cell.cancelButton.addTarget(self, action: #selector(cancelAction), for: .touchUpInside)
    

    然后创建一个函数:

    private func cancelAction(sender: UIButton){
        let storyboard = UIStoryboard(name: "Main", bundle: nil)
        let viewController = storyboard.instantiateViewController(withIdentifier: "TripList") as! TripTableViewController
        self.present(viewController, animated: true , completion: nil) //Move
    }
    

    【讨论】:

    • Im upvoting this.. 我认为您不需要设置委托,只需将目标添加到按钮即可。从我的角度来看.. 这比协议和委托要好得多。
    • 另外,不要忘记通过“as!SubmitCell”将您的单元格转换为自定义单元格。
    【解决方案3】:

    有几种方法可以做到这一点。 - 创建一个委托 - 为您的按钮创建一个引用,以便您可以在 ViewController 中使用。

    我将链接一些案例,以便您选择最适合您的案例的方法:

    参考按钮

    委托

    【讨论】:

      【解决方案4】:

      您可以通过引用自定义单元格类中的按钮来将函数 cancelButton 委托给 viewController。

      基本上,首先您需要为自定义单元格中的按钮创建一个插座:

      @IBOutlet var button: UIButton!
      

      然后在你的 viewController 中:

      button.addTarget(self, action:#selector(cancelButton(_sender:)), for: .touchUpInside)
      

      声明函数:

          func cancelButton (_sender: UIButton) {
      
          let storyboard = UIStoryboard(name: "Main", bundle: nil)
          let viewController = storyboard.instantiateViewController(withIdentifier: "TripList") as! TripTableViewController
          self.present(viewController, animated: true , completion: nil) //Move
      }
      

      PS:如果你有多个按钮,你可以将它们添加到同一个动作中,并通过一个标签来控制行为。

       button.tag = 0
      
       if ( _sender.tag == 0.) {
           // do tag 0
        } else ... 
      

      【讨论】:

        【解决方案5】:

        我会看看delegate 模式。

        为您的 UITableViewCell 委托创建协议

        protocol SubmitCellDelegate: class {
            func cancelButtonPressed()
        }
        

        将委托添加到您的 UITableViewCell 子类

        class SubmitCell: UITableViewCell {
            weak var delegate: SubmitCellDelegate?
        
            @IBAction func cancelPressed(_ sender: UIButton) {
                delegate?.cancelButtonPressed()
            }
        }
        

        在您的 UIViewController 子类中实现委托

        这必须在引用您的 tableview 单元格的类中实现。

        class ViewController: UIViewController, SubmitCellDelegate {
        
            // ... 
            // wherever you create your cell
                submitCell.delegate = self
            // ...
        
            // Implement the SubmitCellDelegate function (Xcode will force you to)
            func cancelButtonPressed() {
                let storyboard = UIStoryboard(name: "Main", bundle: nil)
                let viewController = storyboard.instantiateViewController(withIdentifier: "TripList") as! TripTableViewController
                self.present(viewController, animated: true , completion: nil)
            }
        }
        

        旁注:在大多数(全部?)面向对象的编程语言中,在类名上使用标题大小写是一种很好的做法(例如,SubmitCell 而不是submitCell)。

        【讨论】: