You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

SwiftUI:用户点击内购确认弹窗“OK”后如何自动关闭.sheet模态视图?

SwiftUI:用户点击内购确认弹窗“OK”后如何自动关闭.sheet模态视图?

我太懂你这个痛点了!用StoreKit 2做内购时,明明用户已经付款成功、点了确认弹窗的OK,结果那个装着ProductView的sheet还赖在屏幕上,得手动划走,体验太不流畅了。别担心,咱用SwiftUI的状态绑定就能轻松解决这个问题,我给你一步步捋清楚:

首先,核心思路就是用状态变量来同时控制sheet的显示和确认弹窗的触发,当用户点OK时,直接把控制sheet的状态开关关掉就行。

第一步:准备状态变量

在你的父视图(就是弹出sheet的那个视图)里,加两个@State变量:

  • 一个用来控制sheet的显示/隐藏,比如isPresentingStoreView
  • 另一个用来控制购买成功后的确认弹窗,比如showSuccessAlert

第二步:修改内购完成的回调逻辑

在onInAppPurchaseCompletion的成功分支里,除了打印日志,还要记得结束交易(StoreKit要求必须手动finish成功的交易,不然会重复触发回调),然后把showSuccessAlert设为true,弹出确认弹窗。

第三步:给确认弹窗加关闭sheet的动作

在Alert的OK按钮闭包里,直接把控制sheet的isPresentingStoreView设为false,这样用户一点OK,sheet就自动关了。

完整的修改后代码示例

结合你给的代码,调整后的版本大概是这样:

struct YourParentView: View {
    // 控制sheet显示的状态
    @State private var isPresentingStoreView = false
    // 控制成功弹窗的状态
    @State private var showSuccessAlert = false
    
    var body: some View {
        // 这里是你的主视图内容,比如触发sheet的按钮
        Button("解锁终身权限") {
            isPresentingStoreView = true
        }
        // 用状态变量绑定sheet的显示
        .sheet(isPresented: $isPresentingStoreView) {
            StoreView(ids: [StrikeProducts.lifeTime]) {_ in
                VStack(spacing: 12) {
                    Text("Life Time")
                        .font(.headline)
                    Text("Life Time Access")
                        .foregroundColor(.secondary)
                    Image("lifetimeIcon")
                        .resizable()
                        .frame(width: 100, height: 100)
                        .cornerRadius(20)
                }
            }
            .productViewStyle(.large)
            .onInAppPurchaseStart { product in
                print("User has started buying \(product.id)")
            }
            .onInAppPurchaseCompletion { product, result in
                if case .success(.success(let transaction)) = result {
                    print("Purchased successfully: \(transaction.signedDate)")
                    // 必须结束交易,不然会重复触发回调
                    transaction.finish()
                    // 触发成功弹窗
                    showSuccessAlert = true
                } else {
                    print("Something else happened")
                }
            }
        }
        // 购买成功的确认弹窗,点击OK自动关sheet
        .alert("购买成功", isPresented: $showSuccessAlert) {
            Button("OK") {
                // 关闭sheet
                isPresentingStoreView = false
            }
        } message: {
            Text("你已成功解锁终身权限!")
        }
    }
}

额外提醒

  • 如果你是用sheet(item:)而不是isPresented来触发sheet的,逻辑一样,只要在OK按钮的闭包里把绑定的item设为nil就行
  • 测试的时候一定要用沙盒测试账号,不然内购流程可能走不通
  • 别忘了处理购买失败的情况,比如用户取消付款,这时候可以根据需要显示对应的提示,或者直接自动关闭sheet(看你想要的体验)

内容来源于stack exchange

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.08 14:40:31