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

SwiftUI列表选中行滚动至居中问题:选中后无法滚动到指定行

SwiftUI列表选中行滚动到屏幕中央的修复方案

你的代码里有两个关键问题导致滚动失效:

  1. 滚动目标ID错误:你给List设置的标识是每个video的id(id: \.id),但调用scrollTo时传了数字1,ScrollViewReader找不到对应的元素,自然无法滚动。
  2. 滚动锚点不对:要让选中行居中,应该用.center作为anchor参数,而不是.top。

修改后的关键代码

把.onChange闭包改成下面这样:

.onChange(of: selectedVideoId) { vid in
    // 确保选中的ID不为空
    guard let targetId = vid else { return }
    // 滚动到选中的video的ID位置,锚点设为屏幕中央
    scrollView.scrollTo(targetId, anchor: .center)
}

完整修改后的body代码

var body: some View {
    ScrollViewReader { scrollView in
        List(videos, id: \.id) { video in
            VStack(alignment: .leading) {
                WebImage(url: URL(string: video.thumbnailURL))
                    .resizable()
                    .placeholder {
                        Rectangle().foregroundColor(.clear)
                    }
                    .transition(.fade(duration: 0.5))
                    .aspectRatio(contentMode: .fit)
                    .frame(minHeight:100.0, alignment: .center)
                Text(video.title)
                    .foregroundColor(.white)
                    .padding(.horizontal, 5)
                    .lineLimit(1)
                    .font(Font.custom("Montserrat Bold", size: 14))
                Text(video.artist)
                    .foregroundColor(.white)
                    .padding(.horizontal, 5)
                    .lineLimit(1)
                    .font(Font.custom("Montserrat Medium", size: 14))
                    .padding(.bottom, 5)
                
            }.background(Color.black)
                .listRowBackground(Color.clear)
                .onTapGesture {
                    selectedVideoId = video.id
                    delegate?.videoSelected(video: video)
                }
                .border((selectedVideoId == video.id) ? Color(red: 0.9607843161, green: 0.7058823705, blue: 0.200000003) : Color.clear, width: (selectedVideoId == video.id) ? 1.5 : 0.0)
            
        }.padding(.horizontal, 20.0)
            .padding(.bottom, 10.0)
            .background(Color.clear)
            .listStyle(.plain)
            .onChange(of: selectedVideoId) { vid in
                guard let targetId = vid else { return }
                scrollView.scrollTo(targetId, anchor: .center)
            }
    }
}

这样修改后,当你选中某一行时,该行就会自动滚动到屏幕中央位置。

内容的提问来源于stack exchange,提问作者HarshIT

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.10 11:05:02