1419 lines
48 KiB
Swift
1419 lines
48 KiB
Swift
//
|
|
// PopupWindow.swift
|
|
// QuickLocation
|
|
//
|
|
// Created by 八条 on 2026/7/2.
|
|
//
|
|
|
|
import UIKit
|
|
import RxSwift
|
|
import RxCocoa
|
|
import Lottie
|
|
|
|
enum PopupType {
|
|
/// 搜索位置
|
|
case search
|
|
/// 注册
|
|
case register
|
|
/// 会员
|
|
case vip
|
|
}
|
|
|
|
class PopupWindow: UIView {
|
|
|
|
private static let shared = PopupWindow(frame: CGRect(origin: .zero, size: kScreenSize))
|
|
|
|
var disposeBag = DisposeBag()
|
|
|
|
private var popupType: PopupType? {
|
|
didSet {
|
|
switch popupType {
|
|
case .search:
|
|
searchPopupView.isHidden = false
|
|
earthLottieView.play()
|
|
case .register:
|
|
if Bool.random() {
|
|
registerPopupView.isHidden = true
|
|
register2PopupView.isHidden = false
|
|
slideInRegister2Popup()
|
|
} else {
|
|
register2PopupView.isHidden = true
|
|
registerPopupView.isHidden = false
|
|
slideInRegisterPopup()
|
|
}
|
|
case .vip:
|
|
let roll = Int.random(in: 0...3)
|
|
switch roll {
|
|
case 0:
|
|
unlockVip2View.isHidden = true
|
|
unlockVip3View.isHidden = true
|
|
unlockVip4View.isHidden = true
|
|
unlockVip1View.isHidden = false
|
|
slideInUnlockVip1Popup()
|
|
case 1:
|
|
unlockVip1View.isHidden = true
|
|
unlockVip3View.isHidden = true
|
|
unlockVip4View.isHidden = true
|
|
unlockVip2View.isHidden = false
|
|
slideInUnlockVip2Popup()
|
|
case 2:
|
|
unlockVip1View.isHidden = true
|
|
unlockVip2View.isHidden = true
|
|
unlockVip4View.isHidden = true
|
|
unlockVip3View.isHidden = false
|
|
slideInUnlockVip3Popup()
|
|
default:
|
|
unlockVip1View.isHidden = true
|
|
unlockVip2View.isHidden = true
|
|
unlockVip3View.isHidden = true
|
|
unlockVip4View.isHidden = false
|
|
slideInUnlockVip4Popup()
|
|
}
|
|
default:
|
|
break
|
|
}
|
|
}
|
|
}
|
|
|
|
private static var dismissCompletion: (() -> Void)?
|
|
|
|
static func show(popupType: PopupType, dismissCompletion: (() -> Void)? = nil) {
|
|
Self.dismissCompletion = dismissCompletion
|
|
guard let superView = kKeyWindow else {
|
|
return
|
|
}
|
|
|
|
if PopupWindow.shared.superview != nil {
|
|
PopupWindow.shared.removeFromSuperview()
|
|
PopupWindow.shared.bgView.frame = .zero
|
|
}
|
|
|
|
PopupWindow.shared.resetPopupState()
|
|
|
|
PopupWindow.shared.popupType = popupType
|
|
PopupWindow.shared.bgView.alpha = 1
|
|
PopupWindow.shared.bgView.frame = CGRect(x: 0, y: 0, width: kScreenWidth, height: kScreenHeight)
|
|
superView.addSubview(PopupWindow.shared)
|
|
superView.bringSubviewToFront(PopupWindow.shared)
|
|
|
|
UIView.animate(withDuration: 0.25) {
|
|
PopupWindow.shared.bgView.alpha = 1
|
|
}
|
|
}
|
|
|
|
private func resetPopupState() {
|
|
stopRegisterStarFlash()
|
|
stopRegister1LottieAlternate()
|
|
stopUnlockVip1Animations()
|
|
stopUnlockVip2Animations()
|
|
stopUnlockVip3Animations()
|
|
stopUnlockVip4Animations()
|
|
registerPopupView.transform = .identity
|
|
register2PopupView.transform = .identity
|
|
unlockVip1View.transform = .identity
|
|
unlockVip2View.transform = .identity
|
|
unlockVip3View.transform = .identity
|
|
unlockVip4View.transform = .identity
|
|
registerStar1.transform = .identity
|
|
// register2Star1.transform = .identity
|
|
|
|
searchPopupView.isHidden = true
|
|
registerPopupView.isHidden = true
|
|
register2PopupView.isHidden = true
|
|
unlockVip1View.isHidden = true
|
|
unlockVip2View.isHidden = true
|
|
unlockVip3View.isHidden = true
|
|
unlockVip4View.isHidden = true
|
|
bgView.isUserInteractionEnabled = true
|
|
}
|
|
|
|
/// 关闭
|
|
static func dismiss() {
|
|
guard PopupWindow.shared.superview != nil else { return }
|
|
|
|
UIView.animate(withDuration: 0.25, delay: 0, options: [.curveEaseIn]) {
|
|
PopupWindow.shared.bgView.alpha = 0
|
|
} completion: { _ in
|
|
PopupWindow.shared.resetPopupState()
|
|
PopupWindow.shared.removeFromSuperview()
|
|
let completion = Self.dismissCompletion
|
|
Self.dismissCompletion = nil
|
|
completion?()
|
|
}
|
|
}
|
|
|
|
private func setupRx() {
|
|
registerCloseBtn.rx.tap
|
|
.subscribe(onNext: { [weak self] _ in
|
|
self?.activePopupView == 2 ? self?.slideOutRegister2Popup() : self?.slideOutRegisterPopup()
|
|
})
|
|
.disposed(by: disposeBag)
|
|
|
|
registerBtn.rx.tap
|
|
.subscribe(onNext: { [weak self] _ in
|
|
NotificationCenter.default.post(name: .pausePopupQueue, object: nil)
|
|
self?.activePopupView == 2 ? self?.slideOutRegister2Popup() : self?.slideOutRegisterPopup()
|
|
let topVC = UIViewController.currentViewController()
|
|
if !(topVC is LoginViewController) {
|
|
AppRouter.push(Route.login)
|
|
}
|
|
})
|
|
.disposed(by: disposeBag)
|
|
|
|
register2CloseBtn.rx.tap
|
|
.subscribe(onNext: { [weak self] _ in
|
|
self?.slideOutRegister2Popup()
|
|
})
|
|
.disposed(by: disposeBag)
|
|
|
|
register2Btn.rx.tap
|
|
.subscribe(onNext: { [weak self] _ in
|
|
NotificationCenter.default.post(name: .pausePopupQueue, object: nil)
|
|
self?.slideOutRegister2Popup()
|
|
let topVC = UIViewController.currentViewController()
|
|
if !(topVC is LoginViewController) {
|
|
AppRouter.push(Route.login)
|
|
}
|
|
})
|
|
.disposed(by: disposeBag)
|
|
|
|
vip1CloseBtn.rx.tap
|
|
.subscribe(onNext: { [weak self] _ in
|
|
self?.slideOutUnlockVip1Popup()
|
|
})
|
|
.disposed(by: disposeBag)
|
|
|
|
vip1UnlockBtn.rx.tap
|
|
.subscribe(onNext: { [weak self] _ in
|
|
self?.slideOutUnlockVip1Popup()
|
|
let topVC = UIViewController.currentViewController()
|
|
if !(topVC is VipRechargeVC) {
|
|
AppRouter.push(Route.vipRecharge)
|
|
}
|
|
})
|
|
.disposed(by: disposeBag)
|
|
|
|
unlockVip2CloseBtn.rx.tap
|
|
.subscribe(onNext: { [weak self] _ in
|
|
self?.slideOutUnlockVip2Popup()
|
|
})
|
|
.disposed(by: disposeBag)
|
|
|
|
unlockVip2Btn.rx.tap
|
|
.subscribe(onNext: { [weak self] _ in
|
|
self?.slideOutUnlockVip2Popup()
|
|
let topVC = UIViewController.currentViewController()
|
|
if !(topVC is VipRechargeVC) {
|
|
AppRouter.push(Route.vipRecharge)
|
|
}
|
|
})
|
|
.disposed(by: disposeBag)
|
|
|
|
unlockVip3CloseBtn.rx.tap
|
|
.subscribe(onNext: { [weak self] _ in
|
|
self?.slideOutUnlockVip3Popup()
|
|
})
|
|
.disposed(by: disposeBag)
|
|
|
|
unlockVip3Btn.rx.tap
|
|
.subscribe(onNext: { [weak self] _ in
|
|
self?.slideOutUnlockVip3Popup()
|
|
let topVC = UIViewController.currentViewController()
|
|
if !(topVC is VipRechargeVC) {
|
|
AppRouter.push(Route.vipRecharge)
|
|
}
|
|
})
|
|
.disposed(by: disposeBag)
|
|
|
|
unlockVip4CloseBtn.rx.tap
|
|
.subscribe(onNext: { [weak self] _ in
|
|
self?.slideOutUnlockVip4Popup()
|
|
})
|
|
.disposed(by: disposeBag)
|
|
|
|
unlockVip4Btn.rx.tap
|
|
.subscribe(onNext: { [weak self] _ in
|
|
self?.slideOutUnlockVip4Popup()
|
|
let topVC = UIViewController.currentViewController()
|
|
if !(topVC is VipRechargeVC) {
|
|
AppRouter.push(Route.vipRecharge)
|
|
}
|
|
})
|
|
.disposed(by: disposeBag)
|
|
}
|
|
|
|
private lazy var bgView: UIView = {
|
|
let view = UIView()
|
|
view.backgroundColor = .black.withAlphaComponent(0.5)
|
|
return view
|
|
}()
|
|
|
|
// MARK: - 实时查位置
|
|
lazy var searchPopupView: UIView = {
|
|
let view = UIView()
|
|
view.backgroundColor = .clear
|
|
view.isHidden = true
|
|
|
|
let bgImgView = UIImageView(image: UIImage(named: "PopupWindow/search_bg"))
|
|
bgImgView.contentMode = .scaleAspectFill
|
|
bgImgView.rx.tapGesture.subscribe(onNext: { _ in
|
|
PopupWindow.dismiss()
|
|
AppRouter.push(Route.searchLocation)
|
|
}).disposed(by: disposeBag)
|
|
view.addSubview(bgImgView)
|
|
bgImgView.layoutChain
|
|
.edges(excludingEdge: .bottom)
|
|
.heightToWidth(828/770)
|
|
|
|
let btn = UIButton(type: .custom)
|
|
btn.backgroundColor = .clear
|
|
btn.setBackgroundImage(UIImage(named: "Group/close"), for: .normal)
|
|
btn.extendEdgeInsets = UIEdgeInsets(top: 10, left: 100, bottom: 100, right: 100)
|
|
btn.rx.tap.subscribe(onNext: { _ in
|
|
PopupWindow.dismiss()
|
|
}).disposed(by: disposeBag)
|
|
view.addSubview(btn)
|
|
btn.layoutChain
|
|
.topToBottomOfView(bgImgView, offset: 0)
|
|
.centerX()
|
|
.width(22)
|
|
.height(22)
|
|
.bottom()
|
|
|
|
// let peopleIcon = UIImageView(image: UIImage(named: "PopupWindow/search_people"))
|
|
// peopleIcon.contentMode = .scaleAspectFill
|
|
// view.addSubview(peopleIcon)
|
|
// peopleIcon.layoutChain
|
|
// .top(20)
|
|
// .width(73)
|
|
// .height(95)
|
|
// .rightToCenterXOfView(view)
|
|
|
|
// let eartIcon = UIImageView(image: UIImage(named: "PopupWindow/search_earth"))
|
|
// eartIcon.contentMode = .scaleAspectFill
|
|
// view.addSubview(eartIcon)
|
|
// eartIcon.layoutChain
|
|
// .topToView(peopleIcon, offset: 12)
|
|
// .width(88)
|
|
// .height(81)
|
|
// .leftToCenterXOfView(view)
|
|
|
|
view.addSubview(earthLottieView)
|
|
earthLottieView.layoutChain
|
|
.top()
|
|
.edgesHorzontal(50)
|
|
.heightToWidth(95/155)
|
|
|
|
return view
|
|
}()
|
|
|
|
lazy var earthLottieView: LottieAnimationView = {
|
|
let view = LottieAnimationView(name: "dialog_phone_search")
|
|
view.loopMode = .loop
|
|
return view
|
|
}()
|
|
|
|
// MARK: - 解锁会员 1
|
|
lazy var unlockVip1View: UIView = {
|
|
let view = UIView()
|
|
view.backgroundColor = .clear
|
|
view.isHidden = true
|
|
|
|
let bgImg = UIImageView(image: UIImage(named: "PopupWindow/vip_bg"))
|
|
bgImg.contentMode = .scaleAspectFill
|
|
view.addSubview(bgImg)
|
|
bgImg.layoutChain
|
|
.top(45)
|
|
.edgesHorzontal()
|
|
.bottom()
|
|
|
|
view.addSubview(vip1HeartIcon)
|
|
vip1HeartIcon.layoutChain
|
|
.top()
|
|
.left(21)
|
|
.width(116)
|
|
.height(99)
|
|
|
|
let logoImg = UIImageView(image: UIImage(named: "PopupWindow/vip1_logo"))
|
|
logoImg.contentMode = .scaleAspectFill
|
|
view.addSubview(logoImg)
|
|
logoImg.layoutChain
|
|
.topToView(bgImg, offset: 40)
|
|
.centerX()
|
|
.width(125)
|
|
.height(42)
|
|
|
|
view.addSubview(vip1Tips2Img)
|
|
vip1Tips2Img.layoutChain
|
|
.topToBottomOfView(logoImg, offset: 30)
|
|
.centerX()
|
|
.width(71)
|
|
.height(26)
|
|
|
|
view.addSubview(vip1Tips1Img)
|
|
vip1Tips1Img.layoutChain
|
|
.rightToLeftOfView(vip1Tips2Img, offset: -24)
|
|
.centerY(vip1Tips2Img)
|
|
.width(71)
|
|
.height(26)
|
|
|
|
view.addSubview(vip1Tips3Img)
|
|
vip1Tips3Img.layoutChain
|
|
.leftToRightOfView(vip1Tips2Img, offset: 24)
|
|
.centerY(vip1Tips2Img)
|
|
.width(71)
|
|
.height(26)
|
|
|
|
let textLab = UILabel()
|
|
textLab.text = "看看TA真实走过哪里"
|
|
textLab.font = .systemFont(ofSize: 14, weight: .medium)
|
|
textLab.textColor = UIColor(hexStr: "#16B3FF")
|
|
view.addSubview(textLab)
|
|
textLab.layoutChain
|
|
.topToBottomOfView(vip1Tips2Img, offset: 20)
|
|
.centerX()
|
|
|
|
view.addSubview(vip1CloseBtn)
|
|
vip1CloseBtn.layoutChain
|
|
.topToView(bgImg, offset: 16)
|
|
.right(17)
|
|
|
|
view.addSubview(vip1UnlockBtn)
|
|
vip1UnlockBtn.layoutChain
|
|
.width(224)
|
|
.height(50)
|
|
.centerX()
|
|
.bottom(kSafeBottomMargin + 15)
|
|
|
|
return view
|
|
}()
|
|
|
|
lazy var vip1HeartIcon: UIImageView = {
|
|
let view = UIImageView()
|
|
view.image = UIImage(named: "PopupWindow/vip1_heart")
|
|
view.contentMode = .scaleAspectFill
|
|
return view
|
|
}()
|
|
|
|
lazy var vip1Tips1Img: UIImageView = {
|
|
let view = UIImageView()
|
|
view.image = UIImage(named: "PopupWindow/vip1_tips_1")
|
|
view.contentMode = .scaleAspectFill
|
|
return view
|
|
}()
|
|
|
|
lazy var vip1Tips2Img: UIImageView = {
|
|
let view = UIImageView()
|
|
view.image = UIImage(named: "PopupWindow/vip1_tips_2")
|
|
view.contentMode = .scaleAspectFill
|
|
return view
|
|
}()
|
|
|
|
lazy var vip1Tips3Img: UIImageView = {
|
|
let view = UIImageView()
|
|
view.image = UIImage(named: "PopupWindow/vip1_tips_3")
|
|
view.contentMode = .scaleAspectFill
|
|
return view
|
|
}()
|
|
|
|
lazy var vip1CloseBtn: UIButton = {
|
|
let btn = UIButton(type: .custom)
|
|
btn.setImage(UIImage(named: "PopupWindow/close"), for: .normal)
|
|
btn.extendEdgeInsets = UIEdgeInsets(top: 30, left: 30, bottom: 30, right: 17)
|
|
return btn
|
|
}()
|
|
|
|
lazy var vip1UnlockBtn: UIButton = {
|
|
let btn = UIButton(type: .custom)
|
|
btn.setTitle("立即解锁", for: .normal)
|
|
btn.setTitleColor(.white, for: .normal)
|
|
btn.titleLabel?.font = .systemFont(ofSize: 16, weight: .medium)
|
|
btn.setBackgroundImage(UIImage(named: "Common/button_bg_2"), for: .normal)
|
|
btn.cornerRadius = 25
|
|
return btn
|
|
}()
|
|
|
|
private func startUnlockVip1Animations() {
|
|
stopUnlockVip1Animations()
|
|
|
|
let heartAnimation = CABasicAnimation(keyPath: "transform.scale")
|
|
heartAnimation.fromValue = 1.0
|
|
heartAnimation.toValue = 1.2
|
|
heartAnimation.duration = 0.55
|
|
heartAnimation.autoreverses = true
|
|
heartAnimation.repeatCount = .infinity
|
|
heartAnimation.timingFunction = CAMediaTimingFunction(name: .easeInEaseOut)
|
|
vip1HeartIcon.layer.add(heartAnimation, forKey: "vip1HeartBeat")
|
|
|
|
addVip1TipSwingAnimation(to: vip1Tips1Img, from: -0.12, to: 0.12, duration: 0.55)
|
|
addVip1TipSwingAnimation(to: vip1Tips2Img, from: -0.12, to: 0.12, duration: 0.55)
|
|
addVip1TipSwingAnimation(to: vip1Tips3Img, from: -0.12, to: 0.12, duration: 0.55)
|
|
}
|
|
|
|
private func addVip1TipSwingAnimation(to imageView: UIImageView, from: CGFloat, to: CGFloat, duration: CFTimeInterval) {
|
|
let animation = CABasicAnimation(keyPath: "transform.rotation.z")
|
|
animation.fromValue = from
|
|
animation.toValue = to
|
|
animation.duration = duration
|
|
animation.autoreverses = true
|
|
animation.repeatCount = .infinity
|
|
animation.timingFunction = CAMediaTimingFunction(name: .easeInEaseOut)
|
|
imageView.layer.add(animation, forKey: "vip1TipSwing")
|
|
}
|
|
|
|
private func stopUnlockVip1Animations() {
|
|
vip1HeartIcon.layer.removeAnimation(forKey: "vip1HeartBeat")
|
|
vip1Tips1Img.layer.removeAnimation(forKey: "vip1TipSwing")
|
|
vip1Tips2Img.layer.removeAnimation(forKey: "vip1TipSwing")
|
|
vip1Tips3Img.layer.removeAnimation(forKey: "vip1TipSwing")
|
|
}
|
|
|
|
private let unlockVip1PopupHeight: CGFloat = 339
|
|
|
|
private func slideInUnlockVip1Popup() {
|
|
stopUnlockVip1Animations()
|
|
bgView.isUserInteractionEnabled = false
|
|
unlockVip1View.isHidden = false
|
|
unlockVip1View.layoutIfNeeded()
|
|
unlockVip1View.transform = CGAffineTransform(translationX: 0, y: unlockVip1PopupHeight)
|
|
UIView.animate(withDuration: 0.45, delay: 0,
|
|
usingSpringWithDamping: 0.8,
|
|
initialSpringVelocity: 0.5,
|
|
options: .curveEaseOut) {
|
|
self.unlockVip1View.transform = .identity
|
|
} completion: { _ in
|
|
self.bgView.isUserInteractionEnabled = true
|
|
self.startUnlockVip1Animations()
|
|
}
|
|
}
|
|
|
|
private func slideOutUnlockVip1Popup() {
|
|
stopUnlockVip1Animations()
|
|
bgView.isUserInteractionEnabled = false
|
|
UIView.animate(withDuration: 0.3, delay: 0, options: .curveEaseIn) {
|
|
self.unlockVip1View.transform = CGAffineTransform(translationX: 0, y: self.unlockVip1PopupHeight)
|
|
} completion: { _ in
|
|
Self.dismiss()
|
|
}
|
|
}
|
|
|
|
// MARK: - 解锁会员 2
|
|
private let unlockVip2PopupHeight: CGFloat = 412
|
|
|
|
lazy var unlockVip2View: UIView = {
|
|
let view = UIView()
|
|
view.backgroundColor = .clear
|
|
view.isHidden = true
|
|
|
|
let bgImg = UIImageView(image: UIImage(named: "PopupWindow/vip2_bg"))
|
|
bgImg.contentMode = .scaleAspectFill
|
|
view.addSubview(bgImg)
|
|
bgImg.layoutChain
|
|
.top(84)
|
|
.edgesHorzontal()
|
|
.bottom()
|
|
|
|
let titleLab = UILabel()
|
|
let text = "会员升级人次"
|
|
let attr = NSMutableAttributedString(string: text)
|
|
let strokeAttrs: [NSAttributedString.Key: Any] = [
|
|
.strokeWidth: -5,
|
|
.strokeColor: UIColor.black.cgColor,
|
|
.foregroundColor: UIColor.white,
|
|
.font: UIFont(name: "zihunbiantaoti", size: 20) ?? .systemFont(ofSize: 20)
|
|
]
|
|
attr.setAttributes(strokeAttrs, range: NSRange(location: 0, length: text.count))
|
|
titleLab.attributedText = attr
|
|
|
|
view.addSubview(titleLab)
|
|
titleLab.layoutChain
|
|
.top(106)
|
|
.left(29)
|
|
|
|
let countTitleLab = UILabel()
|
|
let countText = "已突破"
|
|
let countAttr = NSMutableAttributedString(string: countText)
|
|
let countStrokeAttrs: [NSAttributedString.Key: Any] = [
|
|
.strokeWidth: -5,
|
|
.strokeColor: UIColor.black.cgColor,
|
|
.foregroundColor: UIColor.white,
|
|
.font: UIFont(name: "zihunbiantaoti", size: 22) ?? .systemFont(ofSize: 22)
|
|
]
|
|
countAttr.setAttributes(countStrokeAttrs, range: NSRange(location: 0, length: countText.count))
|
|
countTitleLab.attributedText = countAttr
|
|
view.addSubview(countTitleLab)
|
|
countTitleLab.layoutChain
|
|
.topToBottomOfView(titleLab, offset: 22)
|
|
.leftToView(titleLab)
|
|
|
|
view.addSubview(unlockVip2CountLab)
|
|
unlockVip2CountLab.layoutChain
|
|
.leftToRightOfView(countTitleLab)
|
|
.bottomToView(countTitleLab, offset: 3)
|
|
|
|
view.addSubview(unlockVip2LogoImg)
|
|
unlockVip2LogoImg.layoutChain
|
|
.top()
|
|
.right()
|
|
.width(178)
|
|
.height(199)
|
|
|
|
let textImg = UIImageView(image: UIImage(named: "PopupWindow/vip2_text"))
|
|
view.addSubview(textImg)
|
|
textImg.layoutChain
|
|
.topToBottomOfView(unlockVip2LogoImg, offset: 15)
|
|
.centerX()
|
|
.width(275)
|
|
.height(41)
|
|
|
|
view.addSubview(unlockVip2CloseBtn)
|
|
unlockVip2CloseBtn.layoutChain
|
|
.bottom(kSafeBottomMargin + 15)
|
|
.left(30)
|
|
.height(50)
|
|
|
|
view.addSubview(unlockVip2Btn)
|
|
unlockVip2Btn.layoutChain
|
|
.bottomToView(unlockVip2CloseBtn)
|
|
.right(30)
|
|
.height(50)
|
|
.widthToView(unlockVip2CloseBtn)
|
|
|
|
unlockVip2CloseBtn.layoutChain.rightToLeftOfView(unlockVip2Btn, offset: -10)
|
|
|
|
return view
|
|
}()
|
|
|
|
lazy var unlockVip2LogoImg: UIImageView = {
|
|
let view = UIImageView()
|
|
view.image = UIImage(named: "PopupWindow/vip2_logo")
|
|
view.contentMode = .scaleAspectFill
|
|
return view
|
|
}()
|
|
|
|
private var unlockVip2CountTarget: Int = 0
|
|
private var unlockVip2CountTimer: Timer?
|
|
|
|
lazy var unlockVip2CountLab: UILabel = {
|
|
let label = UILabel()
|
|
unlockVip2CountTarget = Int.random(in: 10000...15000)
|
|
let text = "0+"
|
|
let attr = NSMutableAttributedString(string: text)
|
|
let strokeAttrs: [NSAttributedString.Key: Any] = [
|
|
.strokeWidth: -5,
|
|
.strokeColor: UIColor.black.cgColor,
|
|
.foregroundColor: UIColor(hexStr: "#7CE7FC"),
|
|
.font: UIFont(name: "zihunbiantaoti", size: 34) ?? .systemFont(ofSize: 34)
|
|
]
|
|
attr.setAttributes(strokeAttrs, range: NSRange(location: 0, length: text.count))
|
|
label.attributedText = attr
|
|
return label
|
|
}()
|
|
|
|
lazy var unlockVip2CloseBtn: UIButton = {
|
|
let btn = UIButton(type: .custom)
|
|
btn.setTitle("稍后再说", for: .normal)
|
|
btn.setTitleColor(UIColor(hexStr: "#16B3FF"), for: .normal)
|
|
btn.titleLabel?.font = .systemFont(ofSize: 16, weight: .medium)
|
|
btn.backgroundColor = .white
|
|
btn.cornerRadius = 25
|
|
btn.borderWidth = 0.5
|
|
btn.borderColor = UIColor(hexStr: "#16B3FF")
|
|
return btn
|
|
}()
|
|
|
|
lazy var unlockVip2Btn: UIButton = {
|
|
let btn = UIButton(type: .custom)
|
|
btn.setTitle("立即升级", for: .normal)
|
|
btn.setTitleColor(.white, for: .normal)
|
|
btn.titleLabel?.font = .systemFont(ofSize: 16, weight: .medium)
|
|
btn.setBackgroundImage(UIImage(named: "Common/button_bg_2"), for: .normal)
|
|
btn.cornerRadius = 25
|
|
return btn
|
|
}()
|
|
|
|
private func startUnlockVip2Animations() {
|
|
stopUnlockVip2Animations()
|
|
let animation = CABasicAnimation(keyPath: "transform.rotation.z")
|
|
animation.fromValue = -0.08
|
|
animation.toValue = 0.08
|
|
animation.duration = 0.7
|
|
animation.autoreverses = true
|
|
animation.repeatCount = .infinity
|
|
animation.timingFunction = CAMediaTimingFunction(name: .easeInEaseOut)
|
|
unlockVip2LogoImg.layer.add(animation, forKey: "unlockVip2LogoSwing")
|
|
startUnlockVip2CountAnimation()
|
|
}
|
|
|
|
private func stopUnlockVip2Animations() {
|
|
unlockVip2LogoImg.layer.removeAnimation(forKey: "unlockVip2LogoSwing")
|
|
unlockVip2CountTimer?.invalidate()
|
|
unlockVip2CountTimer = nil
|
|
}
|
|
|
|
private func startUnlockVip2CountAnimation() {
|
|
unlockVip2CountTimer?.invalidate()
|
|
let target = unlockVip2CountTarget
|
|
let duration: TimeInterval = 2.0
|
|
let interval: TimeInterval = 0.025
|
|
let totalSteps = Int(duration / interval)
|
|
var step = 0
|
|
unlockVip2CountTimer = Timer.scheduledTimer(withTimeInterval: interval, repeats: true) { [weak self] timer in
|
|
step += 1
|
|
let progress = min(Double(step) / Double(totalSteps), 1.0)
|
|
let eased = 1.0 - pow(1.0 - progress, 3)
|
|
let current = Int(Double(target) * eased)
|
|
let text = "\(current)+"
|
|
let attr = NSMutableAttributedString(string: text)
|
|
let strokeAttrs: [NSAttributedString.Key: Any] = [
|
|
.strokeWidth: -3,
|
|
.strokeColor: UIColor.black.cgColor,
|
|
.foregroundColor: UIColor(hexStr: "#7CE7FC"),
|
|
.font: UIFont(name: "zihunbiantaoti", size: 34) ?? .systemFont(ofSize: 34)
|
|
]
|
|
attr.setAttributes(strokeAttrs, range: NSRange(location: 0, length: text.count))
|
|
self?.unlockVip2CountLab.attributedText = attr
|
|
if progress >= 1.0 {
|
|
timer.invalidate()
|
|
self?.unlockVip2CountTimer = nil
|
|
}
|
|
}
|
|
}
|
|
|
|
private func slideInUnlockVip2Popup() {
|
|
stopUnlockVip2Animations()
|
|
unlockVip2CountTarget = Int.random(in: 10000...15000)
|
|
let attr = NSMutableAttributedString(string: "0+")
|
|
let strokeAttrs: [NSAttributedString.Key: Any] = [
|
|
.strokeWidth: -3,
|
|
.strokeColor: UIColor.black.cgColor,
|
|
.foregroundColor: UIColor(hexStr: "#7CE7FC"),
|
|
.font: UIFont(name: "zihunbiantaoti", size: 34) ?? .systemFont(ofSize: 34)
|
|
]
|
|
attr.setAttributes(strokeAttrs, range: NSRange(location: 0, length: 2))
|
|
unlockVip2CountLab.attributedText = attr
|
|
bgView.isUserInteractionEnabled = false
|
|
unlockVip2View.isHidden = false
|
|
unlockVip2View.layoutIfNeeded()
|
|
unlockVip2View.transform = CGAffineTransform(translationX: 0, y: unlockVip2PopupHeight)
|
|
UIView.animate(withDuration: 0.45, delay: 0,
|
|
usingSpringWithDamping: 0.8,
|
|
initialSpringVelocity: 0.5,
|
|
options: .curveEaseOut) {
|
|
self.unlockVip2View.transform = .identity
|
|
} completion: { _ in
|
|
self.bgView.isUserInteractionEnabled = true
|
|
self.startUnlockVip2Animations()
|
|
}
|
|
}
|
|
|
|
private func slideOutUnlockVip2Popup() {
|
|
stopUnlockVip2Animations()
|
|
bgView.isUserInteractionEnabled = false
|
|
UIView.animate(withDuration: 0.3, delay: 0, options: .curveEaseIn) {
|
|
self.unlockVip2View.transform = CGAffineTransform(translationX: 0, y: self.unlockVip2PopupHeight)
|
|
} completion: { _ in
|
|
Self.dismiss()
|
|
}
|
|
}
|
|
|
|
// MARK: - 解锁会员 3
|
|
private let unlockVip3PopupHeight: CGFloat = 385
|
|
|
|
lazy var unlockVip3View: UIView = {
|
|
let view = UIView()
|
|
view.backgroundColor = .clear
|
|
view.isHidden = true
|
|
|
|
let bgImg = UIImageView(image: UIImage(named: "PopupWindow/vip3_bg"))
|
|
bgImg.contentMode = .scaleAspectFill
|
|
view.addSubview(bgImg)
|
|
bgImg.layoutChain
|
|
.top(45)
|
|
.edgesHorzontal()
|
|
.bottom()
|
|
|
|
view.addSubview(unlockVip3LottieView)
|
|
unlockVip3LottieView.layoutChain
|
|
.top(-120)
|
|
.right(-110)
|
|
.width(420)
|
|
.height(370)
|
|
|
|
view.addSubview(unlockVip3CloseBtn)
|
|
unlockVip3CloseBtn.layoutChain
|
|
.bottom(kSafeBottomMargin + 15)
|
|
.left(30)
|
|
.height(50)
|
|
|
|
view.addSubview(unlockVip3Btn)
|
|
unlockVip3Btn.layoutChain
|
|
.bottomToView(unlockVip3CloseBtn)
|
|
.right(30)
|
|
.height(50)
|
|
.widthToView(unlockVip3CloseBtn)
|
|
|
|
unlockVip3CloseBtn.layoutChain.rightToLeftOfView(unlockVip3Btn, offset: -10)
|
|
|
|
return view
|
|
}()
|
|
|
|
lazy var unlockVip3LottieView: LottieAnimationView = {
|
|
let view = LottieAnimationView(name: "dialog_buy_vip_3")
|
|
view.loopMode = .loop
|
|
return view
|
|
}()
|
|
|
|
lazy var unlockVip3CloseBtn: UIButton = {
|
|
let btn = UIButton(type: .custom)
|
|
btn.setTitle("稍后再说", for: .normal)
|
|
btn.setTitleColor(UIColor(hexStr: "#16B3FF"), for: .normal)
|
|
btn.titleLabel?.font = .systemFont(ofSize: 16, weight: .medium)
|
|
btn.backgroundColor = .white
|
|
btn.cornerRadius = 25
|
|
btn.borderWidth = 0.5
|
|
btn.borderColor = UIColor(hexStr: "#16B3FF")
|
|
return btn
|
|
}()
|
|
|
|
lazy var unlockVip3Btn: UIButton = {
|
|
let btn = UIButton(type: .custom)
|
|
btn.setTitle("立即升级", for: .normal)
|
|
btn.setTitleColor(.white, for: .normal)
|
|
btn.titleLabel?.font = .systemFont(ofSize: 16, weight: .medium)
|
|
btn.setBackgroundImage(UIImage(named: "Common/button_bg_2"), for: .normal)
|
|
btn.cornerRadius = 25
|
|
return btn
|
|
}()
|
|
|
|
private func stopUnlockVip3Animations() {
|
|
unlockVip3LottieView.stop()
|
|
}
|
|
|
|
private func slideInUnlockVip3Popup() {
|
|
stopUnlockVip3Animations()
|
|
bgView.isUserInteractionEnabled = false
|
|
unlockVip3View.isHidden = false
|
|
unlockVip3View.layoutIfNeeded()
|
|
unlockVip3View.transform = CGAffineTransform(translationX: 0, y: unlockVip3PopupHeight)
|
|
UIView.animate(withDuration: 0.45, delay: 0,
|
|
usingSpringWithDamping: 0.8,
|
|
initialSpringVelocity: 0.5,
|
|
options: .curveEaseOut) {
|
|
self.unlockVip3View.transform = .identity
|
|
} completion: { _ in
|
|
self.bgView.isUserInteractionEnabled = true
|
|
self.unlockVip3LottieView.play()
|
|
}
|
|
}
|
|
|
|
private func slideOutUnlockVip3Popup() {
|
|
stopUnlockVip3Animations()
|
|
bgView.isUserInteractionEnabled = false
|
|
UIView.animate(withDuration: 0.3, delay: 0, options: .curveEaseIn) {
|
|
self.unlockVip3View.transform = CGAffineTransform(translationX: 0, y: self.unlockVip3PopupHeight)
|
|
} completion: { _ in
|
|
Self.dismiss()
|
|
}
|
|
}
|
|
|
|
// MARK: - 解锁会员 4
|
|
private let unlockVip4PopupHeight: CGFloat = 368
|
|
|
|
lazy var unlockVip4View: UIView = {
|
|
let view = UIView()
|
|
view.backgroundColor = .clear
|
|
view.isHidden = true
|
|
|
|
let bgImg = UIImageView(image: UIImage(named: "PopupWindow/vip4_bg"))
|
|
bgImg.contentMode = .scaleAspectFill
|
|
view.addSubview(bgImg)
|
|
bgImg.layoutChain
|
|
.top()
|
|
.edgesHorzontal()
|
|
.bottom()
|
|
|
|
view.addSubview(unlockVip4AnimateView)
|
|
unlockVip4AnimateView.layoutChain
|
|
.top(143)
|
|
.rightToCenterXOfView(view, offset: 50)
|
|
.width(60)
|
|
.height(52)
|
|
|
|
let label = UILabel()
|
|
label.text = "终身会员"
|
|
label.font = .systemFont(ofSize: 14, weight: .medium)
|
|
view.addSubview(label)
|
|
label.layoutChain
|
|
.leftToRightOfView(unlockVip4AnimateView, offset: 17)
|
|
.bottomToView(unlockVip4AnimateView)
|
|
|
|
view.addSubview(unlockVip4DiscountLab)
|
|
unlockVip4DiscountLab.layoutChain
|
|
.bottomToView(label, offset: 10)
|
|
.leftToRightOfView(label)
|
|
|
|
let unitLab = UILabel()
|
|
unitLab.text = "折"
|
|
unitLab.font = .systemFont(ofSize: 14, weight: .medium)
|
|
view.addSubview(unitLab)
|
|
unitLab.layoutChain
|
|
.bottomToView(label, offset: 0)
|
|
.leftToRightOfView(unlockVip4DiscountLab)
|
|
|
|
view.addSubview(unlockVip4CloseBtn)
|
|
unlockVip4CloseBtn.layoutChain
|
|
.top()
|
|
.right(18)
|
|
.width(22)
|
|
.height(22)
|
|
|
|
view.addSubview(unlockVip4Btn)
|
|
unlockVip4Btn.layoutChain
|
|
.centerX()
|
|
.width(224)
|
|
.height(50)
|
|
.bottom(49)
|
|
|
|
return view
|
|
}()
|
|
|
|
lazy var unlockVip4AnimateView: UIImageView = {
|
|
let view = UIImageView()
|
|
view.image = UIImage(named: "PopupWindow/vip4_animate")
|
|
return view
|
|
}()
|
|
|
|
lazy var unlockVip4DiscountLab: UILabel = {
|
|
let label = UILabel()
|
|
label.font = .systemFont(ofSize: 44, weight: .bold)
|
|
label.textColor = UIColor(hexStr: "#FF4E41")
|
|
return label
|
|
}()
|
|
|
|
lazy var unlockVip4CloseBtn: UIButton = {
|
|
let btn = UIButton(type: .custom)
|
|
btn.setImage(UIImage(named: "PopupWindow/close"), for: .normal)
|
|
btn.extendEdgeInsets = UIEdgeInsets(top: 30, left: 30, bottom: 30, right: 18)
|
|
return btn
|
|
}()
|
|
|
|
lazy var unlockVip4Btn: UIButton = {
|
|
let btn = UIButton(type: .custom)
|
|
btn.setTitle("立即升级", for: .normal)
|
|
btn.setTitleColor(.white, for: .normal)
|
|
btn.titleLabel?.font = .systemFont(ofSize: 16, weight: .medium)
|
|
btn.setBackgroundImage(UIImage(named: "Common/button_bg_2"), for: .normal)
|
|
btn.cornerRadius = 25
|
|
return btn
|
|
}()
|
|
|
|
private func startUnlockVip4Animations() {
|
|
stopUnlockVip4Animations()
|
|
|
|
let animateScale = CABasicAnimation(keyPath: "transform.scale")
|
|
animateScale.fromValue = 1.0
|
|
animateScale.toValue = 1.15
|
|
animateScale.duration = 0.6
|
|
animateScale.autoreverses = true
|
|
animateScale.repeatCount = .infinity
|
|
animateScale.timingFunction = CAMediaTimingFunction(name: .easeInEaseOut)
|
|
unlockVip4AnimateView.layer.add(animateScale, forKey: "unlockVip4AnimateScale")
|
|
|
|
let btnScale = CABasicAnimation(keyPath: "transform.scale")
|
|
btnScale.fromValue = 1.0
|
|
btnScale.toValue = 1.08
|
|
btnScale.duration = 0.8
|
|
btnScale.autoreverses = true
|
|
btnScale.repeatCount = .infinity
|
|
btnScale.timingFunction = CAMediaTimingFunction(name: .easeInEaseOut)
|
|
unlockVip4Btn.layer.add(btnScale, forKey: "unlockVip4BtnScale")
|
|
}
|
|
|
|
private func stopUnlockVip4Animations() {
|
|
unlockVip4AnimateView.layer.removeAnimation(forKey: "unlockVip4AnimateScale")
|
|
unlockVip4Btn.layer.removeAnimation(forKey: "unlockVip4BtnScale")
|
|
}
|
|
|
|
private func slideInUnlockVip4Popup() {
|
|
if let systemConfig = AppContextManager.shared.systemConfig,
|
|
let timeConfig = systemConfig.timeConfig {
|
|
unlockVip4DiscountLab.text = (String(format: "%.1f", timeConfig.min_discount/10))
|
|
}
|
|
stopUnlockVip4Animations()
|
|
bgView.isUserInteractionEnabled = false
|
|
unlockVip4View.isHidden = false
|
|
unlockVip4View.layoutIfNeeded()
|
|
unlockVip4View.transform = CGAffineTransform(translationX: 0, y: unlockVip4PopupHeight)
|
|
UIView.animate(withDuration: 0.45, delay: 0,
|
|
usingSpringWithDamping: 0.8,
|
|
initialSpringVelocity: 0.5,
|
|
options: .curveEaseOut) {
|
|
self.unlockVip4View.transform = .identity
|
|
} completion: { _ in
|
|
self.bgView.isUserInteractionEnabled = true
|
|
self.startUnlockVip4Animations()
|
|
}
|
|
}
|
|
|
|
private func slideOutUnlockVip4Popup() {
|
|
stopUnlockVip4Animations()
|
|
bgView.isUserInteractionEnabled = false
|
|
UIView.animate(withDuration: 0.3, delay: 0, options: .curveEaseIn) {
|
|
self.unlockVip4View.transform = CGAffineTransform(translationX: 0, y: self.unlockVip4PopupHeight)
|
|
} completion: { _ in
|
|
Self.dismiss()
|
|
}
|
|
}
|
|
|
|
// MARK: - 注册账号 1
|
|
lazy var registerPopupView: UIView = {
|
|
let view = UIView()
|
|
view.backgroundColor = .clear
|
|
view.isHidden = true
|
|
|
|
let bgImg = UIImageView(image: UIImage(named: "PopupWindow/register_bg"))
|
|
bgImg.contentMode = .scaleAspectFill
|
|
view.addSubview(bgImg)
|
|
bgImg.layoutChain
|
|
.top(51)
|
|
.edgesHorzontal()
|
|
.bottom()
|
|
|
|
let logoImg = UIImageView(image: UIImage(named: "PopupWindow/register_logo"))
|
|
logoImg.contentMode = .scaleAspectFill
|
|
view.addSubview(logoImg)
|
|
logoImg.layoutChain
|
|
.top()
|
|
.centerX()
|
|
.width(250)
|
|
.height(123)
|
|
|
|
let textImg = UIImageView(image: UIImage(named: "PopupWindow/register_text"))
|
|
textImg.contentMode = .scaleAspectFill
|
|
view.addSubview(textImg)
|
|
textImg.layoutChain
|
|
.topToBottomOfView(logoImg, offset: 20)
|
|
.width(272)
|
|
.height(50)
|
|
.centerX()
|
|
|
|
view.addSubview(register1UpLottieView)
|
|
register1UpLottieView.layoutChain
|
|
.bottomToTopOfView(logoImg, offset: 120)
|
|
.edgesHorzontal()
|
|
.height(200)
|
|
|
|
view.addSubview(register1DownLottieView)
|
|
register1DownLottieView.layoutChain
|
|
.topToBottomOfView(logoImg, offset: -140)
|
|
.edgesHorzontal()
|
|
.height(200)
|
|
|
|
// view.addSubview(registerStar1)
|
|
// registerStar1.layoutChain
|
|
// .top(19)
|
|
// .leftToView(logoImg, offset: -31)
|
|
// .width(68)
|
|
// .heightToWidth(1.0)
|
|
|
|
view.addSubview(registerStar3)
|
|
registerStar3.layoutChain
|
|
.top(23)
|
|
.rightToView(logoImg, offset: -9)
|
|
.width(26)
|
|
.height(20)
|
|
|
|
view.addSubview(registerStar2)
|
|
registerStar2.layoutChain
|
|
.top(31)
|
|
.rightToView(logoImg, offset: 20)
|
|
.width(48)
|
|
.height(44)
|
|
|
|
view.addSubview(registerCloseBtn)
|
|
registerCloseBtn.layoutChain
|
|
.topToBottomOfView(textImg, offset: 30)
|
|
.left(30)
|
|
.height(50)
|
|
|
|
view.addSubview(registerBtn)
|
|
registerBtn.layoutChain
|
|
.topToBottomOfView(textImg, offset: 30)
|
|
.right(30)
|
|
.height(50)
|
|
.widthToView(registerCloseBtn)
|
|
|
|
registerCloseBtn.layoutChain.rightToLeftOfView(registerBtn, offset: -10)
|
|
|
|
return view
|
|
}()
|
|
|
|
lazy var register1UpLottieView: LottieAnimationView = {
|
|
let view = LottieAnimationView(name: "dialog_register_tip1_1")
|
|
return view
|
|
}()
|
|
|
|
lazy var register1DownLottieView: LottieAnimationView = {
|
|
let view = LottieAnimationView(name: "dialog_register_tip1_2")
|
|
return view
|
|
}()
|
|
|
|
lazy var registerStar1: UIImageView = {
|
|
let view = UIImageView()
|
|
view.image = UIImage(named: "PopupWindow/star_1")
|
|
return view
|
|
}()
|
|
|
|
lazy var registerStar2: UIImageView = {
|
|
let view = UIImageView()
|
|
view.image = UIImage(named: "PopupWindow/star_2")
|
|
return view
|
|
}()
|
|
|
|
lazy var registerStar3: UIImageView = {
|
|
let view = UIImageView()
|
|
view.image = UIImage(named: "PopupWindow/star_3")
|
|
return view
|
|
}()
|
|
|
|
lazy var registerCloseBtn: UIButton = {
|
|
let btn = UIButton(type: .custom)
|
|
btn.setTitle("稍后再说", for: .normal)
|
|
btn.setTitleColor(UIColor(hexStr: "#16B3FF"), for: .normal)
|
|
btn.titleLabel?.font = .systemFont(ofSize: 16, weight: .medium)
|
|
btn.backgroundColor = .white
|
|
btn.cornerRadius = 25
|
|
btn.borderWidth = 0.5
|
|
btn.borderColor = UIColor(hexStr: "#16B3FF")
|
|
return btn
|
|
}()
|
|
|
|
lazy var registerBtn: UIButton = {
|
|
let btn = UIButton(type: .custom)
|
|
btn.setTitle("免费注册", for: .normal)
|
|
btn.setTitleColor(.white, for: .normal)
|
|
btn.titleLabel?.font = .systemFont(ofSize: 16, weight: .medium)
|
|
btn.setBackgroundImage(UIImage(named: "Common/button_bg_2"), for: .normal)
|
|
btn.cornerRadius = 25
|
|
return btn
|
|
}()
|
|
|
|
private var register1LottieAlternating = false
|
|
|
|
private func startRegister1LottieAlternate() {
|
|
stopRegister1LottieAlternate()
|
|
register1LottieAlternating = true
|
|
playRegister1Up()
|
|
}
|
|
|
|
private func playRegister1Up() {
|
|
guard register1LottieAlternating else { return }
|
|
register1UpLottieView.isHidden = false
|
|
register1DownLottieView.isHidden = true
|
|
register1UpLottieView.play { [weak self] _ in
|
|
self?.playRegister1Down()
|
|
}
|
|
}
|
|
|
|
private func playRegister1Down() {
|
|
guard register1LottieAlternating else { return }
|
|
register1UpLottieView.isHidden = true
|
|
register1DownLottieView.isHidden = false
|
|
register1DownLottieView.play { [weak self] _ in
|
|
self?.playRegister1Up()
|
|
}
|
|
}
|
|
|
|
private func stopRegister1LottieAlternate() {
|
|
register1LottieAlternating = false
|
|
register1UpLottieView.stop()
|
|
register1DownLottieView.stop()
|
|
register1UpLottieView.isHidden = true
|
|
register1DownLottieView.isHidden = true
|
|
}
|
|
|
|
private func startRegisterStarFlash() {
|
|
stopRegisterStarFlash()
|
|
let (star2, star3) = activePopupView == 2 ? (register2Star2, register2Star3) : (registerStar2, registerStar3)
|
|
|
|
let animation2 = CABasicAnimation(keyPath: "opacity")
|
|
animation2.fromValue = 1.0
|
|
animation2.toValue = 0.0
|
|
animation2.duration = 0.4
|
|
animation2.autoreverses = true
|
|
animation2.repeatCount = .infinity
|
|
star2.layer.add(animation2, forKey: "starFlash")
|
|
|
|
let animation3 = CABasicAnimation(keyPath: "opacity")
|
|
animation3.fromValue = 0.0
|
|
animation3.toValue = 1.0
|
|
animation3.duration = 0.4
|
|
animation3.autoreverses = true
|
|
animation3.repeatCount = .infinity
|
|
star3.layer.add(animation3, forKey: "starFlash")
|
|
}
|
|
|
|
private func stopRegisterStarFlash() {
|
|
registerStar2.layer.removeAnimation(forKey: "starFlash")
|
|
registerStar3.layer.removeAnimation(forKey: "starFlash")
|
|
register2Star2.layer.removeAnimation(forKey: "starFlash")
|
|
register2Star3.layer.removeAnimation(forKey: "starFlash")
|
|
}
|
|
|
|
private func animateRegisterStarSlideIn() {
|
|
UIView.animate(withDuration: 0.5, delay: 0,
|
|
usingSpringWithDamping: 0.7,
|
|
initialSpringVelocity: 0.6,
|
|
options: .curveEaseOut) {
|
|
self.registerStar1.transform = .identity
|
|
}
|
|
}
|
|
|
|
private let registerPopupHeight: CGFloat = 308
|
|
|
|
private var activePopupView = 1
|
|
|
|
private func slideInRegisterPopup() {
|
|
activePopupView = 1
|
|
stopRegisterStarFlash()
|
|
bgView.isUserInteractionEnabled = false
|
|
registerPopupView.isHidden = false
|
|
registerPopupView.layoutIfNeeded()
|
|
// registerStar1.transform = CGAffineTransform(translationX: -(registerStar1.frame.maxX + 30), y: 0)
|
|
registerPopupView.transform = CGAffineTransform(translationX: 0, y: registerPopupHeight)
|
|
UIView.animate(withDuration: 0.45, delay: 0,
|
|
usingSpringWithDamping: 0.8,
|
|
initialSpringVelocity: 0.5,
|
|
options: .curveEaseOut) {
|
|
self.registerPopupView.transform = .identity
|
|
} completion: { _ in
|
|
self.bgView.isUserInteractionEnabled = true
|
|
self.startRegisterStarFlash()
|
|
self.startRegister1LottieAlternate()
|
|
// self.animateRegisterStarSlideIn()
|
|
}
|
|
}
|
|
|
|
private func slideOutRegisterPopup() {
|
|
stopRegisterStarFlash()
|
|
stopRegister1LottieAlternate()
|
|
bgView.isUserInteractionEnabled = false
|
|
UIView.animate(withDuration: 0.3, delay: 0, options: .curveEaseIn) {
|
|
self.registerPopupView.transform = CGAffineTransform(translationX: 0, y: self.registerPopupHeight)
|
|
} completion: { _ in
|
|
Self.dismiss()
|
|
}
|
|
}
|
|
|
|
private func slideInRegister2Popup() {
|
|
activePopupView = 2
|
|
stopRegisterStarFlash()
|
|
bgView.isUserInteractionEnabled = false
|
|
register2PopupView.isHidden = false
|
|
register2PopupView.layoutIfNeeded()
|
|
// register2Star1.transform = CGAffineTransform(translationX: -(register2Star1.frame.maxX + 30), y: 0)
|
|
register2PopupView.transform = CGAffineTransform(translationX: 0, y: register2PopupView.bounds.height)
|
|
UIView.animate(withDuration: 0.45, delay: 0,
|
|
usingSpringWithDamping: 0.8,
|
|
initialSpringVelocity: 0.5,
|
|
options: .curveEaseOut) {
|
|
self.register2PopupView.transform = .identity
|
|
} completion: { _ in
|
|
self.bgView.isUserInteractionEnabled = true
|
|
self.startRegisterStarFlash()
|
|
self.register2LottieView.play()
|
|
// self.animateRegister2StarSlideIn()
|
|
}
|
|
}
|
|
|
|
private func slideOutRegister2Popup() {
|
|
stopRegisterStarFlash()
|
|
bgView.isUserInteractionEnabled = false
|
|
UIView.animate(withDuration: 0.3, delay: 0, options: .curveEaseIn) {
|
|
self.register2PopupView.transform = CGAffineTransform(translationX: 0, y: self.register2PopupView.bounds.height)
|
|
} completion: { _ in
|
|
Self.dismiss()
|
|
}
|
|
}
|
|
|
|
private func animateRegister2StarSlideIn() {
|
|
UIView.animate(withDuration: 0.55, delay: 0.1,
|
|
usingSpringWithDamping: 0.65,
|
|
initialSpringVelocity: 0.4,
|
|
options: .curveEaseOut) {
|
|
self.register2Star1.transform = .identity
|
|
}
|
|
}
|
|
|
|
// MARK: - 注册账号 2
|
|
lazy var register2PopupView: UIView = {
|
|
let view = UIView()
|
|
view.backgroundColor = .clear
|
|
view.isHidden = true
|
|
|
|
let bgImg = UIImageView(image: UIImage(named: "PopupWindow/register_bg"))
|
|
bgImg.contentMode = .scaleAspectFill
|
|
view.addSubview(bgImg)
|
|
bgImg.layoutChain
|
|
.top(58)
|
|
.edgesHorzontal()
|
|
.bottom()
|
|
|
|
let logoImg = UIImageView(image: UIImage(named: "PopupWindow/register2_logo"))
|
|
logoImg.contentMode = .scaleAspectFill
|
|
view.addSubview(register2LottieView)
|
|
view.addSubview(logoImg)
|
|
logoImg.layoutChain
|
|
.top()
|
|
.centerX()
|
|
.width(243)
|
|
.height(97)
|
|
|
|
let textLab = UILabel()
|
|
textLab.text = "注册后即可保存历史轨迹、多人 共享地图、跨设备同步。"
|
|
textLab.font = .systemFont(ofSize: 16, weight: .medium)
|
|
textLab.textColor = UIColor(hexStr: "#16B3FF")
|
|
textLab.numberOfLines = 0
|
|
view.addSubview(textLab)
|
|
textLab.layoutChain
|
|
.topToBottomOfView(logoImg, offset: 33)
|
|
.edgesHorzontal(75)
|
|
|
|
register2LottieView.layoutChain
|
|
.top()
|
|
.rightToLeftOfView(logoImg, offset: 45)
|
|
.width(100)
|
|
.heightToWidth(1.0)
|
|
|
|
view.addSubview(register2Star3)
|
|
register2Star3.layoutChain
|
|
.top(25)
|
|
.rightToView(logoImg, offset: -6)
|
|
.width(26)
|
|
.height(20)
|
|
|
|
view.addSubview(register2Star2)
|
|
register2Star2.layoutChain
|
|
.top(32)
|
|
.rightToView(logoImg, offset: 25)
|
|
.width(48)
|
|
.height(44)
|
|
|
|
view.addSubview(register2Btn)
|
|
register2Btn.layoutChain
|
|
.topToBottomOfView(textLab, offset: 30)
|
|
.width(224)
|
|
.height(50)
|
|
.centerX()
|
|
|
|
view.addSubview(register2CloseBtn)
|
|
register2CloseBtn.layoutChain
|
|
.topToView(bgImg, offset: 32)
|
|
.right(15)
|
|
|
|
return view
|
|
}()
|
|
|
|
lazy var register2LottieView: LottieAnimationView = {
|
|
let view = LottieAnimationView(name: "dialog_register_tip2")
|
|
view.loopMode = .loop
|
|
return view
|
|
}()
|
|
|
|
lazy var register2Star1: UIImageView = {
|
|
let view = UIImageView()
|
|
view.image = UIImage(named: "PopupWindow/register_heart")
|
|
return view
|
|
}()
|
|
|
|
lazy var register2Star2: UIImageView = {
|
|
let view = UIImageView()
|
|
view.image = UIImage(named: "PopupWindow/star_2")
|
|
return view
|
|
}()
|
|
|
|
lazy var register2Star3: UIImageView = {
|
|
let view = UIImageView()
|
|
view.image = UIImage(named: "PopupWindow/star_3")
|
|
return view
|
|
}()
|
|
|
|
lazy var register2CloseBtn: UIButton = {
|
|
let btn = UIButton(type: .custom)
|
|
btn.setImage(UIImage(named: "PopupWindow/close"), for: .normal)
|
|
btn.extendEdgeInsets = UIEdgeInsets(top: 30, left: 30, bottom: 30, right: 15)
|
|
return btn
|
|
}()
|
|
|
|
lazy var register2Btn: UIButton = {
|
|
let btn = UIButton(type: .custom)
|
|
btn.setTitle("免费注册", for: .normal)
|
|
btn.setTitleColor(.white, for: .normal)
|
|
btn.titleLabel?.font = .systemFont(ofSize: 16, weight: .medium)
|
|
btn.setBackgroundImage(UIImage(named: "Common/button_bg_2"), for: .normal)
|
|
btn.cornerRadius = 25
|
|
return btn
|
|
}()
|
|
|
|
// MARK: - Init
|
|
override init(frame: CGRect) {
|
|
super.init(frame: frame)
|
|
backgroundColor = .clear
|
|
addSubview(bgView)
|
|
bgView.addSubview(searchPopupView)
|
|
bgView.addSubview(unlockVip1View)
|
|
bgView.addSubview(unlockVip2View)
|
|
bgView.addSubview(unlockVip3View)
|
|
bgView.addSubview(unlockVip4View)
|
|
bgView.addSubview(registerPopupView)
|
|
bgView.addSubview(register2PopupView)
|
|
|
|
searchPopupView.layoutChain
|
|
.centerY()
|
|
.centerX()
|
|
|
|
registerPopupView.layoutChain
|
|
.edgesHorzontal()
|
|
.bottom()
|
|
.height(308)
|
|
|
|
register2PopupView.layoutChain
|
|
.edgesHorzontal()
|
|
.bottom()
|
|
.height(295)
|
|
|
|
unlockVip1View.layoutChain
|
|
.edgesHorzontal()
|
|
.bottom()
|
|
.height(unlockVip1PopupHeight)
|
|
|
|
unlockVip2View.layoutChain
|
|
.edgesHorzontal()
|
|
.bottom()
|
|
.height(unlockVip2PopupHeight)
|
|
|
|
unlockVip3View.layoutChain
|
|
.edgesHorzontal()
|
|
.bottom()
|
|
.height(unlockVip3PopupHeight)
|
|
|
|
unlockVip4View.layoutChain
|
|
.edgesHorzontal()
|
|
.bottom()
|
|
.height(unlockVip4PopupHeight)
|
|
|
|
|
|
setupRx()
|
|
}
|
|
|
|
required init?(coder aDecoder: NSCoder) {
|
|
fatalError("init(coder:) has not been implemented")
|
|
}
|
|
|
|
override func layoutSubviews() {
|
|
super.layoutSubviews()
|
|
|
|
}
|
|
}
|