这是一个示例代码,单击另一个视图按钮来更改原始视图文本。现在一切进展顺利。
import SwiftUI
struct ContentView: View {
@EnvironmentObject var test:Test
var body: some View {
NavigationView{
VStack{
Text(test.a)
NavigationLink("change now",destination: editView())
}
}
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView().environmentObject(Test())
}
}
class Test:ObservableObject{
@Published var a:String = "Old"
}
struct editView:View{
@EnvironmentObject var test:Test
var body:some View{
Button(action:{
self.test.a = "New"
}){
Text("Change !")
}
}
}
但是,如果我将编辑视图移到单张,内容视图的文本不能更改!事实上,数据已经更改,但是ContentView不重新渲染.
这是bug?或者任何解决方法,强制ContentView重新呈现。
import SwiftUI
struct ContentView: View {
@EnvironmentObject var test:Test
@State var show:Bool = false
var body: some View {
NavigationView{
VStack{
Text(test.a)
Button(action:{self.show.toggle()}){
Text("show sheet")
}
}
}.sheet(isPresented: $show){
editView().environmentObject(Test())
}
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView().environmentObject(Test())
}
}
class Test:ObservableObject{
@Published var a:String = "Old"
}
struct editView:View{
@EnvironmentObject var test:Test
var body:some View{
Button(action:{
self.test.a = "New"
}){
Text("Change !")
}
}
}
我做过这件事。
let contentView = ContentView().environmentObject(Test())
版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。
在 SwiftUI 中,当您在一个 .sheet 或其他类似呈现的视图中修改了环境对象(如 Test),并且希望这个改变能影响到父视图(这里是 ContentView),确保所有共享相同数据源的视图都正确使用了 @EnvironmentObject 是关键。然而,在您的示例代码中,问题可能出在当您在 .sheet 中创建一个新的 editView 实例时,它实际上创建了一个新的 Test 实例,这与主 ContentView 使用的不是同一个实例。
为了解决这个问题,您需要确保在展示 .sheet 时复用已经在环境中存在的 Test 实例,而不是为 .sheet 内容重新创建一个。您已经通过 .environmentObject(Test()) 在调用 editView 时传递了环境对象,但这实际上创建了一个新的实例。正确的做法是直接传递已有的环境对象给 .sheet 中的内容视图,而不需要再次初始化 Test()。
不过,根据您的代码结构,您似乎已经在 ContentView 的层级上绑定了 Test 对象,因此在调用 .sheet 时应该利用已有的环境对象,而不是显式地再次注入。SwiftUI 应该能够自动管理并传递这个环境对象到 sheet 中,只要您不显式地重新创建它。
修正后的代码看起来应该是这样的:
struct ContentView: View {
@EnvironmentObject var test: Test
@State var show: Bool = false
var body: some View {
NavigationView{
VStack{
Text(test.a)
Button(action: { self.show.toggle() }) {
Text("show sheet")
}
}
.sheet(isPresented: $show) {
editView() // 不需要再这里显式地注入 Test,因为其应该从环境获取
}
}
}
}
请确保在整个应用生命周期内只创建一次 Test 类的实例,并且在任何需要该实例的地方通过 @EnvironmentObject 注入。这样,当 Test 中的 @Published 属性发生变化时,所有观察这些变化的视图都会自动更新。