jsdw_ios/QuickLocation/Section/LockDistract/LockDistractView.swift

606 lines
18 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.

//
// LockDistractView.swift
// QuickLocation
//
import UIKit
import RxSwift
import RxCocoa
final class LockDistractView: UIView {
var disposeBag = DisposeBag()
let wallpaperNames = [
"LockDistract/wallpaper_1",
"LockDistract/wallpaper_2",
"LockDistract/wallpaper_3"
]
private(set) var selectedWallpaperIndex = 0
private let copyMaxLength = 20
// MARK: - Init
override init(frame: CGRect) {
super.init(frame: frame)
backgroundColor = UIColor(hexStr: "#FAFAFA")
setupUI()
setupCopyLimit()
}
required init?(coder: NSCoder) { fatalError("init(coder:) has not been implemented") }
// MARK: - Public
func configureMember(name: String, avatar: UIImage?) {
memberNameLab.text = name.isEmpty ? " " : name
memberAvatar.image = avatar ?? UIImage(named: "Common/default_avatar")
}
func setTodayLockCount(_ count: Int) {
todayCountLab.text = "\(count)"
}
// MARK: - UI
private func setupUI() {
addSubview(navBgView)
addSubview(navView)
navView.addRightButton(switchGroupBtn)
addSubview(scrollView)
scrollView.addSubview(contentView)
addSubview(lockBtn)
contentView.addSubview(titleLab)
contentView.addSubview(subtitleLab)
contentView.addSubview(heroPlaceholder)
contentView.addSubview(statsRow)
statsRow.addArrangedSubview(memberCard)
statsRow.addArrangedSubview(todayCard)
contentView.addSubview(appsSectionTitle)
contentView.addSubview(appsCard)
appsCard.addSubview(appsHeaderRow)
appsCard.addSubview(unknownAppIcon)
contentView.addSubview(styleSectionTitle)
contentView.addSubview(styleCard)
addSubview(tipRow)
navBgView.layoutChain
.edges(excludingEdge: .bottom)
.heightToWidth(160/375)
navView.layoutChain
.edges(excludingEdge: .bottom)
.height(kNaviHeight)
lockBtn.layoutChain
.bottom(kSafeBottomMargin + 0)
.edgesHorzontal(30)
.height(56)
scrollView.layoutChain
.topToBottomOfView(navView)
.edgesHorzontal()
.bottomToTopOfView(tipRow, offset: -12)
contentView.layoutChain
.edges()
.widthToView(scrollView)
titleLab.layoutChain
.top(8)
.left(20)
subtitleLab.layoutChain
.topToBottomOfView(titleLab, offset: 6)
.left(20)
.right(140)
heroPlaceholder.layoutChain
.top(0)
.right(16)
.width(120)
.height(100)
statsRow.layoutChain
.topToBottomOfView(subtitleLab, offset: 20)
.edgesHorzontal(16)
.height(120)
appsSectionTitle.layoutChain
.topToBottomOfView(statsRow, offset: 22)
.left(20)
appsCard.layoutChain
.topToBottomOfView(appsSectionTitle, offset: 12)
.edgesHorzontal(16)
appsHeaderRow.layoutChain
.top(16)
.edgesHorzontal(14)
unknownAppIcon.layoutChain
.topToBottomOfView(appsHeaderRow, offset: 14)
.left(14)
.width(56)
.height(56)
.bottom(16)
styleSectionTitle.layoutChain
.topToBottomOfView(appsCard, offset: 22)
.left(20)
styleCard.layoutChain
.topToBottomOfView(styleSectionTitle, offset: 12)
.edgesHorzontal(16)
.bottom(20)
tipRow.layoutChain
.centerX()
.bottomToTopOfView(lockBtn, offset: -6)
}
private func setupCopyLimit() {
copyTF.rx.text.orEmpty
.subscribe(onNext: { [weak self] text in
guard let self else { return }
if text.count > self.copyMaxLength {
self.copyTF.text = String(text.prefix(self.copyMaxLength))
}
let count = self.copyTF.text?.count ?? 0
self.copyCountLab.text = "\(count)/\(self.copyMaxLength)"
})
.disposed(by: disposeBag)
}
// MARK: - Views
lazy var navBgView: UIImageView = {
let iv = UIImageView()
iv.image = UIImage(named: "Common/navBar_bg_2")
iv.contentMode = .scaleAspectFill
return iv
}()
lazy var navView: BaseNavigationView = {
BaseNavigationView(title: "")
}()
lazy var switchGroupBtn: UIButton = {
let btn = UIButton(type: .custom)
btn.backgroundColor = .white.withAlphaComponent(0.9)
btn.setTitle(" 切换圈子 ", for: .normal)
btn.titleLabel?.font = .systemFont(ofSize: 12, weight: .medium)
btn.setTitleColor(UIColor(hexStr: "#293445"), for: .normal)
btn.cornerRadius = 8
btn.extendEdgeInsets = UIEdgeInsets(top: 20, left: 12, bottom: 12, right: 4)
return btn
}()
lazy var scrollView: UIScrollView = {
let sv = UIScrollView()
sv.showsVerticalScrollIndicator = false
sv.alwaysBounceVertical = true
sv.keyboardDismissMode = .onDrag
return sv
}()
lazy var contentView = UIView()
lazy var titleLab: UILabel = {
let lab = UILabel()
lab.text = "锁住分心"
lab.font = FontManager.boboBold(30)
lab.textColor = UIColor(hexStr: "#293445")
return lab
}()
lazy var subtitleLab: UILabel = {
let lab = UILabel()
lab.text = "减少干扰,只专注重要的事"
lab.font = .systemFont(ofSize: 13, weight: .medium)
lab.textColor = UIColor(hexStr: "#8A94A6")
lab.numberOfLines = 2
return lab
}()
lazy var heroPlaceholder: UIView = {
let view = UIView()
view.backgroundColor = .clear
return view
}()
lazy var statsRow: UIStackView = {
let stack = UIStackView()
stack.axis = .horizontal
stack.spacing = 12
stack.distribution = .fillEqually
return stack
}()
lazy var memberCard: UIView = {
let view = UIView()
view.backgroundColor = .white
view.cornerRadius = 16
view.addSubview(memberPrevBtn)
view.addSubview(memberAvatar)
view.addSubview(memberNextBtn)
view.addSubview(memberNameChip)
memberNameChip.addSubview(memberNameLab)
memberAvatar.layoutChain
.top(18)
.centerX()
.width(56)
.height(56)
memberPrevBtn.layoutChain
.centerY(memberAvatar)
.left(8)
.width(28)
.height(28)
memberNextBtn.layoutChain
.centerY(memberAvatar)
.right(8)
.width(28)
.height(28)
memberNameChip.layoutChain
.topToBottomOfView(memberAvatar, offset: 10)
.centerX()
.left(8, relation: .greaterThanOrEqual)
.right(8, relation: .greaterThanOrEqual)
.bottom(14)
memberNameLab.layoutChain
.top(6)
.bottom(6)
.left(5)
.right(5)
return view
}()
lazy var memberAvatar: UIImageView = {
let iv = UIImageView(image: UIImage(named: "Common/default_avatar"))
iv.contentMode = .scaleAspectFill
iv.clipsToBounds = true
iv.cornerRadius = 16
return iv
}()
lazy var memberNameChip: UIView = {
let view = UIView()
view.backgroundColor = UIColor(hexStr: "#F2F2F2")
view.cornerRadius = 8
return view
}()
lazy var memberNameLab: UILabel = {
let lab = UILabel()
lab.text = " "
lab.font = .systemFont(ofSize: 10, weight: .bold)
lab.textColor = UIColor(hexStr: "#293445")
lab.textAlignment = .center
lab.lineBreakMode = .byTruncatingTail
return lab
}()
lazy var memberPrevBtn: UIButton = {
let btn = UIButton(type: .system)
btn.setImage(UIImage(systemName: "chevron.left"), for: .normal)
btn.tintColor = UIColor(hexStr: "#9CA3AF")
return btn
}()
lazy var memberNextBtn: UIButton = {
let btn = UIButton(type: .system)
btn.setImage(UIImage(systemName: "chevron.right"), for: .normal)
btn.tintColor = UIColor(hexStr: "#9CA3AF")
return btn
}()
lazy var todayCard: UIView = {
let view = UIView()
view.backgroundColor = .white
view.cornerRadius = 16
let title = UILabel()
title.text = "今日锁定应用"
title.font = .systemFont(ofSize: 16, weight: .bold)
title.textColor = UIColor(hexStr: "#293445")
view.addSubview(title)
title.layoutChain.top(21).left(23)
view.addSubview(todayCountLab)
view.addSubview(todayUnitLab)
todayCountLab.layoutChain
.leftToView(title, offset: 4)
.bottom(10)
todayUnitLab.layoutChain
.leftToRightOfView(todayCountLab, offset: 7)
.bottomToView(todayCountLab, offset: -12)
return view
}()
lazy var todayCountLab: UILabel = {
let lab = UILabel()
lab.text = "0"
lab.font = .systemFont(ofSize: 50, weight: .heavy)
lab.textColor = UIColor(hexStr: "#00ADFE")
return lab
}()
lazy var todayUnitLab: UILabel = {
let lab = UILabel()
lab.text = ""
lab.font = .systemFont(ofSize: 16, weight: .bold)
lab.textColor = UIColor(hexStr: "#293445")
return lab
}()
lazy var appsSectionTitle: UIView = {
makeSectionTitle("锁定应用")
}()
lazy var appsCard: UIView = {
let view = UIView()
view.backgroundColor = .white
view.cornerRadius = 26
return view
}()
lazy var appsHeaderRow: UIView = {
let row = UIView()
let left = UILabel()
left.text = "选择锁定TA的app"
left.font = .systemFont(ofSize: 14, weight: .medium)
left.textColor = UIColor(hexStr: "#293445")
row.addSubview(left)
left.layoutChain.left().centerY()
row.addSubview(notFetchedView)
notFetchedView.layoutChain.right().centerY().height(28)
row.layoutChain.height(28)
return row
}()
lazy var notFetchedView: UIView = {
let view = UIView()
let warn = UIView()
warn.backgroundColor = UIColor(hexStr: "#FA5151")
warn.cornerRadius = 5
let warnText = UILabel()
warnText.text = "!"
warnText.textColor = .white
warnText.font = .systemFont(ofSize: 8)
view.addSubview(warn)
warn.addSubview(warnText)
warnText.layoutChain.centerX().centerY()
let notFetchedText = UILabel()
notFetchedText.text = "未获取"
notFetchedText.textColor = UIColor(hexStr: "#293445")
notFetchedText.font = .systemFont(ofSize: 12, weight: .medium)
view.addSubview(notFetchedText)
let arrow = UIImageView(image: UIImage(named: "LockDistract/arrow_right"))
view.addSubview(arrow)
view.addSubview(notFetchedText)
arrow.layoutChain
.right(14)
.width(10)
.heightToWidth(1)
.centerY()
notFetchedText.layoutChain
.rightToLeftOfView(arrow)
.centerY()
warn.layoutChain
.rightToLeftOfView(notFetchedText, offset: -4)
.centerY()
.width(10).height(10)
return view
}()
lazy var unknownAppIcon: UIImageView = {
let iv = UIImageView(image: UIImage(named: "LockDistract/app_unknown"))
iv.contentMode = .scaleAspectFit
return iv
}()
lazy var styleSectionTitle: UIView = {
makeSectionTitle("锁定界面样式")
}()
lazy var styleCard: UIView = {
let card = UIView()
card.backgroundColor = .white
card.cornerRadius = 26
let wallLab = UILabel()
wallLab.text = "锁定壁纸图片"
wallLab.font = .systemFont(ofSize: 13, weight: .medium)
wallLab.textColor = UIColor(hexStr: "#8A94A6")
card.addSubview(wallLab)
wallLab.layoutChain.top(16).left(14)
card.addSubview(wallpaperCV)
wallpaperCV.layoutChain
.topToBottomOfView(wallLab, offset: 10)
.edgesHorzontal(14)
.height(74)
let copyLab = UILabel()
copyLab.text = "锁定文案"
copyLab.font = .systemFont(ofSize: 13, weight: .medium)
copyLab.textColor = UIColor(hexStr: "#8A94A6")
card.addSubview(copyLab)
copyLab.layoutChain.topToBottomOfView(wallpaperCV, offset: 16).left(14)
let input = UIView()
input.backgroundColor = UIColor(hexStr: "#F5F6F8")
input.cornerRadius = 12
card.addSubview(input)
input.layoutChain
.topToBottomOfView(copyLab, offset: 10)
.edgesHorzontal(14)
.height(44)
.bottom(16)
input.addSubview(copyTF)
input.addSubview(copyCountLab)
copyCountLab.layoutChain.centerY().right(12).width(35)
copyTF.layoutChain.edgesVertical().left(12).rightToLeftOfView(copyCountLab, offset: -8)
return card
}()
lazy var wallpaperCV: UICollectionView = {
let layout = UICollectionViewFlowLayout()
layout.scrollDirection = .horizontal
layout.itemSize = CGSize(width: 50, height: 74)
layout.minimumLineSpacing = 12
layout.minimumInteritemSpacing = 0
let cv = UICollectionView(frame: .zero, collectionViewLayout: layout)
cv.backgroundColor = .clear
cv.showsHorizontalScrollIndicator = false
cv.register(LockDistractWallpaperCell.self)
cv.dataSource = self
cv.delegate = self
return cv
}()
lazy var copyTF: UITextField = {
let tf = UITextField()
tf.font = .systemFont(ofSize: 14, weight: .medium)
tf.textColor = UIColor(hexStr: "#293445")
tf.placeholderColor(placeholder: "随便说点什么吧~",
color: UIColor(hexStr: "#999999"),
font: .systemFont(ofSize: 14, weight: .medium))
return tf
}()
lazy var copyCountLab: UILabel = {
let lab = UILabel()
lab.text = "0/20"
lab.font = .systemFont(ofSize: 14, weight: .medium)
lab.textColor = UIColor(hexStr: "#AAAAAA")
return lab
}()
lazy var tipRow: UIView = {
let row = UIView()
let icon = UIImageView(image: UIImage(systemName: "info.circle.fill"))
icon.tintColor = UIColor(hexStr: "#16B3FF")
let lab = UILabel()
lab.text = "锁定功能只有在圈主的情况下才能使用哟~"
lab.font = .systemFont(ofSize: 12, weight: .regular)
lab.textColor = UIColor(hexStr: "#00ADFE")
lab.numberOfLines = 0
row.addSubview(icon)
row.addSubview(lab)
icon.layoutChain.left().top(1).width(14).height(14)
lab.layoutChain.leftToRightOfView(icon, offset: 6).right().top().bottom()
return row
}()
lazy var lockBtn: UIButton = {
let btn = UIButton(type: .custom)
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)
btn.cornerRadius = 20
return btn
}()
private func makeSectionTitle(_ text: String) -> UIView {
let row = UIView()
let star = UIImageView(image: UIImage(named: "LockDistract/section_star"))
// SF Symbol LockDistract/section_star
// let config = UIImage.SymbolConfiguration(pointSize: 12, weight: .bold)
// star.image = UIImage(systemName: "sparkle", withConfiguration: config)
// star.tintColor = UIColor(hexStr: "#16B3FF")
// star.contentMode = .scaleAspectFit
let lab = UILabel()
lab.text = text
lab.font = .systemFont(ofSize: 16, weight: .bold)
lab.textColor = UIColor(hexStr: "#1F2A44")
row.addSubview(star)
row.addSubview(lab)
star.layoutChain.left().centerY().width(14).height(14)
lab.layoutChain.leftToRightOfView(star, offset: 6).right().centerY()
row.layoutChain.height(22)
return row
}
}
extension LockDistractView: UICollectionViewDataSource, UICollectionViewDelegate {
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
wallpaperNames.count
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(for: indexPath) as LockDistractWallpaperCell
cell.configure(imageName: wallpaperNames[indexPath.item],
isSelected: indexPath.item == selectedWallpaperIndex)
return cell
}
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
selectedWallpaperIndex = indexPath.item
collectionView.reloadData()
}
}
final class LockDistractWallpaperCell: UICollectionViewCell {
private let frameView: UIView = {
let view = UIView()
view.backgroundColor = UIColor(hexStr: "#F6F6F6")
view.cornerRadius = 14
return view
}()
private let imageView: UIImageView = {
let iv = UIImageView()
iv.contentMode = .scaleAspectFill
iv.clipsToBounds = true
iv.cornerRadius = 10
return iv
}()
override init(frame: CGRect) {
super.init(frame: frame)
contentView.addSubview(frameView)
frameView.addSubview(imageView)
frameView.layoutChain.edges()
imageView.layoutChain
.centerY()
.centerX()
.width(40)
.height(40)
}
required init?(coder: NSCoder) { fatalError("init(coder:) has not been implemented") }
func configure(imageName: String, isSelected: Bool) {
imageView.image = UIImage(named: imageName)
frameView.backgroundColor = UIColor(hexStr: isSelected ? "#EAF8FF" : "#F6F6F6")
frameView.borderWidth = isSelected ? 1 : 0
frameView.borderColor = UIColor(hexStr: isSelected ? "#00ADFE" : "")
}
}