2016-02-16 3 views
1

У меня есть панель поиска и табличный вид под ней. Когда я ищу что-то, происходит сетевой вызов, и 10 элементов добавляются в массив для заполнения таблицы. Когда я прокручиваю нижнюю часть таблицы, другой сетевой вызов выполняется для еще 10 элементов, поэтому теперь в массиве есть 20 элементов ... это может продолжаться, потому что это бесконечный свиток, подобный ленте новостей Facebook.Перезагрузка таблицы вызывает мерцание

Каждый раз, когда я делаю сетевой вызов, я также вызываю self.tableView.reloadData() в основной теме. Поскольку в каждой ячейке есть изображение, вы можете видеть мерцание - изображения сотовых изображений мигают белым.

Я пробовал реализовать this solution, но я не знаю, где его поместить в мой код или как это сделать. Мой код Swift и Objective-C.

Любые мысли?

Обновить К вопросу 1

override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell { 
    let cell = tableView.dequeueReusableCellWithIdentifier(R.reuseIdentifier.searchCell.identifier, forIndexPath: indexPath) as! CustomTableViewCell 

    let book = booksArrayFromNetworkCall[indexPath.row] 

    // Set dynamic text 
    cell.titleLabel.font = UIFont.preferredFontForTextStyle(UIFontTextStyleHeadline) 
    cell.authorsLabel.font = UIFont.preferredFontForTextStyle(UIFontTextStyleFootnote) 

    // Update title 
    cell.titleLabel.text = book.title 

    // Update authors 
    cell.authorsLabel.text = book.authors 

    /* 
    - Getting the CoverImage is done asynchronously to stop choppiness of tableview. 
    - I also added the Title and Author inside of this call, even though it is not 
    necessary because there was a problem if it was outside: the first time a user 
    presses Search, the call for the CoverImage was too slow and only the Title 
    and Author were displaying. 
    */ 
    Book.convertURLToImagesAsynchronouslyAndUpdateCells(book, cell: cell, task: task) 

    return cell 
} 

cellForRowAtIndexPath использует этот метод внутри него:

class func convertURLToImagesAsynchronouslyAndUpdateCells(bookObject: Book, cell: CustomTableViewCell, var task: NSURLSessionDataTask?) { 

    guard let coverImageURLString = bookObject.coverImageURLString, url = NSURL(string: coverImageURLString) else { 
     return 
    } 

    // Asynchronous work being done here. 
    task = NSURLSession.sharedSession().dataTaskWithURL(url, completionHandler: { (data, response, error) -> Void in 

     dispatch_async(dispatch_get_main_queue(), { 

      // Update cover image with data 

      guard let data = data else { 
       return 
      } 

      // Create an image object from our data 
      let coverImage = UIImage(data: data) 
      cell.coverImageView.image = coverImage 
     }) 
    }) 

    task?.resume() 
} 

Когда я прокручиваю в нижней части таблицы, я обнаружить, если я достигнет дна с willDisplayCell , Если это дно, я снова делаю тот же сетевой вызов.

override func tableView(tableView: UITableView, willDisplayCell cell: UITableViewCell, forRowAtIndexPath indexPath: NSIndexPath) { 

    if indexPath.row+1 == booksArrayFromNetworkCall.count { 

     // Make network calls when we scroll to the bottom of the table. 
     refreshItems(currentIndexCount) 
    } 

} 

Это код сети. Он вызывается в первый раз, когда я нажимаю Enter на панели поиска, тогда он вызывается каждый раз, когда я добираюсь до нижней части ячейки, как вы можете видеть в willDisplayCell.

func refreshItems(index: Int) { 

    // Make to network call to Google Books 
    GoogleBooksClient.getBooksFromGoogleBooks(self.searchBar.text!, startIndex: index) { (books, error) -> Void in 

     guard let books = books else { 
      return 
     } 

     self.footerView.hidden = false 

     self.currentIndexCount += 10 

     self.booksArrayFromNetworkCall += books 

     dispatch_async(dispatch_get_main_queue()) { 
      self.tableView.reloadData() 
     } 
    } 
} 
+0

Можете ли вы показать код при создании ячейки (cellForRowAtIndexPath)? Раньше я делал такой поиск, и у меня нет этой проблемы.Если только изображение вспыхивает белым цветом, а текст рядом с ним не появляется, возможно, когда вы вызываете reloadData(), изображение снова загружается из источника, что вызывает вспышку. В этом случае вам может потребоваться сохранить изображения в кеше. –

+0

@ OscarJ.Irun См. Обновленный вопрос, я добавил запрошенный вами код. После просмотра приложения снова будет отображаться только изображение, белое, а не текст. Как бы вы решили это? – JEL

+0

