繁体   English   中英

如何在阵列中放置Firebase数据的节点

How to place nodes of Firebase Data in Array

提示:本站收集StackOverFlow近2千万问答,支持中英文搜索,鼠标放在语句上弹窗显示对应的参考中文或英文, 本站还提供   中文繁体   英文版本   中英对照 版本,有任何建议请联系yoyou2525@163.com。

在我的应用程序的第一页上,我使用的是UIViewPicker,它允许用户选择他们想要选择的国家。 而不是我通过数组将国家/地区名称硬编码到UIPicker中(如下所示):

var country = ["USA", "CANADA"]

我认为最好将应用程序连接到我的Firebase数据库,在该数据库中可以获取所有国家/地区,然后将其附加到数组中,并从中读取UIPicker。

这样,如果我想添加更多的国家/地区,则无需发布新版本的应用程序。 我只需在数据库中添加另一个国家,应用程序就会自动更新它。 但是我不确定如何做到这一点。 当我打印数据库快照时,我得到了整个数据库,但是我只是想将美国和加拿大放入一个阵列中。

所以这是我的firebase数据库的结构:

countries
  Canada
     states
        Alberta
        British Columbia
  USA
     states
        Alabama
        Arkansas

这是我当前的代码:

import UIKit
import FirebaseDatabase

class ViewController: UIViewController, UIPickerViewDelegate, UIPickerViewDataSource {

    @IBOutlet weak var countryPicker: UIPickerView!

    //let country = ["USA", "Canada"] I am no longer using this hardcoded array

    var countrySelected = String()
    var action = 0 

    override func viewDidLoad() {
        super.viewDidLoad()

        //this is where I reach out to the database
        let database = Database.database().reference()
        database.child("countries").observeSingleEvent(of: .value) { (Snapshot) in
            print(Snapshot)
        }

        //add code here that takes the snapshot and appends the the array below
        var country = string()

        countrySelected = country[0]
        countryPicker.selectRow(action, inComponent: 0, animated: false)
        //print(countrySelected)
    }

    func numberOfComponents(in pickerView: UIPickerView) -> Int {
        return 1
    }

    func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
        return country.count
    }

    func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? {
        return country[row]
    }

    func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
        countrySelected = country[row]
        action = country.firstIndex(of: countrySelected)!
        //print(countrySelected)
    }
}

如果有人可以帮助解释,那就太好了!

2 个回复

为了使事情变得容易,我们可以创建一些结构来代表国家和州。

struct Country {
    struct State {
        let country: String
        let name: String
    }

    let name: String
    let states: [State]

    static var ref: DatabaseReference {
        return Database.database().reference(withPath: "countries")
    }

    static func from(key: String, value: Any?) -> Country? {
        guard
            let value = value as? [String:[String]],
            let states = value["states"] else { return nil }

        return Country(name: key, states: states.map {
            State(country: key, name: $0)
        })
    }

    static func countries(from snapshot: DataSnapshot) -> [Country]? {
        return snapshot.snapshots.compactMap {
            Country.from(key: $0.key, value: $0.value)
        }
    }
}

DataSnapshot的扩展使我们可以方便地访问快照的子级。

extension DataSnapshot {
    var snapshots: [DataSnapshot] {
        return children.allObjects as? [DataSnapshot] ?? []
    }
}

接下来,我们创建一些属性来处理国家/地区–一个存储它们的数组以及一些计算出的属性以返回所选国家和州。

class CountryStatePickerViewController: UIViewController {

    // MARK: Outlets

    @IBOutlet weak var pickerView: UIPickerView! {
        didSet {
            loadCountries()
        }
    }

    // MARK: Properties

    private var countries = [Country]() {
        didSet {
            pickerView.reloadAllComponents()
        }
    }

    var selectedCountry: Country? {
        return country(at: pickerView.selectedRow(inComponent: 0))
    }

    var selectedState: Country.State? {
        return selectedCountry.flatMap {
            state(at: pickerView.selectedRow(inComponent: 1), in: $0)
        }
    }
}

