【问题标题】:Pass data between ViewController and ContainerViewController在 ViewController 和 ContainerViewController 之间传递数据
【发布时间】:2016-03-24 17:30:10
【问题描述】:

我正在开发一个应用程序,需要在视图和容器视图之间传递数据。我需要从两个视图发送数据和接收数据。

让我解释得更好:

我可以通过protocol更改Label Master(触摸容器按钮),但不能更改标签容器(触摸容器按钮)主按钮)。发生的情况是 Master 通过以下方式与容器连接。但是没有一个follow Container链接到Master。

我尝试添加但继续,但它起作用了。

主视图控制器:

import UIKit

protocol MasterToContainer {
    func changeLabel(text:String)
}

class Master: UIViewController, ContainerToMaster {

    @IBOutlet var containerView: UIView!

    var masterToContainer:MasterToContainer?

    @IBOutlet var labelMaster: UILabel!


    override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
        if segue.identifier == "containerViewSegue" {
            let view = segue.destinationViewController as? Container
            view!.containerToMaster = self
        }
    }

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

    @IBAction func button_Container(sender: AnyObject) {
        masterToContainer?.changeLabel("Nice! It's work!")
    }


    func changeLabel(text: String) {
        labelMaster.text = text
    }
}

容器视图控制器:

import UIKit

protocol ContainerToMaster {
    func changeLabel(text:String)
}

class Container: UIViewController, MasterToContainer {

    var containerToMaster:ContainerToMaster?

    @IBOutlet var labelContainer: UILabel!

    override func viewDidLoad() {
        super.viewDidLoad()

    }

    @IBAction func button_Master(sender: AnyObject) {
        containerToMaster?.changeLabel("Amazing! It's work!")
    }


    func changeLabel(text: String) {
        labelContainer.text = text
    }
}

有人可以帮我吗?

【问题讨论】:

  • 如果您使用 NSUserDefaults 存储要发送的值怎么办?
  • 我正在寻找一种使用协议的方法,但还没有找到任何东西。如何使用 NSUserDefaults 来传递这些数据?
  • 在objective-c中寻找相同的解决方案

标签: swift swift2 segue uistoryboardsegue swift-protocols


【解决方案1】:

您需要做的就是在您的主视图控制器中保留对Container 的引用。

也就是说,您应该向Master 添加一个实例变量,该变量将保存对视图控制器的引用,而不仅仅是视图。您需要将其设置为prepareForSegue。

所以主视图控制器的开头看起来像这样:

class Master: UIViewController, ContainerToMaster {

@IBOutlet var containerView: UIView!

var containerViewController: Container?

@IBOutlet var labelMaster: UILabel!

override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
    if segue.identifier == "containerViewSegue" {
        containerViewController = segue.destinationViewController as? Container
        containerViewController!.containerToMaster = self
    }
}

然后在您的按钮功能中,只需使用您刚刚添加的变量更改标签。

例子:

@IBAction func button_Container(sender: AnyObject) {
    containerViewController?.changeLabel("Nice! It's work!")
}

这意味着您也可以摆脱 MasterToContainer 协议。

我测试了这段代码,所以我知道它可以工作,但不幸的是,我是一名 Objective-C 开发人员,对 Swift 的最佳实践一无所知。所以我不知道这是否是最好的方法,但它确实有效。

编辑:

这是我测试过的确切代码:

Master.swift:

import UIKit

class Master: UIViewController, ContainerToMaster {

    @IBOutlet var containerView: UIView!
    @IBOutlet var labelMaster: UILabel!
    var containerViewController: Container?

    override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
        if segue.identifier == "containerViewSegue" {
            containerViewController = segue.destinationViewController as? Container
            containerViewController!.containerToMaster = self
        }
    }

    @IBAction func button_Container(sender: AnyObject) {
        containerViewController?.changeLabel("Nice! It's work!")
    }

    func changeLabel(text: String) {
        labelMaster.text = text
    }
}

Container.swift:

import UIKit

protocol ContainerToMaster {
    func changeLabel(text:String)
}

class Container: UIViewController {

    @IBOutlet var labelContainer: UILabel!
    var containerToMaster:ContainerToMaster?

    @IBAction func button_Master(sender: AnyObject) {
        containerToMaster?.changeLabel("Amazing! It's work!")
    }

    func changeLabel(text: String) {
        labelContainer.text = text
    }
}

【讨论】:

  • 这基本上就是我所拥有的。我必须将Master与Container连接起来。但我没有追随者。
  • @James Downvote?严重地?我想在这里帮助你。 “我没有追随者”是什么意思?据我了解,您希望Master 中的按钮更改Container 中的标签。不对吗?
  • 投反对票:显然,您得到了我发布的示例代码,并且我“被教导使用”。我需要什么:我需要一个视图来向另一个视图发送数据我只有一个 segue,将 Master 链接到容器,因此容器可以通过主协议“通信”。我需要 Master 的 Container “is cominique”。
  • @James 我几乎听不懂你,但我用我测试的完整代码更新了我的答案。 Master 可以使用变量containerViewController 向Container 发送数据,Container 可以使用containerToMaster 变量向Master 发送数据,这符合ContainerToMaster 协议。我认为您缺少的部分是将变量设置为 prepareForSegue 而不是使用常量。
  • 对不起我的英语,我是巴西人。这个问题是第四个问题,我做什么才能得到我真正需要的结果。感谢您的回答,并为 Downvote 道歉。
【解决方案2】:

我用这段代码解决了它

从 ViewController 发送数据 -> ContainerViewController

Class ViewController : UIViewController {

func sendData(MyStringToSend : String) {

let CVC = childViewControllers.last as! ContainerViewController
CVC.ChangeLabel( MyStringToSend)
}

}

在您的 ContainerViewController 中

Class ContainerViewController : UIViewController {

@IBOutlet weak var myLabel: UILabel!

func ChangeLabel(labelToChange : String){

myLabel.text = labelToChange

 }
}

从 ContainerViewController -> ViewController 发送数据

Class ContainerViewController : UIViewController {

func sendDataToVc(myString : String) {

   let Vc = parentViewController as! ViewController
   Vc.dataFromContainer(myString)
 }

}

在 ViewController 中

  Class ViewController : UIViewController {

  func dataFromContainer(containerData : String){

   print(containerData)
  }

  }

我希望这会对某人有所帮助。

【讨论】:

  • 感谢 rob 非常简单干净。
  • childViewControllers 是什么?
【解决方案3】:

你可以使用这个扩展来访问容器子

extension UIViewController {
  func getContainerChild<vc:UIViewController>(_ viewController : vc,_ hasNavigation : Bool = true) -> (vc) {
    guard let vc = self.children[0] as? UINavigationController else {return viewController}
    if hasNavigation {
        guard let childVC = vc.children[0] as? PurchasedHistoryListVC else {
            return viewController}
        return childVC as! vc
    } else {
        return vc as! vc
    }
   }
}

所以你可以在你的视图控制器中做一些这样的事情

let vc = self.getContainerChild(yourChildViewControllerClass())
vc.functionName()

【讨论】:

    猜你喜欢
    • 2017-01-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-12-05
    • 1970-01-01
    • 2020-08-23
    • 1970-01-01
    • 2017-12-09
    相关资源
    最近更新 更多