Skip to content
Merged
11 changes: 11 additions & 0 deletions Projects/Chat/Sources/View/ChatViewController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ public class ChatViewController: BaseViewController {

// 초기에 endButton 숨기기
chatView.hideEndButton()
setupTapGesture()
}

public override func setupViewProperty() {
Expand Down Expand Up @@ -242,4 +243,14 @@ public class ChatViewController: BaseViewController {
// 이전 화면으로 이동
navigationController?.popViewController(animated: true)
}

private func setupTapGesture() {
let tapGesture = UITapGestureRecognizer(target: self, action: #selector(dismissKeyboard))
tapGesture.cancelsTouchesInView = false
view.addGestureRecognizer(tapGesture)
}

@objc private func dismissKeyboard() {
view.endEditing(true)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ public enum CommonUIAsset: Sendable {
public static let lmRed02 = CommonUIColors(name: "LMRed02")
}
public enum Images {
public static let add = CommonUIImages(name: "add")
public static let add = CommonUIImages(name: "add")
public static let back = CommonUIImages(name: "back")
public static let bubble = CommonUIImages(name: "bubble")
public static let close = CommonUIImages(name: "close")
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
{
"images" : [
{
"idiom" : "universal",
"scale" : "1x"
},
{
"filename" : "[email protected]",
"idiom" : "universal",
"scale" : "2x"
},
{
"filename" : "[email protected]",
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
45 changes: 43 additions & 2 deletions Projects/CommonUI/Sources/Component/LMAlert.swift
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,8 @@ public class LMAlert: UIView {
// MARK: - Properties
private var cancelAction: (() -> Void)?
private var confirmAction: (() -> Void)?
private var titleTopConstraint: Constraint?
private var buttonTopConstraint: Constraint?

// MARK: - Initialization
public init(title: String, cancelTitle: String = "아니요", confirmTitle: String = "네") {
Expand Down Expand Up @@ -102,7 +104,7 @@ public class LMAlert: UIView {
}

titleLabel.snp.makeConstraints {
$0.top.equalToSuperview().inset(24)
self.titleTopConstraint = $0.top.equalToSuperview().inset(24).constraint
$0.horizontalEdges.equalToSuperview().inset(20)
$0.bottom.lessThanOrEqualTo(buttonStackView.snp.top).offset(-16)
}
Expand All @@ -111,7 +113,7 @@ public class LMAlert: UIView {
$0.bottom.equalToSuperview().inset(20)
$0.horizontalEdges.equalToSuperview().inset(20)
$0.height.equalTo(44)
$0.top.greaterThanOrEqualTo(titleLabel.snp.bottom).offset(16)
self.buttonTopConstraint = $0.top.greaterThanOrEqualTo(titleLabel.snp.bottom).offset(16).constraint
}
}

Expand All @@ -137,7 +139,10 @@ public class LMAlert: UIView {
// cancelTitle이 비어있으면 취소 버튼 숨기기
if cancelTitle.isEmpty {
cancelButton.isHidden = true
} else {
cancelButton.isHidden = false
}
updateSpacing(for: attributedString)
}

// MARK: - Actions
Expand Down Expand Up @@ -195,4 +200,40 @@ public class LMAlert: UIView {
completion()
}
}

// MARK: - Layout Helpers
private func updateSpacing(for attributedString: NSAttributedString) {
let contentWidth: CGFloat = 280 - 40 // container width - horizontal inset
let lineCount = calculateLineCount(for: attributedString, maxWidth: contentWidth)
let spacing = spacingConfiguration(for: lineCount)
titleTopConstraint?.update(offset: spacing.topInset)
buttonTopConstraint?.update(offset: spacing.betweenSpacing)
layoutIfNeeded()
}

private func spacingConfiguration(for lineCount: Int) -> (topInset: CGFloat, betweenSpacing: CGFloat) {
switch lineCount {
case ..<2:
return (32, 24)
case 2:
return (28, 20)
default:
return (24, 16)
}
}

private func calculateLineCount(for attributedString: NSAttributedString, maxWidth: CGFloat) -> Int {
guard attributedString.length > 0 else { return 1 }
let boundingRect = attributedString.boundingRect(
with: CGSize(width: maxWidth, height: .greatestFiniteMagnitude),
options: [.usesLineFragmentOrigin, .usesFontLeading],
context: nil
)
let font = (attributedString.attribute(.font, at: 0, effectiveRange: nil) as? UIFont) ?? titleLabel.font ?? .systemFont(ofSize: 16)
let paragraphStyle = attributedString.attribute(.paragraphStyle, at: 0, effectiveRange: nil) as? NSParagraphStyle
let lineHeight = font.lineHeight + (paragraphStyle?.lineSpacing ?? 0)
if lineHeight == 0 { return 1 }
let rawCount = Int(ceil(boundingRect.height / lineHeight))
return max(1, rawCount)
}
}
1 change: 1 addition & 0 deletions Projects/CommonUI/Sources/Enum/CommonUIAssets.swift
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ public enum CommonUIAssets {
public static let IconNext = image(named: "next")
public static let IconNext2 = image(named: "next2")
public static let IconAdd = image(named: "add")
public static let IconProfile = image(named: "profile")

/// color
public static let LMOrange0 = color(named: "LMOrange00")
Expand Down
20 changes: 19 additions & 1 deletion Projects/CommonUI/Sources/View/Chat/ChatView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -156,13 +156,19 @@ open class ChatView: UIView {
$0.center.equalToSuperview()
$0.leading.trailing.equalToSuperview().inset(16)
}

// 탭 이벤트 설정
view.tag = index
view.isUserInteractionEnabled = true
let tap = UITapGestureRecognizer(target: self, action: #selector(handleRecommendTap(_:)))
view.addGestureRecognizer(tap)
}

titleLabel.snp.makeConstraints {
$0.top.equalTo(self.safeAreaLayoutGuide).offset(20)
$0.leading.equalToSuperview().inset(20)
}

subtitleLabel.snp.makeConstraints {
$0.top.equalTo(titleLabel.snp.bottom).offset(10)
$0.leading.equalToSuperview().inset(20)
Expand Down Expand Up @@ -213,6 +219,18 @@ open class ChatView: UIView {
}
}

@objc private func handleRecommendTap(_ gesture: UITapGestureRecognizer) {
guard let view = gesture.view else { return }
let index = view.tag
guard index >= 0 && index < recommendLabels.count else { return }
let text = recommendLabels[index].text ?? ""
guard !text.trimmingCharacters(in: .whitespacesAndNewlines).isEmpty else { return }

// 추천 섹션 숨기고 바로 전송 콜백 호출
hideRecommendSection()
onSendButtonTapped?(text)
}

// 추천 섹션 숨기기 메서드
public func hideRecommendSection() {
UIView.animate(withDuration: 0.3) {
Expand Down
24 changes: 6 additions & 18 deletions Projects/CommonUI/Sources/View/Diary/DiaryView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -56,24 +56,12 @@ open class DiaryView: UIView {
bindEvents()
calendarView.configureSubviews()
calendarView.makeConstraints()
setupSampleEmotionData()
updateMonthButtonTitle()
}

required public init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}

private func setupSampleEmotionData() {
// 샘플 이모지 데이터 설정 (이미지와 동일하게)
let sampleEmotions: [Int: String] = [
1: "😢", // 우는 얼굴
7: "😐", // 무표정한 얼굴
12: "🥳", // 파티 모자
13: "😡" // 화난 얼굴
]
calendarView.setEmotionData(sampleEmotions)
}

// MARK: Configuration
func configureSubviews() {
Expand Down Expand Up @@ -108,11 +96,11 @@ open class DiaryView: UIView {
$0.height.width.equalTo(monthLabel.snp.height)
}

addButton.snp.makeConstraints {
$0.centerY.equalTo(monthLabel)
$0.trailing.equalToSuperview().inset(20)
$0.height.width.equalTo(monthLabel.snp.height)
}
// addButton.snp.makeConstraints {
// $0.centerY.equalTo(monthLabel)
// $0.trailing.equalToSuperview().inset(20)
// $0.height.width.equalTo(monthLabel.snp.height)
// }

calendarView.snp.makeConstraints {
$0.top.equalTo(monthLabel.snp.bottom).offset(17)
Expand All @@ -121,7 +109,7 @@ open class DiaryView: UIView {
}

diaryTodayView.snp.makeConstraints {
$0.top.equalTo(calendarView.snp.bottom).offset(3)
$0.top.equalTo(calendarView.snp.bottom).offset(30)
$0.centerX.equalToSuperview()
$0.width.equalToSuperview().inset(20)
$0.height.equalTo(141)
Expand Down
1 change: 0 additions & 1 deletion Projects/CommonUI/Sources/View/Home/HomeProgressView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,6 @@ open class HomeProgressView: UIView {
self.layer.cornerRadius = 12

courseLabel = courseLabel.then {
$0.text = "한국어 훈련 1단계"
$0.textColor = CommonUIAssets.LMBlack
$0.font = .systemFont(ofSize: 18, weight: .semibold)
}
Expand Down
3 changes: 1 addition & 2 deletions Projects/CommonUI/Sources/View/Home/HomeQuizView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -34,14 +34,13 @@ open class HomeQuizView: UIView, UICollectionViewDataSource, UICollectionViewDel
}

public func bind(course: CourseVO) {
// courseLabel.text = "\(course.courseLv ?? 1)단계 퀴즈"
courseLabel.text = "\(course.courseLv)단계 퀴즈"
}

func initAttribute() {
self.backgroundColor = .clear

courseLabel = courseLabel.then {
$0.text = "1단계 퀴즈"
$0.textColor = CommonUIAssets.LMBlack
$0.font = .systemFont(ofSize: 16, weight: .medium)
}
Expand Down
13 changes: 10 additions & 3 deletions Projects/CommonUI/Sources/View/Home/HomeView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import Then

open class HomeView: UIView {
let logoImageView = UIImageView()
var profileView = UIView()
var profileView = UIImageView()
var titleLabelStackView = UIStackView()
var titleLabel = UILabel()
var subtitleLabel = UILabel()
Expand All @@ -26,13 +26,20 @@ open class HomeView: UIView {

public func bind(course: CourseVO) {
}

public func updateGreeting(name: String?) {
if let name = name, !name.isEmpty {
titleLabel.text = "안녕하세요 \(name)님!"
} else {
titleLabel.text = "안녕하세요!"
}
}

func initAttribute() {
self.backgroundColor = .clear

profileView = profileView.then {
$0.backgroundColor = CommonUIAssets.LMOrange3
$0.layer.cornerRadius = 28
$0.image = CommonUIAssets.IconProfile
}

titleLabelStackView = titleLabelStackView.then {
Expand Down
36 changes: 28 additions & 8 deletions Projects/CommonUI/Sources/View/Home/QuizCollectionViewCell.swift
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ final class HomeQuizCell: UICollectionViewCell {

private func initAttribute() {
contentView.backgroundColor = .white
contentView.layer.cornerRadius = 12
contentView.layer.cornerRadius = 10
contentView.layer.borderWidth = 2
contentView.layer.borderColor = CommonUIAssets.LMOrange1?.cgColor

Expand Down Expand Up @@ -106,18 +106,38 @@ final class HomeQuizCell: UICollectionViewCell {

private func updateButtonTitle(_ title: String) {
var config = startButton.configuration ?? UIButton.Configuration.plain()
let attributedTitle = AttributedString(title, attributes: AttributeContainer([
.font: UIFont.systemFont(ofSize: 12, weight: .regular)
]))
config.attributedTitle = attributedTitle

if title == "완료" {
config.image = nil
config.baseBackgroundColor = CommonUIAssets.LMOrange4
config.baseForegroundColor = CommonUIAssets.LMGray1
var background = UIBackgroundConfiguration.clear()
background.backgroundColor = CommonUIAssets.LMOrange3
background.cornerRadius = 10
config.background = background
let attributedTitle = AttributedString(title, attributes: AttributeContainer([
.font: UIFont.systemFont(ofSize: 12, weight: .regular),
.foregroundColor: CommonUIAssets.LMGray3 ?? UIColor.black
]))
config.attributedTitle = attributedTitle
config.baseForegroundColor = .white
startButton.layer.borderWidth = 0
startButton.layer.borderColor = UIColor.clear.cgColor
startButton.isEnabled = false
startButton.isUserInteractionEnabled = false
} else {
config.image = CommonUIAssets.IconPlay
config.baseForegroundColor = CommonUIAssets.LMGray1
var background = UIBackgroundConfiguration.clear()
background.cornerRadius = 10
config.background = background
let attributedTitle = AttributedString(title, attributes: AttributeContainer([
.font: UIFont.systemFont(ofSize: 12, weight: .regular),
.foregroundColor: CommonUIAssets.LMGray3 ?? .gray
]))
config.attributedTitle = attributedTitle
config.baseForegroundColor = CommonUIAssets.LMGray3
startButton.layer.borderWidth = 1
startButton.layer.borderColor = CommonUIAssets.LMOrange1?.cgColor
startButton.isEnabled = true
startButton.isUserInteractionEnabled = true
}

startButton.configuration = config
Expand Down
6 changes: 3 additions & 3 deletions Projects/CommonUI/Sources/View/Login/LoginView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ open class LoginView: UIView {
[logoLabel, logoView, loginButtonStackView]
.forEach { self.addSubview($0) }

[lmLoginButton, googleLoginButton, appleLoginButton]
[lmLoginButton]
.forEach { loginButtonStackView.addArrangedSubview($0)}

logoLabel.snp.makeConstraints {
Expand All @@ -115,8 +115,8 @@ open class LoginView: UIView {

loginButtonStackView.snp.makeConstraints {
$0.horizontalEdges.equalToSuperview().inset(20)
$0.height.equalTo(205)
$0.bottom.equalToSuperview().inset(70)
$0.height.equalTo(55) // 205
$0.bottom.equalToSuperview().inset(85) // 70
}
}

Expand Down
10 changes: 6 additions & 4 deletions Projects/CommonUI/Sources/View/MyPageView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -59,14 +59,15 @@ open class MyPageView: UIView {
title: "내 정보",
items: [
MyPageItem(title: "내 정보", icon: "person.fill", hasChevron: false),
MyPageItem(title: "사용자 이름", subtitle: "", hasChevron: false)
MyPageItem(title: "사용자 이름", subtitle: "", hasChevron: false),
MyPageItem(title: "사용자 id", subtitle: "", hasChevron: false)
]
),
MyPageSection(
title: "앱 정보",
items: [
MyPageItem(title: "앱 정보", icon: "info.circle.fill", hasChevron: false),
MyPageItem(title: "앱 버전", subtitle: "v 1.0.0", hasChevron: false)
MyPageItem(title: "앱 버전", subtitle: "v 1.0.2", hasChevron: false)
]
),
MyPageSection(
Expand All @@ -82,11 +83,12 @@ open class MyPageView: UIView {
}

// MARK: - Public Methods
public func updateUserName(_ name: String) {
// "내 정보" 섹션의 두 번째 아이템(사용자 이름) 업데이트
public func updateUserName(_ name: String, _ id: Int) {
if sections.count > 0 && sections[0].items.count > 1 {
var updatedItems = sections[0].items

updatedItems[1] = MyPageItem(title: "사용자 이름", subtitle: name, hasChevron: false)
updatedItems[2] = MyPageItem(title: "사용자 id", subtitle: "\(id)", hasChevron: false)
sections[0] = MyPageSection(title: sections[0].title, items: updatedItems)
tableView.reloadData()
}
Expand Down
Loading
Loading