首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >SwiftUI - onChange不被呼叫

SwiftUI - onChange不被呼叫
EN

Stack Overflow用户
提问于 2022-08-07 03:28:05
回答 1查看 984关注 0票数 3

首先添加代码,以帮助更好地理解问题。

代码语言:javascript
运行
复制
struct MainSetupView: View {
    @StateObject var viewModel: MainViewModel
    
    var body: some View {
        VStack {
            switch viewModel.state {
            case .idle:
                Color.clear.onAppear(perform: { viewModel.prepare() })
            case .loading:
                ProgressView()
            case .showMessage(let messageType, let messageText):
                ErrorHandlingView(messageType: messageType, messageText: messageText)
            }
        }.onAppear() {
            viewModel.state = .idle
        }
    }
}

struct ErrorHandlingView: View {
    @State var messageType: String
    var messageText: String

    @State private var messageViewImageDetails: (imageName: String, isSystemImage: Bool) = (imageName: "", isSystemImage: false)

    var body: some View {
        VStack {
            MessageViewWithActions(imageName: messageViewImageDetails.imageName, isSystemImage: messageViewImageDetails.isSystemImage, mainMessageText: messageText)
        }.onChange(of: messageType) {_ in
            self.messageViewImageDetails = getImageForError()
            // call more functions
        }
    }
    
    private func getImageForError() -> (imageName: String, isSystemImage: Bool) {
        var imageName = ""
        var isSystemImage = false
        
        switch messageType {
        case "noInternetError":
            imageName = "xmark.icloud"
            isSystemImage = true
        case "userSignedOut":
            imageName = "person.crop.circle.fill.badge.xmark"
            isSystemImage = true
        case "userSignedIn":
            imageName = "person.crop.circle.badge.checkmark"
            isSystemImage = true
        // more cases.
        default:
            imageName = "info.circle"
            isSystemImage = true
        }
        
        return (imageName: imageName, isSystemImage: isSystemImage)
    }
}

如果"MainSetupView“是打开的,并且我收到了一条消息,即.showMessage,则显示" ErrorHandlingView”,并在调用ErrorHandlingView时设置"messageType“和"messageText”。在显示第一条消息时,假设我收到了另一条消息,然后再次调用"ErrorHandlingView“,现在使用的是不同的消息类型。但是,"onChange(of: messageType)“中的"ErrorHandlingView”从未被调用。

"onChange( of : messageType)“调用一个函数"getImageForError”,该函数根据messageType的值告诉应用程序要显示哪个图像。由于onChange中的代码没有被执行,"getImageForError“永远不会被调用,因此"messageViewImageDetails”永远不会被填充,从而导致视图中没有图像。

知道为什么没有执行.onChange()吗?我做错了什么?

注意:我有很多代码,我正在分享一些代码,我认为这些代码会有所帮助。如果需要更多代码,请告诉我。

编辑:为MessageViewWithActions添加代码。

代码语言:javascript
运行
复制
struct MessageViewWithActions: View {
    // Image properties
    var imageName: String?
    var isSystemImage: Bool = false
    
    // Text properties
    var mainMessageText: String?

    var body: some View {
        ScrollView {
            VStack {
                Text("")
                VStack {
                    if let imageName = imageName {
                        if isSystemImage {
                            Image(systemName: imageName)
                        } else {
                            Image(imageName)
                        }
                    }
                }.frame(maxWidth: .infinity).padding(.bottom, 8)
                
                if let mainMessageText = mainMessageText {
                    Text(mainMessageText).font(.subheadline).fixedSize(horizontal: false, vertical: true)
                }
            }
        }
    }
}
EN

回答 1

Stack Overflow用户

发布于 2022-08-07 04:06:32

将messageType更改为绑定变量而不是状态变量有效。分享今后更新的代码:

代码语言:javascript
运行
复制
struct MainSetupView: View {
    @StateObject var viewModel: MainViewModel
    @State var messageType: String
    
    var body: some View {
        VStack {
            switch viewModel.state {
            case .idle:
                Color.clear.onAppear(perform: { viewModel.prepare() })
            case .loading:
                ProgressView()
            case .showMessage(_, let messageText):
                ErrorHandlingView(messageType: messageType, messageText: messageText)
            }
        }.onAppear() {
            viewModel.state = .idle
        }.onReceive(viewModel.$state, perform: { (value) in
            switch value {
            case .showMessage(let messageType, _):
                self.messageType = messageType
            case .idle, .loading:
                print("")
            }
        })
    }
}

struct ErrorHandlingView: View {
    @Binding var messageType: String
    var messageText: String

    @State private var messageViewImageDetails: (imageName: String, isSystemImage: Bool) = (imageName: "", isSystemImage: false)

    var body: some View {
        VStack {
            MessageViewWithActions(imageName: messageViewImageDetails.imageName, isSystemImage: messageViewImageDetails.isSystemImage, mainMessageText: messageText)
        }.onChange(of: messageType) {_ in
            self.messageViewImageDetails = getImageForError()
            // call more functions
        }
    }
    
    private func getImageForError() -> (imageName: String, isSystemImage: Bool) {
        var imageName = ""
        var isSystemImage = false
        
        switch messageType {
        case "noInternetError":
            imageName = "xmark.icloud"
            isSystemImage = true
        case "userSignedOut":
            imageName = "person.crop.circle.fill.badge.xmark"
            isSystemImage = true
        case "userSignedIn":
            imageName = "person.crop.circle.badge.checkmark"
            isSystemImage = true
        // more cases.
        default:
            imageName = "info.circle"
            isSystemImage = true
        }
        
        return (imageName: imageName, isSystemImage: isSystemImage)
    }
}
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/73264683

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档