为什么 UICollectionView 的 didDeselectItemAt 会抛出意外发现 nil 错误并使应用程序 Swift 崩溃? [复制]

2023-12-14

我使用了集合视图来显示图像集合。它正在工作,但是当我使用该功能时didDeselectItemAt如果我单击某些图像,它会崩溃。

出现的错误: fatal error: unexpectedly found nil while unwrapping an Optional value

代码设置:

部分中的项目数:

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
            }
        })

    }

上面的代码可以工作,但是如果我单击某些图像,则会抛出错误。每个集合视图的第一个单元格的 alpha 值为 100% - 1.0,所有其他单元格的 alpha 值为 0.6。我注意到 - 除了集合视图的第一个单元格 - 每第 7 个单元格的 alpha 值也为 100%,如果集合视图包含 videoUrl,它将具有红色背景和 50% 的 alpha 值。

这是因为像 UITableViewController 这样的可重用单元,您在其中使用dequeueReusableCell你是否也应该在内部使用该函数didDeselectItemAt或者还有其他没有正确实施的事情吗?

因此,只有集合视图中的第一个单元格的 alpha 值应为 100,其他所有单元格的 alpha 值应为 60%。如果对象具有 videoUrl,则第一个元素的 alpha 值为 50%,背景为红色。

如果还有任何问题,请告诉我。提前致谢,祝您度过一个美好的夜晚!

UPDATE:

当我单击集合视图的第一个图像和第二个图像时,以下打印行将输出以下代码。这不会使应用程序崩溃,它仍然可以工作

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

上面的代码片段我已经放置在两个中didSelectItemAt and didDeselectItemAt:

didSelectItemAt 输出:

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

didDeselectItemAt 输出:

输出 可选(>)

当我单击集合视图中的第一张或第二张图像,然后单击最后一张图像时,将发生错误并使我的应用程序崩溃。触摸第一张图像会给我输出:

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>>).

因此,当您单击集合视图中的第一个图像之一,然后单击集合视图中的最后一个图像时,当第一个图像超出画布时,可能会触发崩溃。我用了一个水平的集合视图。


所以发生崩溃是因为在选择一个项目时,didDeselectItemAt可以为不再可见的项目调用。 这UICollectionView reuses UICollectionViewCells,这意味着collectionView.cellForItem(at: indexPath)对于不可见的单元格,方法将返回 nil。 要解决此问题,您可以使用以下代码:

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")
}

当细胞类型不同时可能会发生这种情况

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

