2017-02-06 8 views
2

В моем приложении swift я показываю ячейки в UITableView, первые 10 ячеек содержат фотографию. Я решил добавить эффект параллакса для каждой ячейки, так что когда пользователь прокручивает таблицу вверх и вниз, изображение меняет его смещение.cellForRow (at: indexPath) возвращает nil и сбой моего быстрого приложения

Это, как я получить данные из моего веб-сервиса и первоначально добавьте его в Tableview:

func makePostQueryForFetchingData(_ parameters: [String:AnyObject], url: String, type: String) 
{ 
    Alamofire.request(url, method: .post, parameters: (parameters), encoding: JSONEncoding.default) 
     .validate() 
     .responseJSON { response in 

      switch response.result { 
      case .success: 
       DispatchQueue.main.async(execute: { 
        items.removeAllObjects() 
        tview.reloadData() 
        if let jsonData = response.result.value as? [[String: AnyObject]] { 
         for singleJSON in jsonData { 
          if let single = SingleNode.fromJSON(JSON(singleJSON)){ 
            self.items.add(single) 
          } 
         } 
        } 
        self.refreshController.endRefreshing() 
        print("before crash") 
        self.tview.reloadData() 
        print("end") 
       }) 
      case .failure(let error): 
       print(error) 
      } 
    } 
} 

Когда я запускаю эту функцию при запуске - все работает хорошо. Однако, если я прокручиваю вниз по таблице, а затем быстро прокручиваю вверх и вытягиваю, чтобы обновить - приложение вылетает.

В попытке обновления я вызываю функцию сверху.

Функция для обработки эффекта параллакса выглядит следующим образом:

override func scrollViewDidScroll(_ scrollView: UIScrollView) { 
    if (scrollView == self.tview) { 
     for indexPath in self.tview.indexPathsForVisibleRows! { 
      if (indexPath.row < 10) { 
       print(indexPath) 
       print(self.tview.cellForRow(at: indexPath)) 
       self.setCellImageOffset(cell: self.tview.cellForRow(at: indexPath) as! BigDetailsOnListCell, indexPath: indexPath as NSIndexPath) 
      } 
     } 
    } 
} 

, и я понял, что, когда я быстро прокручивать таблицу и обновляет его - я вижу в консоли:

before crash 
0 
nil 
fatal error: unexpectedly found nil while unwrapping an Optional value 

так почему же self.tview.cellForRow(at: indexPath) возвращает ноль?

+0

Пожалуйста, также введите код метода cellForRow –

+0

'cellForRow (at:)' возвращает 'nil', если ячейка не видна или indexPath выходит за пределы допустимого диапазона. – JAL

+0

@KuntalGajjar Я проверил, что 'cellForRow' вообще не вызывается, я добавил« print' msg на первой строке там, и он не появился. Проблема заключается в этой строке: 'self.tview.cellForRow (at: indexPath) как! BigDetailsOnListCell', потому что 'nil' не может быть передан в' BigDetails ... '. Я думаю, что это потому, что моя ячейка отсутствует, но я не уверен, в какой момент я их удаляю. – user3766930

ответ

4

cellForRow(at:) будет возвращать ячейку только в том случае, если в таблице в настоящее время имеется видимая ячейка для этой строки. Он не будет вызывать метод источника данных в виде таблицы, чтобы получить ячейку, если нет видимой ячейки, она вернет nil.

Вам нужно иметь дело с тем фактом, что cellForRow(at:) может возвращать ноль. Не пытайтесь развернуть его. Используйте условную развертку. Аналогично indexPathsForVisibleRows; нет веских оснований для того, чтобы заставить разворачивать эту ценность.

override func scrollViewDidScroll(_ scrollView: UIScrollView) { 
    if (scrollView == self.tview) { 
     if let visiblePaths = self.tview.indexPathsForVisibleRows { 
      for indexPath in visiblePaths { 
       if (indexPath.row < 10) { 
        if let cell = self.tview.cellForRow(at: indexPath as? BigDetailsOnListCell) { 
        self.setCellImageOffset(cell: cell, indexPath: indexPath as NSIndexPath) 
       } 
      } 
     } 
    } 
} 
+1

Для массивов проще использовать '?? [] '. – Sulthan

+0

У меня было это в моем исходном коде для ответа, но я решил быть более явным. Оператор объединения nil может быть немного «продвинутым» для тех, кто только начинает работу. – Paulw11

+0

- это «условное разворот» в этом случае, равное 'if (self.tview.cellForRow (at: indexPath)! = Nil) {'? – user3766930

0

in pullToRefresh метод make yourArray nil, и он будет заполняться новыми данными, когда вы получите ответ.

0

Индекс indexPathsForVisibleRows не дает вам никаких гарантий, что ячейка уже отображается. Обратите внимание на разницу между «видимая строка» и «отображаемая ячейка». Видимая строка означает, что положение прокрутки таково, что будет отображаться строка или будет отображаться. Он основан на расчетах видимости. С другой стороны, cellForRow(at:) основан на ячейках, которые в настоящее время добавлены в виде подзонов.

Пока ячейка фактически не отображается cellForRow(at:) все еще может вернуться nil.

Это может произойти сразу же после звонка reloadTable() или при прокрутке.