SwiftUI中基于Identifiable协议的List无法通过ScrollViewReader实现滚动定位的问题求助
解决ScrollViewReader在List中无法滚动定位的问题
我帮你梳理下代码里的关键问题,咱们一步步来修复:
1. 核心问题:ID类型不匹配
你的Country模型里id是可选类型Int64?,但你调用proxy.scrollTo(38)时传入的是Int字面量,这俩类型完全不匹配,ScrollViewReader自然找不到对应的视图!
你需要做两处调整:
- 调用
scrollTo时,把参数转换成和id一致的Int64类型:proxy.scrollTo(Int64(38)) - 显式给List的每行绑定ID——哪怕遵循了
Identifiable,可选类型的ID也可能让SwiftUI识别出错:ForEach(countries) { country in Button(action: { wine.countryId = country.id self.mode.wrappedValue.dismiss() }) { HStack { Image(country.flag).resizable().frame(width: 24.0, height: 24.0) Text(country.name) } } // 这里假设数据库返回的id都非空,若有空值需额外处理 .id(country.id!) }
2. 额外的验证点
- 确认
id:38对应的Country对象确实存在于countries数组中,毕竟展示顺序和id顺序无关,但目标ID必须存在才能定位。 - 确保List内容足够长(超过屏幕高度),如果内容太短,
scrollTo不会有视觉上的滚动效果。
更安全的优化建议
既然是数据库字段,id作为主键应该是非空的,建议直接把模型里的id改成非可选类型,从根源避免类型匹配问题:
struct Country: Identifiable, Codable, Hashable { var id: Int64 // 去掉可选标记,确保是必填字段 var name: String }
修改后的完整测试代码:
ScrollViewReader { proxy in VStack { Button(action: { proxy.scrollTo(Int64(38)) }) { Text("Jump to") } List() { ForEach(countries) { country in Button (action: { wine.countryId = country.id self.mode.wrappedValue.dismiss() }) { HStack { Image(country.flag).resizable().frame(width: 24.0, height: 24.0) Text(country.name) } } .id(country.id) } } } }
这样调整后,滚动定位应该就能正常工作了!
内容的提问来源于stack exchange,提问作者alex.bour
相关产品推荐
相关产品推荐

