如何在横屏模式下触发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) }
解决方案
要让系统内购界面以横屏模式展示,可以通过以下步骤实现:
确保Info.plist配置正确
先确认App在Info.plist中声明了支持的横屏方向,添加或修改UISupportedInterfaceOrientations字段:<key>UISupportedInterfaceOrientations</key> <array> <string>UIInterfaceOrientationLandscapeLeft</string> <string>UIInterfaceOrientationLandscapeRight</string> </array>添加购买状态标志位并修改方向控制逻辑
在AppDelegate中新增标志位标记内购状态,修改方向控制方法:var allowedOrientation: UIInterfaceOrientationMask = .landscape // 新增:标记是否正在处理内购 var isProcessingPurchase = false public func application(_ application: UIApplication, supportedInterfaceOrientationsFor window: UIWindow?) -> UIInterfaceOrientationMask { // 内购过程中强制仅允许横屏 if isProcessingPurchase { return .landscape } 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 } // 设置内购处理标志位 (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) }交易完成后重置状态
在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 } } }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
相关产品推荐
相关产品推荐