我们还需要一些方法来安全地访问特定索引下的国家和州,以及一种首先加载国家/地区的方法。

extension DataSnapshot {
    var snapshots: [DataSnapshot] {
        return children.allObjects as? [DataSnapshot] ?? []
    }
}

extension CountryStatePickerViewController {

    private func loadCountries() {
        Country.ref.observeSingleEvent(of: .value, with: { [weak self] in
            self?.countries = Country.countries(from: $0) ?? []
        })
    }

    private func country(at index: Int) -> Country? {
        return countries.indices.contains(index) ? countries[index] : nil
    }

    private func state(at index: Int, in country: Country) -> Country.State? {
        return country.states.indices.contains(index) ? country.states[index] : nil
    }
}

最后,在我们的UIPickerView协议一致性中,countries数组填充了数据源。 我们可以使用两个组件来代表国家及其相应的州。

extension CountryStatePickerViewController: UIPickerViewDataSource, UIPickerViewDelegate {

    func numberOfComponents(in pickerView: UIPickerView) -> Int {
        return 2
    }

    func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
        switch component {
        case 0:
            return countries.count
        case 1:
            return selectedCountry?.states.count ?? 0
        default:
            return 0
        }
    }

    func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? {
        switch component {
        case 0:
            return country(at: row)?.name
        case 1:
            return selectedCountry.flatMap { state(at: row, in: $0)?.name }
        default:
            return nil
        }
    }

    func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {

        if component == 0 { pickerView.reloadComponent(1) }

        selectedState.flatMap { print($0.name, $0.country) }
    }
}
var countries : [Any] = []

override func viewDidLoad() {
    super.viewDidLoad()
    database.child("countries").observeSingleEvent(of: .value) { (snapshot) in
        if snapshot.exists() {
            if let dict : [String : AnyObject] = snapshot.value as? [String : AnyObject] {
                let array : [Any] = (dict as AnyObject).allValues
                self.countries = array
                // reload countryPicker data 

            } 
        } 
        else {
            // not exist in db 
        }
    }
}
2 如何在DOM树中放置节点?

我正在学习JavaScript。 我是文档对象模型(DOM)主题的新手。 关于如何在DOM树中放置节点我很困惑? 我用过这个HTML文件。 我用过这个JavaScript文件。 这两个变量: var li = document.getElementById('o ...

3 如何在Graphviz中居中放置节点

我有这张图: 产生以下输出: 为什么会这样? (不确定图片为什么这么小)文本/标签应居中( labelloc=c ),但不能居中。 ...

4 如何在中心图像周围的阵列中放置对象?

我有一个按钮数组,当我将它们附加到视图时,我希望将其放置在中间的图像视图周围。 根据数组中有多少个对象,我希望它们在整个圆上均匀分布。 以下是我这样做的尝试。 我在做什么错,应该如何解决? 驼鹿后面有多个按钮。 ...

5 如何在datagridview中放置多个xml数据

假设我有多个这样的 xml 数据: 假设我有多个这种 xml 数据,我如何在不覆盖它们的情况下在 datagridview 中显示值? 我尝试了以下代码: 但是我的表被覆盖了,它只显示最后一个 XmlData。请帮助。提前谢谢 ...

9 如何在每个xml节点中放置值

我已经用C#通过此代码生成了xmldocument, } 在另一种方法中,我有: ..... 然后,我想在每个XML节点中放入数据:(而不是我想将(string.Concat(bill.invoice,bill.num);)分配给s10838652)。 我有正确 ...

2013-06-11 20:35:57 2 150   c#/ xml
10 如何在D3节点中放置图像?

到目前为止,我已经创建了这些D3节点,用于创建可折叠的分层树。 到目前为止,这些节点的颜色为#AA1C1C(深红色),表明如果单击它们,它们将扩展为更多节点。 我想要做的是在节点中使用图像中的位置,这将是所有用户知道它可点击的加号。 我该怎么做呢? 我试图使用这个符号: http : / ...

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2021 STACKOOM.COM