Skip to content

Commit eca7f10

Browse files
design: datepicker UI 변경 및 사소한 로직 수정
1 parent 148b437 commit eca7f10

6 files changed

Lines changed: 104 additions & 15 deletions

File tree

Koin/Core/Extensions/UIViewController+.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
import UIKit.UIViewController
99

1010
extension UIViewController {
11-
func hideKeyboardWhenTappedAround() {
11+
@objc func hideKeyboardWhenTappedAround() {
1212
let tap = UITapGestureRecognizer(target: self, action: #selector(UIViewController.dismissKeyboard))
1313
tap.cancelsTouchesInView = false
1414
view.addGestureRecognizer(tap)

Koin/Presentation/LostItem/EditLostItem/EditLostItemViewController.swift

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,11 @@ final class EditLostItemViewController: UIViewController {
8787
configureNavigationBar(style: .empty)
8888
}
8989

90+
override func hideKeyboardWhenTappedAround() {
91+
super.hideKeyboardWhenTappedAround()
92+
foundDateView.dismissDropdown()
93+
}
94+
9095
private func bind() {
9196
viewModel.transform(with: inputSubject.eraseToAnyPublisher()).sink { [weak self] output in
9297
guard let self else { return }
@@ -120,6 +125,13 @@ final class EditLostItemViewController: UIViewController {
120125
contentView.shouldDismissDropDownPublisher.sink { [weak self] in
121126
self?.foundDateView.dismissDropdown()
122127
}.store(in: &subscriptions)
128+
129+
foundDateView.focusDropdownPublisher.sink { [weak self] targetView in
130+
guard let self else { return }
131+
var rect = targetView.convert(targetView.bounds, to: scrollView)
132+
rect.size.height += 15
133+
scrollView.scrollRectToVisible(rect, animated: true)
134+
}.store(in: &subscriptions)
123135
}
124136
}
125137

@@ -130,6 +142,9 @@ extension EditLostItemViewController {
130142
}
131143

132144
@objc private func editButtonTapped() {
145+
dismissKeyboard()
146+
foundDateView.dismissDropdown()
147+
133148
if foundDateView.isValid && foundPlaceView.isValid {
134149
let imageUrls = imagesView.imageUploadCollectionView.imageUrls
135150
let category = categoryView.selectedCategory

Koin/Presentation/LostItem/EditLostItem/SubViews/EditLostItemFoundDateView.swift

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ final class EditLostItemFoundDateView: ExtendedTouchAreaView {
1818
dateWarningLabel.isHidden
1919
}
2020
private(set) var foundDate: String
21+
let focusDropdownPublisher = PassthroughSubject<UIView, Never>()
2122

2223
// MARK: - UI Components
2324
private lazy var dateLabel = UILabel().then {
@@ -106,6 +107,9 @@ final class EditLostItemFoundDateView: ExtendedTouchAreaView {
106107
dropdownView.valueChangedPublisher.sink { [weak self] in
107108
self?.dropdownValueChanged()
108109
}.store(in: &subscriptions)
110+
dropdownView.dismissDropdownPublisher.sink { [weak self] in
111+
self?.dismissDropdown()
112+
}.store(in: &subscriptions)
109113
}
110114

111115
private func setAddTargets() {
@@ -116,6 +120,7 @@ final class EditLostItemFoundDateView: ExtendedTouchAreaView {
116120
if dropdownView.isHidden {
117121
presentDropdown()
118122
endEditing(true)
123+
focusDropdownPublisher.send(dropdownView)
119124
} else {
120125
dismissDropdown()
121126
}
@@ -134,7 +139,7 @@ final class EditLostItemFoundDateView: ExtendedTouchAreaView {
134139
}
135140

136141
@objc func dismissDropdown() {
137-
UIView.animate(withDuration: 0.1) { [weak self] in
142+
UIView.animate(withDuration: 0.2) { [weak self] in
138143
guard let self else { return }
139144
dropdownView.alpha = 0
140145
dropdownView.transform = CGAffineTransform(translationX: 0, y: -20)

Koin/Presentation/LostItem/PostLostItem/PostLostItemViewController.swift

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -187,6 +187,8 @@ extension PostLostItemViewController: UITextViewDelegate, PHPickerViewController
187187
return allCellData
188188
}
189189
private func writeButtonTapped() {
190+
dismissKeyboardDropdown()
191+
190192
var isAllValid = true
191193
for index in 0..<addLostItemCollectionView.numberOfItems(inSection: 0) {
192194
let indexPath = IndexPath(item: index, section: 0)

Koin/Presentation/LostItem/PostLostItem/SubViews/AddLostItemCollectionView/AddLostItemCollectionViewCell.swift

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -224,6 +224,9 @@ final class AddLostItemCollectionViewCell: UICollectionViewCell {
224224
dropdownView.valueChangedPublisher.sink { [weak self] in
225225
self?.dropdownValueChanged()
226226
}.store(in: &cancellable)
227+
dropdownView.dismissDropdownPublisher.sink { [weak self] in
228+
self?.shouldDismissDropDownPublisher.send(nil)
229+
}.store(in: &cancellable)
227230
}
228231
required init?(coder: NSCoder) {
229232
fatalError("init(coder:) has not been implemented")

Koin/Presentation/LostItem/PostLostItem/SubViews/DatePickerDropdownView.swift

Lines changed: 77 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -7,45 +7,109 @@
77

88
import UIKit
99
import Combine
10+
import SnapKit
1011

1112
final class DatePickerDropdownView: UIView {
1213

14+
// MARK: - Properties
1315
let valueChangedPublisher = PassthroughSubject<Void, Never>()
16+
let dismissDropdownPublisher = PassthroughSubject<Void, Never>()
17+
1418
var dateValue: Date {
1519
get { return datePicker.date }
1620
set { datePicker.date = newValue }
1721
}
1822

23+
// MARK: - UI Components
1924
private let datePicker = UIDatePicker().then {
2025
$0.datePickerMode = .date
2126
$0.preferredDatePickerStyle = .wheels
2227
$0.locale = Locale(identifier: "ko_KR")
2328
$0.minimumDate = Calendar.current.date(byAdding: .year, value: -10, to: Date())
2429
$0.maximumDate = Date()
2530
}
31+
private let separatorView = UIView().then {
32+
$0.backgroundColor = .appColor(.neutral200)
33+
}
34+
private let resetButton = UIButton().then {
35+
$0.setAttributedTitle(NSAttributedString(
36+
string: "초기화",
37+
attributes: [
38+
.font : UIFont.appFont(.pretendardMedium, size: 14),
39+
.foregroundColor : UIColor.appColor(.primary600)
40+
]), for: .normal)
41+
}
42+
private let applyButton = UIButton().then {
43+
$0.setAttributedTitle(NSAttributedString(
44+
string: "확인",
45+
attributes: [
46+
.font : UIFont.appFont(.pretendardMedium, size: 14),
47+
.foregroundColor : UIColor.appColor(.primary600)
48+
]), for: .normal)
49+
}
2650

27-
var onDateSelected: ((Date) -> Void)?
28-
51+
// MARK: - Initializer
2952
override init(frame: CGRect) {
3053
super.init(frame: frame)
31-
setupView()
54+
configureView()
55+
setAddTargets()
3256
datePicker.addTarget(self, action: #selector(datePickerValueChagned), for: .valueChanged)
3357
}
3458

3559
required init?(coder: NSCoder) {
3660
fatalError("init(coder:) has not been implemented")
3761
}
62+
}
63+
64+
extension DatePickerDropdownView {
65+
66+
private func setAddTargets() {
67+
resetButton.addTarget(self, action: #selector(resetButtonTapped), for: .touchUpInside)
68+
applyButton.addTarget(self, action: #selector(applyButtonTapped), for: .touchUpInside)
69+
}
70+
71+
@objc private func resetButtonTapped() {
72+
dateValue = Date()
73+
datePickerValueChagned()
74+
}
75+
76+
@objc private func applyButtonTapped() {
77+
dismissDropdownPublisher.send()
78+
}
79+
}
80+
81+
extension DatePickerDropdownView {
82+
83+
private func setUpLayouts() {
84+
[datePicker, separatorView, applyButton, resetButton].forEach {
85+
addSubview($0)
86+
}
87+
}
88+
private func setUpConstraints() {
89+
datePicker.snp.makeConstraints {
90+
$0.top.leading.trailing.equalToSuperview()
91+
$0.height.equalTo(114)
92+
}
93+
separatorView.snp.makeConstraints {
94+
$0.top.equalTo(datePicker.snp.bottom)
95+
$0.leading.trailing.equalToSuperview()
96+
$0.height.equalTo(1)
97+
}
98+
applyButton.snp.makeConstraints {
99+
$0.top.equalTo(separatorView.snp.bottom).offset(10)
100+
$0.trailing.equalToSuperview().offset(-40)
101+
$0.bottom.equalToSuperview().offset(-14)
102+
$0.height.equalTo(22)
103+
}
104+
resetButton.snp.makeConstraints {
105+
$0.height.centerY.equalTo(applyButton)
106+
$0.trailing.equalTo(applyButton.snp.leading).offset(-16)
107+
}
108+
}
38109

39-
private func setupView() {
40-
addSubview(datePicker)
41-
datePicker.translatesAutoresizingMaskIntoConstraints = false
42-
NSLayoutConstraint.activate([
43-
datePicker.leadingAnchor.constraint(equalTo: leadingAnchor),
44-
datePicker.trailingAnchor.constraint(equalTo: trailingAnchor),
45-
datePicker.topAnchor.constraint(equalTo: topAnchor),
46-
datePicker.bottomAnchor.constraint(equalTo: bottomAnchor),
47-
heightAnchor.constraint(equalToConstant: 114)
48-
])
110+
private func configureView(){
111+
setUpLayouts()
112+
setUpConstraints()
49113

50114
DispatchQueue.main.async {
51115
self.updatePickerTextColor()

0 commit comments

Comments
 (0)