Skip to content

Commit c02e980

Browse files
authored
Merge pull request #267 from thingineeer/#265-fastlane
[Feat] #265 - fastlane & 유저 QA 진행
2 parents f564c5f + 040f837 commit c02e980

File tree

10 files changed

+270
-150
lines changed

10 files changed

+270
-150
lines changed

.gitignore

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,11 @@ Dependencies/
8585
**/fastlane/report.xml
8686
**/fastlane/Preview.html
8787
**/fastlane/screenshots/**/*.png
88+
**/fastlane/screenshots/
8889
**/fastlane/BuildOutputs
90+
**/fastlane/metadata
91+
**/fastlane/Deliverfile
92+
8993

9094
**/fastlane/.env.default
9195

Runnect-iOS/Runnect-iOS.xcodeproj/project.pbxproj

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1703,7 +1703,7 @@
17031703
CODE_SIGN_IDENTITY = "Apple Development";
17041704
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
17051705
CODE_SIGN_STYLE = Manual;
1706-
CURRENT_PROJECT_VERSION = 2024.0319.2120;
1706+
CURRENT_PROJECT_VERSION = 2024.0402.1647;
17071707
DEVELOPMENT_TEAM = "";
17081708
"DEVELOPMENT_TEAM[sdk=iphoneos*]" = 8Q4H7X3Q58;
17091709
GENERATE_INFOPLIST_FILE = NO;
@@ -1747,7 +1747,7 @@
17471747
CODE_SIGN_IDENTITY = "Apple Development";
17481748
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
17491749
CODE_SIGN_STYLE = Manual;
1750-
CURRENT_PROJECT_VERSION = 2024.0319.2120;
1750+
CURRENT_PROJECT_VERSION = 2024.0402.1647;
17511751
DEVELOPMENT_TEAM = "";
17521752
"DEVELOPMENT_TEAM[sdk=iphoneos*]" = 8Q4H7X3Q58;
17531753
GENERATE_INFOPLIST_FILE = NO;

Runnect-iOS/Runnect-iOS/Global/Utils/Toast.swift

Lines changed: 34 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -2,16 +2,22 @@
22
// Toast.swift
33
// Runnect-iOS
44
//
5-
// Created by sejin on 2022/12/31.
5+
// Created by 이명진 on 2024/03/25.
66
//
77

88
import UIKit
99

1010
import SnapKit
11+
import Then
1112

