223 lines
7.3 KiB
Swift
223 lines
7.3 KiB
Swift
//
|
||
// LaunchPrivacyConsentView.swift
|
||
// QuickLocation
|
||
//
|
||
|
||
import UIKit
|
||
|
||
final class LaunchPrivacyConsentView: UIView, UITextViewDelegate {
|
||
|
||
var onAgree: (() -> Void)?
|
||
var onDisagree: (() -> Void)?
|
||
var onOpenURL: ((String) -> Void)?
|
||
|
||
override init(frame: CGRect) {
|
||
super.init(frame: frame)
|
||
setupUI()
|
||
configureBody()
|
||
}
|
||
|
||
required init?(coder: NSCoder) {
|
||
fatalError("init(coder:) has not been implemented")
|
||
}
|
||
|
||
func show(in host: UIView) {
|
||
frame = host.bounds
|
||
autoresizingMask = [.flexibleWidth, .flexibleHeight]
|
||
host.addSubview(self)
|
||
layoutIfNeeded()
|
||
dimView.alpha = 0
|
||
card.transform = CGAffineTransform(translationX: 0, y: bounds.height * 0.4)
|
||
UIView.animate(withDuration: 0.32, delay: 0, options: [.curveEaseOut]) {
|
||
self.dimView.alpha = 1
|
||
self.card.transform = .identity
|
||
}
|
||
}
|
||
|
||
private func setupUI() {
|
||
addSubview(dimView)
|
||
addSubview(card)
|
||
card.addSubview(gradientView)
|
||
card.addSubview(titleLab)
|
||
card.addSubview(bodyTextView)
|
||
card.addSubview(agreeBtn)
|
||
card.addSubview(disagreeBtn)
|
||
|
||
dimView.layoutChain.edges()
|
||
|
||
card.layoutChain
|
||
.edgesHorzontal()
|
||
.bottom()
|
||
|
||
gradientView.layoutChain
|
||
.top()
|
||
.edgesHorzontal()
|
||
.height(120)
|
||
|
||
titleLab.layoutChain
|
||
.top(28)
|
||
.edgesHorzontal(24)
|
||
.height(28)
|
||
|
||
bodyTextView.layoutChain
|
||
.topToBottomOfView(titleLab, offset: 16)
|
||
.edgesHorzontal(24)
|
||
|
||
agreeBtn.layoutChain
|
||
.topToBottomOfView(bodyTextView, offset: 22)
|
||
.edgesHorzontal(30)
|
||
.height(56)
|
||
|
||
disagreeBtn.layoutChain
|
||
.topToBottomOfView(agreeBtn, offset: 12)
|
||
.centerX()
|
||
.bottom(kSafeBottomMargin + 8)
|
||
.height(24)
|
||
|
||
agreeBtn.addTarget(self, action: #selector(handleAgree), for: .touchUpInside)
|
||
disagreeBtn.addTarget(self, action: #selector(handleDisagree), for: .touchUpInside)
|
||
}
|
||
|
||
private func configureBody() {
|
||
let full = """
|
||
请你知悉,为保障为您正常提供相应服务,当您在未登录/未注册状态下进行浏览和搜索时,需要开启以下权限:
|
||
1.个人信息类型:设备信息(包括设备型号、设备标识符)。
|
||
2.位置权限(始终允许),您同意开启设备定位服务后,我们会通过GPS或WiFi等方式持续收集您的地理位置信息,将用于为您记录位置信息和为您的好友发送位置信息。您可以通过关闭手机定位服务,停止我们对您的地理位置信息进行收集,同时我们将对您的好友停止更新您的位置。
|
||
想了解更多服务协议、隐私内容和使用第三方SDK详情,请阅读我们的《用户服务协议》和《隐私政策》。
|
||
"""
|
||
let paragraph = NSMutableParagraphStyle()
|
||
paragraph.lineSpacing = 5
|
||
paragraph.paragraphSpacing = 8
|
||
|
||
let attributed = NSMutableAttributedString(
|
||
string: full,
|
||
attributes: [
|
||
.font: UIFont.systemFont(ofSize: 14, weight: .regular),
|
||
.foregroundColor: UIColor(hexStr: "#333333"),
|
||
.paragraphStyle: paragraph
|
||
]
|
||
)
|
||
let agreementRange = (full as NSString).range(of: "《用户服务协议》")
|
||
let privacyRange = (full as NSString).range(of: "《隐私政策》")
|
||
if agreementRange.location != NSNotFound {
|
||
attributed.addAttributes([
|
||
.foregroundColor: UIColor(hexStr: "#16B3FF"),
|
||
.link: "UserAgreement"
|
||
], range: agreementRange)
|
||
}
|
||
if privacyRange.location != NSNotFound {
|
||
attributed.addAttributes([
|
||
.foregroundColor: UIColor(hexStr: "#16B3FF"),
|
||
.link: "PrivacyPolicy"
|
||
], range: privacyRange)
|
||
}
|
||
bodyTextView.attributedText = attributed
|
||
bodyTextView.linkTextAttributes = [
|
||
.foregroundColor: UIColor(hexStr: "#16B3FF"),
|
||
.underlineStyle: NSUnderlineStyle.single.rawValue
|
||
]
|
||
bodyTextView.delegate = self
|
||
}
|
||
|
||
func textView(
|
||
_ textView: UITextView,
|
||
shouldInteractWith URL: URL,
|
||
in characterRange: NSRange,
|
||
interaction: UITextItemInteraction
|
||
) -> Bool {
|
||
switch URL.absoluteString {
|
||
case "UserAgreement":
|
||
onOpenURL?(URLManager.shared.userAgreementUrl)
|
||
case "PrivacyPolicy":
|
||
onOpenURL?(URLManager.shared.privacyPolicyUrl)
|
||
default:
|
||
break
|
||
}
|
||
return false
|
||
}
|
||
|
||
func textViewShouldBeginEditing(_ textView: UITextView) -> Bool { false }
|
||
|
||
@objc private func handleAgree() {
|
||
onAgree?()
|
||
}
|
||
|
||
@objc private func handleDisagree() {
|
||
onDisagree?()
|
||
}
|
||
|
||
private lazy var dimView: UIView = {
|
||
let view = UIView()
|
||
view.backgroundColor = UIColor.black.withAlphaComponent(0.45)
|
||
return view
|
||
}()
|
||
|
||
private lazy var card: UIView = {
|
||
let view = UIView()
|
||
view.backgroundColor = .white
|
||
view.layer.cornerRadius = 28
|
||
view.layer.maskedCorners = [.layerMinXMinYCorner, .layerMaxXMinYCorner]
|
||
view.clipsToBounds = true
|
||
return view
|
||
}()
|
||
|
||
private lazy var gradientView: LaunchPrivacyGradientView = {
|
||
let view = LaunchPrivacyGradientView()
|
||
view.isUserInteractionEnabled = false
|
||
return view
|
||
}()
|
||
|
||
private lazy var titleLab: UILabel = {
|
||
let label = UILabel()
|
||
label.text = "服务协议及隐私政策"
|
||
label.font = .systemFont(ofSize: 20, weight: .semibold)
|
||
label.textColor = UIColor(hexStr: "#1A1A1A")
|
||
label.textAlignment = .center
|
||
return label
|
||
}()
|
||
|
||
private lazy var bodyTextView: UITextView = {
|
||
let textView = UITextView()
|
||
textView.backgroundColor = .clear
|
||
textView.isEditable = false
|
||
textView.isScrollEnabled = false
|
||
textView.isSelectable = true
|
||
textView.textContainerInset = .zero
|
||
textView.textContainer.lineFragmentPadding = 0
|
||
return textView
|
||
}()
|
||
|
||
private lazy var agreeBtn: UIButton = {
|
||
let btn = UIButton(type: .custom)
|
||
btn.cornerRadius = 20
|
||
btn.setTitle("同意并进入", for: .normal)
|
||
btn.setTitleColor(.white, for: .normal)
|
||
btn.titleLabel?.font = FontManager.boboBold(18)
|
||
btn.setBackgroundImage(UIImage(named: "Common/button_bg_2"), for: .normal)
|
||
return btn
|
||
}()
|
||
|
||
private lazy var disagreeBtn: UIButton = {
|
||
let btn = UIButton(type: .system)
|
||
btn.setTitle("不同意", for: .normal)
|
||
btn.setTitleColor(UIColor(hexStr: "#16B3FF"), for: .normal)
|
||
btn.titleLabel?.font = .systemFont(ofSize: 15, weight: .regular)
|
||
return btn
|
||
}()
|
||
}
|
||
|
||
private final class LaunchPrivacyGradientView: UIView {
|
||
override class var layerClass: AnyClass { CAGradientLayer.self }
|
||
|
||
override func layoutSubviews() {
|
||
super.layoutSubviews()
|
||
guard let layer = layer as? CAGradientLayer else { return }
|
||
layer.colors = [
|
||
UIColor(hexStr: "#D9F8F0").cgColor,
|
||
UIColor.white.cgColor
|
||
]
|
||
layer.startPoint = CGPoint(x: 0.5, y: 0)
|
||
layer.endPoint = CGPoint(x: 0.5, y: 1)
|
||
}
|
||
}
|