Почему 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") } 

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

  • didBeginContact вызывается несколько раз для того же SKPhysicsBody
  • Почему возникает ошибка Code = 3840 Parsing JSON?
  • AVAudioSession Swift
  • Как подсчитать строки в классе Parse программно в приложении iOS с помощью swift?
  • Передавать данные между двумя приложениями по схеме URL в swift?
  • RestKit RKAttributeMapping fromKeyPath Ошибка в архиве
  • Сделать заголовок навигационной панели кликабельным быстрым
  • В конвертации приложений / Swift
  • Невозможно включить видео с помощью Google для корректной работы в приложении iOS.
  • Ошибки компиляции SDVO SDO в быстром проекте
  • Scale SCNNode в SceneKit
  • Interesting Posts

    Программно обновлять повторяющиеся значения в coredata?

    Приложение для скриншотов, которое может делать скриншоты в любом представлении

    iOS и несколько представлений OpenGL

    Клавиатура UITableViewController и UITextField

    NSCoder – кодирование массива с несколькими уровнями вложенных массивов

    React Native: Отключить клавиатуру не работает с панелью поиска

    Передача данных между двумя контроллерами просмотра с помощью настраиваемого класса панели управления панелью

    Инспектор Appium не может найти xpath для выбора даты в iOS

    Amazon Web Services Objective-C SDK для подписи запроса на запрос

    Как я могу получить стандартный пузырь для копирования iPhone на UIImage?

    POST AFNetworking отправляется как GET

    Использование основных данных с существующим одноразовым приложением

    Создайте UIView только с одной диагональной стороной

    Пользовательское изображение маркера на быстром (MapKit)

    Как я могу центрировать элемент SVG-файла, отображаемого в UIWebView?

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