Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/swift/18.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Swift 如何将变量从secondViewController传递到TableViewController中的loadData()函数?_Swift_Google Cloud Firestore - Fatal编程技术网

Swift 如何将变量从secondViewController传递到TableViewController中的loadData()函数?

Swift 如何将变量从secondViewController传递到TableViewController中的loadData()函数?,swift,google-cloud-firestore,Swift,Google Cloud Firestore,这是我的第一个Swift/Firestore practice应用程序,我正在尝试访问要在“EventTableViewController”文件中使用的“AddEventViewController”文件中的变量(eventLocation、eventDate) 然而,我似乎无法找出遗漏了什么或者我做错了什么 希望能得到经验丰富的人的帮助。非常感谢 EventTableViewController.swift import UIKit import FirebaseFirestore cl

这是我的第一个Swift/Firestore practice应用程序,我正在尝试访问要在“EventTableViewController”文件中使用的“AddEventViewController”文件中的变量(eventLocation、eventDate)

然而,我似乎无法找出遗漏了什么或者我做错了什么

希望能得到经验丰富的人的帮助。非常感谢

EventTableViewController.swift

import UIKit
import FirebaseFirestore

class EventsTableViewController: UITableViewController {

 var eventsArray = [Event]()

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

func loadData() {
// How to pass variables from 'AddEventViewController' and use it inside this function??

   Firestore.firestore().collection("Locations").document(??).collection("Dates").document(??).collection("Events").getDocuments() { (querySnapshot, error) in
        if let error = error {
            print("Error getting documents: \(error)")
        } else {
            self.eventsArray = querySnapshot!.documents.compactMap({Event(dictionary: $0.data())})
            DispatchQueue.main.async {
                self.tableView.reloadData()
            }
        }
    }
}
override func numberOfSections(in tableView: UITableView) -> Int {
    // #warning Incomplete implementation, return the number of sections
    return 1
}

override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    // #warning Incomplete implementation, return the number of rows
    return eventsArray.count
}


override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCell(withIdentifier: "eventCell", for: indexPath)

    let event = eventsArray[indexPath.row]

    // Configure the cell...
    cell.textLabel?.text = "\(event.programType)"
    cell.detailTextLabel?.text = "\(event.eventLocation) \(event.eventDate)"

    return cell
}
import UIKit
import FirebaseFirestore

class AddEventViewController: UIViewController {

@IBOutlet weak var eventLocation: UITextField!
@IBOutlet weak var eventDate: UITextField!
@IBOutlet weak var programType: UITextField!

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

@IBAction func saveEventButtonTapped(_ sender: UIBarButtonItem) {
// Check if textfields are not empty
    guard let EventLocation = eventLocation.text, !EventLocation.isEmpty else { return }
    guard let EventDate = eventDate.text, !EventDate.isEmpty else { return }
    guard let Program = programType.text, !Program.isEmpty else {return}

**// need to find a way to pass variables i.e. eventLocation and eventDate to 'EventsTableViewController'**        

    // Save profile details of person to Firestore as data fields
    let eventDetail: [String: Any] = ["Event Location": EventLocation, "Event Date": EventDate, "Program": Program]

    // Write data to Firestore
    Firestore.firestore().collection("Locations").document(EventLocation).collection("Dates").document(EventDate).collection("Events").document(Program).setData(eventDetail)
    { error in
        if let error = error {
            print("ERROR: Event not saved to database. Please try again! \(error)")
        } else {
            print("Event has been saved to the database!")
        }
        self.dismiss(animated: true, completion: nil)
    }
}
struct Event {
var programType: String
var eventLocation: String
var eventDate: String

var dictionary: [String: Any] {
    return [
        "programType": programType,
        "eventLocation" : eventLocation,
        "eventDate" : eventDate
    ]
}
}

extension Event : DocumentSerializable {
init?(dictionary: [String: Any]) {
    guard let programType = dictionary["Program"] as? String,
        let eventLocation = dictionary["Event Location"] as? String,
        let eventDate = dictionary["Event Date"] as? String else { return nil}

    self.init(programType: programType, eventLocation: eventLocation, eventDate: eventDate)
}
}
添加了EVENTVIEWCONTROLLER.swift

import UIKit
import FirebaseFirestore

class EventsTableViewController: UITableViewController {

 var eventsArray = [Event]()

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

func loadData() {
// How to pass variables from 'AddEventViewController' and use it inside this function??

   Firestore.firestore().collection("Locations").document(??).collection("Dates").document(??).collection("Events").getDocuments() { (querySnapshot, error) in
        if let error = error {
            print("Error getting documents: \(error)")
        } else {
            self.eventsArray = querySnapshot!.documents.compactMap({Event(dictionary: $0.data())})
            DispatchQueue.main.async {
                self.tableView.reloadData()
            }
        }
    }
}
override func numberOfSections(in tableView: UITableView) -> Int {
    // #warning Incomplete implementation, return the number of sections
    return 1
}

override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    // #warning Incomplete implementation, return the number of rows
    return eventsArray.count
}


override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCell(withIdentifier: "eventCell", for: indexPath)

    let event = eventsArray[indexPath.row]

    // Configure the cell...
    cell.textLabel?.text = "\(event.programType)"
    cell.detailTextLabel?.text = "\(event.eventLocation) \(event.eventDate)"

