swift - SwiftUI - 是否可以在显示后更改 ActionSheet 按钮文本?
问题描述
我想展示一个ActionSheet
包含用户可以购买的 InApp 购买对象。
但我希望该表包含此类对象的价格,例如:
Object 1 ($1.99)
Object 2 ($2.99)
...
但是价格是异步的,因为它必须从商店中检索。
所以,我想这样做:
struct Package {
enum Packtype:String {
typealias RawValue = String
case obj1 = "com.example.object1"
case obj2 = "com.example.object2"
}
var productID:String = ""
@State var namePriceString:String = ""
init(productID:String) {
self.productID = productID
}
}
然后,当我创建操作表按钮时,我会这样做:
var obj1 = Package(productID: Package.Packtype.obj1.rawValue)
var obj2 = Package(productID: Package.Packtype.obj2.rawValue)
self.getPrices(packages:[obj1, obj2])
let obj1Button = ActionSheet.Button.default(Text(obj1.$namePriceString)) {
// do something with obj1
}
let obj2Button = ActionSheet.Button.default(Text(obj2.$namePriceString)) {
// do something with obj1
}
// build the actionsheet
稍后在代码中:
func getPrices(packages:[Package]) {
let productIDS = Set(packages.map {$0.productID})
SwiftyStoreKit.retrieveProductsInfo(productIDS) { (answer) in
if answer.invalidProductIDs.first != nil { return }
let results = answer.retrievedProducts
if results.count == 0 { return }
for result in answer {
if let package = packages.filter({ ($0.productID == result.productIdentifier) }).first {
package.namePriceString = result.localizedTitle + "(" + "\(result.localizedPrice!)" + ")"
}
}
}
}
我有一个错误指向Text
按钮创建行说
初始化程序 'init(_:)' 要求 'Binding' 符合 'StringProtocol'
简而言之,我需要这个:
- 我显示操作表。它的按钮不包含价格。
- 我检索价格
- 操作表按钮随价格更新。
解决方案
一种可能的解决方案是在处理程序中返回价格,completion
然后才显示操作表:
struct ContentView: View {
@State var showActionSheet = false
@State var localizedPrices = [Package: String]()
var body: some View {
Button("Get prices") {
getPrices(packages: Package.allCases, completion: {
localizedPrices = $0
showActionSheet = true
})
}
.actionSheet(isPresented: $showActionSheet) {
let buttons = localizedPrices.map { package, localizedPrice in
ActionSheet.Button.default(Text(localizedPrice), action: { buy(package: package) })
}
return ActionSheet(title: Text("Title"), message: Text("Message"), buttons: buttons + [.cancel()])
}
}
}
func getPrices(packages: [Package], completion: @escaping ([Package: String]) -> Void) {
// simulates an asynchronous task, should be replaced with the actual implementation
DispatchQueue.main.asyncAfter(deadline: .now() + 3) {
let localizedPrices = Dictionary(uniqueKeysWithValues: packages.map { ($0, "\(Int.random(in: 1 ..< 100))") })
completion(localizedPrices)
}
}
func buy(package: Package) {
print("Buying \(package.rawValue)")
}
enum Package: String, CaseIterable {
case obj1 = "com.example.object1"
case obj2 = "com.example.object2"
}
这可以通过加载动画等进一步调整......
推荐阅读
- python - 如何在 Python 中使用一个 Excel 列中的多个数据点?
- r - 如何对行进行分组并在 r 中以列表形式排列它们的单元格关联?
- r - R按类别填充缺失的日期
- arrays - 无法将 JSON 解析响应转换为数组
- c - STM32相同的while循环代码但编译成不同的汇编代码
- angular - Angular @Input 将数字值从父组件传递到子组件
- google-apps-script - 是否有 Classroom.Courses.Topics.get 的示例,以便我可以使用现有 topicId 调用 Classroom.Courses.CourseWork.create?
- laravel - 如何在 Laravel 中建立这种 Eloquent 关系
- html - HTML img 自动旋转
- json - overpass-turbo.eu 在地图上找到所有城市