我正在开发一个围绕Tab View Controller构建的iOS应用程序。我创建了一个" Contacts"选项卡,用户可以从列表中查找并选择联系人。当用户选择联系人时,它会获取联系人的姓名并将其传递给其他选项卡。该功能正在这样完成:
func passName(name: String) {
let navTab = self.tabBarController!.viewControllers![2] as! UINavigationController
let homeTab = navTab.viewControllers[0] as! MainController
homeTab.passedName = name
tabBarController?.selectedIndex = 2
}
到目前为止一切正常(名称加载到文本字段中)。我的问题是,每次更改标签然后返回“我的主页”选项卡时,值似乎都会继续回来。例如,如果我选择" John"从我的联系人那里,它将带我到Home标签,并将John的名字放在文本字段中。让我们说我删除了名字的最后两个字母,所以现在它是" Jo"。如果我加载一个不同的选项卡并返回,名称字段已重置为" John"。每次打开“主页”选项卡时,都会重新传递该值。此外,每次在传递名称后加载“主页”选项卡时,我的控制台都会打印:"名称已通过:约翰",因此它显示每次选项卡出现时都会处理此选项卡。这是我处理名称的代码:
var passedName: String!
override func viewWillAppear(animated: Bool) {
super.viewWillAppear(animated)
//Checks if name was passed to controller
if let validName = passedName {
print("Name passed: \(validName)")
nameTextField.text = validName
}
}
我是否错误地传递了数据?我想这可能是因为我在viewWillAppear方法中调用了上面的代码,但这没有意义,因为实际上数据只从“联系人”选项卡传递一次。谢谢!
答案 0 :(得分:1)
问题是您实际上没有将值传回原始视图。 Apple在类之间传递信息的建议是使用委托模式。这允许模态视图调用委托类的函数,该函数将名称本地更改为原始视图,因为该函数在原始视图的viewController中声明。您可以阅读有关模式in this tutorial的更多信息,但我还提供了与您的用例相关的简短示例。
mainViewController:
class namesTableViewController: UITableViewController, editNameDetailsViewControllerDelegate {
var name : String
@IBAction func editButtonPressed(_ sender: UIBarButtonItem) {
performSegue(withIdentifier: "editPerson", sender: self)
}
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "editPerson" { //Modal segue
let navController = segue.destination as! UINavigationController
let controller = navController.topViewController as! editNameViewController
controller.delegate = self
if let person = sender as? Person {
print("Sending person to edit")
controller.personToEdit = person
}
} else {
super.prepare(for: segue, sender: sender)
}
}
//Protocol function
func changeName(n: String, controller: UIViewController) {
name = n
dismiss(animated: true, completion: nil)
}
}
editNameViewController:
class editNameViewController: UIViewController {
@IBOutlet weak var personNameTextField: UITextField!
var personToEdit : Person?
weak var delegate : PersonTableViewController?
override func viewDidLoad() {
super.viewDidLoad()
if personToEdit != nil {
personNameTextField.text = personToEdit?.name
}
}
// Button Actions
@IBAction func saveButtonPressed(_ sender: UIBarButtonItem) {
delegate?.personDetailsView(n: personNameTextField.text, controller: self)
}
}
最后,协议类:
protocol editNameDetailsViewControllerDelegate : class {
func personDetailsView(n: String, controller: UIViewController)
}
希望这有帮助。
答案 1 :(得分:0)
问题是“passName”变量在每次在UITextField中编辑时都不会更改其值。请记住,每次更改选项卡时,UIViewController都将调用viewWillAppear和viewDidAppear。因此,一旦选择其他选项卡并返回,您的UITextField将始终显示passName值。
我建议您每次编辑文本字段时都应更新passName值。
抱歉我的英语不好。