如何在Swift

时间:2016-09-04 15:57:17

标签: ios swift firebase firebase-realtime-database

大家好,我目前正在开发一个程序,该程序包含UITableView中的书籍列表。如您所知,TableView采用两种方法,一种是使用cellForRowAtIndexPath,另一种是我今天要讨论的方法,numberOfRowsInSection。所以我遇到的问题是我访问我的数据库以获取当前在数据库中的书籍数量,以便返回我将在Book stucts数组中需要多少个索引。所以我有两个团体,买卖,可能有也可能没有任何书籍。

无论如何,我填充我的数组(它开始时为空)然后我将books.count作为numberOfRowsInSection返回。问题是我一直返回0,因为在执行返回后数组会被填充。

以下是我的代码。

func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    populateArray()
    print("books.count: ",books.count)
    return books.count // KEEPS RETURNING 0 BC IT HASN'T POPULATED YET *ARRRRRRGH*
}

func populateArray(){
    print("started looking")
    var indices = 0

    if divider.selectedSegmentIndex == 0{
        ref.child(school).observeEventType(.Value, withBlock: {     (snapshot) in
            let numSelling = snapshot.value!["numSelling"] as! Int // gets numSelling
            if numSelling  > 0 {
                self.noEntries = false
                print("numSelling: ", numSelling) //see console
                indices = numSelling
            }else{
                self.noEntries = true
                indices = 1
                print("No Values Selling")
            }
        }) { (error) in
            print(error.localizedDescription)
        }
    }else{
        ref.child(school).observeEventType(.Value, withBlock: {     (snapshot) in
            let numBuying = snapshot.value!["numBuying"] as! Int // gets numBuying
            if numBuying  > 0 {
                self.noEntries = false
                print("numBuying: ", numBuying) //see console
                indices = numBuying
            }else{
                self.noEntries = true
                indices = 1
            }
        }) { (error) in
            print(error.localizedDescription)
        }
    }



    delay(0.5){
        print("ind: ", indices) // printing correctly
        if(self.noEntries){ // just add one book to get the indices to be 1
            self.books.append(Book(isbn: "", title: "", author: "", edition: "", price: "", uid: ""))

            return
        }
        if self.divider.selectedSegmentIndex == 0{
            self.ref.child(self.school).child("selling").observeEventType(.Value, withBlock: {    (snapshot) in
                let booksJSON = snapshot.value! as! NSArray

                for bookJSON in booksJSON { // add the book to the array
                    let tempAuthor = bookJSON["authors"] as! String
                    let tempTitle = bookJSON["title"] as! String
                    let tempEdition = bookJSON["edition"] as! String
                    let tempPrice = bookJSON["price"] as! String
                    let tempISBN = bookJSON["isbn"] as! String
                    let tempUID = bookJSON["uid"] as! String
                    self.books.append(Book(isbn: tempISBN, title: tempTitle, author: tempAuthor, edition: tempEdition, price: tempPrice, uid: tempUID))
                }

            }) { (error) in
                print(error.localizedDescription)
            }
        }else if self.divider.selectedSegmentIndex == 1{
            self.ref.child(self.school).child("buying").observeEventType(.Value, withBlock: {    (snapshot) in
                let booksJSON = snapshot.value! as! NSArray

                for bookJSON in booksJSON { // add the book to the array
                    let tempAuthor = bookJSON["authors"] as! String
                    let tempTitle = bookJSON["title"] as! String
                    let tempEdition = bookJSON["edition"] as! String
                    let tempPrice = bookJSON["price"] as! String
                    let tempISBN = bookJSON["isbn"] as! String
                    let tempUID = bookJSON["uid"] as! String
                    self.books.append(Book(isbn: tempISBN, title: tempTitle, author: tempAuthor, edition: tempEdition, price: tempPrice, uid: tempUID))
                }

            }) { (error) in
                print(error.localizedDescription)
            }
        }
    }

}

func delay(delay:Double, closure:()->()) {
    dispatch_after(
        dispatch_time(
            DISPATCH_TIME_NOW,
            Int64(delay * Double(NSEC_PER_SEC))
        ),
        dispatch_get_main_queue(), closure)
}

请记住,我无法在此方法中进行回调,因为在加载视图时程序会自动调用它。

此外,延迟部分正在努力阻止同样的事情发生。问题是我不能把延迟放在返回周围,因为它认为我想为延迟块返回一个Int。

控制台:

started looking
books.count:  0
started looking
books.count:  0
started looking
books.count:  0
started looking
books.count:  0
numSelling:  6
numSelling:  6
numSelling:  6
numSelling:  6
ind:  6
ind:  6
ind:  6
ind:  6

正如您所看到的,它甚至在从数据库获取numSelling值之前返回0。

非常感谢你的帮助,祝你有个美好的一天!

2 个答案:

答案 0 :(得分:2)

一旦调用了方法,就无法延迟返回方法,但您可以要求表视图再次调用数据源方法。

最简单的解决方案是在填充数据后(即在populateArray()方法结束时)在表格视图上调用populateArray()。我可能也会将呼叫转移到其他地方的viewDidLoad()(如果合适的话,可能是User。)

答案 1 :(得分:1)

我会:

  1. delay方法中移出“检索已购买/已售出的标题”。从observeEventType / numSelling的相应numBuying内拨打该电话。摆脱delay

  2. 正如Charles所说,当viewDidLoad完成时,不要担心值为空。完成后只需要例程调用tableView.reloadData()

  3. 假设您的用户界面显示同时购买和出售的两个标题(或者您正在快速跳转并且不想等待检索数据),您的例程可能需要继续检索两个数组,只在两者完成时调用reloadData。这意味着您的模型中可能需要两个数组,一个用于booksSelling,另一个用于booksBuying