为什么 UICollectionView 的 didDeselectItemAt 会抛出意外发现 nil 错误并使应用程序 Swift 崩溃? [复制] 的相关文章

  • SwiftUI 检测用户何时截取屏幕截图或屏幕录制

    On UIViewController我们可以轻松地将观察者添加到控制器 喜欢 class ViewController UIViewController override func viewDidLoad super viewDidLoa
  • Swift 结构类型集

    说我有一个struct 可以是任何东西 struct Cube var x Int var y Int var z Int var width Int 然后我该如何创建一个Set这些点中 是否存在两个具有相同属性的对象 let points
  • 带有自定义 init 的 SwiftUI 视图

    假设我正在制作一个如下所示的自定义输入元素 struct CustomInput View Binding var text String var name String var body some View TextField name
  • Draggable Boxview 不更新 Xamarin

    我的第一个问题是框视图生成在左上角 而不是我指定的设计网格第 10 行和网格第 3 列 第二个问题在于可拖动视图 在代码本地可拖动视图的第一部分中 它正确地调用了触摸事件 但也许它没有在GUI中更新
  • sizeToFit 运行异常

    我有一段代码 每次发生后端数据库更改时都会执行 本质上我在父视图中有一个标签 标签由许多状态消息之一更新 每个状态消息位于不同的行上 并以换行符 n 结尾 每条状态消息只能在一行上 并且不能过多 我遇到的问题是 当视图首次重新加载时 一切正
  • 从 iOS 设备向 Google App Engine 进行身份验证

    我正在开发一个 iPhone 应用程序 它使用 Google 应用程序引擎来托管后端 我需要通过 Google 进行身份验证 但我似乎无法找到从我的应用程序中执行此操作的方法 看来我要做一个UIWebView让用户登录到我从 Google
  • iOS - 在 UITabBar 上方获取所需的阴影

    我试图让我的标签栏阴影看起来像这张图片中看到的那样 这样做的最佳方法是什么 我正在使用 Objective C Thanks 您可以使用以下代码为任何 UI 对象提供阴影 tabBar layer shadowOffset CGSize w
  • 如何在 iOS 上更改设备音量 - 而不是音乐音量

    我想更改 iOS iPhone 上的设备音量 我知道我可以使用以下几行更改音乐库的音量 implement at first MediaPlayer framework MPMusicPlayerController musicPlayer
  • 解析迁移到 mLabs 和 Heroku 的错误

    我至少一年前将解析数据库迁移到 Mlabs 从那时起我就一直在开发该应用程序 解析仪表板表示我已成功迁移 Mlab 和 Parse 都收到了数据库的更新 然而 在过去一两周内 该应用程序不再经过登录页面 没有调整代码 这是服务器问题 以下是
  • 如何计算CLLocationDistance的中心坐标

    我想计算我的位置和一些注释之间的中心点 到目前为止我已经这样做了 CLLocation myLoc self locMgr location MKPointAnnotation middleAnnotation locationV anno
  • 如何在 iPad 应用程序上禁用横向方向?

    我创建了一个全新的单视图 iOS 通用 Swift 应用程序 然后 我在应用程序设置中取消选中 横向左 和 横向右 我在 iPhone 上运行了它 万岁 无论我如何旋转手机 它都会保持纵向模式 然后我在 iPad 上运行它 它会旋转到任何内
  • 使用基于 Cookie 的身份验证的 Capacitor iOS

    我正在使用 Capacitor v3 NextJS 静态导出和 Django 后端基于生产网站构建 iOS 应用程序 当前的后端身份验证方案通过 cookie 使用 Django 会话 并通过 cookie 设置 CSRF 令牌 应用程序可
  • 视频中的图像/文本叠加 swift

    我正在使用 swift 在视频中使用图像叠加来实现水印效果 我正在使用AVFoundation为此 但不知何故我没有成功 以下是我的覆盖图像 文本的代码 let path NSBundle mainBundle pathForResourc
  • Xcode 服务器 ibtool 构建失败

    我一直在研究使用 Xcode Server 进行 CI 我已经解决了一些问题 但现在有一个问题困扰着我 构建似乎工作正常 但在测试阶段挂起 并在日志底部生成以下内容 2015 11 25 14 44 45 650 xcodebuild 58
  • 使用 UIWebView 显示 PDF 不起作用

    因此 我意识到有关使用 UIWebView 在应用程序 在 iPad 上 中显示 PDF 存在很多问题 我已经审查了我能找到的所有内容 但似乎找不到任何满意的东西 我想做的事情非常基本 所以我真的不知道为什么它不起作用 我需要做的就是在 U
  • 在后台继续下载

    我正在创建一个应用程序 其中我从服务器下载一些数据 在后台运行时 我希望连接继续运行 以便可以下载数据 我知道有方法应用程序委托 void applicationDidEnterBackground UIApplication applic
  • Swift 错误:发出 SIGABRT 信号如何解决

    我只是 Swift 编码的初学者 我的想法很简单 就是一个有两个按钮的应用程序 单击时 文本字段将更改其文本 在 Main StoryBoard 中 我添加一个文本字段和两个按钮 在 ViewController swift 文件中 我这样
  • dyld:无法加载插入的库,但可以在模拟器和另一部 iPhone 上使用

    所以我在过去的几个小时里在我的应用程序上编码 在某个时候我决定在我的 iPhone 8 13 3 1 上启动我的应用程序而不是使用模拟器 13 3 它立即崩溃并出现以下错误 dyld warning could not load inser
  • AGVTool new-version 和 What-version 不对应

    当我做 agvtool new version all 99 它更新我的 Info plist 文件 但是 如果我这样做 agvtool what version or agvtool next version 我收到此错误 There d
  • 游戏中心玩家显示名称在沙盒中始终为“我”

    我使用用户的游戏中心显示名称和玩家 ID 来维护他们在我的服务器上的个人资料 当我进行测试时 一切似乎都正确执行 但我的沙箱帐户的用户显示名称显示为 Me 而不是附加到我的帐户的显示名称 Billybobbo 这应该在沙盒模式下发生吗 Co

随机推荐