【问题标题】:Fail calling back about protocol and delegate by Swift4Swift4 回调协议和委托失败
【发布时间】:2018-09-21 01:11:05
【问题描述】:

我对使用协议和委托进行回调感到困惑。
问题是。我有两个视图控制器vcA & vcB vcA 有一个 tableView,vcB 有一个按钮。
vcA 点击单元格到vcB.
然后我想点击vcB中的按钮,做以下两件事。

1.vcA tableView reloadData.
2.vcB popViewcontroller To vcA.

我不明白如何解决这个问题。
有样品可以教我吗?

谢谢。

【问题讨论】:

  • 为什么要使用delegate/protocol?您一次只能显示一个 VC,因此您可以逐步进行:vcB.handleButton { popVC to vcA } 并且在 vcA 中您可以在 viewDidAppear() 中执行您的 reloadData
  • 因为我想弄清楚这个话题。
  • 我认为@SH_Khan 的答案就是你要找的
  • @Sandu 你说得对。

标签: ios swift delegates protocols


【解决方案1】:

这是委托解决方案,但最好将 self.tableView.reloadData() 方法放在 viewDidAppear 中,因为它会在您弹出 VcB 时被调用

class VcA: UIViewController ,TableRefresh {

    func reloadTable()
    {
        // reload here
    }

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

        let des = segue.destination as! VcB

         des.delegate = self

    }
}

protocol TableRefresh {
    func reloadTable()
}

class VcB: UIViewController {
    var delegate: TableRefresh?

    @IBAction func closeClicked(_ sender: UIButton) {
        self.delegate?.reloadTable()
        // pop here
    }
}

【讨论】:

  • 感谢您帮我解决这个问题。
【解决方案2】:

我希望这对你有用:

 class vcA : UIViewController {

    override func viewWillAppear(_ animated: Bool) {
        tableView.reloadData()
    }
  }

class vcB : UIViewController {

    @IBAction fun button(bin : UIButton){
    self.navigationController.popViewController(true)
    }
  }

【讨论】:

    【解决方案3】:

    如果您的内存中没有任何 VC 对象的方法,则无法调用它。

    第一次,它 vcB 不会在内存中。因此,相同的对象不存在。

    如果你真的想调用那个类的函数,并且如果它可行的话,请创建一个 vcB 的对象并调用该方法。 或者您可以尝试使用 VC 的共享对象并在可行的情况下继续使用它。您可以发布确切的场景,以便人们可以提出更好的建议

    【讨论】:

      【解决方案4】:

      您的vcA 引用了vcB,因此您可以在vcA 中编写类似的内容

      class vcA {
          var vcB: vcB?
          ...
          vcB?.doSmth()
          ....
      }
      

      但是您无法从vcB 调用vcA,因为它没有对它的引用。所以要让vcA 知道vcB 中发生了一些事情,或者从vcB 调用一些函数,你可以做几件事。 代表、键值观察、反应式编程和其他一些。 既然您要求代表解决方案,请坚持下去。

      委托背后的一般想法是顾名思义,让delegate 别人做某事。在您的情况下,您希望将按钮单击处理委托给vcA。为此,您需要做一些事情。

      接下来的步骤只是上述想法的实现。

      class VcA {
          var vcB: VcB?
          ...
          vcB?.delegate = self
          ...
          vcB?.doSmth()
          ....
      }
      
      extension VcA: VcBDelegate {
          func buttonIsClicked() {
              // reload data
              // pop vcB
          }
      }
      
      protocol VcBDelegate: class {
          func buttonIsClicked()
      }
      
      class VcB {
          var delegate: VcBDelegate?
          ...
          // when the button is clicked
          // delegate handling to someone who is 'listening' for this event
          self.delegate?.buttonIsClicked()
          ...
      }
      

      注意 VcB 中的 delegate 是可选的,这意味着如果没有人被签名为 VcB 的代表,则该事件将被忽略。

      【讨论】:

        【解决方案5】:

        有多种方法可以做到这一点。

        1:将tableView.reloadData() 放入viewDidAppear(),然后弹出vcB

        2:当您推送 vcB 时,您会创建一个对它的引用,然后在 vcB 中您有一个侦听器,您可以将其应用于该引用。像这样:

            class viewControllerB: UIViewController {
                  var reloadTableView: (() -> ())
        
                  @objc func buttonPressed() {
                     reloadTableView()
                     self.navigationController?.popViewController(animated: true)
        
                  }
            }
        

        然后:

        let vcB = viewControllerB()
        vcB.reloadTableView = {
             self.tableView.reloadData()
        }
        present(vcB, animated: true)
        

        3:像 Sh_Khan 一样做事

        【讨论】:

          猜你喜欢
          • 2017-09-24
          • 1970-01-01
          • 2021-03-14
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2010-11-07
          相关资源
          最近更新 更多