chat setting font size

This commit is contained in:
mh 2025-10-31 18:53:40 +08:00
parent 4c4c578d0b
commit 1cedc98838
1 changed files with 222 additions and 41 deletions

View File

@ -6,6 +6,7 @@
// //
import UIKit import UIKit
import SnapKit
// font // font
struct FontRow: RowModel { struct FontRow: RowModel {
@ -13,57 +14,129 @@ struct FontRow: RowModel {
let icon: String let icon: String
let title: String let title: String
var cellReuseID: String { "ChatFontCell" } var cellReuseID: String { "ChatFontCell" }
func cellHeight(tableWidth: CGFloat) -> CGFloat { 50 } func cellHeight(tableWidth: CGFloat) -> CGFloat { 80 }
} }
class ChatFontCell: ChatSettingBaseCell, CellConfigurable { class ChatFontCell: ChatSettingBaseCell, CellConfigurable {
private var currentFontSize: Int = 20
private let minFontSize: Int = 10
private let maxFontSize: Int = 30
lazy var iconImgView: UIImageView = { lazy var iconImgView: UIImageView = {
let imgView = UIImageView(image: UIImage(named: "role_exchange_mode")) let imgView = UIImageView(image: UIImage(named: "role_font"))
return imgView return imgView
}() }()
lazy var titleLab: UILabel = { lazy var titleLab: UILabel = {
let lab = UILabel() let lab = UILabel()
lab.text = "XL-0826-32K" lab.text = "Font size"
lab.font = UIFont.boldSystemFont(ofSize: 14) lab.font = UIFont.systemFont(ofSize: 14)
lab.textColor = UIColor(hex: "#666666") lab.textColor = UIColor(hex: "#666666")
return lab return lab
}() }()
lazy var fontSub: UIButton = { lazy var fontSizeLab: UILabel = {
let btn = UIButton()
btn.setImage(UIImage(named: "role_setting_font_sub"), for: .normal)
btn.addTarget(self, action: #selector(fontSubTap), for: .touchUpInside)
return btn
}()
lazy var fontAdd: UIButton = {
let btn = UIButton()
btn.setImage(UIImage(named: "role_setting_font_add"), for: .normal)
btn.addTarget(self, action: #selector(fontAddTap), for: .touchUpInside)
return btn
}()
lazy var fontLab: UILabel = {
let lab = UILabel() let lab = UILabel()
lab.text = "20" lab.text = "20"
lab.font = UIFont.systemFont(ofSize: 14) lab.font = UIFont.systemFont(ofSize: 14)
lab.textColor = UIColor(hex: "#999999") lab.textColor = UIColor(hex: "#999999")
lab.textAlignment = .center lab.textAlignment = .right
return lab return lab
}() }()
lazy var sliderContainer: UIView = {
let view = UIView()
return view
}()
lazy var minusButton: UIButton = {
let btn = UIButton(type: .custom)
// 使
if let image = UIImage(named: "role_setting_font_sub") {
btn.setImage(image, for: .normal)
} else {
btn.setTitle("A-", for: .normal)
btn.setTitleColor(UIColor(hex: "#0066FF"), for: .normal)
btn.titleLabel?.font = UIFont.systemFont(ofSize: 14, weight: .medium)
}
btn.addTarget(self, action: #selector(decreaseFontSize), for: .touchUpInside)
return btn
}()
lazy var plusButton: UIButton = {
let btn = UIButton(type: .custom)
// 使
if let image = UIImage(named: "role_setting_font_add") {
btn.setImage(image, for: .normal)
} else {
btn.setTitle("A+", for: .normal)
btn.setTitleColor(UIColor(hex: "#0066FF"), for: .normal)
btn.titleLabel?.font = UIFont.systemFont(ofSize: 14, weight: .medium)
}
btn.addTarget(self, action: #selector(increaseFontSize), for: .touchUpInside)
return btn
}()
lazy var slider: UISlider = {
let slider = UISlider()
slider.minimumValue = Float(minFontSize)
slider.maximumValue = Float(maxFontSize)
slider.value = Float(currentFontSize)
// track
slider.minimumTrackTintColor = UIColor(hex: "#E0E0E0")
slider.maximumTrackTintColor = UIColor(hex: "#E0E0E0")
// thumb
let thumbSize: CGFloat = 24
UIGraphicsBeginImageContextWithOptions(CGSize(width: thumbSize, height: thumbSize), false, 0.0)
if let context = UIGraphicsGetCurrentContext() {
context.setFillColor(UIColor.white.cgColor)
context.fillEllipse(in: CGRect(x: 0, y: 0, width: thumbSize, height: thumbSize))
// 使thumb
context.setShadow(offset: CGSize(width: 0, height: 1), blur: 2, color: UIColor.black.withAlphaComponent(0.2).cgColor)
}
let thumbImage = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
slider.setThumbImage(thumbImage, for: .normal)
slider.setThumbImage(thumbImage, for: .highlighted)
//
slider.addTarget(self, action: #selector(sliderValueChanged(_:)), for: .valueChanged)
slider.addTarget(self, action: #selector(sliderTouchDown(_:)), for: .touchDown)
slider.addTarget(self, action: #selector(sliderTouchUp(_:)), for: [.touchUpInside, .touchUpOutside])
return slider
}()
private lazy var tickMarksContainer: UIView = {
let view = UIView()
view.backgroundColor = .clear
return view
}()
private var tickMarks: [UIView] = []
func configure(with row: RowModel) { func configure(with row: RowModel) {
guard let row = row as? FontRow else { return } guard let row = row as? FontRow else { return }
titleLab.text = row.title titleLab.text = row.title
iconImgView.image = UIImage(named: row.icon) iconImgView.image = UIImage(named: row.icon)
//
updateContainerHeight(80)
if let size = Int(row.count) {
currentFontSize = max(minFontSize, min(maxFontSize, size))
updateFontSize(currentFontSize, updateSlider: true)
}
} }
override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) { override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
super.init(style: style, reuseIdentifier: reuseIdentifier) super.init(style: style, reuseIdentifier: reuseIdentifier)
configureViews() configureViews()
setupTickMarks()
} }
required init?(coder: NSCoder) { required init?(coder: NSCoder) {
@ -71,48 +144,156 @@ class ChatFontCell: ChatSettingBaseCell, CellConfigurable {
} }
func configureViews() { func configureViews() {
containerView.addSubview(iconImgView) containerView.addSubview(iconImgView)
containerView.addSubview(titleLab) containerView.addSubview(titleLab)
containerView.addSubview(fontSub) containerView.addSubview(fontSizeLab)
containerView.addSubview(fontAdd) containerView.addSubview(sliderContainer)
containerView.addSubview(fontLab)
// slider tick marks
sliderContainer.addSubview(minusButton)
sliderContainer.addSubview(plusButton)
sliderContainer.addSubview(slider)
sliderContainer.addSubview(tickMarksContainer)
// tick marks
sliderContainer.bringSubviewToFront(tickMarksContainer)
iconImgView.snp.makeConstraints { make in iconImgView.snp.makeConstraints { make in
make.centerY.equalToSuperview() make.top.equalToSuperview().offset(12)
make.left.equalToSuperview().offset(12) make.left.equalToSuperview().offset(12)
make.width.height.equalTo(21) make.width.height.equalTo(21)
} }
titleLab.snp.makeConstraints { make in titleLab.snp.makeConstraints { make in
make.centerY.equalToSuperview() make.centerY.equalTo(iconImgView)
make.left.equalTo(iconImgView.snp.right).offset(9) make.left.equalTo(iconImgView.snp.right).offset(9)
make.right.equalTo(fontSub.snp.left).offset(-5)
} }
fontAdd.snp.makeConstraints { make in fontSizeLab.snp.makeConstraints { make in
make.centerY.equalToSuperview() make.centerY.equalTo(iconImgView)
make.right.equalToSuperview().inset(20) make.right.equalToSuperview().inset(20)
make.width.height.equalTo(40)
} }
fontLab.snp.makeConstraints { make in sliderContainer.snp.makeConstraints { make in
make.top.equalTo(iconImgView.snp.bottom).offset(12)
make.left.right.equalToSuperview().inset(12)
make.bottom.equalToSuperview().inset(12)
make.height.equalTo(30)
}
minusButton.snp.makeConstraints { make in
make.left.centerY.equalToSuperview()
make.width.equalTo(30)
}
plusButton.snp.makeConstraints { make in
make.right.centerY.equalToSuperview()
make.width.equalTo(30)
}
slider.snp.makeConstraints { make in
make.left.equalTo(minusButton.snp.right).offset(8)
make.right.equalTo(plusButton.snp.left).offset(-8)
make.centerY.equalToSuperview() make.centerY.equalToSuperview()
make.right.equalTo(fontAdd.snp.left).offset(-10) make.height.equalTo(30)
} }
fontSub.snp.makeConstraints { make in // tick marks slider 穿 slider
make.centerY.equalToSuperview() tickMarksContainer.snp.makeConstraints { make in
make.right.equalTo(fontLab.snp.left).offset(-10) make.left.right.equalTo(slider)
make.width.height.equalTo(40) make.centerY.equalTo(slider)
make.height.equalTo(slider).offset(4) // tick marks
}
// tick marks
tickMarksContainer.isUserInteractionEnabled = false
}
private func setupTickMarks() {
// 5tick marks
let tickCount = 5
for _ in 0..<tickCount {
let tick = UIView()
tick.backgroundColor = UIColor(hex: "#CCCCCC")
tick.layer.cornerRadius = 2
tick.isUserInteractionEnabled = false //
tickMarksContainer.addSubview(tick)
tickMarks.append(tick)
} }
} }
@objc func fontSubTap() { override func layoutSubviews() {
print("sub sub sub") super.layoutSubviews()
// tick markslayout
updateTickMarksLayout()
} }
@objc func fontAddTap() { private func updateTickMarksLayout() {
print("add add add") guard tickMarks.count == 5, tickMarksContainer.bounds.width > 0 else { return }
let totalWidth = tickMarksContainer.bounds.width
// 54
let spacing = totalWidth / 4.0
let tickSize: CGFloat = 4
let centerY = tickMarksContainer.bounds.height / 2.0
for (index, tick) in tickMarks.enumerated() {
let centerX = CGFloat(index) * spacing
tick.frame = CGRect(
x: centerX - tickSize / 2.0,
y: centerY - tickSize / 2.0,
width: tickSize,
height: tickSize
)
tick.layer.cornerRadius = tickSize / 2.0
}
}
@objc private func decreaseFontSize() {
if currentFontSize > minFontSize {
currentFontSize -= 1
updateFontSize(currentFontSize, updateSlider: true)
}
}
@objc private func increaseFontSize() {
if currentFontSize < maxFontSize {
currentFontSize += 1
updateFontSize(currentFontSize, updateSlider: true)
}
}
@objc private func sliderValueChanged(_ slider: UISlider) {
//
let newValue = Int(round(slider.value))
if newValue != currentFontSize {
currentFontSize = newValue
updateFontSize(currentFontSize, updateSlider: false) // slider
}
}
@objc private func sliderTouchDown(_ slider: UISlider) {
//
}
@objc private func sliderTouchUp(_ slider: UISlider) {
//
let newValue = Int(round(slider.value))
currentFontSize = newValue
updateFontSize(currentFontSize, updateSlider: true)
}
private func updateFontSize(_ size: Int, updateSlider: Bool = true) {
fontSizeLab.text = "\(size)"
if updateSlider {
slider.setValue(Float(size), animated: false)
}
//
// minusButton.isEnabled = size > minFontSize
// plusButton.isEnabled = size < maxFontSize
//
// delegate?.fontSizeChanged(to: size)
} }
} }