2016-11-11 115 views
0

我正在構建一個基於Tab View Controller的iOS應用程序。我創建了一個「聯繫人」選項卡,用戶可以從列表中找到並選擇聯繫人。當用戶選擇聯繫人時,它將接收聯繫人的姓名並將其傳遞到不同的選項卡。該功能正在做像這樣:因爲它應該到目前爲止(名稱被加載到文本字段)Segue w/Tab View Controller保持傳遞值

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

問題是每當在UITextField中編輯它時,「passedName」變量都不會改變它的值。請記住,每次更改選項卡時,UIViewController都會調用viewWillAppear和viewDidAppear。因此,一旦您選擇其他選項卡並返回,您的UITextField將始終顯示passedName值。

我建議您每次編輯文本字段時都應該更新一次通過名稱的值。

對不起,我的英語不好。

+0

謝謝!如果我更新了passedName值,當我更改標籤並返回時,它是否會被覆蓋?將代碼放在viewDidLoad中可能會改變這一點嗎? – JD2017

+0

不,請勿將其放入viewDidLoad中,因爲每次回到該選項卡時都不會調用它。只要讓它在viewWillAppear中並在更改UiTextField時繼續更新passedName –

+0

正確,但是我所說的每次加載Home選項卡時,都會更新passedName。因此,無論我是否更改並更新值,如果切換標籤並返回,它將被傳遞值 – JD2017

0

問題是,你實際上沒有將值傳遞迴原始視圖。 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) 
} 

希望這有助於。

+0

謝謝!我唯一的問題是,我不相信這個解決方案適用於Tab Bar Controller。我有一個標籤欄控制器,並且這些標籤的各個視圖都嵌入在導航控制器中 – JD2017

相關問題