2017-02-15 3 views
0

Вот описание высокого уровня того, чего я пытаюсь достичь; 1. выборки данных 2. Сохраните принесенных данные в объект 3. обновление представления коллекции массива с размером массиваUICollectionView reloadData() не обновляет ячейки в виде коллекции

Вот мой код

class ItemcollectionViewController:UICollectionViewController, UICollectionViewDelegateFlowLayout { 

    let cellId = "CellId" 
    var categories = [Category]() 
    let viewOptionVar:ViewOptionBar = { 
     let vOV = ViewOptionBar() 
     vOV.translatesAutoresizingMaskIntoConstraints = false 
     return vOV 
    }() 

    private func fetchData() { 
     let categoryController = CategoryController() 
     categoryController.getAllCategory(username: "blah", password: "password") {(returnedCategories, error) -> Void in 
      if error != nil { 
       print(error) 
       return 
      } 
      self.categories = returnedCategories! 
      print("size of the array is \(self.categories.count)") 
      OperationQueue.main.addOperation{self.collectionView?.reloadData()} 
     } 

    } 

    override func viewDidLoad() { 
    super.viewDidLoad() 
    fetchData() 
    collectionView?.backgroundColor = UIColor.white 
    collectionView?.register(ItemCell.self, forCellWithReuseIdentifier: cellId) 
    collectionView?.contentInset = UIEdgeInsetsMake(50, 0, self.view.frame.height, self.view.frame.width) 
    collectionView?.scrollIndicatorInsets = UIEdgeInsetsMake(50, 0, 0, self.view.frame.width) 
    } 

    override func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int { 
    print("in the method \(self.categories.count)") 
    return self.categories.count 
    } 

    override func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell { 
    let cell = collectionView.dequeueReusableCell(withReuseIdentifier: cellId, for: indexPath) as! ItemCell 
    cell.category = categories[indexPath.item] 
    return cell 
    } 

    func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize { 
    return CGSize(width: 111, height: 111) 
    } 

    func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumLineSpacingForSectionAt section: Int) -> CGFloat { 
    return 0 
    } 

    private func setupViweOptionBar() { 
    view.addSubview(viewOptionVar) 
    view.addConstraintsWithFormat(format: "H:|[v0]|", views: viewOptionVar) 
    view.addConstraintsWithFormat(format: "V:|[v0(50)]", views: viewOptionVar) 
    } 
} 

В журнале я мог видеть следующее высказывания:

в методе 0

размер массива составляет 3

и не видел ни одной ячейки с моего просмотра.

Может кто-нибудь посоветует мне, что я сделал неправильно? Спасибо заранее.

EDIT 1 Теперь я извлекаю данные после регистрации настраиваемых ячеек. Тем не менее, он по-прежнему не работает

обновленный код:

class ItemcollectionViewController:UICollectionViewController, UICollectionViewDelegateFlowLayout { 

    let cellId = "CellId" 
    var categories = [Category]() 
    let viewOptionVar:ViewOptionBar = { 
     let vOV = ViewOptionBar() 
     vOV.translatesAutoresizingMaskIntoConstraints = false 
     return vOV 
    }() 

    private func fetchData() { 
     let categoryController = CategoryController() 
     categoryController.getAllCategory(username: "blah", password: "password") {(returnedCategories, error) -> Void in 
      if error != nil { 
       print(error) 
       return 
      } 
      self.categories = returnedCategories! 
      print("size of the array is \(self.categories.count)") 

     } 

    } 

    override func viewDidLoad() { 
    super.viewDidLoad() 
    collectionView?.backgroundColor = UIColor.white 
    collectionView?.register(ItemCell.self, forCellWithReuseIdentifier: cellId) 
    collectionView?.contentInset = UIEdgeInsetsMake(50, 0, self.view.frame.height, self.view.frame.width) 
    collectionView?.scrollIndicatorInsets = UIEdgeInsetsMake(50, 0, 0, self.view.frame.width) 
    collectionView?.dataSource = self 
    collectionView?.delegate = self 
    fetchData() 
    DispatchQueue.main.async{self.collectionView?.reloadData()} 
    } 

    override func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int { 
    print("in the method \(self.categories.count)") 
    return self.categories.count 
    } 

    override func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell { 
    let cell = collectionView.dequeueReusableCell(withReuseIdentifier: cellId, for: indexPath) as! ItemCell 
    cell.category = categories[indexPath.item] 
    return cell 
    } 

    func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize { 
    return CGSize(width: 111, height: 111) 
    } 

