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

iOS UI Tab栏标签页锁定实现咨询:内购解锁访问权限

UITabBar内购专属标签页锁定实现方案

一、标签页遮罩视图实现

给需要锁定的Tab对应的ViewController添加可复用的遮罩视图,未付费时显示遮罩并引导购买,付费后移除。

class LockOverlayView: UIView {
    override init(frame: CGRect) {
        super.init(frame: frame)
        setupLockUI()
    }
    
    required init?(coder: NSCoder) {
        super.init(coder: coder)
        setupLockUI()
    }
    
    private func setupLockUI() {
        backgroundColor = UIColor.black.withAlphaComponent(0.7)
        // 添加锁定图标
        let lockIcon = UIImageView(image: UIImage(systemName: "lock.fill"))
        lockIcon.tintColor = .white
        lockIcon.translatesAutoresizingMaskIntoConstraints = false
        addSubview(lockIcon)
        
        // 添加引导文字
        let tipLabel = UILabel()
        tipLabel.text = "解锁内购即可访问"
        tipLabel.textColor = .white
        tipLabel.textAlignment = .center
        tipLabel.translatesAutoresizingMaskIntoConstraints = false
        addSubview(tipLabel)
        
        // 布局约束
        NSLayoutConstraint.activate([
            lockIcon.centerXAnchor.constraint(equalTo: centerXAnchor),
            lockIcon.centerYAnchor.constraint(equalTo: centerYAnchor, constant: -20),
            tipLabel.topAnchor.constraint(equalTo: lockIcon.bottomAnchor, constant: 15),
            tipLabel.centerXAnchor.constraint(equalTo: centerXAnchor)
        ])
    }
}

// 在目标ViewController中集成遮罩
class PremiumTabVC: UIViewController {
    private let lockOverlay = LockOverlayView()
    
    override func viewDidLoad() {
        super.viewDidLoad()
        updateLockStatus()
    }
    
    override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(animated)
        // 二次校验,防止通过deeplink等绕过拦截
        updateLockStatus()
    }
    
    func updateLockStatus() {
        let isPaid = UserDefaults.standard.bool(forKey: "user paid")
        if isPaid {
            lockOverlay.removeFromSuperview()
        } else {
            lockOverlay.frame = view.bounds
            view.addSubview(lockOverlay)
            // 遮罩添加点击手势,触发购买流程
            let tap = UITapGestureRecognizer(target: self, action: #selector(showPurchaseFlow))
            lockOverlay.addGestureRecognizer(tap)
        }
    }
    
    @objc private func showPurchaseFlow() {
        // 这里跳转内购页面或弹出购买弹窗
        print("展示内购购买流程")
    }
}

二、TabBar点击拦截与状态校验

自定义UITabBarController,拦截锁定Tab的点击事件,未付费时阻止页面切换并引导购买。

class CustomTabBarController: UITabBarController, UITabBarControllerDelegate {
    private var lastSelectedIndex = 0
    
    override func viewDidLoad() {
        super.viewDidLoad()
        lastSelectedIndex = selectedIndex
        delegate = self
    }
    
    func tabBarController(_ tabBarController: UITabBarController, shouldSelect viewController: UIViewController) -> Bool {
        guard let tabIndex = viewControllers?.firstIndex(of: viewController) else { return true }
        
        // 假设索引2是需要锁定的Tab
        let isPremiumTab = tabIndex == 2
        let isPaid = UserDefaults.standard.bool(forKey: "user paid")
        
        if isPremiumTab && !isPaid {
            showPurchaseAlert()
            return false // 阻止切换到该页面
        }
        lastSelectedIndex = tabIndex
        return true
    }
    
    private func showPurchaseAlert() {
        let alert = UIAlertController(title: "需要解锁内购", message: "购买专属会员即可访问此功能", preferredStyle: .alert)
        alert.addAction(UIAlertAction(title: "去购买", style: .default) { _ in
            // 触发内购流程
        })
        alert.addAction(UIAlertAction(title: "取消", style: .cancel))
        present(alert, animated: true)
    }
}

三、付费成功后的状态同步

内购完成后更新本地标识,并通知相关页面刷新状态:

// 内购成功后执行
UserDefaults.standard.set(true, forKey: "user paid")
NotificationCenter.default.post(name: NSNotification.Name("PremiumPurchased"), object: nil)

// 在PremiumTabVC中监听通知
class PremiumTabVC: UIViewController {
    override func viewDidLoad() {
        super.viewDidLoad()
        NotificationCenter.default.addObserver(self, selector: #selector(updateLockStatus), name: NSNotification.Name("PremiumPurchased"), object: nil)
    }
    
    deinit {
        NotificationCenter.default.removeObserver(self)
    }
    
    // ...其他方法
}

注意事项

  • 不要仅依赖本地user paid标识,建议结合服务器校验,防止用户篡改本地数据;
  • 遮罩UI可根据App风格自定义,比如添加淡入淡出动画提升体验;
  • 内购流程需严格遵循App Store审核规范,避免违规引导。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.20 09:27:29