gpt4 book ai didi

ios - SwiftUI - onChange 没有被调用

转载 作者:行者123 更新时间:2023-12-05 05:36:39 24 4
gpt4 key购买 nike

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

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”再次被调用,现在使用不同的消息类型。然而,“ErrorHandlingView”中的“onChange(of: messageType)”永远不会被调用。

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

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

注意:我有很多代码,我正在分享我认为有用的代码片段。让我知道是否需要更多代码。

编辑:为 MessageViewWithActions 添加代码。

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)
}
}
}
}
}

最佳答案

将 messageType 更改为 Binding var 而不是 State var 有效。为 future 共享更新的代码:

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)
}
}

关于ios - SwiftUI - onChange 没有被调用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/73264683/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com