在 ViewController 和 ContainerViewController 之间传递数据
Pass data between ViewController and ContainerViewController
我正在开发一个应用程序,需要在视图和容器视图之间传递数据。我需要从两个视图发送数据和接收数据。
让我更好地解释一下:
我可以通过协议更改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
}
}
有人可以帮助我吗?
您需要做的就是在主视图控制器中保留对 Container
的引用。
也就是说,您应该向 Master
添加一个实例变量,它将保存对 视图控制器 的引用,而不仅仅是视图。您需要在 prepareForSegue
.
中进行设置
所以 Master View Controller 的开头看起来像这样:
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
}
}
我用这段代码解决了
从ViewController发送数据 -> 容器ViewController
Class ViewController : UIViewController {
func sendData(MyStringToSend : String) {
let CVC = childViewControllers.last as! ContainerViewController
CVC.ChangeLabel( MyStringToSend)
}
}
在您的容器中ViewController
Class ContainerViewController : UIViewController {
@IBOutlet weak var myLabel: UILabel!
func ChangeLabel(labelToChange : String){
myLabel.text = labelToChange
}
}
从容器发送数据ViewController -> 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)
}
}
我希望这会对某人有所帮助。
您可以使用此扩展来访问子容器
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()
我正在开发一个应用程序,需要在视图和容器视图之间传递数据。我需要从两个视图发送数据和接收数据。
让我更好地解释一下:
我可以通过协议更改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
}
}
有人可以帮助我吗?
您需要做的就是在主视图控制器中保留对 Container
的引用。
也就是说,您应该向 Master
添加一个实例变量,它将保存对 视图控制器 的引用,而不仅仅是视图。您需要在 prepareForSegue
.
所以 Master View Controller 的开头看起来像这样:
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
}
}
我用这段代码解决了
从ViewController发送数据 -> 容器ViewController
Class ViewController : UIViewController {
func sendData(MyStringToSend : String) {
let CVC = childViewControllers.last as! ContainerViewController
CVC.ChangeLabel( MyStringToSend)
}
}
在您的容器中ViewController
Class ContainerViewController : UIViewController {
@IBOutlet weak var myLabel: UILabel!
func ChangeLabel(labelToChange : String){
myLabel.text = labelToChange
}
}
从容器发送数据ViewController -> 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)
}
}
我希望这会对某人有所帮助。
您可以使用此扩展来访问子容器
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()