【问题标题】:Swift3 : Delegate function is not runningSwift3:委托功能未运行
【发布时间】:2017-04-08 19:12:11
【问题描述】:

我正在构建一个应用程序,从 TableViewController 开始,当我单击一个单元格时,它将转到另一个视图控制器并运行我在新视图控制器中创建的函数。我目前正在使用协议和委托,但即使按照我在网上找到的教程和指南进行操作,我仍然无法运行该函数。

这是我的 tableview 控制器代码。我包含了我认为相关的代码。

class interestPTableViewController: BaseViewController, UITableViewDataSource, UITableViewDelegate {

        var ipSearchDelegate: IPSearch?

        public func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {       
                ipSearchDelegate?.ipZoom()
        }
}

这是我的其他视图控制器代码。我无法让它打印“你好”

protocol IPSearch: class{
      func ipZoom()
}

class searchMapViewController: BaseViewController{
      override func viewDidLoad(){
            let ipip = storyboard!.instantiateViewController(withIdentifier: "interestP") as! interestPTableViewController
            ipip.ipSearchDelegate = self
      }
}
extension searchMapViewController: IPSearch {
      func ipZoom(){
           print("hello")
      }
}

任何帮助都会很好。提前致谢。

【问题讨论】:

  • 你有没有下过断点并测试了发生了什么?
  • 嗯,不太清楚如何准确地看到发生了什么。但是当我检查时我的代表为零
  • 这看起来有点倒退...一般来说,使用委托模式,以便加载/显示的类可以与加载它的类通信back。这是看起来,您正在尝试“在您刚刚加载的类中调用委托函数”?
  • @DonMag 我实际上想要做的是,当我单击一个单元格时,我希望它转到我的视图控制器,其中包含一个地图,然后通过加载给定的数据放大到该区域通过细胞。但是地图本身可以很好地工作,而无需将数据加载到其中。我只希望它在我浏览我的表格视图单元格时缩放。如果这有意义的话。
  • @JackieXY - 您的 TableView 和 MapViewController 中的视图是否同时在屏幕上可见?就像您的地图显示在顶部一样,并且您在其下方有一个表格可供选择?

标签: ios swift3 delegates protocols


【解决方案1】:

这是您的任务在“传统”协议/委托模式中的完成方式。

这是“地图视图”控制器...

//
//  SearchMapViewController.swift
//

import UIKit

protocol IPSearch: class{
    func ipZoom()
}

extension SearchMapViewController: IPSearch {
    func ipZoom(){
        print("hello")
    }
}

class SearchMapViewController: BaseViewController {

    override func viewDidLoad() {
        super.viewDidLoad()
    }

    // MARK: - Navigation

    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {

        // assuming another button (hamburger menu?) is triggering a segue
        // to the "table view" controller, this is where you
        // assign the delegate

        if let vc = segue.destination as? InterestPViewController {
            vc.delegate = self
        }

    }

}

这是带有可供选择的行表的视图...

//
//  InterestPViewController.swift
//

import UIKit

class InterestPViewController: BaseViewController, UITableViewDelegate, UITableViewDataSource {

    var delegate: IPSearch?

    override func viewDidLoad() {
        super.viewDidLoad()
    }

    // MARK: - Table view data source

    func numberOfSections(in tableView: UITableView) -> Int {
        return 1
    }

    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return 15
    }

    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "basicCell", for: indexPath)

        cell.textLabel?.text = "\(indexPath)"

        return cell
    }

    func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {

        // just print so we know we've tapped a row
        print("row selected", indexPath.row)

        // call a func in the "map view" - likely, ipZoom() will be changed to
        // something along the lines of ipZoom(selectedRow: indexPath.row)
        delegate?.ipZoom()

        // returning to the "map view"

        // either
        self.navigationController?.popViewController(animated: true)

        // or
        //presentingViewController?.dismiss(animated: true, completion: nil)

    }

}

【讨论】:

    【解决方案2】:

    这样试试,你应该保留你的VC实例:

        class searchMapViewController: BaseViewController{
          var ipip: interestPTableViewController! // <- This is important part
    
          override func viewDidLoad(){
                ipip = storyboard!.instantiateViewController(withIdentifier: "interestP") as! interestPTableViewController
                ipip.ipSearchDelegate = self
          }
    }
    

    【讨论】:

    • 感谢您的快速回答,但不幸的是,这并没有解决问题。您还有其他建议吗?
    【解决方案3】:

    您的 SearchMapViewController 的 viewDidLoad 正在实例化一个新的 InterestPTableViewController 并设置它的委托,然后丢弃它。一旦您的 viewDidLoad 退出,新创建的视图控制器将被释放。设置委托的时间在prepareForSegue中

    .

    【讨论】:

    • 我应该在哪里设置 prepareForSegue?抱歉,我是 C 语言的新手,而且总体来说很快
    • 点击单元格时如何触发第二个视图控制器?
    • 更正:我在单击单元格时附加了视图控制器。
    【解决方案4】:

    让你的第一个 VC 符合你的协议

     class interestPTableViewController: BaseViewController, UITableViewDataSource, UITableViewDelegate, IPSearch {
    
            var ipSearchDelegate: IPSearch?
    
            public func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {       
                    ipSearchDelegate?.ipZoom()
            }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-03-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多