You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.30 20:59:07