SwiftUI变量更新顺序错误致Sheet显示图片异常求助
SwiftUI Sheet显示错误图片问题原因分析
问题场景
开发图片列表APP时,点击列表中第二个图片(index=1),弹出的Sheet却显示第一张图片。执行日志显示,设置photoEdition = true时,selectedIndex尚未完成更新。
原代码
import SwiftUI struct SheetView: View { @Binding var photo: String var body: some View { Text("photo title: " + photo) } } struct ContentView: View { @State private var selectedIndex: Int = 0 @State private var photoEdition: Bool = false @State var photos: [String] = ["gigio", "lulu", "lucky"] private var photoToEdit: Binding<String> { .init(get: { () -> String in print("get", photos[selectedIndex], selectedIndex) return photos[selectedIndex] }, set: { (newValue) in photos[selectedIndex] = newValue print("set", photos[selectedIndex], selectedIndex) }) } var body: some View { VStack { ForEach(photos.indices, id:\.self) { index in Button(action: { photoTapHandler(selectedIndex: index) }) { Text(photos[index]).padding(10) } } } .sheet(isPresented: $photoEdition, content: { SheetView(photo: photoToEdit) }) } private func photoTapHandler(selectedIndex: Int) { print("updating selected index to ", selectedIndex) self.selectedIndex = selectedIndex self.photoEdition = true } }
执行日志
updating selected index to 1 get gigio 0 get gigio 0
修复后的代码
var body: some View { VStack { ForEach(photos.indices, id:\.self) { index in Button(action: { photoTapHandler(selectedIndex: index) }) { Text(photos[index]).padding(10) } } }.onChange(of: selectedIndex) { selectedIndex in self.photoEdition = true } .sheet(isPresented: $photoEdition, content: { SheetView(photo: photoToEdit) }) } private func photoTapHandler(selectedIndex: Int) { print("updating selected index to ", selectedIndex) self.selectedIndex = selectedIndex // self.photoEdition = true }
问题原因
SwiftUI的@State变量更新采用异步批量处理机制,赋值操作不会立即生效。原代码中,在同一个函数内先后给selectedIndex和photoEdition赋值,这两个状态更新会被SwiftUI合并处理。当photoEdition变为true触发Sheet展示时,selectedIndex的更新尚未完成,导致photoToEdit绑定读取的仍是旧的索引值(0),最终Sheet显示错误图片。
修复方案通过onChange(of: selectedIndex)监听索引的变化,确保只有在selectedIndex完全更新后,再将photoEdition设为true弹出Sheet,此时photoToEdit就能读取到最新的索引值,展示正确的图片。
内容的提问来源于stack exchange,提问作者Laura Corssac
相关产品推荐
相关产品推荐

