具有标签视图控制器的Segue保持传递值

时间:2016-11-11 00:48:44

标签: swift uitabbarcontroller segue

我正在开发一个围绕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方法中调用了上面的代码,但这没有意义,因为实际上数据只从“联系人”选项卡传递一次。谢谢!

2 个答案:

答案 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值。

抱歉我的英语不好。