1213
public extension UIViewController {
13-
func showToast(message: String) {
14-
Toast.show(message: message, view: self.view, safeAreaBottomInset: self.safeAreaBottomInset())
14+
func showToast(message: String, heightOffset: CGFloat = 0) {
15+
Toast.show(
16+
message: message,
17+
view: self.view,
18+
safeAreaBottomInset: self.safeAreaBottomInset(),
19+
heightOffset: heightOffset
20+
)
1521
}
1622

1723
func showNetworkFailureToast() {
@@ -20,34 +26,39 @@ public extension UIViewController {
2026
}
2127

2228
public class Toast {
23-
public static func show(message: String, view: UIView, safeAreaBottomInset: CGFloat = 0) {
24-
25-
let toastContainer = UIView()
26-
let toastLabel = UILabel()
27-
28-
toastContainer.backgroundColor = UIColor.g2.withAlphaComponent(0.7)
29-
toastContainer.alpha = 1.0
30-
toastContainer.layer.cornerRadius = 15
31-
toastContainer.clipsToBounds = true
32-
toastContainer.isUserInteractionEnabled = false
29+
public static func show(
30+
message: String,
31+
view: UIView,
32+
safeAreaBottomInset: CGFloat = 0,
33+
heightOffset: CGFloat = 0
34+
) {
35+
let toastContainer = UIView().then {
36+
$0.backgroundColor = UIColor.g2.withAlphaComponent(0.7)
37+
$0.alpha = 1.0
38+
$0.layer.cornerRadius = 15
39+
$0.clipsToBounds = true
40+
$0.isUserInteractionEnabled = false
41+
}
3342

34-
toastLabel.textColor = .m4
35-
toastLabel.font = .b4
36-
toastLabel.textAlignment = .center
37-
toastLabel.text = message
38-
toastLabel.clipsToBounds = true
39-
toastLabel.numberOfLines = 0
40-
toastLabel.sizeToFit()
43+
let toastLabel = UILabel().then {
44+
$0.textColor = .m4
45+
$0.font = .b4
46+
$0.textAlignment = .center
47+
$0.text = message
48+
$0.clipsToBounds = true
49+
$0.numberOfLines = 0
50+
$0.sizeToFit()
51+
}
4152

4253
toastContainer.addSubview(toastLabel)
4354
view.addSubview(toastContainer)
4455

45-
let toastConatinerWidth = toastLabel.intrinsicContentSize.width + 40.0
56+
let toastContainerWidth = toastLabel.intrinsicContentSize.width + 40.0
4657

4758
toastContainer.snp.makeConstraints {
4859
$0.centerX.equalToSuperview()
49-
$0.bottom.equalToSuperview().inset(safeAreaBottomInset+160)
50-
$0.width.equalTo(toastConatinerWidth)
60+
$0.bottom.equalToSuperview().inset(safeAreaBottomInset + 160 + heightOffset)
61+
$0.width.equalTo(toastContainerWidth)
5162
$0.height.equalTo(31)
5263
}
5364

Runnect-iOS/Runnect-iOS/Info.plist

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@
2121
<key>CFBundlePackageType</key>
2222
<string>$(PRODUCT_BUNDLE_PACKAGE_TYPE)</string>
2323
<key>CFBundleShortVersionString</key>
24-
<string>2.0.2</string>
24+
<string>2.0.3</string>
2525
<key>CFBundleURLTypes</key>
2626
<array>
2727
<dict>
@@ -46,7 +46,7 @@
4646
</dict>
4747
</array>
4848
<key>CFBundleVersion</key>
49-
<string>2024.0319.2120</string>
49+
<string>2024.0402.1647</string>
5050
<key>LSApplicationQueriesSchemes</key>
5151
<array>
5252
<string>kakaokompassauth</string>

Runnect-iOS/Runnect-iOS/Presentation/CourseDiscovery/Views/VC/CourseUploadVC.swift

Lines changed: 48 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ class CourseUploadVC: UIViewController {
4545
}
4646
private let distanceInfoView = CourseDetailInfoView(title: "거리", description: "0.0km")
4747
private let departureInfoView = CourseDetailInfoView(title: "출발지", description: "")
48-
private let placeholder = "코스에 대한 소개를 적어주세요.(난이도/풍경/지형)"
48+
private let placeholder = "코스에 대한 소개를 적어주세요.(난이도/풍경/지형)\n(최대 150자)"
4949

5050
let activityTextView = UITextView().then {
5151
$0.font = .b4
@@ -61,11 +61,10 @@ class CourseUploadVC: UIViewController {
6161
setNavigationBar()
6262
setUI()
6363
setLayout()
64-
setupTextView()
64+
setDelegate()
6565
setAddTarget()
66-
setKeyboardNotification()
6766
setTapGesture()
68-
addKeyboardObserver()
67+
setKeyboardObservers()
6968
analyze(screenName: GAEvent.View.viewCourseUpload)
7069
}
7170

@@ -107,29 +106,21 @@ extension CourseUploadVC {
107106
self.uploadButton.addTarget(self, action: #selector(uploadButtonDidTap), for: .touchUpInside)
108107
}
109108

110-
// 키보드가 올라오면 scrollView 위치 조정
111-
private func setKeyboardNotification() {
112-
NotificationCenter.default.addObserver(
113-
self,
114-
selector: #selector(keyboardWillShow),
115-
name: UIResponder.keyboardWillShowNotification,
116-
object: nil)
117-
118-
NotificationCenter.default.addObserver(
119-
self,
120-
selector: #selector(keyboardWillHide),
121-
name: UIResponder.keyboardWillHideNotification,
122-
object: nil)
123-
}
124-
125109
// 화면 터치 시 키보드 내리기
126110
private func setTapGesture() {
127111
let tap = UITapGestureRecognizer(target: view, action: #selector(UIView.endEditing))
128112
tap.cancelsTouchesInView = false
129113
view.addGestureRecognizer(tap)
130114
}
131115

132-
private func addKeyboardObserver() {
116+
// 업로드 버튼 상태 업데이트 메소드
117+
private func updateUploadButtonState() {
118+
let isTitleNotEmpty = !(courseTitleTextField.text?.trimmingCharacters(in: .whitespacesAndNewlines).isEmpty ?? true)
119+
let isContentNotEmptyAndNotPlaceholder = !(activityTextView.text.trimmingCharacters(in: .whitespacesAndNewlines).isEmpty || activityTextView.text == placeholder)
120+
uploadButton.setEnabled(isTitleNotEmpty && isContentNotEmptyAndNotPlaceholder)
121+
}
122+
123+
private func setKeyboardObservers() {
133124
NotificationCenter.default.addObserver(
134125
self,
135126
selector: #selector(keyboardWillShow),
@@ -146,19 +137,7 @@ extension CourseUploadVC {
146137

147138
extension CourseUploadVC {
148139
@objc private func textFieldTextDidChange() {
149-
guard let text = courseTitleTextField.text else { return }
150-
151-
if text.count > courseTitleMaxLength {
152-
let index = text.index(text.startIndex, offsetBy: courseTitleMaxLength)
153-
let newString = text[text.startIndex..<index]
154-
self.courseTitleTextField.text = String(newString)
155-
}
156-
157-
if text.count == 0 && activityTextView.text != self.placeholder && activityTextView.text.count == 0 {
158-
uploadButton.setEnabled(true)
159-
} else {
160-
uploadButton.setEnabled(false)
161-
}
140+
updateUploadButtonState()
162141
}
163142

164143
@objc private func keyboardWillShow(_ notification: Notification) {
@@ -175,11 +154,12 @@ extension CourseUploadVC {
175154
scrollView.contentInset = contentInset
176155
scrollView.scrollIndicatorInsets = contentInset
177156

178-
if activityTextView.isFirstResponder {
157+
// scrollView 높이 설정
158+
if courseTitleTextField.isFirstResponder || activityTextView.isFirstResponder {
179159
let contentViewHeight = scrollView.contentSize.height
180160
let textViewHeight = activityTextView.frame.height
181161
let textViewOffsetY = contentViewHeight - (contentInset.bottom + textViewHeight)
182-
let position = CGPoint(x: 0, y: textViewOffsetY + 100)
162+
let position = CGPoint(x: 0, y: textViewOffsetY + 50)
183163
scrollView.setContentOffset(position, animated: true)
184164
return
185165
}
@@ -198,28 +178,29 @@ extension CourseUploadVC {
198178
}
199179
}
200180

201-
// MARK: - naviVar Layout
202-
203181
extension CourseUploadVC {
182+
183+
// MARK: - naviVar Layout
184+
204185
private func setNavigationBar() {
205186
view.addSubview(navibar)
206187
navibar.snp.makeConstraints {
207188
$0.top.leading.trailing.equalTo(view.safeAreaLayoutGuide)
208189
$0.height.equalTo(48)
209190
}
210191
}
211-
// MARK: - setUI
192+
// MARK: - UI & Layout
212193

213194
private func setUI() {
214195
view.backgroundColor = .w1
215196
scrollView.backgroundColor = .clear
216197
buttonContainerView.backgroundColor = .w1
217198
mapImageView.backgroundColor = .systemGray4
218199

200+
activityTextView.text = placeholder
201+
activityTextView.textColor = .g3
219202
}
220203

221-
// MARK: - Layout Helpers
222-
223204
private func setLayout() {
224205
view.addSubview(buttonContainerView)
225206
view.bringSubviewToFront(uploadButton)
@@ -241,14 +222,15 @@ extension CourseUploadVC {
241222

242223
private func setScrollViewLayout() {
243224
view.addSubview(scrollView)
244-
[mapImageView,
245-
courseTitleTextField,
246-
dividerView,
247-
distanceInfoView,
248-
departureInfoView,
249-
activityTextView].forEach {
250-
scrollView.addSubview($0)
251-
}
225+
226+
scrollView.addSubviews(
227+
mapImageView,
228+
courseTitleTextField,
229+
dividerView,
230+
distanceInfoView,
231+
departureInfoView,
232+
activityTextView
233+
)
252234

253235
scrollView.snp.makeConstraints {
254236
$0.top.equalTo(navibar.snp.bottom)
@@ -294,13 +276,14 @@ extension CourseUploadVC {
294276
}
295277
}
296278

297-
func setupTextView() {
279+
func setDelegate() {
298280
activityTextView.delegate = self
299-
activityTextView.text = placeholder
300-
activityTextView.textColor = .g3
281+
courseTitleTextField.delegate = self
301282
}
302283
}
303284

285+
// MARK: - UITextViewDelegate
286+
304287
extension CourseUploadVC: UITextViewDelegate {
305288
func textViewDidBeginEditing(_ textView: UITextView) {
306289
if textView.text.trimmingCharacters(in: .whitespacesAndNewlines).isEmpty {
@@ -314,16 +297,13 @@ extension CourseUploadVC: UITextViewDelegate {
314297
}
315298

316299
func textViewDidChange(_ textView: UITextView) {
317-
if !courseTitleTextField.isEmpty && !activityTextView.text.isEmpty {
318-
uploadButton.setEnabled(true)
319-
} else {
320-
uploadButton.setEnabled(false)
321-
}
300+
updateUploadButtonState()
322301

323302
if activityTextView.text.count > 150 {
324303
activityTextView.deleteBackward()
325304
}
326305
}
306+
327307
func textViewDidEndEditing(_ textView: UITextView) {
328308
if textView.text.trimmingCharacters(in: .whitespacesAndNewlines).isEmpty || textView.text == placeholder {
329309
activityTextView.textColor = .g3
@@ -332,6 +312,18 @@ extension CourseUploadVC: UITextViewDelegate {
332312
}
333313
}
334314

315+
// MARK: - UITextFieldDelegate
316+
317+
extension CourseUploadVC: UITextFieldDelegate {
318+
func textFieldShouldReturn(_ textField: UITextField) -> Bool {
319+
if textField == courseTitleTextField {
320+
activityTextView.becomeFirstResponder()
321+
return true
322+
}
323+
return false
324+
}
325+
}
326+
335327
// MARK: - Network
336328

337329
extension CourseUploadVC {

0 commit comments

Comments
 (0)