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 37 commits into
base: develop
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
37 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
e639169
[#465] 커스텀얼럿 적용 및 뷰 세부사항 수정
Dorii0513 Mar 7, 2025
928b920
[#465] 태그 셀 너비 조정 및 아이콘 에셋 추가
Dorii0513 Mar 8, 2025
5645648
[#465] useCase분리
Dorii0513 Mar 8, 2025
0a43815
[#465] print문 삭제
Dorii0513 Mar 8, 2025
c61ca50
[#465] 리뷰 반영
Dorii0513 Mar 8, 2025
63d187a
[#465] 리뷰 반영2
Dorii0513 Mar 9, 2025
7cbfd78
[#465] tag구조체 isSeleted 추가
Dorii0513 Mar 10, 2025
97d31ed
[#465] deinit 추가
Dorii0513 Mar 11, 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
64 changes: 64 additions & 0 deletions DesignSystem/Views/CustomAlert.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
//
// CustomAlert.swift
// Reazy
//
// Created by 김예림 on 3/6/25.
//

import SwiftUI

struct CustomAlert: View {
let mainText: String
let message: String

let cancleAction: () -> Void
let confirmAction: () -> Void

var body: some View {
VStack(spacing: 0) {
VStack(alignment: .center, spacing: 0) {
Text(mainText)
.reazyFont(.button1)
.foregroundStyle(.gray900)
.multilineTextAlignment(.center)
Text(message)
.reazyFont(.body1)
.foregroundStyle(.gray900)
.lineLimit(1)
}
.padding(.top, 25)
.padding(.horizontal, 30)
Spacer()

Rectangle()
.frame(height: 1)
.foregroundStyle(.gray400)

HStack(spacing: 70) {
Button {
cancleAction()
} label: {
Text("취소")
.reazyFont(.text1)
}
Rectangle()
.frame(width: 1)
.foregroundStyle(.gray400)
Button {
confirmAction()
} label: {
Text("삭제")
.reazyFont(.text1)
.foregroundStyle(.pen1)
}
}
.frame(height: 52)
}
.frame(width: 350, height: 176)
.background(
RoundedRectangle(cornerRadius: 20)
.foregroundStyle(.gray200)
)

}
}
24 changes: 15 additions & 9 deletions DesignSystem/Views/DynamicCellLayout.swift
Original file line number Diff line number Diff line change
Expand Up @@ -12,23 +12,26 @@ 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 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()
let itemWidth = item.itemWidth(isEditMode: isEditMode)

if currentWidth + itemWidth >= screenWidth {
resultRows.append(currentArrays)
Expand All @@ -45,17 +48,20 @@ struct DynamicCellLayout<Data: RandomAccessCollection>: View where Data.Element:
currentWidth += itemWidth
currentArrays.append(item)
}

return VStack(alignment: .leading) {
ForEach(resultRows, id: \.self) { row in
HStack {
ForEach(row) { tag in
PDFTagCell(tag: tag) {
action(tag.name)
}
PDFTagCell(isMultiSelectable: isMultiSelectable,
isEditMode: isEditMode,
tag: tag,
selectAction: {selectAction(tag.name)},
deleteAction: {deleteAction(tag.id)}
)
}
}
}
.padding(.bottom, 10)
}
}
}
29 changes: 29 additions & 0 deletions DesignSystem/Views/EllipsisView.swift
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)
}
}
}

4 changes: 3 additions & 1 deletion Domain/Entities/Tag.swift
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,12 @@ import Foundation
struct Tag: DynamicCell {
let id: UUID
var name: String
var isSeleted: Bool

init(id: UUID = .init(), name: String) {
init(id: UUID = .init(), name: String, isSeleted: Bool = false) {
self.id = id
self.name = name
self.isSeleted = isSeleted
}

func getCellWidth() -> CGFloat {
Expand Down
8 changes: 8 additions & 0 deletions Domain/Interfaces/DynamicCell.swift
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,14 @@ import Foundation
protocol DynamicCell: Hashable, Identifiable {
var id: UUID { get }
var name: String { get }
var isSeleted: Bool { get set }

func getCellWidth() -> CGFloat
}

extension DynamicCell {
func itemWidth(isEditMode: Bool) -> CGFloat {
let padding: CGFloat = isEditMode ? 35 : 16
Copy link
Collaborator Author

@Dorii0513 Dorii0513 Mar 8, 2025

Choose a reason for hiding this comment

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

DynamicCellLayout에서 셀의 너비를 계산하는 과정에서 셀 안의 패딩 값 계산이 빠져있더라구요.
-> 그러다보니 셀이 줄바꿈하는 과정에서 오차가 발생해서 해당 코드로 추가해두었습니다
( 셀을 삭제하는 x 버튼이 있냐 없냐에 따라 패딩 값이 달라져서 isEditMode에 따라 바뀌도록 설정합니다 )

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

import Foundation

//MARK: - TODO : - 코어데이터 연결
protocol TagViewUseCase {
func deleteTag(id: UUID, from tags: inout [Tag])
func createTag(name: String, in tags: inout [Tag])
}

class DefaultTagViewUseCase: TagViewUseCase {
func deleteTag(id: UUID, from tags: inout [Tag]) {
tags.removeAll { $0.id == id }
}

func createTag(name: String, in tags: inout [Tag]) {
tags.append(Tag(name: name))
}
}
30 changes: 5 additions & 25 deletions Presentation/Home/HomeSearch/Cell/HomePDFCell.swift
Original file line number Diff line number Diff line change
Expand Up @@ -112,9 +112,11 @@ private struct PaperInformationView: View {

HStack {
ForEach(tags) { tag in
PDFTagCell(tag: tag) {
tagAction(tag.id)
}
PDFTagCell(isMultiSelectable: false,
isEditMode: false,
tag: tag,
selectAction: {tagAction(tag.id)},
deleteAction: {})
}
}
.padding(.bottom, 22)
Expand All @@ -123,28 +125,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
43 changes: 32 additions & 11 deletions Presentation/Home/HomeSearch/Cell/PDFTagCell.swift
Original file line number Diff line number Diff line change
Expand Up @@ -9,24 +9,45 @@ import SwiftUI


struct PDFTagCell<Tag: DynamicCell>: View {
let tag: Tag
@State private 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 : 위와 마찬가지로 태그를 편집(=삭제) 가능 여부를 구분합니다


var tag: Tag

let action: () -> Void
let selectAction: () -> Void
let deleteAction: () -> Void
Comment on lines +18 to +19
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()
if !isEditMode {
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: 0) {
Text(tag.name)
.reazyFont(isMultiSelectable ? .body1 : .h3)
.foregroundStyle(tag.isSeleted ? .gray300 : .gray800)
.fixedSize(horizontal: true, vertical: false)

// 삭제 버튼
if isEditMode {
Button {
deleteAction()
} label: {
Image(systemName: "x.circle.fill")
.foregroundStyle(.gray700)
.font(.system(size: 12))
}
}
}
.frame(height: 24)
.padding(.horizontal, 8)
.background {
RoundedRectangle(cornerRadius: 4)
.foregroundStyle(tag.isSeleted ? .point4 : .primary3)
}
}
}
}
8 changes: 6 additions & 2 deletions Presentation/Home/HomeSearch/HomeSearchView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -153,9 +153,13 @@ private struct RecentlySearchedKeywordView: View {
.foregroundStyle(.primary1)
}

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

Spacer()
Expand Down
Loading