问题
I have this previous question properly answer. That case is of an image somewhere in the interface.
I have another variation of the same problem but now the image is inside a List Cell.
That image shows a padlock that must only show if a particular inapp purchase was not purchased, on SwiftUI.
Something like
Image(systemName: "lock.circle.fill")
.renderingMode(.template)
.foregroundColor(.white)
.font(symbolFont)
.opacity(wasPurchased(item: item))
But as far as I see wasPurchased must be a synchronous function, right?
Something like
func wasPurchased(item: item) -> Bool {
return check(item:item) ? true : false
}
But, such checks normally happen asynchronously, over the network, and the function, as I see, must have a signature like
func wasPurchased(item: item, runOnFinishChecking:(Bool)->()) {
That list is populated from Core Data, like this
@FetchRequest(fetchRequest: Expressao.getAllItemsRequest())
private var allItems: FetchedResults<Expressao>
var body: some View {
List {
ForEach(allItems, id: \.self) { item in
HStack {
Text(item.term)
.font(fontItems)
.foregroundColor(.white)
Image(systemName: "lock.circle.fill")
.renderingMode(.template)
.foregroundColor(.white)
.font(symbolFont)
.opacity(wasPurchased(item: item))
}
}
}
}
I don't see how I can use something asynchronous to control the opacity of such element when the whole thing is an array.
How do I do that?
回答1:
Just separate your row content into standalone view and apply approach from previous post.
var body: some View {
List {
ForEach(allItems, id: \.self) {
ExpressaoRowView(item: $0)
}
}
}
...
struct ExpressaoRowView: View {
@ObservedObject var item: Expressao
@State private var locked = true
var body: some View {
HStack {
Text(item.term)
.font(fontItems)
.foregroundColor(.white)
Image(systemName: "lock.circle.fill")
.renderingMode(.template)
.foregroundColor(.white)
.font(symbolFont)
.opacity(self.locked ? 1 : 0)
}
.onAppear {
self.wasPurchased(self.item) { purchased in
DispatchQueue.main.async {
self.locked = !purchased
}
}
}
}
}
Note: you can even keep wasPurchased checker somewhere outside (in parent or in some helper) and inject into ExpressaoRowView as a property
来源:https://stackoverflow.com/questions/64710021/swiftui-how-do-i-change-a-synchronous-value-using-an-asynchronous-operation-in