swift 3 从父 ViewController 调用函数

问题描述 投票:0回答:3

我有一个 ViewController,这个视图容器有一个类,它创建 2 个容器视图,并向第一个容器添加一个表,为第二个容器添加一个 HashtagPicker。

hashTagPicker 有一个函数,每当选定的 hashTags 发生更改时就会调用该函数。

问题:每当标签更改时我想调用更新表函数。如何从包含容器的类中定义的主题标签类调用函数?

ios class swift3 protocols uicontainerview
3个回答
4
投票

我个人喜欢委托方法而不是通知 - 后一种解决方案几乎总是会导致令人困惑的架构。可悲的是,委托方法的示例(也是公认的答案)更糟糕 - 它基本上为内存泄漏提供了机会。我会解释一下。在公认的解决方案中,

ParentView
持有对
HashtagPicker
的强引用,反过来,
HastagPicker
持有对
ParentView
的强引用,这会创建一个保留周期,意味着两个控制器都不会被拾取通过 ARC 并被取消初始化。因此,例如,如果您从其他视图呈现
ParentView
并且继续前往
ParentView
并返回,您将不断生成
ParentView
(和
HashtagPicker
)的新实例,而旧实例仍占用内存.

现在,这应该如何完成。我将使用与接受的答案中完全相同的名称。

协议应该这样定义:

// note the ": class" part
protocol HashTagPickerDelegate: class {
  func picked(hashtag: String)
}

如果我们指定

class
,则意味着该协议只能在类上使用。这将允许使用创建弱引用,否则这是不可能的。

class HashtagPicker: UIViewController {
  // if HashTagPickerDelegate wouldn't be limited to class, 
  // we couldn't have made a weak reference here!
  weak var delegate: HashTagPickerDelegate?

  // at some point, you call the delegate, it can be anywhere, this is just an example
  @IBAction func tappedHashtag(_ sender: Any) {
    delegate?.picked(hashtag: "bla")
  }
}

现在我们对委托有一个弱引用,因此没有保留周期,并且 ARC 可以很好地清理所有内容!

我将添加其余的代码以获得完整的答案:

class ParentView: UIViewController {
  func prepare(for segue: UIStoryboardSegue, sender: Any?) {
    // we are presenting the nested controller
    if segue.identifier == "SegueHastagPickerContainer",
       let destinationController = segue.destination as? HashtagPicker {
      destinationController.delegate = self
    } 
  }
}

extension ParentView: HashTagPickerDelegate {
  func picked(hashtag: String) {
    // we just got info from the child controller, do something with it!
  }
}

4
投票

您可以使用上面答案中提到的委托。或者您可以使用通知。所以这是一个使用通知的解决方案。

首先在父视图控制器的

viewDidLoad
中注册一个通知,如下所示

NSNotificationCenter.defaultCenter().addObserver(self, selector: #selector(ParentViewController.someActionToBePerformed), name: "myNotification", object: nil)

在父视图控制器中创建一个与上面名称相同的函数,所以它会像

func someActionToBePerformed () {
    // this will be called when hashTag is changed
    // do something when hashTag is changed 
}

现在您只需从您的标签

viewController
发布通知即可。当你想要这样的时候。

NotificationCenter.default.post(name: NSNotification.Name(rawValue: "myNotification"), object: nil)

1
投票

您可以使用这个(没有通知,没有委托)

 func exitButtonTapped() {
    if let viewController : YourParnetViewController = self.parent as? YourParnetViewController {
        viewController.removeBlurEffect()
        self.removeFromParentViewController()
        self.view.removeFromSuperview()
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.