2016-11-20 4 views
-5

Ich habe diese Tabellenansicht und ich möchte den Benutzernamen an einen View-Controller übergeben und es dort in einem Etikett anzeigen, aber es funktioniert nicht. Der Benutzername stammt aus einer Firebase-Datenbank. Ich habe auch andere Fragen überprüft, kann sie aber nicht auf mein Problem anwenden. Ich bin kein Experte in Codierung:Übergeben von Daten Tableview -> Viewcontroller

import Foundation 
import UIKit 
import Firebase 
import FirebaseDatabase 
import FirebaseAuth 

struct user { 
    let username : String! 
} 

class MainScreen: UITableViewController { 

    var Users = [user]() 

    override func viewDidLoad() { 

    let databaseRef = FIRDatabase.database().reference() 

    databaseRef.child("users").queryOrderedByKey() 
       .observe(.childAdded, with: { snapshot in 

     print(snapshot) 
     let username = (snapshot.value as? NSDictionary)!["username"] as! String 
     print(username) 
     self.Users.append(user(username: username)) 
     self.tableView.reloadData() 
     print(self.Users) 
    }) 
} 

override func tableView(_ tableView: UITableView, 
         numberOfRowsInSection section: Int) -> Int { 
    return Users.count 
} 

override func tableView(_ tableView: UITableView, 
         cellForRowAt indexPath: IndexPath) -> UITableViewCell { 

    let cell = tableView.dequeueReusableCell(withIdentifier: "Cell") 
    let nameLbl = cell?.viewWithTag(1) as! UILabel 
    nameLbl.text = self.Users[indexPath.row].username 
    return cell! 
    } 

@IBAction func ShowDetail(_ sender: Any) { 
    var selectedLabel:String? 

    func tableView(tableView: UITableView, 
        didSelectRowAtIndexPath indexPath: NSIndexPath) { 
     print("Row \(indexPath.row)selected") 
     selectedLabel = self.Users[indexPath.row].username 
     performSegue(withIdentifier: "detailView", sender: self) 
    } 

    func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) { 

     if(segue.identifier == "detailView") { 
      let vc = segue.destination as! CallDetail 
      vc.stringPassed = selectedLabel! 
     } 
    } 
} 

und die Empfangsviewcontroller sieht wie folgt aus:

import UIKit 

class CallDetail: UIViewController { 

    @IBOutlet weak var UserName: UILabel! 
    var stringPassed = String() 

    override func viewDidLoad() { 
     super.viewDidLoad() 

     UserName = stringPassed.text 
    } 
} 
+0

was ist der Zweck der func showdetail (_ Absender: ANY) Methode? Sie sollten seine innere Methode auf der gleichen Klassenbereichsebene implementieren –

+0

Können Sie uns sagen, was nicht funktioniert? Zum Beispiel, in Ihrer Beobachtung Schließung, druckt (Schnappschuss) den Schnappschuss? Gibt print (Benutzername) den Benutzernamen aus? Wohin gehen Sie die Daten? Es scheint, dass es in einem Array gespeichert ist und dann einer Variablen zugewiesen wird, sobald der viewController instanziiert ist (was den Benutzernamen nicht weitergibt) – Jay

+0

Hi Jay, tut mir leid, dass ich nicht genau genug bin. Das einzige, was aus meiner Sicht nicht funktioniert, ist die Weitergabe der Daten. Das Label im neuen Viewcontroller bleibt also leer. Ich übergebe die Daten an einen anderen View-Controller und dort sollte der Benutzername im Label-Feld erscheinen. Im Wesentlichen versuche ich eine Tabellenansicht mit einem Detail (Detail im Viewcontroller) zu erstellen. –

Antwort

0

Beide didSelectRowAtIndexPath und prepareForSegue Methoden sollten außerhalb von @IBAction func ShowDetail(_ sender: Any) (eigentlich sein, ich kann den Zweck nicht verstehen davon):

erklären selectedLabel als Instanzvariable und trenne die Methoden:

import Foundation 
import UIKit 
import Firebase 
import FirebaseDatabase 
import FirebaseAuth 

struct user { 
    let username : String! 
} 

class MainScreen: UITableViewController { 

    // 'selectedLabel' should be here: 
    var selectedLabel:String? 

    var Users = [user]() 

    override func viewDidLoad() { 

     let databaseRef = FIRDatabase.database().reference() 

     databaseRef.child("users").queryOrderedByKey().observe(.childAdded, with: { 
      snapshot in 

      print(snapshot) 

      let username  = (snapshot.value as? NSDictionary)!["username"] as! String 

      print(username) 

      self.Users.append(user(username: username)) 

      self.tableView.reloadData() 

      print(self.Users) 

     }) 
    } 

    override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { 
     return Users.count 
    } 
    override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { 

     let cell = tableView.dequeueReusableCell(withIdentifier: "Cell") 

     let nameLbl = cell?.viewWithTag(1) as! UILabel 

     nameLbl.text = self.Users[indexPath.row].username 

     return cell! 

    } 

    func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) { 
     print("Row \(indexPath.row)selected") 
     selectedLabel = self.Users[indexPath.row].username 
     performSegue(withIdentifier: "detailView", sender: self) 
    } 

    func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) { 
     if(segue.identifier == "detailView") { 
      let vc = segue.destination as! CallDetail 

      vc.stringPassed = selectedLabel! 
     } 
    } 

    // just remove it if you don't need it... 
    @IBAction func ShowDetail(_ sender: Any) { 

    } 

} 

Stellen Sie außerdem sicher, dass die Datenquelle und der Delegate der TabelleView mit dem viewController verbunden sind.

+0

Danke Ahmed, aber es funktioniert immer noch nicht. Ich habe den folgenden Fehler im Compiler: fataler Fehler: unerwartet gefunden Null beim Entpacken ein optionaler Wert –

+0

debuggen Sie den Code, wo dieser Fehler generiert? –

+0

der Fehler wird in der DetailViewController generiert: Klasse CallDetail: UIViewController { @IBOutlet schwach var UserName: UILabel! var stringPassed: Zeichenfolge? Überschreibung func viewDidLoad() { super.viewDidLoad() UserName.text = stringPassed –

0

Zuerst müssen Sie

tableView(tableView: UITableView, didSelectRowAtIndexPath entfernen, weil es automatisch aufgerufen wird, wenn Sie auf eine Zelle klicken, wenn Sie die Tableview Delegierter der Viewcontroller festgelegt haben.

prepareForSegue wird nach performSegue(withIdentifier: "detailView", sender: self) aufgerufen und löschen ShowDetail(_ sender: Any) es ist nicht notwendig.

und ändern diese Linien

let nameLbl = cell?.viewWithTag(1) as! UILabel 

nameLbl.text = self.Users[indexPath.row].username 

zu

cell.textLabel?.text = self.Users[indexPath.row].username 
Verwandte Themen