Ios 将数据传递给TabBar控制器
我希望在两个ViewController之间传递数据,并抛出TabBarController。 在第一个ViewController中,我找到了文本字段和按钮。 在我找到的第二个标签里面。 当我在textField和push button中写入一些文本时,我希望这些文本出现在第二个ViewController的标签中。但什么也没发生 我的代码是: 第一个视图控制器:Ios 将数据传递给TabBar控制器,ios,iphone,swift,tabbar,Ios,Iphone,Swift,Tabbar,我希望在两个ViewController之间传递数据,并抛出TabBarController。 在第一个ViewController中,我找到了文本字段和按钮。 在我找到的第二个标签里面。 当我在textField和push button中写入一些文本时,我希望这些文本出现在第二个ViewController的标签中。但什么也没发生 我的代码是: 第一个视图控制器: import UIKit class FirstViewController: UIViewController { @
import UIKit
class FirstViewController: UIViewController {
@IBOutlet weak var textField: UITextField!
@IBAction func enter(_ sender: Any) {
if textField.text != "" {
if let window = UIApplication.shared.delegate?.window, let tabBarController = window?.rootViewController as? UITabBarController, let second = tabBarController.viewControllers?.first as? SecondViewController {
second.label.text = textField.text
tabBarController.selectedIndex = 0
}
}
}
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
}
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
import UIKit
class SecondViewController: UIViewController {
@IBOutlet weak var label: UILabel!
var myString = String()
override func viewDidLoad() {
super.viewDidLoad()
label.text = myString
// Do any additional setup after loading the view, typically from a nib.
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
import Foundation
import UIKit
protocol LabelChangeDelegate: class {
func changeLabelWithText(_ text: String?)
}
class FirstViewController: UIViewController {
weak var delegate: LabelChangeDelegate?
@IBOutlet weak var textField: UITextField!
@IBAction func enter(_ sender: UIButton) {
if textField.text != "" {
if let window = UIApplication.shared.delegate?.window, let tabBarController = window?.rootViewController as? UITabBarController {
//check if there are view controllers in the tabBarController
guard let vcList = tabBarController.viewControllers else {
return
}
for controller in vcList {
if let second = controller as? SecondViewController {
//this will be executed only when a controller is SeconfViewController
//set the delegate - who needs the data
delegate = second
//call the delegate function which will commmunicate with the delegate
delegate?.changeLabelWithText(textField.text!)
//don't know why you need this
tabBarController.selectedIndex = 0
}
}
}
}
}
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
}
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
import Foundation
import UIKit
class SecondViewController: UIViewController, LabelChangeDelegate {
@IBOutlet weak var label: UILabel!
//lazy init
lazy var myString = String()
override func viewDidLoad() {
super.viewDidLoad()
//set label when the view loads, not in the first controller
label.text = myString
// Do any additional setup after loading the view, typically from a nib.
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
//delegate function
func changeLabelWithText(_ text: String?) {
guard let sentText = text else {
//no text sent
return
}
myString = sentText
}
}
第二视图控制器:
import UIKit
class FirstViewController: UIViewController {
@IBOutlet weak var textField: UITextField!
@IBAction func enter(_ sender: Any) {
if textField.text != "" {
if let window = UIApplication.shared.delegate?.window, let tabBarController = window?.rootViewController as? UITabBarController, let second = tabBarController.viewControllers?.first as? SecondViewController {
second.label.text = textField.text
tabBarController.selectedIndex = 0
}
}
}
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
}
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
import UIKit
class SecondViewController: UIViewController {
@IBOutlet weak var label: UILabel!
var myString = String()
override func viewDidLoad() {
super.viewDidLoad()
label.text = myString
// Do any additional setup after loading the view, typically from a nib.
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
import Foundation
import UIKit
protocol LabelChangeDelegate: class {
func changeLabelWithText(_ text: String?)
}
class FirstViewController: UIViewController {
weak var delegate: LabelChangeDelegate?
@IBOutlet weak var textField: UITextField!
@IBAction func enter(_ sender: UIButton) {
if textField.text != "" {
if let window = UIApplication.shared.delegate?.window, let tabBarController = window?.rootViewController as? UITabBarController {
//check if there are view controllers in the tabBarController
guard let vcList = tabBarController.viewControllers else {
return
}
for controller in vcList {
if let second = controller as? SecondViewController {
//this will be executed only when a controller is SeconfViewController
//set the delegate - who needs the data
delegate = second
//call the delegate function which will commmunicate with the delegate
delegate?.changeLabelWithText(textField.text!)
//don't know why you need this
tabBarController.selectedIndex = 0
}
}
}
}
}
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
}
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
import Foundation
import UIKit
class SecondViewController: UIViewController, LabelChangeDelegate {
@IBOutlet weak var label: UILabel!
//lazy init
lazy var myString = String()
override func viewDidLoad() {
super.viewDidLoad()
//set label when the view loads, not in the first controller
label.text = myString
// Do any additional setup after loading the view, typically from a nib.
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
//delegate function
func changeLabelWithText(_ text: String?) {
guard let sentText = text else {
//no text sent
return
}
myString = sentText
}
}
我认为问题出在
tabBarController.viewControllers?.first as? SecondViewController
您可能希望这样做:
tabBarController.viewControllers?[1] as? SecondViewController
不要忘记数组是从0索引的,因此
viewControllers?[1]
实际上返回数组中的第二个元素。我认为问题出在
tabBarController.viewControllers?.first as? SecondViewController
您可能希望这样做:
tabBarController.viewControllers?[1] as? SecondViewController
不要忘记数组是从0索引的,因此
viewControllers?[1]
实际上返回数组中的第二个元素。首先,我认为表示选项卡的视图控制器应该嵌入导航控制器,然后链接到TabBarController
其次,在控制器之间发送数据的首选和推荐方式是通过协议(委托)。下面是一个很好的示例,您可以一步一步地查看:
然而,如果你正在寻找解决方案的快速解决方案,我认为布鲁诺·菲利普的回答在某种程度上是正确的,但不是完全正确的。我们无法确定视图控制器列表中的哪个索引中有哪个控制器。我认为这应该奏效:
@IBAction func enter(_ sender: Any) {
if textField.text != "" {
if let window = UIApplication.shared.delegate?.window, let tabBarController = window?.rootViewController as? UITabBarController {
//check if there are view controllers in the tabBarController
guard let vcList = tabBarController.viewControllers else {
return
}
for controller in vcList {
if let second = controller as? SecondViewController {
//this will be executed only when a controller is SeconfViewController
second.label.text = textField.text
tabBarController.selectedIndex = 0
}
}
}
}
}
编辑:
我自己尝试过,问题是您试图设置label.text,而事实上label组件从未初始化过。我认为,如果您只是将textField值存储到SecondViewController中的myString变量中,它就会工作(不确定)
然而,这里有一个使用协议(委托)的解决方案,这是在控制器之间发送数据的正确方式。问你可能有的任何问题。这应该起作用:
@IBAction func enter(_ sender: Any) {
if textField.text != "" {
if let window = UIApplication.shared.delegate?.window, let tabBarController = window?.rootViewController as? UITabBarController {
//check if there are view controllers in the tabBarController
guard let vcList = tabBarController.viewControllers else {
return
}
for controller in vcList {
if let second = controller as? SecondViewController {
//this will be executed only when a controller is SeconfViewController
second.label.text = textField.text
tabBarController.selectedIndex = 0
}
}
}
}
}
FirstViewController:
import UIKit
class FirstViewController: UIViewController {
@IBOutlet weak var textField: UITextField!
@IBAction func enter(_ sender: Any) {
if textField.text != "" {
if let window = UIApplication.shared.delegate?.window, let tabBarController = window?.rootViewController as? UITabBarController, let second = tabBarController.viewControllers?.first as? SecondViewController {
second.label.text = textField.text
tabBarController.selectedIndex = 0
}
}
}
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
}
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
import UIKit
class SecondViewController: UIViewController {
@IBOutlet weak var label: UILabel!
var myString = String()
override func viewDidLoad() {
super.viewDidLoad()
label.text = myString
// Do any additional setup after loading the view, typically from a nib.
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
import Foundation
import UIKit
protocol LabelChangeDelegate: class {
func changeLabelWithText(_ text: String?)
}
class FirstViewController: UIViewController {
weak var delegate: LabelChangeDelegate?
@IBOutlet weak var textField: UITextField!
@IBAction func enter(_ sender: UIButton) {
if textField.text != "" {
if let window = UIApplication.shared.delegate?.window, let tabBarController = window?.rootViewController as? UITabBarController {
//check if there are view controllers in the tabBarController
guard let vcList = tabBarController.viewControllers else {
return
}
for controller in vcList {
if let second = controller as? SecondViewController {
//this will be executed only when a controller is SeconfViewController
//set the delegate - who needs the data
delegate = second
//call the delegate function which will commmunicate with the delegate
delegate?.changeLabelWithText(textField.text!)
//don't know why you need this
tabBarController.selectedIndex = 0
}
}
}
}
}
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
}
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
import Foundation
import UIKit
class SecondViewController: UIViewController, LabelChangeDelegate {
@IBOutlet weak var label: UILabel!
//lazy init
lazy var myString = String()
override func viewDidLoad() {
super.viewDidLoad()
//set label when the view loads, not in the first controller
label.text = myString
// Do any additional setup after loading the view, typically from a nib.
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
//delegate function
func changeLabelWithText(_ text: String?) {
guard let sentText = text else {
//no text sent
return
}
myString = sentText
}
}
第二视图控制器:
import UIKit
class FirstViewController: UIViewController {
@IBOutlet weak var textField: UITextField!
@IBAction func enter(_ sender: Any) {
if textField.text != "" {
if let window = UIApplication.shared.delegate?.window, let tabBarController = window?.rootViewController as? UITabBarController, let second = tabBarController.viewControllers?.first as? SecondViewController {
second.label.text = textField.text
tabBarController.selectedIndex = 0
}
}
}
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
}
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
import UIKit
class SecondViewController: UIViewController {
@IBOutlet weak var label: UILabel!
var myString = String()
override func viewDidLoad() {
super.viewDidLoad()
label.text = myString
// Do any additional setup after loading the view, typically from a nib.
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
import Foundation
import UIKit
protocol LabelChangeDelegate: class {
func changeLabelWithText(_ text: String?)
}
class FirstViewController: UIViewController {
weak var delegate: LabelChangeDelegate?
@IBOutlet weak var textField: UITextField!
@IBAction func enter(_ sender: UIButton) {
if textField.text != "" {
if let window = UIApplication.shared.delegate?.window, let tabBarController = window?.rootViewController as? UITabBarController {
//check if there are view controllers in the tabBarController
guard let vcList = tabBarController.viewControllers else {
return
}
for controller in vcList {
if let second = controller as? SecondViewController {
//this will be executed only when a controller is SeconfViewController
//set the delegate - who needs the data
delegate = second
//call the delegate function which will commmunicate with the delegate
delegate?.changeLabelWithText(textField.text!)
//don't know why you need this
tabBarController.selectedIndex = 0
}
}
}
}
}
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
}
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
import Foundation
import UIKit
class SecondViewController: UIViewController, LabelChangeDelegate {
@IBOutlet weak var label: UILabel!
//lazy init
lazy var myString = String()
override func viewDidLoad() {
super.viewDidLoad()
//set label when the view loads, not in the first controller
label.text = myString
// Do any additional setup after loading the view, typically from a nib.
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
//delegate function
func changeLabelWithText(_ text: String?) {
guard let sentText = text else {
//no text sent
return
}
myString = sentText
}
}
首先,我认为表示选项卡的视图控制器应该嵌入到导航控制器中,然后链接到TabBarController 其次,在控制器之间发送数据的首选和推荐方式是通过协议(委托)。下面是一个很好的示例,您可以一步一步地查看: 然而,如果你正在寻找解决方案的快速解决方案,我认为布鲁诺·菲利普的回答在某种程度上是正确的,但不是完全正确的。我们无法确定视图控制器列表中的哪个索引中有哪个控制器。我认为这应该奏效:
@IBAction func enter(_ sender: Any) {
if textField.text != "" {
if let window = UIApplication.shared.delegate?.window, let tabBarController = window?.rootViewController as? UITabBarController {
//check if there are view controllers in the tabBarController
guard let vcList = tabBarController.viewControllers else {
return
}
for controller in vcList {
if let second = controller as? SecondViewController {
//this will be executed only when a controller is SeconfViewController
second.label.text = textField.text
tabBarController.selectedIndex = 0
}
}
}
}
}
编辑:
我自己尝试过,问题是您试图设置label.text,而事实上label组件从未初始化过。我认为,如果您只是将textField值存储到SecondViewController中的myString变量中,它就会工作(不确定)
然而,这里有一个使用协议(委托)的解决方案,这是在控制器之间发送数据的正确方式。问你可能有的任何问题。这应该起作用:
@IBAction func enter(_ sender: Any) {
if textField.text != "" {
if let window = UIApplication.shared.delegate?.window, let tabBarController = window?.rootViewController as? UITabBarController {
//check if there are view controllers in the tabBarController
guard let vcList = tabBarController.viewControllers else {
return
}
for controller in vcList {
if let second = controller as? SecondViewController {
//this will be executed only when a controller is SeconfViewController
second.label.text = textField.text
tabBarController.selectedIndex = 0
}
}
}
}
}
FirstViewController:
import UIKit
class FirstViewController: UIViewController {
@IBOutlet weak var textField: UITextField!
@IBAction func enter(_ sender: Any) {
if textField.text != "" {
if let window = UIApplication.shared.delegate?.window, let tabBarController = window?.rootViewController as? UITabBarController, let second = tabBarController.viewControllers?.first as? SecondViewController {
second.label.text = textField.text
tabBarController.selectedIndex = 0
}
}
}
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
}
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
import UIKit
class SecondViewController: UIViewController {
@IBOutlet weak var label: UILabel!
var myString = String()
override func viewDidLoad() {
super.viewDidLoad()
label.text = myString
// Do any additional setup after loading the view, typically from a nib.
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
import Foundation
import UIKit
protocol LabelChangeDelegate: class {
func changeLabelWithText(_ text: String?)
}
class FirstViewController: UIViewController {
weak var delegate: LabelChangeDelegate?
@IBOutlet weak var textField: UITextField!
@IBAction func enter(_ sender: UIButton) {
if textField.text != "" {
if let window = UIApplication.shared.delegate?.window, let tabBarController = window?.rootViewController as? UITabBarController {
//check if there are view controllers in the tabBarController
guard let vcList = tabBarController.viewControllers else {
return
}
for controller in vcList {
if let second = controller as? SecondViewController {
//this will be executed only when a controller is SeconfViewController
//set the delegate - who needs the data
delegate = second
//call the delegate function which will commmunicate with the delegate
delegate?.changeLabelWithText(textField.text!)
//don't know why you need this
tabBarController.selectedIndex = 0
}
}
}
}
}
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
}
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
import Foundation
import UIKit
class SecondViewController: UIViewController, LabelChangeDelegate {
@IBOutlet weak var label: UILabel!
//lazy init
lazy var myString = String()
override func viewDidLoad() {
super.viewDidLoad()
//set label when the view loads, not in the first controller
label.text = myString
// Do any additional setup after loading the view, typically from a nib.
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
//delegate function
func changeLabelWithText(_ text: String?) {
guard let sentText = text else {
//no text sent
return
}
myString = sentText
}
}
第二视图控制器:
import UIKit
class FirstViewController: UIViewController {
@IBOutlet weak var textField: UITextField!
@IBAction func enter(_ sender: Any) {
if textField.text != "" {
if let window = UIApplication.shared.delegate?.window, let tabBarController = window?.rootViewController as? UITabBarController, let second = tabBarController.viewControllers?.first as? SecondViewController {
second.label.text = textField.text
tabBarController.selectedIndex = 0
}
}
}
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
}
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
import UIKit
class SecondViewController: UIViewController {
@IBOutlet weak var label: UILabel!
var myString = String()
override func viewDidLoad() {
super.viewDidLoad()
label.text = myString
// Do any additional setup after loading the view, typically from a nib.
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
import Foundation
import UIKit
protocol LabelChangeDelegate: class {
func changeLabelWithText(_ text: String?)
}
class FirstViewController: UIViewController {
weak var delegate: LabelChangeDelegate?
@IBOutlet weak var textField: UITextField!
@IBAction func enter(_ sender: UIButton) {
if textField.text != "" {
if let window = UIApplication.shared.delegate?.window, let tabBarController = window?.rootViewController as? UITabBarController {
//check if there are view controllers in the tabBarController
guard let vcList = tabBarController.viewControllers else {
return
}
for controller in vcList {
if let second = controller as? SecondViewController {
//this will be executed only when a controller is SeconfViewController
//set the delegate - who needs the data
delegate = second
//call the delegate function which will commmunicate with the delegate
delegate?.changeLabelWithText(textField.text!)
//don't know why you need this
tabBarController.selectedIndex = 0
}
}
}
}
}
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
}
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
import Foundation
import UIKit
class SecondViewController: UIViewController, LabelChangeDelegate {
@IBOutlet weak var label: UILabel!
//lazy init
lazy var myString = String()
override func viewDidLoad() {
super.viewDidLoad()
//set label when the view loads, not in the first controller
label.text = myString
// Do any additional setup after loading the view, typically from a nib.
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
//delegate function
func changeLabelWithText(_ text: String?) {
guard let sentText = text else {
//no text sent
return
}
myString = sentText
}
}
我不建议你这样做。这是对理解的一种解释
tabBarController
。您可以使用self.tabBarController
访问它secondViewController
是viewControllers
solet second=tabBarController.viewControllers?[1]as?SecondViewController
secondViewController
,其视图将不会加载,因此插座仍将为nil
。您可以使用强制加载视图
tabBarController.selectedIndex=1
更好的方法… 您应该将字符串传递给
SecondViewController
的属性,而不是直接设置出口:
second.myString = textField.text ?? ""
然后将该字符串指定给覆盖视图的标签
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
label.text = myString
}
在viewwillbeen
中设置它的原因是viewwillbeen
将在每次显示视图之前运行viewDidLoad
仅在首次加载视图时运行一次。由于您希望该功能可以多次运行,视图将显示
是正确的覆盖方式。我不建议您这样做。这是对理解的一种解释
tabBarController中的ViewController知道它们的tabBarController
。您可以使用self.tabBarController
访问它
secondViewController
是viewControllers
solet second=tabBarController.viewControllers?[1]as?SecondViewController
如果您尚未访问secondViewController
,其视图将不会加载,因此插座仍将为nil
。您可以使用强制加载视图
如果要切换到第二个选项卡,则需要使用tabBarController.selectedIndex=1
更好的方法…
您应该将字符串传递给SecondViewController
的属性,而不是直接设置出口:
second.myString = textField.text ?? ""
然后将该字符串指定给覆盖视图的标签
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
label.text = myString
}
在viewwillbeen
中设置它的原因是viewwillbeen
将在每次显示视图之前运行viewDidLoad
仅在首次加载视图时运行一次。由于您希望该功能能够多次工作,viewwillbeen
是正确的覆盖。致命错误:在展开可选值时意外发现nil否,不工作=(f