SwiftUI列表选中行滚动至居中问题:选中后无法滚动到指定行
SwiftUI列表选中行滚动到屏幕中央的修复方案
你的代码里有两个关键问题导致滚动失效:
- 滚动目标ID错误:你给List设置的标识是每个video的
id(id: \.id),但调用scrollTo时传了数字1,ScrollViewReader找不到对应的元素,自然无法滚动。 - 滚动锚点不对:要让选中行居中,应该用
.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
相关产品推荐
相关产品推荐

