2016-09-07 6 views
0

Я новичок в Swift. Я пытаюсь передать данные между двумя контроллерами View. Значение, которое я передаю с первого контроллера представления, равно нулю, когда используется вторым контроллером представления. Я не понимаю, почему это происходит.Swift Переданные данные между контроллерами просмотра остаются пустыми

Это мой вызов функции tableView в первом контроллере. Он получает информацию пользователя выбранной ячейки таблицы.

override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) { 

    let user = User() 


    if(messages.count > 0) { 
     let message = self.messages[indexPath.row] 

     guard let chatPartnerID = message.chatPartnerID() else { 
      return 
     } 


     let ref = FIRDatabase.database().reference().child("users").child(chatPartnerID) 
     ref.observeSingleEventOfType(.Value, withBlock: { (snapshot) in 

      guard let dictionary = snapshot.value as? [String: AnyObject] 
       else { 
        return 
      } 

      user.id = chatPartnerID 
      user.setValuesForKeysWithDictionary(dictionary) 
      self.setupChatLogControllerForUser(user) 

      }, withCancelBlock: nil) 
    }else { 
     let user = users[indexPath.row] 
     self.setupChatLogControllerForUser(user) 
    } 


} 

User в NSObject, который я объявить следующим образом:

class User: NSObject { 

    var id: String? 
    var name: String? 
    var email: String? 
    var profileImageUrl: String? 
} 

Метод setupChatLogControllerForUser(user) в первом контроллере представления принимает в параметре пользователя, который задается в методе tableView и передается на вторую точку зрения контроллер (ChatLogController) примерно:

func setupChatLogControllerForUser(user: User) { 
    let chatLogController = ChatLogController() 
    chatLogController.selectedUserID = user.id! 
    chatLogController.user = user 
} 

Мой второй контроллер просмотра Метод принимает данные с этим:

var selectedUserID = String() 
var user = User() 

Второй контроллер вид также имеет handleSend метод, который связан с кнопкой на моем раскадровки через IBAction.

func handleSend() { 

    let ref = FIRDatabase.database().reference().child("messages") 
    let childRef = ref.childByAutoId() 
    let toID = self.selectedUserID 
    let fromID = FIRAuth.auth()!.currentUser!.uid 
    let timestamp: NSNumber = Int(NSDate().timeIntervalSince1970) 

    let values = ["text": messageInputField.text!, "toID": toID, "fromID": fromID, "timestamp": timestamp] 
    childRef.updateChildValues(values) { (error, ref) in 

     if error != nil { 
      print(error) 
      return 
     } 

     let userMessagesRef = FIRDatabase.database().reference().child("userMessages").child(fromID) 

     let messageID = childRef.key 
     userMessagesRef.updateChildValues([messageID: 1]) 

     let recipientUserMessagesRef = FIRDatabase.database().reference().child("userMessages").child(toID) 
     recipientUserMessagesRef.updateChildValues([messageID: 1]) 

    } 

} 

Этот метод является причиной проблемы. Я установил toID, равный selectedUserID. В отладчике я могу увидеть selectedUserID, заполненный строкой, когда контроллер вида перейдет на ChatLogController. Почему значение selectedUserID переменной nil при вызове метода?

Я понимаю, что передача в selectedUserID и User объекта избыточна, я просто хотел посмотреть, была ли проблема с чем-то, когда переменная String передается между классами, но она остается нулевой.

Любая помощь была бы замечательной!

EDIT: Я использую SEGUE для переключения между моими контроллерами зрения

+0

Как вам перейти от вашего первого vc к второму vc? segue или программно? – Tj3n

+0

вы должны выполнить segue вместо нового ChatLogController() – WeiJay

+0

Проблема заключается в 'ChatLogController()'. Это новый пустой экземпляр вместо ожидаемого контроллера в раскадровке. – vadian

ответ

0

Вам не нужно создать экземпляр ChatLogController для передачи данных, так как если вы создали NavigationController должным образом, то он собирается создать для вас.

func setupChatLogControllerForUser(user: User) { 
    let chatLogController = ChatLogController() 
    chatLogController.selectedUserID = user.id! 
    chatLogController.user = user 
} 

Так что, если вы хотите, чтобы передать данные ChatLogController, вы должны использовать prepareForSegue метод для этой цели.


Я собираюсь предоставить простой пример, как можно имитировать этот тип функциональности:

Это результат:

enter image description here


Это мой раскадровка:

Обратите внимание, что имя segue - showDetail, как вы можете видеть на фотографии.

enter image description here


Это код моего TableViewController:

Когда я касаюсь ячейку на TableViewController, тем didSelectRowAtIndexPath метод вызывается, то получить доступ к ячейке выбрано и задано значение dataToSend переменная, наконец, я звоню performSe gueWithIdentifier, чтобы перейти к ViewController.

Но прямо перед тем, что идет в ViewController, prepareForSegue метод называется поэтому у вас есть возможность здесь, чтобы передать любую переменную, которая ViewController ожидает, в этом случае я передаю dataToSend к ViewController в dataSent переменная.

class TableViewController: UITableViewController { 

    var dataToSend = "" 

    override func viewDidLoad() { 
    super.viewDidLoad() 
    } 

    override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) { 
    let cell = tableView.cellForRowAtIndexPath(indexPath) 

    dataToSend = cell!.textLabel!.text! 

    performSegueWithIdentifier("showDetail", sender: nil) 
    } 

    override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) { 
    if segue.identifier == "showDetail" { 
     if let viewController = segue.destinationViewController as? ViewController { 
     viewController.dataSent = dataToSend 
     } 
    } 
    } 

} 

Это код для ViewController:

для то я могу показать значение в этикетке.

class ViewController: UIViewController { 
    @IBOutlet weak var label: UILabel! 

    var dataSent = String() 

    override func viewDidLoad() { 
    super.viewDidLoad() 

    label.text = dataSent 
    } 

} 
+0

Большое спасибо за четкое объяснение, это сработало! –

Смежные вопросы