jsdw_ios/QuickLocation/Section/Launch/LaunchPrivacyConsentView.swift

223 lines
7.3 KiB
Swift
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

//
// 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)
}
}