场景:
我正在玩访问和显示远程图像,以了解Combine的各种通知标记/协议。
一个目标:
访问错误的URL应该立即显示Alert()。
现实:
警报显示之后,然后显示第二个请求。
这是主(调用)视图:
import Combine
import SwiftUI
struct ContentView: View {
@EnvironmentObject var settings: MySettings
@State private var url: String = "https://garbage.com" // ...purposely set to display alert.
@State private var image: URLImage = URLImage()
@State private var angelFish: Image = Image("QueenAngelfish")
@State private var isPresented = false
var body: some View {
ZStack {
Color.green
NavigationView {
VStack {
Button(action: {
self.url = "garbage.com"
self.isPresented = self.image.imageLoader.isPresented
self.image.imageLoader.load(url: URL(string: self.url)!)
}) {
Text("Get An Image")
}
angelFish
.resizable()
.frame(width: 300, height: 200, alignment: .center)
.padding()
image
.alert(isPresented: $isPresented, content: { () -> Alert in
Alert(title: Text(verbatim: "Unable to Acquire Image."))
})
}.navigationBarTitle(Text(settings.name))
}
}
}
}
这是访问引擎:
import Combine
import SwiftUI
enum ImageURLError: Error {
case dataIsNotAnImage
}
struct URLImage: View {
@EnvironmentObject var settings: MySettings
@ObservedObject var imageLoader: ImageLoader
var placeholder: Image
init() {
self.placeholder = Image(systemName: "photo")
self.imageLoader = ImageLoader()
}
var body: some View {
VStack {
imageLoader.image == nil ?
placeholder : Image(uiImage: imageLoader.image!)
Button(action: {
self.settings.name = "Happy Thanks Giving"
self.settings.isPresented = true
}, label: {
Text("Touch Me")
})
}
}
}
// =====================================================================================================
class ImageLoader: ObservableObject {
let id: String = UUID().uuidString
var didChange = PassthroughSubject<Void, Never>()
@Published var isPresented = false
@Published var image: UIImage? {
didSet {
DispatchQueue.main.async {
self.didChange.send()
}
}
}
// ---------------------------------------------------------------------------
func load(url: URL) {
print("Hello Ric: ", #function)
URLSession.shared.dataTask(with: url) { data, _, error in
DispatchQueue.main.async {
if error != nil {
self.isPresented = true
self.didChange.send() // ...attempting to activate alert().
return
}
self.image = UIImage(data: data!)
}
}.resume()
}
}
由于URL错误,此代码有意创建一个错误。
我试图通过将布尔值“ isPresented”标志作为“ @Published”变量传递来立即通知调用例程
预期结果:
显示的警报。
实际结果:
警报将在首次尝试之后显示。
问题:如何执行即时警报显示?
答案 0 :(得分:1)
好的,这里有几个问题,主要是关于ObservableObject的用法以及将事物链接在一起的问题。请在下面找到有效的修改后模块。 (我将一些不存在的实体替换为我的实体以进行测试)。
{{1}}