我将从上面重复我的评论开始。
可能你误解了 Swift 中全局变量的概念。
如果您有一个全局变量,则不必在任何视图/方法/类等之间“传递”它,因为该变量是在全局范围内定义的(可在任何地方访问)。
一般来说,全局变量不是一个好主意,也是你想要避免的。
关于全局变量和 swift 的问题,您确实应该将单例包括在讨论中。参见例如以下现有的 SO 线程:
TableViewController 和 ViewController 之间通过 segue 进行通信(准备和展开 segue)
(这个答案最终可能非常彻底,因为我不知道您当前的 tableview/viewcontroller 程序状态的详细信息。对于冗长的答案以及它可能给读者带来的任何不便,我们深表歉意)。
现在,让我们保留全局变量并讨论一个(以及其他)可行选项,用于在您的示例中的两个控制器之间进行通信。根据您的问题,我将您的示例总结如下
- VC1:故事板入口点,
UITableViewController
由UITableViewCell
s 组成,在这些单元格中,您可以显示一些文本,例如,通过UILabel
.
- VC2 : a
UIViewController
,可从 VC1 的单元访问,包含一个UITextField
实例。当用户在此文本字段中输入文本时,您希望文本显示在 VC2 中的关联单元格中(关联的意思是 VC1 中用于访问 VC2 的单元格)。
我们将分别将 VC1 和 VC2 与(可可触摸)类TableViewController
(TableViewController.swift)和ViewController
(ViewController.swift)相关联。表格视图控制器中的单元格将与(可可触摸)类TableViewCell
(TableViewCell.swift)相关联。这些课程的详细信息如下。
对于这个简单的示例,请注意我们不会将 VC1 嵌入到导航控制器中(否则它适用于表格视图 -> 视图导航)。
Table View Controller
我们将从情节提要开始,为 a和 a添加对象(从对象库中拖放)View Controller
。表格视图容器还将自动在Table View
其TableViewCell
. 继续故事板:
- 将
UILabel
对象添加到TableViewCell
容器中Table View Controller
(根据需要对齐)
- 在 中
View Controller
,添加一个Text Field
对象和一个Button
对象(根据需要对齐它们)。
- 将入口点设置为
Table View Controller
.
- 此后,按住 Ctrl 键将“显示”segue 从
TableViewCell
拖到View Controller
.
- 选择
Show
segue,然后从 Attributes 检查器中输入它的标识符,例如ShowDetail。
- 最后,
TableViewCell
选择,(如上;来自属性检查器),输入单元格的标识符。在这里,我们将简单地使用标识符TableViewCell。
我们现在暂时离开情节提要并实现三个类,与Table View Controller
、 theView Controller
和 forms'相关联TableViewCell
。
我们从 开始Table View Controller
,并实现我们的UITableViewController
子类。请注意,在这里,我们将简单地使用数组,而不是使用 anNSMutableArray
来保存每个单元格中的文本。UITextLabel
String
// TableViewController.swift
Import UIKit
class TableViewController: UITableViewController {
// Properties
var userTextLabels = [String]()
var numberOfCells: Int?
override func viewDidLoad() {
super.viewDidLoad()
numberOfCells = loadSampleTextLabels() // Load sample labels.
}
func loadSampleTextLabels() -> Int {
userTextLabels += ["Label #1", "Label #2", "Label #3"]
return userTextLabels.count
}
// func numberOfSectionsInTableView(tableView: UITableView) ...
// func tableView(tableView: UITableView, numberOfRowsInSection section: Int) ...
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cellIdentifier = ("TableViewCell")
let cell = tableView.dequeueReusableCellWithIdentifier(cellIdentifier, forIndexPath: indexPath) as! TableViewCell
// Text for current cell
let cellText = userTextLabels[indexPath.row]
cell.userSuppliedTextLabel.text = cellText
return cell
}
// ... communication?
}
其中两个注释掉的方法是 any 中使用的标准方法UITableViewController
,分别用于表中的部分(例如return 1
)和单元格(例如return (numberOfCells ?? 0)
)的数量。我会把这些问题留给你解决。
现在,我们TableViewCell
将表视图中的对象与子类的实例相关联UITableViewCell
。在这里,我们将为我们的单元格使用一个非常简单的类;每个单元格只包含一个UILabel
实例(通过情节提要 Ctrl 拖动创建为@IBOutlet
表格UILabel
视图单元格中的一个)。
// TableViewCell.swift
import UIKit
class TableViewCell: UITableViewCell {
// Properties
@IBOutlet weak var userSuppliedTextLabel: UILabel!
// Ctrl-drag from UILabel (in TableViewCell) in storyboard
override func awakeFromNib() {
super.awakeFromNib()
}
override func setSelected(selected: Bool, animated: Bool) {
super.setSelected(selected, animated: animated)
}
}
最后,对于从表格视图单元格访问的视图控制器:使用单个@IBOutlet
用于UITextField
用户文本输入,并使用预先存在的UITextFieldDelegate
. 例如:
// ViewController.swift
import UIKit
class ViewController: UIViewController, UITextFieldDelegate {
// Properties
@IBOutlet weak var userSuppliedText: UITextField!
// Ctrl-drag from storyboard...
var cellText: String?
override func viewDidLoad() {
super.viewDidLoad()
userSuppliedText.text = cellText ?? "..."
// Handle the user input in the text field through delegate callbacks
userSuppliedText.delegate = self
}
// UITextFieldDelegate
func textFieldShouldReturn(textField: UITextField) -> Bool {
// User finished typing (hit return): hide the keyboard.
textField.resignFirstResponder()
return true
}
func textFieldDidEndEditing(textField: UITextField) {
cellText = textField.text
}
}
我们还在cellText
这里声明了一个字符串属性 ( ),它将充当 VC1 和 VC2 之间通信的容器。
我们返回到故事板,并且——从身份检查器中——将三个故事板对象 ( Table View Controller
, View Controller
, TableViewCell
) 与我们刚刚在上面编写的相关类相关联。
我们现在几乎达到了我们的目标;它只剩下指定如何在两个控制器之间进行通信。
我们将从VC1到VC2 的通信开始。在您上面的评论中,通过查看该prepareForSegue(...)
方法,您走在了正确的轨道上(无论如何,对于这个特定的解决方案)。在 的类中Table View Controller
,我们添加以下方法:
// ... add to TableViewController.swift
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
// Get the new view controller using segue.destinationViewController.
// Pass the selected object to the new view controller.
if segue.identifier == "ShowDetail" {
let viewController = segue.destinationViewController as! ViewController
if let selectedCell = sender as? TableViewCell {
let indexPath = tableView.indexPathForCell(selectedCell)!
let currentTextInCell = userTextLabels[indexPath.row]
viewController.cellText = currentTextInCell // <-- note this
}
}
}
因此,对于 VC1->VC2 通信,我们可以(在此示例中)将当前占用UILabel
发送方单元格中的任何现有文本(由字符串数组指定userTextLabels
)。查看ViewController.swiftviewDidLoad(...)
中的方法,了解该值如何从 VC1 传递并在 VC2 中设置为默认文本。UITextField
现在,对于通信 VC2->VC1,这是您询问的具体通信方向,再次添加另一个方法(以编程方式)到TableViewController.swift:
// ... add to TableViewController.swift
@IBAction func unwindToTableView(sender: UIStoryboardSegue) {
if let sourceViewController = sender.sourceViewController as? ViewController,
text = sourceViewController.cellText {
// ^ note 2nd clause of if let statement above
if let selectedIndexPath = tableView.indexPathForSelectedRow {
// Update cell text
userTextLabels[selectedIndexPath.row] = text
tableView.reloadRowsAtIndexPaths([selectedIndexPath], withRowAnimation: .None)
}
}
}
在这里,我们定义了一个展开动作,当它被触发时,它会检索作为cellText
segue 源的视图控制器的属性,即在我们的例子中是ViewController
. 但是我们如何触发这个动作呢?
返回故事板和View Controller
. 请注意对象顶部的三个小图标View Controller
,更具体地说,是其中最右边的,命名为Exit
. 按住 Ctrl 键将动作从您Button
的图标拖到Exit
图标上,然后选择unwindToTableView
Action Segue。当您单击视图控制器按钮时,视图展开(退出)并降落unwindToTableView
在TableViewController
.
生成的应用程序应如下所示:
这比我预期的要长得多,但是一旦你开始编写......无论如何,上面的方法自然而然地不使用全局变量,而是使用对未来(prepareForSegue
)或历史(unwindToTableView
)视图的引用来获取(通常来自当前或历史视图)或通过使用这些引用(对未来/历史视图)设置(通常在未来视图中的当前)值。
Apple 在 tableviewcontroller/viewcontroller 上下文中的示例应用程序上有他们自己的非常详尽的教程,我建议您复习一下。当我开始编写 Swift 代码时,我自己发现它非常有价值。
开始开发 iOS 应用程序 (Swift)