Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Design] 태그뷰 디자인하기 #470

Open
wants to merge 29 commits into
base: develop
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 28 commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
c8c935b
[#465] 프로젝트 파일 세팅
Dorii0513 Feb 10, 2025
a55bcb5
[#465] 프로젝트 파일 세팅
Dorii0513 Feb 10, 2025
f2950c1
[#465] tagEmpty 상태의 뷰 그리기
Dorii0513 Feb 15, 2025
2b93b4b
[#465] isTagExist 뷰 구현
Dorii0513 Feb 19, 2025
db66410
[#465] 태그 선택, 선택해제 구현
Dorii0513 Feb 19, 2025
69226ff
[#465] 선택한 태그 정렬
Dorii0513 Feb 19, 2025
bb2f3ab
[#465] 태그뷰 메뉴 디자인 구현
Dorii0513 Feb 20, 2025
b7275de
[#465] 태그편집 기능 구현
Dorii0513 Feb 20, 2025
b44aee7
[#465] 태그추가 기능 구현
Dorii0513 Feb 20, 2025
43668d7
[#465] 태그중복 alert
Dorii0513 Feb 22, 2025
080f551
Merge branch 'Design/#465-designTagView' of https://github.com/Develo…
Dorii0513 Feb 22, 2025
2b4bdc0
[#465] 프로젝트 파일 세팅
Dorii0513 Feb 10, 2025
68c65cf
[#465] tagEmpty 상태의 뷰 그리기
Dorii0513 Feb 15, 2025
ed6c433
[#465] isTagExist 뷰 구현
Dorii0513 Feb 19, 2025
bdfa55c
[#465] 태그 선택, 선택해제 구현
Dorii0513 Feb 19, 2025
df81395
[#465] 선택한 태그 정렬
Dorii0513 Feb 19, 2025
01b678b
[#465] 태그뷰 메뉴 디자인 구현
Dorii0513 Feb 20, 2025
833e753
[#465] 태그편집 기능 구현
Dorii0513 Feb 20, 2025
58d7941
[#465] 태그추가 기능 구현
Dorii0513 Feb 20, 2025
091334b
[#465] 태그중복 alert
Dorii0513 Feb 22, 2025
523f8f0
[#465] server 및 googleService 추가, 에러 해결
Dorii0513 Feb 22, 2025
7622f06
[#465] 불필요한 tagViewModel 주입 삭제
Dorii0513 Feb 26, 2025
258df59
Merge branch 'develop' of https://github.com/DeveloperAcademy-POSTECH…
Dorii0513 Feb 26, 2025
21d2912
[#465] conflict 수정
Dorii0513 Feb 26, 2025
ad11f96
Merge branch 'Design/#465-designTagView' of https://github.com/Develo…
Dorii0513 Feb 26, 2025
840f41d
[#465] 불필요한 주석 삭제
Dorii0513 Feb 26, 2025
958bd19
[#465] selectedTags 연결
Dorii0513 Feb 26, 2025
ee052d8
[#465] 버튼 누를때 뷰 변경
Dorii0513 Feb 26, 2025
83bfc20
[#465] 서버 구글 파일 지움
Dorii0513 Feb 28, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 20 additions & 12 deletions DesignSystem/Views/DynamicCellLayout.swift
Original file line number Diff line number Diff line change
Expand Up @@ -12,25 +12,29 @@ import SwiftUI
*/
struct DynamicCellLayout<Data: RandomAccessCollection>: View where Data.Element: DynamicCell {
let data: Data
let action: (String) -> Void
let screenWidth: CGFloat
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

screenWidth : 이건 무니가 UIScreen.main.bounds.width 값을 디폴트로 설정해 두었는데, 제가 활용하려는 뷰에서는 조정이 필요해서 넣었어요!

let selectedTags: [String]

let isMultiSelectable: Bool // 여러 셀 선택 가능
let isEditMode: Bool // x마크

let selectAction: (String) -> Void
let deleteAction: (UUID) -> Void

var body: some View {
generateLayout(items: data)
}

private func generateLayout(items: Data) -> some View {
let screenWidth = UIScreen.main.bounds.width

var currentWidth: CGFloat = 0
var currentArrays = [Data.Element]()

var resultRows = [[Data.Element]]()


for (index, item) in items.enumerated() {
let itemWidth = item.getCellWidth()

if currentWidth + itemWidth >= screenWidth {
let itemWidth = item.itemWidth(isEditMode: isEditMode)
if currentWidth + itemWidth + 10 >= screenWidth {
Comment on lines +36 to +37
Copy link
Collaborator Author

@Dorii0513 Dorii0513 Feb 26, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

셀 너비 계산할때 패딩값때문에 약간 오차가 생기는 거 같아서 넣었습니다!
혹시 테스트해보고 이상하면 말씀해주세요!ㅠㅠ

resultRows.append(currentArrays)
currentArrays.removeAll()
currentWidth = 0
Expand All @@ -42,20 +46,24 @@ struct DynamicCellLayout<Data: RandomAccessCollection>: View where Data.Element:
break
}

currentWidth += itemWidth
currentWidth += itemWidth + 20
currentArrays.append(item)
}

return VStack(alignment: .leading) {
ForEach(resultRows, id: \.self) { row in
HStack {
HStack(spacing: 10) {
ForEach(row) { tag in
PDFTagCell(tag: tag) {
action(tag.name)
}
PDFTagCell(isMultiSelectable: isMultiSelectable,
isEditMode: isEditMode,
selectedTags: selectedTags,
tag: tag,
selectAction: {selectAction(tag.name)},
deleteAction: {deleteAction(tag.id)}
)
}
}
}
.padding(.bottom, 10)
}
}
}
29 changes: 29 additions & 0 deletions DesignSystem/Views/EllipsisView.swift
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ellipsis 버튼 재사용이 많을 거 같아서 무니 코드 따로 분리해뒀어요

Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
//
// Component.swift
// Reazy
//
// Created by 김예림 on 2/17/25.
//

import SwiftUI

struct EllipsisView: View {
let ellipsisAction: () -> Void

var body: some View {
VStack {
Spacer()

Button {
ellipsisAction()
} label: {
Image(systemName: "ellipsis.circle")
.font(.system(size: 24))
.foregroundStyle(.gray550)
}
.padding(.trailing, 24)
.padding(.bottom, 20)
}
}
}

7 changes: 7 additions & 0 deletions Domain/Interfaces/DynamicCell.swift
Original file line number Diff line number Diff line change
Expand Up @@ -14,3 +14,10 @@ protocol DynamicCell: Hashable, Identifiable {

func getCellWidth() -> CGFloat
}

extension DynamicCell {
func itemWidth(isEditMode: Bool) -> CGFloat {
let additionalPadding: CGFloat = isEditMode ? 40 : 16
return getCellWidth() + additionalPadding
}
}
Comment on lines +18 to +23
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

편집모드일 때, x버튼이 생기면서,,, 셀 너비 값 계산할 때 오차 방지를 위해 추가했습니다.

16 changes: 16 additions & 0 deletions Domain/UseCases/TagViewUseCase.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
//
// TagViewUseCase.swift
// Reazy
//
// Created by 김예림 on 2/17/25.
//

import Foundation

protocol TagViewUseCase {
//TODO: - 태그 저장, 수정, 삭제
}

class DefaultTagViewUseCase: TagViewUseCase {

}
30 changes: 30 additions & 0 deletions GoogleService-Info.plist
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>API_KEY</key>
<string>AIzaSyAT_wmkbWRbdvZJFiARSLRTquTXlyFFTxI</string>
<key>GCM_SENDER_ID</key>
<string>309584491328</string>
<key>PLIST_VERSION</key>
<string>1</string>
<key>BUNDLE_ID</key>
<string>com.chillin.reazy</string>
<key>PROJECT_ID</key>
<string>reazy-924ee</string>
<key>STORAGE_BUCKET</key>
<string>reazy-924ee.firebasestorage.app</string>
<key>IS_ADS_ENABLED</key>
<false></false>
<key>IS_ANALYTICS_ENABLED</key>
<false></false>
<key>IS_APPINVITE_ENABLED</key>
<true></true>
<key>IS_GCM_ENABLED</key>
<true></true>
<key>IS_SIGNIN_ENABLED</key>
<true></true>
<key>GOOGLE_APP_ID</key>
<string>1:309584491328:ios:cb4ebfa2ccbff0c08240a5</string>
</dict>
</plist>
31 changes: 6 additions & 25 deletions Presentation/Home/HomeSearch/Cell/HomePDFCell.swift
Original file line number Diff line number Diff line change
Expand Up @@ -112,9 +112,12 @@ private struct PaperInformationView: View {

HStack {
ForEach(tags) { tag in
PDFTagCell(tag: tag) {
tagAction(tag.id)
}
PDFTagCell(isMultiSelectable: false,
isEditMode: false,
selectedTags: [],
tag: tag,
selectAction: {tagAction(tag.id)},
deleteAction: {})
}
}
.padding(.bottom, 22)
Expand All @@ -123,28 +126,6 @@ private struct PaperInformationView: View {
}
}


private struct EllipsisView: View {
let ellipsisAction: () -> Void

var body: some View {
VStack {
Spacer()

Button {
ellipsisAction()
} label: {
Image(systemName: "ellipsis.circle")
.font(.system(size: 24))
.foregroundStyle(.gray550)
}
.padding(.trailing, 24)
.padding(.bottom, 20)
}
}
}


// MARK: - Epllipsis 버튼 뷰
private struct EllipsisButtonView: View {
let editTitleAction: () -> Void
Expand Down
46 changes: 36 additions & 10 deletions Presentation/Home/HomeSearch/Cell/PDFTagCell.swift
Original file line number Diff line number Diff line change
Expand Up @@ -9,24 +9,50 @@ import SwiftUI


struct PDFTagCell<Tag: DynamicCell>: View {
var isSelected: Bool {
return isMultiSelectable && selectedTags.contains(tag.name)
}
@State var isAlertPresented: Bool = false
let isMultiSelectable: Bool // 멀티선택 가능 여부
let isEditMode: Bool // 편집 가능 여부
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

isMultiSelectable : 태그셀을 멀티 선택이 가능한지 구분해 searchView와 tagView에서의 셀 기능을 구별해두었어요.

isEditMode : 위와 마찬가지로 태그를 편집(=삭제) 가능 여부를 구분합니다


let selectedTags: [String]
Copy link
Collaborator Author

@Dorii0513 Dorii0513 Feb 26, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

이걸 어떻게 연결할까 계속 고민했는데 ..ㅜ
각각의 셀들은 자신이 select 되었는지 알고 있어야 해요.
근데 Tag 모델에 isSelected 값이 없다보니,, 일단 상태 변수로 isSelected를 만들고, tagViewModel의 selectedTags를 받아서 isSelected == true일때, selectedTags에 존재하는지 여부를 계속 판단해주는 걸로 일단 했습니닷..

var isSelected: Bool {
        return isMultiSelectable && selectedTags.contains(tag.name)
    }

근데 이렇게 하니까 selectedTags가 필요없는 다른 뷰에서는 얘를 빈배열로 비워두어야 해서 흠.. 이 방식이 괜찮은지 고민이 됩니당

let tag: Tag

let action: () -> Void
let selectAction: () -> Void
let deleteAction: () -> Void
Comment on lines +22 to +23
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

원래는 action 하나만 있었는데,
태그 삭제 버튼이 생기면서 액션기능을 두개로 나누어주었어요


var body: some View {
Button {
action()
selectAction()
} label: {
// TODO: 태그 title
Text(tag.name)
.reazyFont(.h3)
.foregroundStyle(.gray800)
.frame(height: 24)
.padding(.horizontal, 8)
.background {
RoundedRectangle(cornerRadius: 4)
.foregroundStyle(.primary3)
HStack(spacing: 8) {
Text(tag.name)
.reazyFont(isMultiSelectable ? .body1 : .h3)
.foregroundStyle(isSelected ? .gray300 : .gray800)
.frame(width: tag.getCellWidth())
if isEditMode {
Button {
isAlertPresented = true
} label: {
Image(systemName: "x.circle.fill")
.foregroundStyle(.gray700)
.font(.system(size: 12))
}
.alert("\(tag.name)\n태그를 삭제하시겠습니까?\n해당 태그가 달린 모든 논문에서도 삭제됩니다.", isPresented: $isAlertPresented) {
Button("삭제", role: .destructive, action: {
deleteAction()
})
}
}
}
.padding(.horizontal, 8)
.frame(height: 24)
.background {
RoundedRectangle(cornerRadius: 4)
.foregroundStyle(isSelected ? .point4 : .primary3)
}
}
}
}
9 changes: 7 additions & 2 deletions Presentation/Home/HomeSearch/HomeSearchView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -153,9 +153,14 @@ private struct RecentlySearchedKeywordView: View {
.foregroundStyle(.primary1)
}

DynamicCellLayout(data: homeSearchViewModel.recentSearches) { title in
DynamicCellLayout(data: homeSearchViewModel.recentSearches,
screenWidth: UIScreen.main.bounds.width,
selectedTags: [],
isMultiSelectable: false,
isEditMode: false,
selectAction: { title in
homeSearchViewModel.cellTapped(title: title)
}
}, deleteAction: {_ in })
.padding(.top, 20)

Spacer()
Expand Down
Loading