IOS 12 自定义用户协议对话框

实现效果

实现逻辑

本文使用QMUI里面提供的控制器 + 自定义控件 实现。

添加依赖

复制代码
#腾讯开源的UI框架,提供了很多功能,例如:圆角按钮,空心按钮,TextView支持placeholder
#https://github.com/QMUI/QMUIDemo_iOS
#https://qmuiteam.com/ios/get-started
pod "QMUIKit"

还不了解如何使用 CocoaPods 管理依赖的,建议先看前面的文章:IOS 01 CocoaPods 安装与使用

添加完依赖后,看一下Pods文件夹里面是否添加成功。

对话框TermServiceDialogController

添加对话框布局控件

Swift 复制代码
override func initViews() {
        super.initViews()
        view.layer.cornerRadius = MEDDLE_RADIUS
        //让圆角生效
        view.clipsToBounds = true
        view.backgroundColor = .colorDivider
        view.tg_width.equal(.fill)
        view.tg_height.equal(.wrap)
        
        //内容容器
        contentContainer = TGLinearLayout(.vert)
        contentContainer.tg_width.equal(.fill)
        contentContainer.tg_height.equal(.wrap)
        contentContainer.tg_space = 25
        contentContainer.tg_padding = UIEdgeInsets(top: PADDING_OUTER, left: PADDING_OUTER, bottom: PADDING_OUTER, right: PADDING_OUTER)
        contentContainer.backgroundColor = .colorBackground
        contentContainer.tg_gravity = TGGravity.horz.center
        view.addSubview(contentContainer)
        
        //标题
        contentContainer.addSubview(titleView)
        
        //内容
        textView = UITextView()
        textView.tg_width.equal(.fill)
        //超出的内容,自动支持滚动
        textView.tg_height.equal(230)
        textView.text = "公司CFO David Wehner也在财报中给出了眼下正在面临的一系列增长压力。Wehner透露,目前各个内容平台对消费者使用时间的竞争正在加剧。即便是在公司内部的产品线中,消费者的粘性也呈现向Reels这样的视频界面转移的倾向,但该功能的货币转化率要低于信息流等传统文字业务。此外,META也预期苹果的iOS系统规则变更和监管带来的变化将继续对定向广告业务带来负面影响,同时实体经济中的通胀和供应链问题也会影响广告主的预算。此外在美联储加息周期中,外汇(美元对其他货币升值)也将成为公司营收增长的负面因素。作为Facebook的母公司,Meta Platforms Inc.第四季度用户增长陷入停滞,并且本季度展望令人失望,引发了对于该公司未来增长前景的担忧,该公司最终可能难以证明对元宇宙(首席执行官扎克伯格的沉浸式互联网愿景)的昂贵押注是合理的公司CFO David Wehner也在财报中给出了眼下正在面临的一系列增长压力。Wehner透露,目前各个内容平台对消费者使用时间的竞争正在加剧。即便是在公司内部的产品线中,消费者的粘性也呈现向Reels这样的视频界面转移的倾向,但该功能的货币转化率要低于信息流等传统文字业务。此外,META也预期苹果的iOS系统规则变更和监管带来的变化将继续对定向广告业务带来负面影响,同时实体经济中的通胀和供应链问题也会影响广告主的预算。此外在美联储加息周期中,外汇(美元对其他货币升值)也将成为公司营收增长的负面因素。作为Facebook的母公司,Meta Platforms Inc.第四季度用户增长陷入停滞,并且本季度展望令人失望,引发了对于该公司未来增长前景的担忧,该公司最终可能难以证明对元宇宙(首席执行官扎克伯格的沉浸式互联网愿景)的昂贵押注是合理的"
        textView.backgroundColor = .clear
        //禁用编辑
        textView.isEditable = false
        contentContainer.addSubview(textView)
        
        contentContainer.addSubview(primaryButton)
        
        //不同意按钮按钮
        disagreeButton = ViewFactoryUtil.linkButton()
        disagreeButton.setTitle(R.string.localizable.disagree(), for: .normal)
        disagreeButton.setTitleColor(.black80, for: .normal)
        disagreeButton.addTarget(self, action: #selector(disagreeClick(_:)), for: .touchUpInside)
        disagreeButton.sizeToFit()
        contentContainer.addSubview(disagreeButton)
    }

添加自定义布局控件到QMUIModalPresentationViewController,并显示

Swift 复制代码
func show() {
        modalController = QMUIModalPresentationViewController()
        modalController.animationStyle = .fade
        
        //边距
        modalController.contentViewMargins = UIEdgeInsets(top: PADDING_LARGE2, left: PADDING_LARGE2, bottom: PADDING_LARGE2, right: PADDING_LARGE2)
        
        //点击外部不隐藏
        modalController.isModal = true
        
        //设置要显示的内容控件
        modalController.contentViewController = self
        
        modalController.showWith(animated: true)
    }

完整代码

Swift 复制代码
//
//  TermServiceDialogController.swift
//  MyCloudMusic
//
//  Created by jin on 2024/8/19.
//

import UIKit

//提供类似Android中更高层级布局框架
import TangramKit

class TermServiceDialogController: BaseController, QMUIModalPresentationContentViewControllerProtocol {
    
    var contentContainer:TGBaseLayout!
    
    var modalController:QMUIModalPresentationViewController!
    
    var textView:UITextView!
    
    var disagreeButton:QMUIButton!

    override func initViews() {
        super.initViews()
        view.layer.cornerRadius = MEDDLE_RADIUS
        //让圆角生效
        view.clipsToBounds = true
        view.backgroundColor = .colorDivider
        view.tg_width.equal(.fill)
        view.tg_height.equal(.wrap)
        
        //内容容器
        contentContainer = TGLinearLayout(.vert)
        contentContainer.tg_width.equal(.fill)
        contentContainer.tg_height.equal(.wrap)
        contentContainer.tg_space = 25
        contentContainer.tg_padding = UIEdgeInsets(top: PADDING_OUTER, left: PADDING_OUTER, bottom: PADDING_OUTER, right: PADDING_OUTER)
        contentContainer.backgroundColor = .colorBackground
        contentContainer.tg_gravity = TGGravity.horz.center
        view.addSubview(contentContainer)
        
        //标题
        contentContainer.addSubview(titleView)
        
        //内容
        textView = UITextView()
        textView.tg_width.equal(.fill)
        //超出的内容,自动支持滚动
        textView.tg_height.equal(230)
        textView.text = "公司CFO David Wehner也在财报中给出了眼下正在面临的一系列增长压力。Wehner透露,目前各个内容平台对消费者使用时间的竞争正在加剧。即便是在公司内部的产品线中,消费者的粘性也呈现向Reels这样的视频界面转移的倾向,但该功能的货币转化率要低于信息流等传统文字业务。此外,META也预期苹果的iOS系统规则变更和监管带来的变化将继续对定向广告业务带来负面影响,同时实体经济中的通胀和供应链问题也会影响广告主的预算。此外在美联储加息周期中,外汇(美元对其他货币升值)也将成为公司营收增长的负面因素。作为Facebook的母公司,Meta Platforms Inc.第四季度用户增长陷入停滞,并且本季度展望令人失望,引发了对于该公司未来增长前景的担忧,该公司最终可能难以证明对元宇宙(首席执行官扎克伯格的沉浸式互联网愿景)的昂贵押注是合理的公司CFO David Wehner也在财报中给出了眼下正在面临的一系列增长压力。Wehner透露,目前各个内容平台对消费者使用时间的竞争正在加剧。即便是在公司内部的产品线中,消费者的粘性也呈现向Reels这样的视频界面转移的倾向,但该功能的货币转化率要低于信息流等传统文字业务。此外,META也预期苹果的iOS系统规则变更和监管带来的变化将继续对定向广告业务带来负面影响,同时实体经济中的通胀和供应链问题也会影响广告主的预算。此外在美联储加息周期中,外汇(美元对其他货币升值)也将成为公司营收增长的负面因素。作为Facebook的母公司,Meta Platforms Inc.第四季度用户增长陷入停滞,并且本季度展望令人失望,引发了对于该公司未来增长前景的担忧,该公司最终可能难以证明对元宇宙(首席执行官扎克伯格的沉浸式互联网愿景)的昂贵押注是合理的"
        textView.backgroundColor = .clear
        //禁用编辑
        textView.isEditable = false
        contentContainer.addSubview(textView)
        
        contentContainer.addSubview(primaryButton)
        
        //不同意按钮按钮
        disagreeButton = ViewFactoryUtil.linkButton()
        disagreeButton.setTitle(R.string.localizable.disagree(), for: .normal)
        disagreeButton.setTitleColor(.black80, for: .normal)
        disagreeButton.addTarget(self, action: #selector(disagreeClick(_:)), for: .touchUpInside)
        disagreeButton.sizeToFit()
        contentContainer.addSubview(disagreeButton)
    }
    
    @objc func disagreeClick(_ btn :QMUIButton) {
        hide()
        
        //退出应用
        exit(0)
    }

    func show() {
        modalController = QMUIModalPresentationViewController()
        modalController.animationStyle = .fade
        
        //边距
        modalController.contentViewMargins = UIEdgeInsets(top: PADDING_LARGE2, left: PADDING_LARGE2, bottom: PADDING_LARGE2, right: PADDING_LARGE2)
        
        //点击外部不隐藏
        modalController.isModal = true
        
        //设置要显示的内容控件
        modalController.contentViewController = self
        
        modalController.showWith(animated: true)
    }
    
    func hide() {
        modalController.hideWith(animated: true, completion: nil)
    }

    lazy var titleView: UILabel = {
        let r = UILabel()
        r.tg_width.equal(.fill)
        r.tg_height.equal(.wrap)
        r.text = "title"
        r.textColor = .colorOnSurface
        r.font = UIFont.boldSystemFont(ofSize: TEXT_LARGE2)
        r.textAlignment = .center
        return r
    }()
    
    lazy var primaryButton: QMUIButton = {
        let r = ViewFactoryUtil.primaryHalfFilletButton()
        r.setTitle(R.string.localizable.agree(), for: .normal)
        return r
    }()
}

自定义Button

Swift 复制代码
//
//  ViewFactoryUtil.swift
//  MyCloudMusic
//
//  Created by jin on 2024/8/19.
//

import UIKit
import TangramKit

class ViewFactoryUtil{
    
    /// 主色调,小圆角按钮
    /// - Returns: <#description#>
    static func primaryButton() -> QMUIButton {
        let r = QMUIButton()
        r.adjustsTitleTintColorAutomatically = false
        r.adjustsButtonWhenHighlighted = true
        r.titleLabel?.font = .systemFont(ofSize: TEXT_LARGE)
        r.tg_width.equal(.fill)
        r.tg_height.equal(BUTTON_MEDDLE)
        r.backgroundColor = .colorPrimary
        r.layer.cornerRadius = SMALL_RADIUS
        r.tintColor = .colorLightWhite
        r.setTitleColor(.colorLightWhite, for: .normal)
        return r
    }
    
    /// 主色调,半圆角按钮
    /// - Returns: <#description#>
    static func primaryHalfFilletButton() -> QMUIButton {
        let r = primaryButton()
        r.layer.cornerRadius = BUTTON_MEDDLE_RADIUS
        return r
    }
    
    /// 创建只有标题按钮(类似网页连接)
    static func linkButton() -> QMUIButton {
        let r = QMUIButton()
        r.adjustsTitleTintColorAutomatically = false
        r.titleLabel?.font = UIFont.systemFont(ofSize: TEXT_MEDDLE)
        return r
    }
}

使用

Swift 复制代码
//
//  SplashController.swift
//  MyCloudMusic
//
//  Created by jin on 2024/8/18.
//

import UIKit

import TangramKit

class SplashController: BaseLogicController {

    override func viewDidLoad() {
        super.viewDidLoad()
        
    }
    
    override func initDatum() {
        super.initDatum()
        showTermsServiceAgreementDialog()
    }

    /// 显示服务条款对话框
    func showTermsServiceAgreementDialog() {
        dialogController.show()
    }
    
    @objc func primaryClick(){
        dialogController.hide()
        
        AppDelegate.shared.toGuide()
    }
    
    lazy var dialogController: TermServiceDialogController = {
        let r = TermServiceDialogController()
        r.titleView.text = R.string.localizable.termServicePrivacy()
        r.primaryButton.addTarget(self, action: #selector(primaryClick), for: .touchUpInside)
        return r
    }()
}
相关推荐
黑化旺仔13 小时前
【OC】Runtime:类元数据、加载初始化与消息派发
开发语言·macos·ios·objective-c
songgeb13 小时前
iOS App支持设置RTL语言的实践
ios·swift·ui kit
软泡芙14 小时前
【iOS】swift启动屏显示黑屏
ios
用户693717500138415 小时前
当你向领导申请 AI 编程工具预算时,如果领导追问“能提效多少,有量化数据吗”,你该怎么回答?
android·后端·ios
Layer15 小时前
一些脱离 Mac 依赖的 Agent 操作 iPhone 实现
ios·ai编程·测试
用户693717500138417 小时前
当我说 Claude 搭配 GLM-5.3-Flash 太好用了,同事却提醒我:你可能正在失去对代码的掌控
android·后端·ios
茶底世界之下18 小时前
一键裁方会丢掉什么?用 Awaking 给园林照片做两种画幅
ios
Marco_Marco13519 小时前
定位SDK接入实战:Android/iOS/鸿蒙三端怎么选、怎么接
android·ios·harmonyos
老李IT笔记1 天前
关掉设备上的 AI 扩展:两个键各管一层,配错了等于没配
人工智能·ios·智能手机
2501_915921431 天前
iOS应用耗电测试:使用Energy Log、Keymob和Instruments进行性能监控与能源消耗分析
android·ios·小程序·https·uni-app·iphone·webview