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

如何在横屏模式下触发iOS应用内购买?

问题描述

我正在开发一款始终处于横屏模式的iOS游戏,但在模拟器中测试应用内购买时,购买视图控制器(VC)会以竖屏模式弹出,导致用户需要旋转设备,而购买界面后方的视图仍处于横屏状态,体验不佳。请问是否有办法让应用内购买在横屏模式下触发?

当前设置横屏的AppDelegate代码:

var allowedOrientation: UIInterfaceOrientationMask = .landscape

public func application(_ application: UIApplication, supportedInterfaceOrientationsFor window: UIWindow?) -> UIInterfaceOrientationMask {
    return allowedOrientation
}

触发购买的代码:

func purchase(_ product: Product) {
    guard SKPaymentQueue.canMakePayments() else { return }

    self.productBeingPurchased = product
            
    guard !isTesting, let p = products.first(where: {
        $0.productIdentifier == product.id
    }) else { return }
    
    let payment = SKPayment(product: p)
    SKPaymentQueue.default().add(self)
    SKPaymentQueue.default().add(payment)
}
解决方案

要让系统内购界面以横屏模式展示,可以通过以下步骤实现:

  1. 确保Info.plist配置正确
    先确认App在Info.plist中声明了支持的横屏方向,添加或修改UISupportedInterfaceOrientations字段:

    <key>UISupportedInterfaceOrientations</key>
    <array>
        <string>UIInterfaceOrientationLandscapeLeft</string>
        <string>UIInterfaceOrientationLandscapeRight</string>
    </array>
    
  2. 添加购买状态标志位并修改方向控制逻辑
    在AppDelegate中新增标志位标记内购状态,修改方向控制方法:

    var allowedOrientation: UIInterfaceOrientationMask = .landscape
    // 新增:标记是否正在处理内购
    var isProcessingPurchase = false
    
    public func application(_ application: UIApplication, supportedInterfaceOrientationsFor window: UIWindow?) -> UIInterfaceOrientationMask {
        // 内购过程中强制仅允许横屏
        if isProcessingPurchase {
            return .landscape
        }
        return allowedOrientation
    }
    
  3. 触发购买时强制旋转并设置标志位
    修改购买触发方法,在发起支付前强制旋转设备到横屏并设置标志位:

    func purchase(_ product: Product) {
        guard SKPaymentQueue.canMakePayments() else { return }
    
        self.productBeingPurchased = product
                
        guard !isTesting, let p = products.first(where: {
            $0.productIdentifier == product.id
        }) else { return }
        
        // 设置内购处理标志位
        (UIApplication.shared.delegate as? AppDelegate)?.isProcessingPurchase = true
        // 强制旋转设备到横屏(可根据需求替换为LandscapeRight)
        UIDevice.current.setValue(UIInterfaceOrientation.landscapeLeft.rawValue, forKey: "orientation")
        
        let payment = SKPayment(product: p)
        SKPaymentQueue.default().add(self)
        SKPaymentQueue.default().add(payment)
    }
    
  4. 交易完成后重置状态
    在SKPaymentTransactionObserver的回调中,无论交易结果如何都重置标志位:

    func paymentQueue(_ queue: SKPaymentQueue, updatedTransactions transactions: [SKPaymentTransaction]) {
        for transaction in transactions {
            switch transaction.transactionState {
            case .purchased, .failed, .restored, .deferred:
                // 重置内购标志位
                (UIApplication.shared.delegate as? AppDelegate)?.isProcessingPurchase = false
                // 确保设备保持横屏(可选,根据App需求调整)
                UIDevice.current.setValue(UIInterfaceOrientation.landscapeLeft.rawValue, forKey: "orientation")
                // 结束交易
                SKPaymentQueue.default().finishTransaction(transaction)
            case .purchasing:
                break
            @unknown default:
                break
            }
        }
    }
    
  5. iOS 16+ 适配(若使用SceneDelegate)
    若App基于iOS 13+的Scene架构,需在SceneDelegate中添加对应逻辑:

    var isProcessingPurchase = false
    
    func windowScene(_ windowScene: UIWindowScene, supportedInterfaceOrientationsFor window: UIWindow?) -> UIInterfaceOrientationMask {
        if isProcessingPurchase {
            return .landscape
        }
        return .landscape
    }
    

    同时在购买和交易完成的代码中,同步修改SceneDelegate的标志位即可。


内容的提问来源于stack exchange,提问作者Mercutio

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.17 12:25:32