Почему didDeselectItemAt из UICollectionView выдает ошибку неожиданно найденного nil и сбой приложения Swift?

Я использовал представление коллекции для отображения коллекции изображений. Он работает, но когда я использую функцию didDeselectItemAt он сработает, если я didDeselectItemAt определенные изображения.

Ошибка, которая возникает: fatal error: unexpectedly found nil while unwrapping an Optional value

Настройка кода:

numberOfItemsInSection:

 func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int { return images.count } 

cellForItemAt:

 func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell { let cellIdentifier = "ImageCell" let cell = collectionView.dequeueReusableCell(withReuseIdentifier: cellIdentifier, for: indexPath) as! ImageCollectionViewCell let imageUrls = collection?.imageUrls // Configure the cell // Reset alpha of first item in collection if indexPath.row == 0 { cell.imageView.alpha = 1.0 if videoUrl != nil { cell.backgroundColor = UIColor.red cell.imageView.alpha = 0.5 } } cell.imageView.af_setImage(withURL: URL(string: (imageUrls?[indexPath.row])!)!) return cell } 

didDeselectItemAt:

 func collectionView(_ collectionView: UICollectionView, didDeselectItemAt indexPath: IndexPath) { let cell = collectionView.cellForItem(at: indexPath) as! ImageCollectionViewCell UIView.animate(withDuration: 0.3, animations: { cell.imageView.alpha = 0.6 }) } 

didSelectItemAt:

 func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) { print("You've tapped me. NICE!! \(indexPath.row)") let cell = collectionView.cellForItem(at: indexPath) as! ImageCollectionViewCell cell.imageView.alpha = 1 let url = self.collection?.imageUrls?[indexPath.row] self.selectedImageUrl = url Alamofire.request(url!).responseImage(completionHandler: { (response) in if response.result.value != nil { self.selectedImage.image = response.result.value } }) } 

Над кодом работает, но будет вызывать ошибку, если я нажму на определенные изображения. Первая ячейка каждого вида коллекции имеет альфа 100% – 1,0, а все остальные имеют альфа 0,6. Я заметил, что – кроме первой ячейки представления коллекции – каждая 7-я ячейка также имеет альфа 100%, и если в представлении коллекции есть видеоурус, у него будет красный фон и альфа 50%.

Это из-за многоразовых ячеек, таких как UITableViewController, где вы используете dequeueReusableCell и следует ли использовать эту функцию внутри didDeselectItemAt или что-то еще не реализовано правильно?

Таким образом, только первая ячейка в представлении коллекции должна иметь альфа 100, все остальные 60%. Если у объекта есть videoUrl, у первого элемента будет альфа 50% с красным фоном.

Если у вас остались вопросы, пожалуйста, дайте мне знать. Заранее спасибо и отлично провели вечер!

ОБНОВИТЬ:

Следующая строка печати будет выводиться ниже кода, когда я нажимаю первое изображение вида коллекции, а затем второе. Это не приведет к сбою приложения, и оно все равно будет работать

 print("OUTPUT \(String(describing: collectionView.cellForItem(at: indexPath)))") 

Над фрагментом кода, который я разместил в обоих didSelectItemAt и didDeselectItemAt :

didSelectItemAt output:

 OUTPUT Optional(<CollectionViewApp.ImageCollectionViewCell: 0x7ff61679c1a0; baseClass = UICollectionViewCell; frame = (150 0; 150 100); clipsToBounds = YES; opaque = NO; layer = <CALayer: 0x6080000347c0>>) 

didDeselectItemAt output:

OUTPUT Необязательный (>)

Когда я нажимаю первое или второе изображение, а затем последнее изображение в представлении коллекции, произойдет ошибка и приведет к сбою моего приложения. Прикосновение к первому изображению даст мне результат:

OUTPUT Optional(<CollectionViewApp.ImageCollectionViewCell: 0x7fc3cb038540; baseClass = UICollectionViewCell; frame = (150 0; 150 100); clipsToBounds = YES; opaque = NO; layer = <CALayer: 0x610000225980>>)

Последний элемент, который позволит моему краху приложения, будет OUTPUT Optional(<CollectionViewApp.ImageCollectionViewCell: 0x7fc3cb03afb0; baseClass = UICollectionViewCell; frame = (300 0; 150 100); clipsToBounds = YES; opaque = NO; layer = <CALayer: 0x6100002264c0>>) следующий вывод: OUTPUT Optional(<CollectionViewApp.ImageCollectionViewCell: 0x7fc3cb03afb0; baseClass = UICollectionViewCell; frame = (300 0; 150 100); clipsToBounds = YES; opaque = NO; layer = <CALayer: 0x6100002264c0>>) .

