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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.14 15:52:23