Да, я думаю, он загружает изображение из источника каждый раз, когда вы вызываете 'reloadData()'. Я бы рекомендовал использовать [SDWebImage] (https://github.com/rs/SDWebImage) для кэширования изображений и загрузки асинхронно. Это очень просто, и я использую его в большинстве своих проектов. Чтобы убедиться, что это так, просто добавьте статическое изображение из ваших активов в ячейку вместо вызова 'convertURLToImagesAsynchronouslyAndUpdateCells', и вы увидите, что он не будет снова мигать. –

ответ

2

Если только изображение вспыхивает белым цветом, а текст рядом с ним нет, возможно, когда вы вызываете reloadData(), изображение будет загружено снова из источника, что вызывает вспышку. В этом случае вам может потребоваться сохранить изображения в кеше.

Я бы рекомендовал использовать SDWebImage для кеширования изображений и загрузки асинхронно. Это очень просто, и я использую его в большинстве своих проектов. Чтобы убедиться, что это так, просто добавьте статическое изображение из ваших активов в ячейку вместо вызова convertURLToImagesAsynchronouslyAndUpdateCells, и вы увидите, что он не будет мигать.

I dont 'program in Swift, но я вижу, что это просто, как cell.imageView.sd_setImageWithURL(myImageURL). И все!

+0

Работает отлично! Я попытался сделать это без библиотеки сначала, основываясь на ответе выше, используя 'self.tableView.insertRowsAtIndexPaths', и мерцание остановилось, но затем я столкнулся с проблемой, когда таблица оказалась нервной, когда она попала в нижнюю часть и вставила новые строки. Эта библиотека решила все, и это было так просто, спасибо за отправку ссылки, в которой рассказывается о том, как использовать библиотеку. – JEL

+0

рад, что это сработало! –

1

Попробуйте изменить значение альфа-таблицы до и после вызова [tableView reloadData] method..Like

dispatch_async(dispatch_get_main_queue()) { 
      self.aTable.alpha = 0.4f; 
      self.tableView.reloadData() 
      [self.aTable.alpha = 1.0f; 

     } 

я использовал тот же подход в UIWebView reloading..its работал для меня.

+0

Я обновил свой вопрос выше, где вы это положите? – JEL

+0

Я только что обновил свой код ... – iReddy

1

Вот пример бесконечной прокрутки с помощью insertRowsAtIndexPaths(_:withRowAnimation:)

class ViewController: UIViewController, UITableViewDataSource, UITableViewDelegate { 

    @IBOutlet weak var tableView: UITableView! 

    var dataSource = [String]() 
    var currentStartIndex = 0 

    // We use this to only fire one fetch request (not multiple) when we scroll to the bottom. 
    var isLoading = false 

    override func viewDidLoad() { 
     super.viewDidLoad() 

     // Load the first batch of items. 
     loadNextItems() 
    } 

    // Loads the next 20 items using the current start index to know from where to start the next fetch. 
    func loadNextItems() { 

     MyFakeDataSource().fetchItems(currentStartIndex, callback: { fetchedItems in 

      self.dataSource += fetchedItems // Append the fetched items to the existing items. 

      self.tableView.beginUpdates() 

      var indexPathsToInsert = [NSIndexPath]() 
      for i in self.currentStartIndex..<self.currentStartIndex + 20 { 
       indexPathsToInsert.append(NSIndexPath(forRow: i, inSection: 0)) 
      } 
      self.tableView.insertRowsAtIndexPaths(indexPathsToInsert, withRowAnimation: .Bottom) 
      self.tableView.endUpdates() 

      self.isLoading = false 

      // The currentStartIndex must point to next index. 
      self.currentStartIndex = self.dataSource.count 
     }) 
    } 

    // #MARK: - Table View Data Source Methods 

    func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int { 
     return dataSource.count 
    } 

    func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell { 
     let cell = UITableViewCell() 
     cell.textLabel!.text = dataSource[indexPath.row] 
     return cell 
    } 

    // #MARK: - Table View Delegate Methods 

    func scrollViewDidScroll(scrollView: UIScrollView) { 
     if isLoading == false && scrollView.contentOffset.y + scrollView.bounds.size.height > scrollView.contentSize.height { 
      isLoading = true 
      loadNextItems() 
     } 
    } 
} 

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

+0

Это решило проблесковую проблему, которая замечательная, но она представила еще одну проблему. Теперь, когда я добираюсь до нижней части таблицы и делаю новый сетевой вызов, он начинает загружаться, затем клетки оживляются, а таблица «вскакивает». Таким образом, он достигает дна, затем поднимается, как 20% экрана, и загружаются новые ячейки. Полоса прокрутки движется вверх. Все работает отлично, но этого не случилось с моим решением. Любые идеи почему? – JEL

+0

Если я делаю 'self.tableView.insertRowsAtIndexPaths (indexPathsToInsert, withRowAnimation: .None)', то None все еще не удаляет анимацию, я думаю. Может быть, это проблема, не уверен. Кроме того, я использую 'tableView.estimatedRowHeight = 100' и' tableView.rowHeight = UITableViewAutomaticDimension', не уверен, что это проблема? – JEL

+0

Любые мысли? благодаря – JEL

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

  • Нет связанных вопросов^_^