    return cell
}
import UIKit
import FirebaseFirestore

class AddEventViewController: UIViewController {

@IBOutlet weak var eventLocation: UITextField!
@IBOutlet weak var eventDate: UITextField!
@IBOutlet weak var programType: UITextField!

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

@IBAction func saveEventButtonTapped(_ sender: UIBarButtonItem) {
// Check if textfields are not empty
    guard let EventLocation = eventLocation.text, !EventLocation.isEmpty else { return }
    guard let EventDate = eventDate.text, !EventDate.isEmpty else { return }
    guard let Program = programType.text, !Program.isEmpty else {return}

**// need to find a way to pass variables i.e. eventLocation and eventDate to 'EventsTableViewController'**        

    // Save profile details of person to Firestore as data fields
    let eventDetail: [String: Any] = ["Event Location": EventLocation, "Event Date": EventDate, "Program": Program]

    // Write data to Firestore
    Firestore.firestore().collection("Locations").document(EventLocation).collection("Dates").document(EventDate).collection("Events").document(Program).setData(eventDetail)
    { error in
        if let error = error {
            print("ERROR: Event not saved to database. Please try again! \(error)")
        } else {
            print("Event has been saved to the database!")
        }
        self.dismiss(animated: true, completion: nil)
    }
}
struct Event {
var programType: String
var eventLocation: String
var eventDate: String

var dictionary: [String: Any] {
    return [
        "programType": programType,
        "eventLocation" : eventLocation,
        "eventDate" : eventDate
    ]
}
}

extension Event : DocumentSerializable {
init?(dictionary: [String: Any]) {
    guard let programType = dictionary["Program"] as? String,
        let eventLocation = dictionary["Event Location"] as? String,
        let eventDate = dictionary["Event Date"] as? String else { return nil}

    self.init(programType: programType, eventLocation: eventLocation, eventDate: eventDate)
}
}
事件。swift

import UIKit
import FirebaseFirestore

class EventsTableViewController: UITableViewController {

 var eventsArray = [Event]()

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

func loadData() {
// How to pass variables from 'AddEventViewController' and use it inside this function??

   Firestore.firestore().collection("Locations").document(??).collection("Dates").document(??).collection("Events").getDocuments() { (querySnapshot, error) in
        if let error = error {
            print("Error getting documents: \(error)")
        } else {
            self.eventsArray = querySnapshot!.documents.compactMap({Event(dictionary: $0.data())})
            DispatchQueue.main.async {
                self.tableView.reloadData()
            }
        }
    }
}
override func numberOfSections(in tableView: UITableView) -> Int {
    // #warning Incomplete implementation, return the number of sections
    return 1
}

override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    // #warning Incomplete implementation, return the number of rows
    return eventsArray.count
}


override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCell(withIdentifier: "eventCell", for: indexPath)

    let event = eventsArray[indexPath.row]

    // Configure the cell...
    cell.textLabel?.text = "\(event.programType)"
    cell.detailTextLabel?.text = "\(event.eventLocation) \(event.eventDate)"

    return cell
}
import UIKit
import FirebaseFirestore

class AddEventViewController: UIViewController {

@IBOutlet weak var eventLocation: UITextField!
@IBOutlet weak var eventDate: UITextField!
@IBOutlet weak var programType: UITextField!

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

@IBAction func saveEventButtonTapped(_ sender: UIBarButtonItem) {
// Check if textfields are not empty
    guard let EventLocation = eventLocation.text, !EventLocation.isEmpty else { return }
    guard let EventDate = eventDate.text, !EventDate.isEmpty else { return }
    guard let Program = programType.text, !Program.isEmpty else {return}

**// need to find a way to pass variables i.e. eventLocation and eventDate to 'EventsTableViewController'**        

    // Save profile details of person to Firestore as data fields
    let eventDetail: [String: Any] = ["Event Location": EventLocation, "Event Date": EventDate, "Program": Program]

    // Write data to Firestore
    Firestore.firestore().collection("Locations").document(EventLocation).collection("Dates").document(EventDate).collection("Events").document(Program).setData(eventDetail)
    { error in
        if let error = error {
            print("ERROR: Event not saved to database. Please try again! \(error)")
        } else {
            print("Event has been saved to the database!")
        }
        self.dismiss(animated: true, completion: nil)
    }
}
struct Event {
var programType: String
var eventLocation: String
var eventDate: String

var dictionary: [String: Any] {
    return [
        "programType": programType,
        "eventLocation" : eventLocation,
        "eventDate" : eventDate
    ]
}
}

extension Event : DocumentSerializable {
init?(dictionary: [String: Any]) {
    guard let programType = dictionary["Program"] as? String,
        let eventLocation = dictionary["Event Location"] as? String,
        let eventDate = dictionary["Event Date"] as? String else { return nil}

    self.init(programType: programType, eventLocation: eventLocation, eventDate: eventDate)
}
}

有一种方法可以做到这一点,即您可以将
loadData()
添加到
viewwillbeen
方法中,如下所示:

override func viewWillAppear(_ animated: Bool) {
    super.viewWillAppear(animated)

    loadData()
}
并将其从
viewDidLoad
中删除,因为在加载视图时
viewDidLoad
只调用一次。但是每次访问视图时,
视图将出现
将调用。所以,每当您返回到上一个视图时,它都会从服务器获取新的数据