是否有从Firebase实时数据库获取n个元素的功能?

时间:2018-12-21 14:46:48

标签: ios swift firebase uitableview firebase-realtime-database

我的代码包含3个用于创建动态原型UITableViewController的快速文件。

1)Rent_house_Controller.swift

2)Rent_house_Cell.swift

3)Rent_house_Detail.swift

首先,我将UITableViewCell的对象连接到专用的swift文件:

@IBOutlet weak var rentImage: UIImageView!

@IBOutlet weak var rentLabel: UILabel!

然后我定义了UITableViewController

import UIKit
import FirebaseDatabase

class Case_in_affitto: UITableViewController,
UISearchResultsUpdating, UISearchBarDelegate {

var rentImages = [String]()
var rentNames = [String]()
var webAddresses = [String]()

var searching = false
var matches = [Int]()
let searchController = UISearchController(searchResultsController: nil)

override func viewDidLoad() {
    super.viewDidLoad()

    initialize()
}

func initialize() {
    rentNames = ["Red Street",
                       "Green Street",
                       "Blue steet",
                       "Yellow Street",
                       "Colour Square"]

    webAddresses = ["https://website.com/rents/Red-Street",
                    "https://website.com/rents/Green-Street",
                    "https://website.com/rents/Blue-Street",
                    "https://website.com/rents/Yellow-Street",
                    "https://website.com/rents/Colour-Square"]

    rentImages = ["Red-Street.jpg",
                        "Green-Street.jpg",
                        "Blue-Street.jpg",
                        "Yellow-Street.jpg",
                        "Colour-Square.jpg"]

    tableView.estimatedRowHeight = 50
    navigationController?.navigationBar.prefersLargeTitles = true

    searchController.searchBar.delegate = self
    searchController.searchResultsUpdater = self
    searchController.obscuresBackgroundDuringPresentation = false
    searchController.searchBar.placeholder = "Cerca immobile"
    navigationItem.searchController = searchController
    definesPresentationContext = true
    let attributes = [
        NSAttributedString.Key.foregroundColor : UIColor.white,
        NSAttributedString.Key.font : UIFont.boldSystemFont(ofSize: 17)
    ]
    UIBarButtonItem.appearance(whenContainedInInstancesOf: [UISearchBar.self]).setTitleTextAttributes(attributes, for: .normal)
    UIBarButtonItem.appearance(whenContainedInInstancesOf: [UISearchBar.self]).title = "Annulla"
}

override func didReceiveMemoryWarning() {
    super.didReceiveMemoryWarning()
    // Dispose of any resources that can be recreated.
}

// MARK: Search Controller
func updateSearchResults(for searchController: UISearchController) {
    if let searchText = searchController.searchBar.text,
        !searchText.isEmpty {
        matches.removeAll()

        for index in 0..<rentNames.count {
            if rentNames[index].lowercased().contains(
                searchText.lowercased()) {
                matches.append(index)
            }
        }
        searching = true
    } else {
        searching = false
    }
    tableView.reloadData()
}

func searchBarCancelButtonClicked(_ searchBar: UISearchBar) {
    searching = false
    tableView.reloadData()
}



// MARK: - Table view data source

override func numberOfSections(in tableView: UITableView) -> Int {
    return 1
}

override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    return searching ? matches.count : rentNames.count
}


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

    let cell = self.tableView.dequeueReusableCell(withIdentifier:"rentTableCell", for: indexPath) as! Case_in_Affitto_Cell

    let row = indexPath.row
    cell.rentLabel.font = UIFont.preferredFont(forTextStyle: UIFont.TextStyle.headline)
    cell.rentLabel.text = searching ? rentNames[matches[row]] : rentNames[row]
    let imageName = searching ? rentImages[matches[row]] : rentImages[row]

    cell.rentImage.image = UIImage(named: imageName)

    return cell
}



override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
    if segue.identifier == "ShowrentDetails" {

        let detailViewController = segue.destination
            as! Case_in_Affitto_Detail

        let myIndexPath = self.tableView.indexPathForSelectedRow!
        let row = myIndexPath.row
        detailViewController.webSite =
            searching ? webAddresses[matches[row]] : webAddresses[row]
    }
}

//Set cells height
override func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
    switch indexPath.row {
    case 0,1,2,3,4:
        return 100
    default:
        return 40
    }
}


}

在这种情况下,我有一个经典的UITableViewController,它显示了我在项目中实现的值,但是我需要一些不同的东西。

我想根据数据库中节点的数量来指定n个单元格。

例如:

{
"Sales":"",
"Rents":[
{
"Address":"Green_Street",
"Rooms":"2",
"Price":"70000"
},
{
"Address":"Red_Street",
"Rooms":"2",
"Price":"70000"
},
{
"Address":"Blue_Street",
"vani":"2",
"Price":"70000"
},
{
"Address":"Yellow_Street",
"Rooms":"2",
"Price":"70000"
},
{
"Address":"Colour_Square",
"Rooms":"4",
"Price":"140000"
}
]
}

换句话说,第一个问题是,有一天,房子的数量会增加或减少,因此,我需要创建一个功能,使女巫根据数据库的节点数自动填充表格。?


