在集合视图中使用转义闭包中的数组

Posted

技术标签:

【中文标题】在集合视图中使用转义闭包中的数组【英文标题】:Use array from escaping closure in collection view 【发布时间】:2018-07-25 08:33:00 【问题描述】:

首先请原谅任何错误的术语,几周前我才开始学习转义闭包。

我有一个 API 在转义闭包中“返回”一个数组。函数调用如下:

getAllUserMovies(username: user)  (result) in
            switch result 
            case .success(let movies):
                // movies is an array. Do something with each element
                break
            case .error(let error):
                // report error
                break
            

我需要在这个集合视图方法中使用该数组的元素,每次只使用一个(实际上它比这更复杂,因为我也与 TMDB API 接口):

func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell

我尝试以类似的方式使用嵌套闭包:

func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell 

            let cell : collectionViewCell = collectionView.dequeueReusableCell(withReuseIdentifier: self.reuseIdentifierLargeBanners, for: indexPath as IndexPath) as! CollectionViewCell

            getAllUserMovies(username: user) (result) in
                switch result 
                case .success(let movies):
                    let movie = movies[indexPath.row] 
                        cell.imageView.image = movie.poster
                    
                    break
                case .error(let error):
                    print(error?.localizedDescription ?? "")
                    break
                
            
            return cell
        
        return UICollectionViewCell()
    

基本上我有两个问题。首先,我认为这完全是低效的(我必须在每次刷新单元格时获取完整的电影列表),然后我也会得到有趣的结果,比如重复的横幅,不断刷新、四处移动或丢失图标。我实现了这个question 的公认答案,但我仍然无法使其工作。无论我做什么,我都会得到重复的图像、空单元格或两者兼而有之。

更新:丢失的图标似乎是由于 API 中每秒调用次数的限制。超过该数字,API 失败,我没有检查错误。

我想一个可能的解决方案是将“电影”数组存储在某处,然后能够从集合视图方法中从中获取单个电影。如果/需要时刷新它。现在已经解决了,感谢anuraj 的回答!

【问题讨论】:

重复问题是因为单元格被重复使用。而且您不会使用cell.imageView.image = nil(在出现错误或在加载期间)删除潜在的先前图像。此外,只需使用var movies: [MovieClass],并在某个时候调用getAllUserMovies(初始化?),一旦你得到ti,设置电影并重新加载tableView。 我在其他问题中阅读过人们建议重新加载 tableView。但我没有任何tableView。 UICollectionView 也有 reload() 吗?我之前检查过,但我找不到如何实现它。 我的意思是 UICollectionView。这是相同的行为 好吧。我会看看我能从这里去哪里。谢谢。 【参考方案1】:

如果您在cellForItemAt 中实现API 调用,则每次滚动都会导致API 调用。

我建议您在 didLoadwillAppear 中进行 API 调用,并在全局保存结果后刷新集合视图。

func makeAPICall() 
getAllUserMovies(username: user) (result) in
                switch result 
                case .success(let movies):
                    self.movies = movies
                    yourCollectionView.reloadData()
                    break
                case .error(let error):
                    print(error?.localizedDescription ?? "")
                    break
                
            

集合视图数据源

 func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int 
        return self.movies.count
    

【讨论】:

这就是我正在测试的(没有定义函数),我已经在didLoad中,添加了reloadData(),但是在func collectionView()之后执行了didLoad?这会在“let movieID = self.movi​​es[indexPath.row].movi​​e?.ids.tmdb”上给出运行时错误“线程 1:致命错误:索引超出范围” 您为 numberOfRow 代表返回了什么? 我没有。我从互联网上拿了一个样本并将其用作基础。它适用于本地图像。然后我添加了框架,转义闭包,我的噩梦开始了。无论如何, didLoad() (显然)在任何事情之前都会被调用,但是 collectionView() 在 getAllUserMovies 返回其值之前访问数组。抱歉弄错了。 在 numberOfItemsInSection 你应该返回movies.count 天啊!!太漂亮了!现在可以了!!好的,我得到了 765 个细胞,但谁在数呢? ^_^我会放一个如果。我的另外两个收藏视图也消失了,但我想我可以轻松地从这里继续前进。谢谢!!!

以上是关于在集合视图中使用转义闭包中的数组的主要内容,如果未能解决你的问题,请参考以下文章

Groovy集合遍历 ( 使用集合的 find 方法查找集合元素 | 闭包中使用 == 作为查找匹配条件 | 闭包中使用 is 作为查找匹配条件 | 闭包使用 true 作为条件 | 代码示例 )(代

如何处理完成闭包中的多个错误

如何将数组中的非静态图像加载到 Swift 中的集合视图中

将数组中的图像嵌入到集合视图的单元格中

理解Swift中map 和 flatMap对集合的作用

Groovy集合遍历 ( 调用集合的 every 方法判定集合中的所有元素是否符合闭包规则 | =~ 运算符等价于 contains 函数 | 代码示例 )