2016-10-30 3 views
1

Я последовал за 1 учебник и я был в состоянии заполнить CollectionView с некоторыми данными (ImageView и текст):Empty Collection Посмотреть Swift

let appleProducts = ["A", "B", "C", "D"] 
let imageArray = [UIImage(named: "pug1"), UIImage(named: "pug2"), UIImage(named: "pug3"), UIImage(named: "pug4")] 
    func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int 
{ 

    return appleProducts.count 
} 

func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell 
{ 

    let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "cell", for: indexPath as IndexPath) as! CollectionViewCell 

    cell.imageView?.image = self.imageArray[indexPath.row] 

    cell.title?.text = self.appleProducts[indexPath.row] 
    return cell 

} 

Теперь проходящий от демонстрационного проекта в шахту, я хочу, чтобы заполнить эту CollectionView с данными (изображение и текст), что я получаю от FirebaseDatabse, так что я создал этот метод:

struct item { 
let pictureId: String! 
let picture: String! 
} 
var items = [item]() 
    func getLatestAddedItems(){ 
    self.items.removeAll() 
    let databaseRef = FIRDatabase.database().reference() 
    databaseRef.child("Items").observe(.value, with: { 
     snapshot in 

     //self.items.insert(item(picture: picture), at: 0) 
     for childSnap in snapshot.children.allObjects { 

      let snap = childSnap as! FIRDataSnapshot 
      //print(snap.key) 

      let picture = (snap.value as? NSDictionary)?["bookImage"] as? String ?? "" 
      //print(picture) 
      self.items.append(item(pictureId:snap.key, picture:picture)) 

     } 
     print(self.items.count) 


    }) 
} 

и я создаю эту кнопку для вызова GetLatestAddedItems метод:

@IBAction func selectAction(_ sender: AnyObject) { 
    getLatestAddedItems() 
     } 

И это один, чтобы проверить результаты:

@IBAction func gettableAction(_ sender: AnyObject) { 

    print(self.items[0].picture) 
    print(self.items[1].picture) 
    print(self.items[2].picture) 
    print(self.items.count) } 

конечных результатов:

picture 1 link 
picture 2 link 
picture 3 link 
3 

Everythings выглядеть хорошо и правильно, теперь после внесения необходимых изменений в методах ContentView:

func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int 
{ 

    return items.count 
} 
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell 
{ 

    let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "cell", for: indexPath as IndexPath) as! CollectionViewCell 

    //cell.imageView?.image = self.imageArray[indexPath.row] 
    let url = NSURL(string: items[indexPath.row].picture) 
    let data = NSData(contentsOf: url! as URL) 
    cell.imageView?.image = UIImage(data: data! as Data) 

    cell.title?.text = self.items[indexPath.row].pictureId 
    return cell 

} 

сейчас Я получаю пустой ContentView, первый раз с кнопкой работает, потому что я вызываю getLatestAddedItems(), который получит и объявление d в таблицу Items, я пытаюсь вызвать ее как в ViewWillAppear, так и в Viewdidload, но ничего не меняется.

Это то, что я думаю, возврат items.count возвращается 0, поэтому ничего не появятся какие-либо предложения?

+0

Вместо наблюдения за вашими данными с помощью 'value', попробуйте наблюдать данные с помощью .childAdded' –

+0

Теперь я могу заполнить свой CollectionView из firebase, но только когда я нажимаю кнопку, содержащую этот код' self.collectionView.dataSource = self self.collectionView.delegate = self self.collectionView.reloadData() ' –

ответ

1

Перемещайте протокола делегирование инициализацию CollectionView в к одному из ViewController жизненного цикла сферы, такие как viewDidLoad() или viewWillAppear(_animated : Bool) если вы используете пользовательские ViewController (т.е. встроить CollectionView внутри ViewController)

И перезагружайте свой CollectionView каждый раз, когда ваш пользователь получает значение из своей базы данных.

override func viewDidLoad(){ 
    super.viewDidLoad() 

    self.collectionView.dataSource = self 
    self.collectionView.delegate = self 

} 

func getLatestAddedItems(){ 
self.items.removeAll() 
let databaseRef = FIRDatabase.database().reference() 
databaseRef.child("Items").observe(.childAdded, with: { 
    snapshot in 

    for childSnap in snapshot.children.allObjects { 

     let snap = childSnap as! FIRDataSnapshot 
     let picture = (snap.value as? NSDictionary)?["bookImage"] as? String ?? "" 
     self.items.append(item(pictureId:snap.key, picture:picture)) 
     print(self.items.count) 
     self.collectionView.reloadData() 
    } 
    }) 
} 

PS: - Все вызовы на firebase сервер асинхронно, который занимает некоторое время, чтобы извлечь данные из вашего FBDB, так что положить print(self.items.count) должен быть внутри completionBlock из firebase наблюдающей иначе, если он будет установлен вне его, он будет вызван еще до того, как ваши данные будут извлечены из FBDB.

+0

теперь работает, но мне нужно подождать от 4 до 5 секунд, чтобы увидеть загруженные изображения в мой CollectionView, я вызываю метод внутри ViewWillAppear' override func viewWillAppear (_ animated: Bool) { супер.viewWillAppear (анимированные) getLatestAddedItems() // getLatestAddedItems() // reloadbokks() CheckProfileIsCompleted() } 'и я сделать требуемые изменения внутри ** completionBlock ** –

+0

Вы должны ... Просто как сервис, которому требуется бэкэнд для извлечения ваших данных. Это требует времени ... * Все вызовы на ваш сервер Firebase асинхронны, что занимает некоторое время, чтобы получить данные из вашего FBDB * – Dravidian

Смежные вопросы