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

SwiftUI中@State变量点击Toolbar按钮后无法更新问题咨询

SwiftUI中Sheet无法获取@State变量最新值的问题解决

你遇到的核心问题是:sheet(isPresented:)的内容闭包会在HomeView首次渲染时就捕获index的初始值(-1),后续即使通过按钮更新了index,这个闭包也不会重新捕获新值,所以sheet里拿到的始终是初始的-1。

下面给两种实用的解决方法:

方法一:使用sheet(item:)替代isPresented

这种方法通过绑定一个遵循Identifiable的对象来控制sheet的弹出,每次对象更新时,sheet的内容闭包都会基于最新值生成视图,自然能拿到最新的index。

修改后的代码:

import SwiftUI
import SwiftData

struct HomeView: View {
    // 用可选类型的Int作为sheet的触发源,同时传递index值
    @State var presentedIndex: Int? = nil

    var body: some View {
        NavigationStack() {
            VStack(alignment: .leading) {
                Spacer()
            }
            .navigationTitle("title")
            .navigationBarTitleDisplayMode(.inline)
            .toolbar {
                ToolbarItem(placement: .topBarTrailing) {
                    Button {
                        // 设置要传递的index值,同时触发sheet弹出
                        presentedIndex = 1
                    } label: {
                        Label("setting", systemImage: "plus")
                    }
                }
            }
        }
        // 绑定presentedIndex,每次更新都会生成新的sheet内容
        .sheet(item: $presentedIndex) { currentIndex in
            Text("当前index值:\(currentIndex)")
            // 这里可以替换成你实际的sheet视图
        }
    }
}

// 让Int遵循Identifiable协议,满足sheet(item:)的要求
extension Int: Identifiable {
    public var id: Int { self }
}

方法二:将Sheet内容拆分为独立子View

把sheet的内容抽成单独的View,通过绑定或者直接传递参数的方式,让子View获取最新的index值。

修改后的代码:

import SwiftUI
import SwiftData

struct HomeView: View {
    @State var isPresentingAddView = false
    @State var index = -1

    var body: some View {
        NavigationStack() {
            VStack(alignment: .leading) {
                Spacer()
            }
            .navigationTitle("title")
            .navigationBarTitleDisplayMode(.inline)
            .toolbar {
                ToolbarItem(placement: .topBarTrailing) {
                    Button {
                        index = 1
                        isPresentingAddView = true
                    } label: {
                        Label("setting", systemImage: "plus")
                    }
                }
            }
        }
        // 传递index的绑定给子View,确保能拿到最新值
        .sheet(isPresented: $isPresentingAddView) {
            AddView(currentIndex: $index)
        }
    }
}

// 独立的Sheet内容View
struct AddView: View {
    @Binding var currentIndex: Int // 用绑定实时获取父视图的最新值

    var body: some View {
        Text("当前index值:\(currentIndex)")
        // 这里写你原本的sheet逻辑
    }
}

两种方法都能解决问题,你可以根据实际需求选择:如果只需要传递单次的初始值,方法一更简洁;如果需要在sheet中实时同步父视图的index变化,方法二的绑定方式更合适。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.02 23:42:47