Таким образом, сбой может быть вызван, когда вы нажимаете одно из первых изображений в виде коллекции и после этого одно из последних изображений в представлении коллекции, когда первые изображения выходят из холста. Я использовал представление горизонтальной коллекции.

One Solution collect form web for “Почему didDeselectItemAt из UICollectionView выдает ошибку неожиданно найденного nil и сбой приложения Swift?”

Таким образом, авария происходит, потому что при выборе элемента didDeselectItemAt можно вызвать для элемента, который больше не отображается. UICollectionView повторно использует UICollectionViewCells , это означает, что метод collectionView.cellForItem(at: indexPath) возвращает ноль для ячеек, которые не видны. Чтобы исправить это, вы можете использовать следующий код:

 func collectionView(_ collectionView: UICollectionView, didDeselectItemAt indexPath: IndexPath) { guard let cell = collectionView.cellForItem(at: indexPath) as! ImageCollectionViewCell else { return //the cell is not visible } UIView.animate(withDuration: 0.3, animations: { cell.imageView.alpha = 0.6 }) } 

Некоторые другие предложения, которые я имею для улучшения вашего кода:

У вас много мест, где вы можете разворачивать силы.

Рассмотрим следующий подход:

 guard let url = self.collection?.imageUrls?[indexPath.row] else { fatalError("url was nil") } self.selectedImageUrl = url Alamofire.request(url).responseImage(completionHandler: { (response) in if response.result.value != nil { self.selectedImage.image = response.result.value } }) 

Используя инструкцию охраны, вы вынуждаете приложение к сбою с соответствующим сообщением об ошибке, которое поможет вам при отладке. Это более эффективная практика по сравнению с развертыванием силы.

Кроме того, при деоклировании ячеек вы можете найти что-то вроде этого:

 let cellIdentifier = "ImageCell" guard let cell = collectionView.dequeueReusableCell(withReuseIdentifier: cellIdentifier, for: indexPath) as? ImageCollectionViewCell else { fatalError("Wrong cell type") } 

Это может произойти, когда тип ячейки отличается

  • Экспортировать файлы Swift в Objective-C внутри Framework
  • Проблемы CFDictionaryRef в Swift
  • «CGFloat» не конвертируется в «Double» ошибку в SWIFT (iOS)
  • Как создать словарь из массива кортежей?
  • Сценарий анимации с помощью Multi-Node Spritekit, может ли это быть более совершенным?
  • Как изменить цвет фона UIDatePicker как UITextField inputView?
  • Xcode 8.1 «Профиль предоставления не включает права aps-environment»
  • SpriteKit: SKSpriteNodes исчезает из SKEffectNode через несколько секунд
  • Ошибка самоподписанного сертификата при подключении к WebSocket в WKWebView
  • Объем файла? Быстрые делегаты и протоколы
  • Swift - Рамка UIView не равна UIView.layer.frame
  • Interesting Posts

    iOS Objective-C Как получить 2 десятичное округленное значение float?

    раскадровка навигационного контроллера iOS

    код проверки из репозитория SVN дает ошибку в xcode 5

    Объектив C / iOS: выпуск памяти с ARC (утечка памяти)

    Как сделать UITableViewCell с различными подзонами повторно используемыми?

    “ всегда возвращает ДА

    Изображения назначены в xib кэшированном?

    Проверьте, существует ли метод перегрузки на платформе iOS устройства

    Ошибка компиляции файлов раскадровки с использованием Xcode 6 beta 5

    Как перечислить все классы, соответствующие протоколу в Swift?

    Как быстро воспроизводить изображение в динамическом создании в ios

    Ошибка сборки Linphone (IOS) (недействительна на C99)

    Анализ: как эффективно использовать PFFile getDataStreamInBackgroundWithBlock

    Как найти вызовы в экземплярах UIKit из вторичного потока?

    Ошибка IOS 5 (сафари) с событиями HTML-касания на «позиции: исправлена» div

    PhoneC: Разработка iOS проста с помощью XCode, Swift3, UITableView, cocatouch, давайте создадим приложения для iPhone, iPad и Macbook.