编辑:

我做了点什么。 我创建了一个新的UIViewController,它从数据库中调用数据,然后我想通过UserDefaults.standard

传递所有这些数据。

图像是由数据库检索到的URL提供的,因此我还添加了键“ imageURL”。

Loading.swift:

if codesArray.contains("0") {
                    let userRef = rootRef.child("Rents").child("0")

                        userRef.observeSingleEvent(of: .value, with: { snapshot in
                            let userDict = snapshot.value as! [String: Any]

                            let rentAddress = userDict["Address"] as! String
                            self.address = rentAddress

                            let rentnumberOfRooms = userDict["numberOfRooms"] as! String
                            self.numberOfRooms = rentnumberOfRooms

                            let rentPrice = userDict["Price"] as! String
                            self.price = rentPrice

                            let rentimageURL = userDict["imageURL"] as! String
                            self.imageURL = rentimageURL
                            //save data on UserDefaults
                            self.savedata()
                            //loading finished
                            self.loading.stopAnimating()
                            self.performSegue(withIdentifier: "loadingfinish", sender: self)
                        })
                } else {
                    self.loading.stopAnimating()
                    let alert = UIAlertController(title: "Errore", message: "Caricamento annunci non riuscito", preferredStyle: UIAlertController.Style.alert)
                    alert.addAction(UIAlertAction(title: "ok", style: UIAlertAction.Style.default, handler: nil))
                    self.present(alert, animated: true, completion: nil)
                }

如何更改此条件以加载节点“ Rent”的每个子嵌套?

(请记住,我们不知道有多少孩子有房租)


编辑2:

我正在尽力找到这种解决方案。 我想在一段时间内使用nextObject参数来检查数据库中是否还有其他对象要存储在var address = [String]()

//setting firebase database
                        while (snapshotChildren.nextObject() as? DataSnapshot) != nil {

                            let string_child = snapshotChildren.nextObject() as? String

                            let userRef = rootRef.child("Rents").child(string_child!)

                                userRef.observeSingleEvent(of: .value, with: { snapshot in
                                    let userDict = snapshot.value as! [String: Any]

                                    self.address.append(userRef.value(forKey: "Address") as! String)

                                    let rentnumberOfRooms = userDict["numberOfRooms"] as! NSMutableArray
                                    self.numberOfRooms = rentnumberOfRooms

                                    let rentPrice = userDict["Price"] as! NSMutableArray
                                    self.price = rentPrice

                                    let rentimageURL = userDict["imageURL"] as! NSMutableArray
                                    self.imageURL = rentimageURL
                                    //avvio salvataggio dati del volontario
                                    func prepare(for segue: UIStoryboardSegue, sender: Any?) {
                                        let vc = segue.destination as! Case_in_affitto

                                        var i = 0
                                        while i==5 {
                                            //this will pass the value on the address array in the Case_in_affitto.swift file
                                            vc.address.append(self.address[i])
                                            i += 1
                                        }

                                    }
                                })
                        }
                        //loading complete
                        self.loading.stopAnimating()
                        self.performSegue(withIdentifier: "loadingfinish", sender: self)

不幸的是,这是不正确的

1 个答案:

答案 0 :(得分:1)

Il codiceèabbastanza orribile (代码非常可怕)

不要使用多个数组作为数据源。您已经在搜索功能上遇到麻烦了。

使用具有所需所有参数的自定义结构,图像以捆绑包中的名称表示

struct Rent {
    let address : String
    let numberOfRooms : Int
    let price : String
    let image : String
}

初始化器

init(address : String, numberOfRooms : Int, price : String, image : String)

是免费提供的。

声明一个数据源数组并从数据库中填充它

var rents = [Rent]()

声明matches相同的类型

var matches = [Rent]()

并使用此优化代码过滤对象,diacriticInsensitive对于意大利语文本非常有用。

func updateSearchResults(for searchController: UISearchController) {
    if let searchText = searchController.searchBar.text,
        !searchText.isEmpty {
        matches = rents.filter{ $0.name.range(of: searchText, options: [.caseInsensitive, .diacriticInsensitive]) != nil }
        searching = true
    } else {
        matches.removeAll()
        searching = false
    }
    tableView.reloadData()
}

对应的表视图委托方法是

override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    return searching ? matches.count : rents.count
}


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

    let cell = self.tableView.dequeueReusableCell(withIdentifier:"rentTableCell", for: indexPath) as! Case_in_Affitto_Cell
    let object = searching ? matches[indexPath.row] : rents[indexPath.row]

    cell.rentLabel.font = UIFont.preferredFont(forTextStyle: UIFont.TextStyle.headline)
    cell.rentLabel.text = object.name
    cell.rentImage.image = UIImage(named: object.image)

    return cell
}

如果不应将图像放置在捆绑软件中,则将URL保存在数据库中,并将物理图像保存在Documents文件夹中。
在这种情况下,声明

let imageURL : URL
在结构中

并分配图像

cell.rentImage.image = UIImage(contentsOfFile: object.imageURL.path)