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

如何创建可在不同结构体中读写的变量?SwiftUI @State跨视图访问问题

SwiftUI 跨视图共享可读写状态方案

你当前遇到的核心问题是@State的设计限制:@State是专门用于单个视图内部的私有状态,即使加了public修饰也无法实现跨视图的状态同步,子视图拿到的只是值拷贝,既无法反向修改父视图的原值,也无法自动获取最新的状态变更。
根据你的视图层级关系,有两种成熟的实现方案:

方案1:父子视图层级用@Binding传递

如果两个需要读写lane的视图是直接/间接的父子关系,用@Binding做状态绑定是最轻量的选择:

  1. 父视图中保留@State定义的源状态:
@State private var lane = 2 // 替换为你需要的初始值
  1. 给操作lane的按钮视图(也就是你给出的HStack所在的视图)声明@Binding类型的lane属性,替代原来的@State定义:
struct LaneControlView: View {
    @Binding var lane: Int
    var body: some View {
        // 你原来的HStack代码直接放这里即可,对lane的加减操作会自动同步到父视图
        HStack {
          Button(action : {
            if (lane != 1) { lane -= 1 }
          }) {
            Rectangle()
              .frame(width: 200, height: 900)
              .opacity(0)
          }
                        
          Button(action: {
            if (lane != 4) { lane += 1 }
          }) {
            Rectangle()
              .frame(width: 200, height: 900)
              .opacity(0)
          }
        }
    }
}
  1. 父视图调用子视图时,传递绑定值(前缀加$):
LaneControlView(lane: $lane)
  1. 另一个需要访问lane最新值的视图,同样声明@Binding var lane: Int,父视图调用时也传递$lane即可,你需要的判断逻辑里直接访问lane就是最新值:
struct EnemyCheckView: View {
    @Binding var lane: Int
    // 其他属性定义
    var body: some View {
        // 其他逻辑
        if(carLane == enemyLane && Enemy1OffsetY == 150) {
          fatalError()
        }
    }
}

方案2:跨多层级/多视图共享用ObservableObject

如果两个视图层级距离远,或者整个项目多个地方都要用到lane状态,用ObservableObject做全局共享状态更合适:

  1. 先定义继承自ObservableObject的状态管理类:
class GameState: ObservableObject {
    @Published var lane = 2 // @Published修饰会自动通知所有订阅视图状态变更
}
  1. 在项目的根视图层级注入状态实例:
@main
struct YourGameApp: App {
    @StateObject private var gameState = GameState()
    var body: some Scene {
        WindowGroup {
            ContentView()
                .environmentObject(gameState)
        }
    }
}
  1. 所有需要读写lane的视图,都声明@EnvironmentObject属性获取状态实例:
// 按钮控制视图
struct LaneControlView: View {
    @EnvironmentObject var gameState: GameState
    var body: some View {
        HStack {
          Button(action : {
            if (gameState.lane != 1) { gameState.lane -= 1 }
          }) {
            Rectangle()
              .frame(width: 200, height: 900)
              .opacity(0)
          }
          // 另一个按钮同理,操作gameState.lane即可
        }
    }
}
// 碰撞检测视图
struct EnemyCheckView: View {
    @EnvironmentObject var gameState: GameState
    // 其他属性
    var body: some View {
        // 直接访问gameState.lane就是最新值
        if(carLane == enemyLane && Enemy1OffsetY == 150) {
          fatalError()
        }
    }
}

注意事项

  • 不要给@State添加public修饰,完全不符合@State的设计定位,无法实现跨视图同步
  • 使用@EnvironmentObject时要确保注入层级足够高,所有用到该状态的子视图都在注入层级的下方,否则会触发运行时错误

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.27 20:54:00