    func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumLineSpacingForSectionAt section: Int) -> CGFloat { 
    return 0 
    } 

    private func setupViweOptionBar() { 
    view.addSubview(viewOptionVar) 
    view.addConstraintsWithFormat(format: "H:|[v0]|", views: viewOptionVar) 
    view.addConstraintsWithFormat(format: "V:|[v0(50)]", views: viewOptionVar) 
    } 
} 

EDIT 2

Следующий код мой метод выполнение запроса

func getAllCategory(username:String, password:String, callback: @escaping ([Category]?, String?) -> Void){ 
    var categories = [Category]() 
    let fetchCategories = URL(string: userURL + "all") 
    URLSession.shared.dataTask(with: fetchCategories!, completionHandler: { (data, response, error) in 
     if let err = error { 
      print(err) 
      return 
     } 
     do { 
      let jsonCategoryObj = try JSONSerialization.jsonObject(with: data!, options: .mutableContainers) as! [[String: AnyObject]] 
      for categoryDictionary in jsonCategoryObj { 
       let category = Category() 
       category.categoryId = categoryDictionary["categoryId"] as? String 
       category.categoryName = categoryDictionary["categoryName"] as? String 
       category.categoryDescription = categoryDictionary["categoryDescription"] as? String 
       let categoryRegisteredDateString = categoryDictionary["categoryRegisteredDate"] as? String 
       let df = DateFormatter() 
       df.dateFormat = self.shapeDateFormat 
       let categoryRegisteredDate = df.date(from: categoryRegisteredDateString!)! 
       category.categoryRegisteredDate = categoryRegisteredDate 

       categories.append(category) 

      } 
      callback(categories, nil) 
     }catch let jsonError { 
      callback(nil, String(describing: jsonError)) 
     } 

    }).resume() 
} 

FYI: Я знаю, что я m, не используя пройденные учетные данные пользователя, это просто ошибка копирования и вставки из моего метода запросов

+0

Здравствуйте. Получили ли вы решение этой проблемы, или просто дали то, что я собираюсь сделать? – nyxee

ответ

1
DispatchQueue.main.async{self.collectionView?.reloadData()} 
    collectionView?.backgroundColor = UIColor.white 
    collectionView?.register(ItemCell.self, forCellWithReuseIdentifier: cellId) 

Вы перезагружаете данные, прежде чем зарегистрируете свою ячейку.

Сначала зарегистрируйте данные о своих ячейках и источниках данных и делегирования, а затем повторно загрузите данные LAST.

EDIT:

Я вижу, вы редактировали ваше сообщение.

Но опять же, вы находитесь fetchData(), прежде чем вы даже зарегистрировали свою камеру. Итак, снова, переместите метод fetchData ПОСЛЕ того, как вы зарегистрировали все ячейки, источники данных и делегаты.

+0

Это имеет смысл. Однако это не сработало даже после того, как я изменил его на 'collectionView? .backgroundColor = UIColor.white collectionView? .register (ItemCell.self, forCellWithReuseIdentifier: cellId)CollectionView? .contentInset = UIEdgeInsetsMake (50, 0, self .view.frame.height, self.view.frame.width) collectionView? .scrollIndicatorInsets = UIEdgeInsetsMake (50, 0, 0, self.view.frame.width) fetchData() DispatchQueue.main.async {self. collectionView? .reloadData()} ' –

+0

@ J.GS.Han Вы не устанавливаете collectionView.delegate = self и collectionView.datasource = self, shouldve сделал это более ясным в моем ответе, но это ваша единственная проблема сейчас. Также я думаю, что вам нужно ** UICollectionViewDataSource ** и ** UICollectionViewDelegate ** добавлено в ваш код в вашем классе. –

+0

Спасибо за ваш ответ! Я попытался обновить свой код на основе предлагаемого решения, но он не сработал. Я также попытался добавить ** UICollectionViewDataSource ** и ** UICollectionViewDelegate ** в мой класс, но он жалуется на высказывание «Резервное соответствие« ItemcollectionViewController »для протокола« UICollectionViewDataSource »« –

3

Я не уверен, как это разрешило эту проблему. Но я просто добавил

print("size of the array is \(self.categories?.count)") 

рядом с

OperationQueue.main.addOperation{self.collectionView?.reloadData()} 

и волшебно работает .. даже мысль, когда я вернусь и вернусь к экрану, он не показывает ничего.

Я его исследовать все больше и попытаться выяснить, почему это происходит

Обновлено

Использование

DispatchQueue.main.sync 

вместо

DispatchQueue.main.async 

решена проблема ,

+1

@Sneak Спасибо за помощь !!!! –

+0

привет. я не понимаю, что вы подразумеваете, поставив эту линию рядом с другой. вы имеете в виду, что вы помещаете линию перед вызовом очереди? – nyxee

+0

Эта работа огромна в Swift 4! –

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