| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226 |
- //
- // LNHourRangePickerPanel.swift
- // Gami
- //
- // Created by OneeChan on 2026/1/23.
- //
- import Foundation
- import UIKit
- import SnapKit
- class LNHourRangePickerPanel: LNPopupView {
- private let titleLabel = UILabel()
- private let descLabel = UILabel()
-
- private let fromPicker = UIPickerView()
- private let toPicker = UIPickerView()
-
- var isRelative: Bool = true
- var handler: ((Int, Int) -> Void)?
-
- override init(frame: CGRect) {
- super.init(frame: frame)
-
- setupViews()
- }
-
- func setTitles(_ title: String, desc: String? = nil) {
- titleLabel.text = title
- descLabel.text = desc
- descLabel.isHidden = desc?.isEmpty != false
- }
-
- func setDefault(from: Int, to: Int) {
- fromPicker.selectRow(from, inComponent: 0, animated: false)
- let toIndex = if isRelative {
- to - from - 1
- } else {
- to
- }
- toPicker.selectRow(toIndex, inComponent: 0, animated: false)
- }
-
- required init?(coder: NSCoder) {
- fatalError("init(coder:) has not been implemented")
- }
- }
- extension LNHourRangePickerPanel: UIPickerViewDataSource, UIPickerViewDelegate {
- func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
- if pickerView == toPicker, isRelative {
- 24
- } else {
- 24
- }
- }
-
- func numberOfComponents(in pickerView: UIPickerView) -> Int {
- 1
- }
-
- func pickerView(_ pickerView: UIPickerView, viewForRow row: Int, forComponent component: Int, reusing view: UIView?) -> UIView {
- let itemView = view as? LNHourRangeItemView ?? LNHourRangeItemView()
-
- if pickerView == fromPicker {
- itemView.titleLabel.text = String(format: "%02d:00", row)
- } else if pickerView == toPicker {
- if isRelative {
- let from = fromPicker.selectedRow(inComponent: 0)
- itemView.titleLabel.text = String(format: "%02d:00", (row + from + 1) % 24)
- } else {
- itemView.titleLabel.text = String(format: "%02d:00", row)
- }
- }
-
- return itemView
- }
-
- func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
- if pickerView == fromPicker, isRelative {
- toPicker.reloadComponent(0)
- }
- }
-
- func pickerView(_ pickerView: UIPickerView, rowHeightForComponent component: Int) -> CGFloat {
- 52
- }
- }
- extension LNHourRangePickerPanel {
- private func setupViews() {
- let header = UIView()
- container.addSubview(header)
- header.snp.makeConstraints { make in
- make.horizontalEdges.equalToSuperview()
- make.top.equalToSuperview()
- }
-
- let stackView = UIStackView()
- stackView.axis = .vertical
- stackView.spacing = 4
- header.addSubview(stackView)
- stackView.snp.makeConstraints { make in
- make.horizontalEdges.equalToSuperview().inset(22)
- make.verticalEdges.equalToSuperview().inset(9)
- }
-
- titleLabel.font = .heading_h3
- titleLabel.textColor = .text_5
- titleLabel.textAlignment = .center
- stackView.addArrangedSubview(titleLabel)
-
- descLabel.font = .body_s
- descLabel.textColor = .text_4
- descLabel.textAlignment = .center
- descLabel.numberOfLines = 0
- stackView.addArrangedSubview(descLabel)
-
- let pickerView = UIView()
- container.addSubview(pickerView)
- pickerView.snp.makeConstraints { make in
- make.horizontalEdges.equalToSuperview().inset(20)
- make.top.equalTo(header.snp.bottom)
- make.height.equalTo(150)
- }
-
- let textView = UIView()
- pickerView.addSubview(textView)
- textView.snp.makeConstraints { make in
- make.center.equalToSuperview()
- }
-
- let toLabel = UILabel()
- toLabel.font = .body_l
- toLabel.textColor = .text_5
- toLabel.text = .init(key: "B00081")
- toLabel.textAlignment = .center
- toLabel.setContentHuggingPriority(.required, for: .horizontal)
- toLabel.setContentCompressionResistancePriority(.required, for: .horizontal)
- textView.addSubview(toLabel)
- toLabel.snp.makeConstraints { make in
- make.horizontalEdges.equalToSuperview().inset(12)
- make.verticalEdges.equalToSuperview()
- }
-
- fromPicker.delegate = self
- fromPicker.dataSource = self
- pickerView.addSubview(fromPicker)
- fromPicker.snp.makeConstraints { make in
- make.verticalEdges.equalToSuperview()
- make.leading.equalToSuperview()
- make.trailing.equalTo(textView.snp.leading)
- }
-
- toPicker.delegate = self
- toPicker.dataSource = self
- pickerView.addSubview(toPicker)
- toPicker.snp.makeConstraints { make in
- make.verticalEdges.equalToSuperview()
- make.trailing.equalToSuperview()
- make.leading.equalTo(textView.snp.trailing)
- make.width.equalTo(fromPicker)
- }
-
- let confirm = UIButton()
- confirm.setTitle(.init(key: "A00002"), for: .normal)
- confirm.setTitleColor(.text_1, for: .normal)
- confirm.setBackgroundImage(.primary_8, for: .normal)
- confirm.layer.cornerRadius = 23.5
- confirm.titleLabel?.font = .heading_h3
- confirm.clipsToBounds = true
- confirm.addAction(UIAction(handler: { [weak self] _ in
- guard let self else { return }
- dismiss()
- let from = fromPicker.selectedRow(inComponent: 0)
- var to = toPicker.selectedRow(inComponent: 0)
- if isRelative {
- to += from + 1
- }
- handler?(from, to)
- }), for: .touchUpInside)
- container.addSubview(confirm)
- confirm.snp.makeConstraints { make in
- make.horizontalEdges.equalToSuperview().inset(22)
- make.bottom.equalToSuperview().offset(commonBottomInset)
- make.height.equalTo(47)
- make.top.equalTo(pickerView.snp.bottom).offset(4)
- }
-
- DispatchQueue.main.async { [weak self] in
- guard let self else { return }
- fromPicker.subviews.forEach {
- if $0.subviews.isEmpty {
- $0.backgroundColor = .clear
- }
- }
- toPicker.subviews.forEach {
- if $0.subviews.isEmpty {
- $0.backgroundColor = .clear
- }
- }
- }
- }
- }
- private class LNHourRangeItemView: UIView {
- let titleLabel = UILabel()
-
- override init(frame: CGRect) {
- super.init(frame: frame)
-
- titleLabel.font = .body_xl
- titleLabel.textColor = .text_5
- titleLabel.textAlignment = .center
- addSubview(titleLabel)
- titleLabel.snp.makeConstraints { make in
- make.center.equalToSuperview()
- }
- }
-
- required init?(coder: NSCoder) {
- fatalError("init(coder:) has not been implemented")
- }
- }
|