【问题标题】:Passing data between two views (in the same ViewController) [duplicate]在两个视图之间传递数据(在同一个 ViewController 中)[重复]
【发布时间】:2018-03-16 13:46:43
【问题描述】:

非常基本:我需要将信息从一个视图传递到另一个视图。它们在同一个ViewController 中。解决这个问题的最优雅的方法是什么?

NotificationCenter 不是一个选项

如果我可以直接从另一个视图访问某个视图的某些属性,那就太理想了

【问题讨论】:

  • 请使用 KVO 示例检查更新后的答案。
  • 最优雅的方式是将逻辑放在单独的类(非视图类)中。视图不应直接受其他视图的影响。委托的类似 inokey 可以工作,但不要在视图中使用委托,而是在视图控制器中使用。

标签: ios swift model-view-controller


【解决方案1】:

假设您有两个视图 view1view2。 例如,view2 中的某些数据发生了更改,您需要将此数据传递给view1。我会用委托模式来做到这一点。设置如下:

protocol View2Delegate {
    func didChangeSomeData(data: String) 
}

现在在view2

class View2: UIView {

   var delegate: View2Delegate?

   var text: String = String() {
        didSet {
           self.delegate.didChangeSomeData(data: text)
        }
   }
}

view1

class View1: UIView, View2Delegate { 

     var textToChange: String = String()

     func didChangeSomeData(data: String) {
          // Do whatever you want with that changed data from view2
          textToChange = data
     }
}

在你的viewController

class MyViewController: UIViewController {
     var: view1 = View1()
     var: view2 = View2()

  func viewDidLoad() {
      super.viewDidLoad()
      view2.delegate = view1
  }

现在,如果您不想将view1view2 耦合,您可以通过ViewControllerview2 的相同模式更改进行侦听,然后通过属性将其直接传递给view1访问者。

class MyViewController: UIViewController, View2Delegate {
     var: view1 = View1()
     var: view2 = View2()

  func viewDidLoad() {
      super.viewDidLoad()
      view2.delegate = self
  }

  func didChangeSomeData(data: String) {
        view1.textToChange = data
  }

Apple's Documentation 中有关协议的更多信息

更新

您也可以使用Key Value Observing 模式。你可以这样设置:

class MyViewController: UIViewController {
     var view1 = View1()
     var view2 = View2()

     override func viewDidLoad() {
         super.viewDidLoad()

         let observation = view2.observe(\.text) { (observed, change) in
           if let newValue = change.newValue {
                view1.textToChange = newValue
           }
         }

     }

 }

【讨论】:

  • 我认为视图控制器应该对代表负责,而不是视图本身。
  • @J.Doe 理想情况下是的。这就是我在答案中包含解耦逻辑的原因。但是我想在某些情况下,假设您不使用像字符串这样的具体值,并且您可能希望对动画的调用完成?在我的理解中,ViewController 不应该关心它的某些子视图中动画的完成,但其他视图可能是。
【解决方案2】:

在上一个答案中建议使用委托或 KVO 在 2 个对象(可能是 UIView 或不是 UIView)之间进行通信。

您还可以使用完成处理程序,使用闭包非常简单。

下面是一个例子

class Object1 {
    func foo(completed: () -> Void) {
        print("do some work")
        completed()
    }
}

class Object2 {
    func callFoo() {
        let obj1 = Object1()
        obj1.foo {
            print("foo() from object 1 completed")
        }

    }
}


let obj2 = Object2()
obj2.callFoo()

// should print:
// do some work
// foo() from object 1 completed

【讨论】:

    猜你喜欢
    • 2015-09-13
    • 2017-12-27
    • 1970-01-01
    • 1970-01-01
    • 2021-05-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多