SwiftUI开发中如何访问超出当前作用域的@State状态变量?
解决方案
通过 SwiftUI 内置的 @Binding 属性包装器即可实现需求,它可以创建指向父视图@State属性的读写引用,不需要依赖全局状态。
代码修改说明
- 为
CardView新增@Binding类型的percent属性,用于接收父视图的进度状态引用 - 在
ContentView中初始化CardView时,使用$前缀传入percent的绑定值 - 滑动逻辑中直接修改绑定的
percent值即可同步到父视图的进度条
修改后完整代码
import Photos import SwiftUI struct ContentView: View { // 父视图存储的进度状态 @State var percent: CGFloat = 0 var body: some View { ZStack{ // 进度条视图可直接绑定$percent实现同步更新 ForEach(imageObjectGroup){ card in // 传入percent的绑定引用 CardView(card: $card, percent: $percent).padding(8) } }.zIndex(1.0) } } struct ContentView_Previews: PreviewProvider { static var previews: some View { ContentView() } } //Card Structure struct CardView: View{ // 若修改的card属性需要同步到父数组,需改成@Binding @Binding var card: ImageObject // 绑定父视图传入的percent状态 @Binding var percent: CGFloat var body: some View { // 此处保留你原有卡片布局代码 .gesture( DragGesture().onChanged { value in card.x = value.translation.width card.y = value.translation.height card.degree = 7 * (value.translation.width > 0 ? 1 : -1) } // 用户停止滑动触发逻辑 .onEnded { value in withAnimation(.interpolatingSpring(mass: 1.0, stiffness: 50, damping: 8, initialVelocity: 0)){ switch value.translation.width { case 0...100: card.x = 0; card.degree = 0; card.y = 0 // 右滑保留逻辑 case let x where x > 100: card.x = 800; case (-100)...(-1): card.x = 0; card.degree = 0; card.y = 0; // 左滑删除逻辑 case let x where x < -100: card.x = -200; card.degree = -12 // 直接修改绑定值即可同步更新父视图进度条 percent += 1 default: card.x = 0; card.y = 0 } } } ) } }
补充说明
如果你的ImageObject是遵守ObservableObject协议的类类型,把@Binding var card替换为@ObservedObject var card即可;增量值可以根据卡片总数灵活调整,比如总共有20张卡片的话每次加0.05,刚好满100%进度。
内容的提问来源于stack exchange,提问作者Sachu
相关产品推荐
相关产品推荐

