如何将Service类获取的宝可梦能力数据传递至InfoViewController?
简洁实现方案:从Service传递能力数据到UI
看起来你已经走对路了——已经通过ServiceDelegate拿到了宝可梦的能力数据,接下来只需要把数据同步到UI和CollectionView数据源就行,给你两个关键步骤的实用实现:
1. 先更新InfoViewController的Ability标签
网络请求通常在后台线程执行,所以拿到数据后必须切回主线程更新UI,否则会出现不显示甚至崩溃的问题。修改你的Delegate方法:
extension InfoController: ServiceDelegate { func finishedWithPokemonAbilities(abilities: [String], id: Int) { self.abilities = abilities self.ids = id // 切回主线程更新UI,把能力数组转成易读的字符串(比如用逗号分隔) DispatchQueue.main.async { // 假设你已经给Ability标签IBOutlet命名为abilityLabel let abilityText = abilities.isEmpty ? "No abilities found" : abilities.joined(separator: ", ") self.abilityLabel.text = abilityText } print(abilities) } }
注意:确保你已经在Storyboard/XIB里把Weight下方的Ability标签和
InfoController的abilityLabelIBOutlet正确连接。
2. 同步CollectionView的宝可梦能力数据
如果要让CollectionView的每个Cell对应显示对应宝可梦的能力,你需要维护一个包含宝可梦完整信息的数据源数组,比如先定义一个简单的宝可梦模型:
struct Pokemon { let id: Int let name: String let weight: Int var abilities: [String] = [] // 初始为空,后续从Service填充 }
然后在InfoController里声明数据源数组:
var pokemonList: [Pokemon] = []
接下来修改Delegate方法,找到对应ID的宝可梦并更新其能力,再刷新对应的Cell:
extension InfoController: ServiceDelegate { func finishedWithPokemonAbilities(abilities: [String], id: Int) { // 1. 更新当前Info页面的标签(和第一步逻辑一致) DispatchQueue.main.async { let abilityText = abilities.isEmpty ? "No abilities found" : abilities.joined(separator: ", ") self.abilityLabel.text = abilityText } // 2. 找到数据源中对应ID的宝可梦,更新能力并刷新Cell if let targetIndex = pokemonList.firstIndex(where: { $0.id == id }) { pokemonList[targetIndex].abilities = abilities DispatchQueue.main.async { let targetIndexPath = IndexPath(item: targetIndex, section: 0) self.collectionView.reloadItems(at: [targetIndexPath]) } } print(abilities) } }
最后在CollectionView的Cell配置方法里,把能力数据设置到Cell的标签上:
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell { let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "你的Cell复用ID", for: indexPath) as! PokemonCell let currentPokemon = pokemonList[indexPath.item] // 配置其他UI(比如名称、体重) cell.nameLabel.text = currentPokemon.name cell.weightLabel.text = "\(currentPokemon.weight) kg" // 配置能力标签 cell.abilityLabel.text = currentPokemon.abilities.isEmpty ? "No abilities found" : currentPokemon.abilities.joined(separator: ", ") return cell }
额外小提示
- 确保你的Service类在获取到能力数据后,正确调用了Delegate的
finishedWithPokemonAbilities方法,并且传递的id和abilities是匹配的 - 可以给UI元素加个默认文本(比如"No abilities found"),避免空数据时标签显示空白
- 如果担心IBOutlet为nil,可以加个断言或者可选绑定来提前发现问题:
guard let abilityLabel = abilityLabel else { assertionFailure("Ability label not connected"); return }
内容的提问来源于stack exchange,提问作者3rnestocs
相关产品推荐
相关产品推荐

