简体   繁体   English

在 Else 块中访问 ObservableObject 时视图不更新

[英]View not updating when accessing ObservableObject in Else block

My detail View does not update when I change its @Binding value.当我更改其@Binding值时,我的详细View不会更新。

struct ContentView: View {

    class ViewModel: ObservableObject {

        @Published var imageSize: ImageSize?
        @Published var anotherValue: Int? = 5

        var cancellable: AnyCancellable?

        init() {
            cancellable = $imageSize.sink(receiveValue: { imageSize in
                print("🚨 \(imageSize?.rawValue ?? "Unknown")")
            })
        }
    }

    @ObservedObject private var viewModel = ViewModel()

    var body: some View {

        NavigationView {
            List {

                if viewModel.anotherValue == nil {
                    Text("Another value is nil")
                } else {
                    NavigationLink(destination: SelectImageSizeView(selectedImageSize: $viewModel.imageSize)
                                    .navigationBarTitle("ImageSize", displayMode: .inline)) {

                        Text("ImageSize: \(viewModel.imageSize?.rawValue ?? "Not Set")")

                    }
                }
            }
        }
    }
}

struct SelectImageSizeView: View {

    @Binding var selectedImageSize: ImageSize?

    var body: some View {

        List{
            ForEach(ImageSize.allCases, id: \.self) { imageSize in

                HStack {

                    Button {
                        withAnimation {
                            self.selectedImageSize = imageSize
                        }
                    } label: {

                        HStack {
                            Text(imageSize.rawValue)
                            Image(systemName: imageSize == selectedImageSize ? "checkmark.circle.fill" : "circle")
                        }
                        .font(.title)
                    }
                }
            }
        }
    }
}

public enum ImageSize: String, Codable, CaseIterable {

    case small = "Small"
    case medium = "Medium"
    case large = "Large"
}

It does work when I move the NavigationLink to out of the if block:当我将NavigationLink移出if块时,它确实有效:

NavigationView {
            List {

                if viewModel.anotherValue == nil {
                    Text("Another value is nil")
                }

                NavigationLink(destination: SelectImageSizeView(selectedImageSize: $viewModel.imageSize)
                                .navigationBarTitle("ImageSize", displayMode: .inline)) {

                    Text("ImageSize: \(viewModel.imageSize?.rawValue ?? "Not Set")")

                }
            }
        }

Am I missing something here?我在这里错过了什么吗?

Hm.嗯。 I don't know why that's the case.我不知道为什么会这样。 But you could instead pass over your whole ViewModel ?但是您可以转而忽略整个ViewModel吗?

You would have to put it outside your ContentView .你必须把它放在你的ContentView之外。 I have made it fileprivate if you don't want to access it from other files.如果您不想从其他文件访问它,我已将其fileprivate文件私有。

Works for me.为我工作。

fileprivate class ViewModel: ObservableObject {

    @Published var imageSize: ImageSize?
    @Published var anotherValue: Int? = 5

    var cancellable: AnyCancellable?

    init() {
        cancellable = $imageSize.sink(receiveValue: { imageSize in
            print("🚨 \(imageSize?.rawValue ?? "Unknown")")
        })
    }
}

struct ContentView: View {

    @StateObject private var viewModel = ViewModel()

    var body: some View {

        NavigationView {
            List {

                if viewModel.anotherValue == nil {
                    Text("Another value is nil")
                } else {
                    NavigationLink(destination: SelectImageSizeView(viewModel: viewModel)
                                    .navigationBarTitle("ImageSize", displayMode: .inline)) {

                        Text("ImageSize: \(viewModel.imageSize?.rawValue ?? "Not Set")")

                    }
                }
            }
        }
    }
}

struct SelectImageSizeView: View {

    @ObservedObject fileprivate var viewModel: ViewModel

    var body: some View {

        List{
            ForEach(ImageSize.allCases, id: \.self) { imageSize in

                HStack {

                    Button {
                        withAnimation {
                            viewModel.imageSize = imageSize
                        }
                    } label: {

                        HStack {
                            Text(imageSize.rawValue)
                            Image(systemName: imageSize == viewModel.imageSize ? "checkmark.circle.fill" : "circle")
                        }
                        .font(.title)
                    }
                }
            }
        }
    }
}

public enum ImageSize: String, Codable, CaseIterable {

    case small = "Small"
    case medium = "Medium"
    case large = "Large"
}

It is very silly but there is bug in simulator.这很愚蠢,但模拟器中有错误。 It is working with device.它正在与设备一起使用。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM