From 77a53a896cbadd0d238347b0a4b79f05ac534d18 Mon Sep 17 00:00:00 2001 From: Thina Date: Tue, 27 Sep 2022 13:48:22 +0900 Subject: [PATCH 1/4] =?UTF-8?q?[feat]=20#89=20=EC=8B=B1=EC=9E=89=EB=A6=AC?= =?UTF-8?q?=EC=8A=A4=ED=8A=B8=20=EB=94=94=ED=85=8C=EC=9D=BC=20=EB=B7=B0=20?= =?UTF-8?q?=ED=8E=B8=EC=A7=91=20=EB=B2=84=ED=8A=BC=20=ED=99=9C=EC=84=B1?= =?UTF-8?q?=ED=99=94=20UI=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Semo/Extensions/ViewExtension.swift | 6 ++--- Semo/Views/Others/TextFieldView.swift | 4 +-- Semo/Views/SingingList/SingingListView.swift | 6 ----- .../SingingListDetailView.swift | 27 ++++++++++++++++--- 4 files changed, 28 insertions(+), 15 deletions(-) diff --git a/Semo/Extensions/ViewExtension.swift b/Semo/Extensions/ViewExtension.swift index d1ea5a8..a320024 100644 --- a/Semo/Extensions/ViewExtension.swift +++ b/Semo/Extensions/ViewExtension.swift @@ -16,7 +16,7 @@ extension View { /// - Parameter isEditing: 텍스트 필드 편집 여부 확인 /// - Parameter isFull: 텍스트 필드 공백 여부 확인 /// - Returns: 텍스트 필드 뷰 - func underlineTextField(isEditing : Bool, isFull: Bool) -> some View { + func underlineTextField(isEditing : Bool, isFull: Bool, inset: CGFloat) -> some View { var lineColor: Color = Color.grayScale4 if isEditing == true { lineColor = Color.mainPurpleColor @@ -25,8 +25,8 @@ extension View { lineColor = Color.grayScale2 } return self - .padding(.vertical, 10) - .overlay(Rectangle().frame(height: 2).padding(.top, 35)) +// .padding(.vertical, 10) + .overlay(Rectangle().frame(height: 2).padding(.top, inset)) .padding(10) .foregroundColor(lineColor) } diff --git a/Semo/Views/Others/TextFieldView.swift b/Semo/Views/Others/TextFieldView.swift index fc06baf..a60df9f 100644 --- a/Semo/Views/Others/TextFieldView.swift +++ b/Semo/Views/Others/TextFieldView.swift @@ -34,7 +34,7 @@ struct TextFieldView: View { } .foregroundColor(.white) } - .underlineTextField(isEditing: isEditing, isFull: !text.isEmpty) + .underlineTextField(isEditing: isEditing, isFull: !text.isEmpty, inset: 35) } } @@ -52,7 +52,7 @@ struct SingListTitleTextFieldView: View { } .foregroundColor(.white) } - .underlineTextField(isEditing: isSingingListTitleEditing, isFull: !singingListTitle.isEmpty) + .underlineTextField(isEditing: isSingingListTitleEditing, isFull: !singingListTitle.isEmpty, inset: 35) } } diff --git a/Semo/Views/SingingList/SingingListView.swift b/Semo/Views/SingingList/SingingListView.swift index 3fc8900..fdc5205 100644 --- a/Semo/Views/SingingList/SingingListView.swift +++ b/Semo/Views/SingingList/SingingListView.swift @@ -50,9 +50,3 @@ struct SingingListView: View { } } } - -//struct SingingListView_Preview: PreviewProvider { -// static var previews: some View { -// SingingListView() -// } -//} diff --git a/Semo/Views/SingingListDetail/SingingListDetailView.swift b/Semo/Views/SingingListDetail/SingingListDetailView.swift index d10e50d..1e26a2c 100644 --- a/Semo/Views/SingingListDetail/SingingListDetailView.swift +++ b/Semo/Views/SingingListDetail/SingingListDetailView.swift @@ -10,7 +10,8 @@ import SwiftUI struct SingingListDetailView: View { @Environment(\.presentationMode) var presentationMode: Binding @GestureState private var dragOffset = CGSize.zero - @Binding var editButtonTap: Bool + @State var singingListTitle: String = "" + @State var isSingingListTitleEditing: Bool = false @Binding var listEditButtonTap: Bool @Binding var songEditButtonTap: Bool @@ -24,15 +25,33 @@ struct SingingListDetailView: View { VStack { Rectangle() .edgesIgnoringSafeArea(.all) - .frame(height: UIScreen.main.bounds.height * 0.12) + .frame(height: UIScreen.main.bounds.height * 0.16) .foregroundColor(listEditButtonTap == true ? .grayScale7 : .grayScale6) .opacity(listEditButtonTap == true ? 1 : 0.4) Spacer() } + + VStack { + HStack { + TextField("", text: $singingListTitle, onEditingChanged: { changed in + self.isSingingListTitleEditing = changed + }) + .placeholder(when: singingListTitle.isEmpty) { + Text("\(singingList.title ?? "제목없음")") + .font(.system(size: 35, weight: .bold)) + .foregroundColor(.white) + } + } + .underlineTextField(isEditing: isSingingListTitleEditing, isFull: !singingListTitle.isEmpty, inset: 60) + .padding(.horizontal, 10) + Spacer() + } + .padding(.top, 60) SingingListDetailCellView(songEditButtonTap: $songEditButtonTap, singingList: singingList) + .padding(.top, 40) } - // TODO: - navigationtitle 폰트 크기, 굵기 수정(커스텀으로만 가능) - .navigationBarTitle(singingList.title ?? "제목 없음") +// .navigationBarTitle(singingList.title ?? "제목 없음") +// .navigationBarTitleDisplayMode(.large) .toolbar { ToolbarItem(placement: .navigationBarTrailing) { SongEditButtonView(buttonName: listEditButtonTap == true ? "완료" : "편집", buttonWidth: 50) { From cfab590e629ef96ff7bd93f69797ef65bfd1348f Mon Sep 17 00:00:00 2001 From: Thina Date: Wed, 28 Sep 2022 22:16:10 +0900 Subject: [PATCH 2/4] =?UTF-8?q?[feat]=20#89=20=EB=94=94=ED=85=8C=EC=9D=BC?= =?UTF-8?q?=EB=B7=B0=20=ED=8E=B8=EC=A7=91=20UI=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Semo.xcodeproj/project.pbxproj | 4 ++ .../xcschemes/xcschememanagement.plist | 2 +- Semo/Extensions/BindingExtension.swift | 12 ++++ Semo/Extensions/ViewExtension.swift | 6 +- .../SingingList/SingingListCellView.swift | 2 +- .../SingingListDetailCellView.swift | 3 +- .../SingingListDetailView.swift | 55 +++++++++++++------ 7 files changed, 62 insertions(+), 22 deletions(-) create mode 100644 Semo/Extensions/BindingExtension.swift diff --git a/Semo.xcodeproj/project.pbxproj b/Semo.xcodeproj/project.pbxproj index d4c63d9..9d0a710 100644 --- a/Semo.xcodeproj/project.pbxproj +++ b/Semo.xcodeproj/project.pbxproj @@ -46,6 +46,7 @@ EEAD17812882E48D009388DD /* SingingListView.swift in Sources */ = {isa = PBXBuildFile; fileRef = EEAD17802882E48D009388DD /* SingingListView.swift */; }; EEAD17842882E4CD009388DD /* SingingListCellView.swift in Sources */ = {isa = PBXBuildFile; fileRef = EEAD17832882E4CD009388DD /* SingingListCellView.swift */; }; EEAD17862882FB6C009388DD /* SongEditButtonView.swift in Sources */ = {isa = PBXBuildFile; fileRef = EEAD17852882FB6C009388DD /* SongEditButtonView.swift */; }; + EEB6BDE228E46BD30017297B /* BindingExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = EEB6BDE128E46BD30017297B /* BindingExtension.swift */; }; EEC3B54A28839F250036BE34 /* TabBarItemView.swift in Sources */ = {isa = PBXBuildFile; fileRef = EEC3B54928839F250036BE34 /* TabBarItemView.swift */; }; EEC3B54C28839FB30036BE34 /* TabBarView.swift in Sources */ = {isa = PBXBuildFile; fileRef = EEC3B54B28839FB30036BE34 /* TabBarView.swift */; }; EEC3B54E2883A79C0036BE34 /* MainView.swift in Sources */ = {isa = PBXBuildFile; fileRef = EEC3B54D2883A79C0036BE34 /* MainView.swift */; }; @@ -97,6 +98,7 @@ EEAD17802882E48D009388DD /* SingingListView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SingingListView.swift; sourceTree = ""; }; EEAD17832882E4CD009388DD /* SingingListCellView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SingingListCellView.swift; sourceTree = ""; }; EEAD17852882FB6C009388DD /* SongEditButtonView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SongEditButtonView.swift; sourceTree = ""; }; + EEB6BDE128E46BD30017297B /* BindingExtension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BindingExtension.swift; sourceTree = ""; }; EEC3B54928839F250036BE34 /* TabBarItemView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TabBarItemView.swift; sourceTree = ""; }; EEC3B54B28839FB30036BE34 /* TabBarView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TabBarView.swift; sourceTree = ""; }; EEC3B54D2883A79C0036BE34 /* MainView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MainView.swift; sourceTree = ""; }; @@ -280,6 +282,7 @@ children = ( EEAD177C2882BE63009388DD /* ColorExtension.swift */, 209E12E42883F1F9006FB3A8 /* ViewExtension.swift */, + EEB6BDE128E46BD30017297B /* BindingExtension.swift */, ); path = Extensions; sourceTree = ""; @@ -464,6 +467,7 @@ 209E12E52883F1F9006FB3A8 /* ViewExtension.swift in Sources */, 3916A1392883AD0500C21828 /* Song+CoreDataClass.swift in Sources */, 3928C5A028A18962006D3D19 /* FinalConfirmButtonView.swift in Sources */, + EEB6BDE228E46BD30017297B /* BindingExtension.swift in Sources */, 39FE869B28828DBD00D0F24F /* TestModel.swift in Sources */, 3916A13B2883AD0500C21828 /* SingingList+CoreDataClass.swift in Sources */, B2983F7228A2C6E50064C79A /* NavigationUtil.swift in Sources */, diff --git a/Semo.xcodeproj/xcuserdata/jungin-yoo.xcuserdatad/xcschemes/xcschememanagement.plist b/Semo.xcodeproj/xcuserdata/jungin-yoo.xcuserdatad/xcschemes/xcschememanagement.plist index 2b54e1a..edc65c1 100644 --- a/Semo.xcodeproj/xcuserdata/jungin-yoo.xcuserdatad/xcschemes/xcschememanagement.plist +++ b/Semo.xcodeproj/xcuserdata/jungin-yoo.xcuserdatad/xcschemes/xcschememanagement.plist @@ -7,7 +7,7 @@ Semo.xcscheme_^#shared#^_ orderHint - 0 + 1 diff --git a/Semo/Extensions/BindingExtension.swift b/Semo/Extensions/BindingExtension.swift new file mode 100644 index 0000000..5d20e37 --- /dev/null +++ b/Semo/Extensions/BindingExtension.swift @@ -0,0 +1,12 @@ +// +// BindingExtension.swift +// Semo +// +// Created by 유정인 on 2022/09/28. +// +// +//import SwiftUI +// +//extension Binding { +// init( +//} diff --git a/Semo/Extensions/ViewExtension.swift b/Semo/Extensions/ViewExtension.swift index a320024..125ad5e 100644 --- a/Semo/Extensions/ViewExtension.swift +++ b/Semo/Extensions/ViewExtension.swift @@ -16,7 +16,7 @@ extension View { /// - Parameter isEditing: 텍스트 필드 편집 여부 확인 /// - Parameter isFull: 텍스트 필드 공백 여부 확인 /// - Returns: 텍스트 필드 뷰 - func underlineTextField(isEditing : Bool, isFull: Bool, inset: CGFloat) -> some View { + func underlineTextField(isEditing : Bool, isFull: Bool, inset: CGFloat, active: Bool = true) -> some View { var lineColor: Color = Color.grayScale4 if isEditing == true { lineColor = Color.mainPurpleColor @@ -24,7 +24,11 @@ extension View { if isFull == true && isEditing == false { lineColor = Color.grayScale2 } + if active == false { + lineColor = Color.clear + } return self + //TODO: - 불필요한 패딩값 삭제 // .padding(.vertical, 10) .overlay(Rectangle().frame(height: 2).padding(.top, inset)) .padding(10) diff --git a/Semo/Views/SingingList/SingingListCellView.swift b/Semo/Views/SingingList/SingingListCellView.swift index a4bf2c3..21cc912 100644 --- a/Semo/Views/SingingList/SingingListCellView.swift +++ b/Semo/Views/SingingList/SingingListCellView.swift @@ -26,7 +26,7 @@ struct SingingListCellView: View { // TODO: - animation(_:value:)로 변경 .animation(.easeInOut) } - NavigationLink(destination: SingingListDetailView(listEditButtonTap: $listEditButtonTap, songEditButtonTap: $songEditButtonTap, singingList: singingList)) { + NavigationLink(destination: SingingListDetailView(listEditButtonTap: $listEditButtonTap, songEditButtonTap: $songEditButtonTap, singingList: singingList, singingListTitle: singingList.title ?? "제목없음")) { // MARK: - 노래 정보 표시 VStack(alignment: .leading, spacing: 10) { Text(singingList.title ?? "제목없음") diff --git a/Semo/Views/SingingListDetail/SingingListDetailCellView.swift b/Semo/Views/SingingListDetail/SingingListDetailCellView.swift index 254508c..0412c57 100644 --- a/Semo/Views/SingingListDetail/SingingListDetailCellView.swift +++ b/Semo/Views/SingingListDetail/SingingListDetailCellView.swift @@ -9,7 +9,9 @@ import SwiftUI struct SingingListDetailCellView: View { @Binding var songEditButtonTap: Bool + var singingList: SingingList + // MARK: - BODY var body: some View { VStack { @@ -29,7 +31,6 @@ struct SingingListDetailCellView: View { .background(Color.grayScale6) .frame(width: 350) ForEach(singingList.songArray) { - // TODO: coreData에서 가져온 데이터 넣어주기 SongListCellView(songEditButtonTap: $songEditButtonTap, song: $0) Divider() .background(Color.grayScale6) diff --git a/Semo/Views/SingingListDetail/SingingListDetailView.swift b/Semo/Views/SingingListDetail/SingingListDetailView.swift index 1e26a2c..1803a38 100644 --- a/Semo/Views/SingingListDetail/SingingListDetailView.swift +++ b/Semo/Views/SingingListDetail/SingingListDetailView.swift @@ -10,13 +10,18 @@ import SwiftUI struct SingingListDetailView: View { @Environment(\.presentationMode) var presentationMode: Binding @GestureState private var dragOffset = CGSize.zero - @State var singingListTitle: String = "" @State var isSingingListTitleEditing: Bool = false @Binding var listEditButtonTap: Bool @Binding var songEditButtonTap: Bool - + var singingList: SingingList + @State var singingListTitle: String { + willSet { + singingListTitle = singingList.title ?? "제목없음" + } + } + // MARK: - BODY var body: some View { ZStack { @@ -26,46 +31,57 @@ struct SingingListDetailView: View { Rectangle() .edgesIgnoringSafeArea(.all) .frame(height: UIScreen.main.bounds.height * 0.16) - .foregroundColor(listEditButtonTap == true ? .grayScale7 : .grayScale6) - .opacity(listEditButtonTap == true ? 1 : 0.4) + .foregroundColor(songEditButtonTap == true ? .grayScale7 : .grayScale6) + .opacity(songEditButtonTap == true ? 1 : 0.4) Spacer() } - VStack { HStack { TextField("", text: $singingListTitle, onEditingChanged: { changed in self.isSingingListTitleEditing = changed }) + .font(.system(size: 24, weight: .semibold)) + .foregroundColor(.white) .placeholder(when: singingListTitle.isEmpty) { - Text("\(singingList.title ?? "제목없음")") - .font(.system(size: 35, weight: .bold)) - .foregroundColor(.white) + Text("빠른 싱잉리스트") + .font(.system(size: 24, weight: .semibold)) + .foregroundColor(.grayScale2) } + .disabled(!songEditButtonTap) } - .underlineTextField(isEditing: isSingingListTitleEditing, isFull: !singingListTitle.isEmpty, inset: 60) + .underlineTextField(isEditing: isSingingListTitleEditing, isFull: !singingListTitle.isEmpty, inset: 55, active: songEditButtonTap) .padding(.horizontal, 10) Spacer() } - .padding(.top, 60) + .padding(.top, 65) SingingListDetailCellView(songEditButtonTap: $songEditButtonTap, singingList: singingList) - .padding(.top, 40) + .padding(.top, 35) } -// .navigationBarTitle(singingList.title ?? "제목 없음") -// .navigationBarTitleDisplayMode(.large) .toolbar { ToolbarItem(placement: .navigationBarTrailing) { - SongEditButtonView(buttonName: listEditButtonTap == true ? "완료" : "편집", buttonWidth: 50) { - self.listEditButtonTap.toggle() + SongEditButtonView(buttonName: songEditButtonTap == true ? "완료" : "편집", buttonWidth: 50) { + self.songEditButtonTap.toggle() } .padding(.trailing, 20) } } .toolbar { ToolbarItem(placement: .navigationBarLeading) { - CustomBackButton(buttonName: "") { - self.presentationMode.wrappedValue.dismiss() + if songEditButtonTap == false { + CustomBackButton(buttonName: "") { + self.presentationMode.wrappedValue.dismiss() + } + .navigationBarBackButtonHidden(true) + } else { + Button { + print("리스트 편집 그만하기") + } label: { + Image(systemName: "xmark") + .font(.system(size: 16, weight: .medium)) + .foregroundColor(.white) + } + .navigationBarBackButtonHidden(true) } - .navigationBarBackButtonHidden(true) } } .gesture(DragGesture().updating($dragOffset) { (value, state, transaction) in @@ -73,5 +89,8 @@ struct SingingListDetailView: View { self.presentationMode.wrappedValue.dismiss() } }) + .onDisappear { + self.songEditButtonTap = false + } } } From c3a7a2e93b7d7953c86e9df3fe20bc28a254d354 Mon Sep 17 00:00:00 2001 From: Thina Date: Wed, 28 Sep 2022 22:35:49 +0900 Subject: [PATCH 3/4] =?UTF-8?q?[feat]=20#89=20=EB=A6=AC=EC=8A=A4=ED=8A=B8?= =?UTF-8?q?=20=ED=8E=B8=EC=A7=91=20=EC=A4=91=20X=20=EB=B2=84=ED=8A=BC=20?= =?UTF-8?q?=ED=84=B0=EC=B9=98=20=EC=8B=9C=20=EB=B0=9C=EC=83=9D=ED=95=98?= =?UTF-8?q?=EB=8A=94=20=EC=95=8C=EB=A6=BC=20=EA=B8=B0=EB=8A=A5=20=EA=B5=AC?= =?UTF-8?q?=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../SingingListDetail/SingingListDetailCellView.swift | 3 ++- .../SingingListDetail/SingingListDetailView.swift | 11 +++++++++++ 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/Semo/Views/SingingListDetail/SingingListDetailCellView.swift b/Semo/Views/SingingListDetail/SingingListDetailCellView.swift index 0412c57..869362f 100644 --- a/Semo/Views/SingingListDetail/SingingListDetailCellView.swift +++ b/Semo/Views/SingingListDetail/SingingListDetailCellView.swift @@ -37,7 +37,8 @@ struct SingingListDetailCellView: View { .frame(width: 350) } .padding(.top, 10) - AddSongButtonView() + // TODO: - 이후 업데이트에서 새 노래 추가가 아닌 기존 노래 추가로 기능 변경 +// AddSongButtonView() Spacer() } diff --git a/Semo/Views/SingingListDetail/SingingListDetailView.swift b/Semo/Views/SingingListDetail/SingingListDetailView.swift index 1803a38..51d4711 100644 --- a/Semo/Views/SingingListDetail/SingingListDetailView.swift +++ b/Semo/Views/SingingListDetail/SingingListDetailView.swift @@ -11,6 +11,7 @@ struct SingingListDetailView: View { @Environment(\.presentationMode) var presentationMode: Binding @GestureState private var dragOffset = CGSize.zero @State var isSingingListTitleEditing: Bool = false + @State private var showSaveAlert: Bool = false @Binding var listEditButtonTap: Bool @Binding var songEditButtonTap: Bool @@ -74,6 +75,7 @@ struct SingingListDetailView: View { .navigationBarBackButtonHidden(true) } else { Button { + self.showSaveAlert = true print("리스트 편집 그만하기") } label: { Image(systemName: "xmark") @@ -81,6 +83,15 @@ struct SingingListDetailView: View { .foregroundColor(.white) } .navigationBarBackButtonHidden(true) + .alert("변경사항을 저장하시겠습니까?", isPresented: $showSaveAlert) { + Button("아니요", role: .cancel) { + self.presentationMode.wrappedValue.dismiss() + } + Button("저장", role: .none) { + // TODO: - 리스트 데이터 변경사항 코어데이터에 저장하는 코드 + self.presentationMode.wrappedValue.dismiss() + } + } } } } From eabd852be506cbf06570a2d74defa4905e49de69 Mon Sep 17 00:00:00 2001 From: Thina Date: Thu, 29 Sep 2022 23:12:11 +0900 Subject: [PATCH 4/4] =?UTF-8?q?[refactor]=20#89=20=EB=A6=AC=EC=8A=A4?= =?UTF-8?q?=ED=8A=B8=20=ED=8E=B8=EC=A7=91=20=EB=B7=B0=20=EC=BD=94=EB=93=9C?= =?UTF-8?q?=20=EB=A6=AC=ED=8E=99=ED=86=A0=EB=A7=81=20=EB=B0=8F=20=EB=B3=80?= =?UTF-8?q?=EC=88=98=20=EB=84=A4=EC=9D=B4=EB=B0=8D=20=EB=B3=80=EA=B2=BD,?= =?UTF-8?q?=20=ED=95=A8=EC=88=98=20=ED=8C=8C=EB=9D=BC=EB=AF=B8=ED=84=B0=20?= =?UTF-8?q?=EC=84=A4=EB=AA=85=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Semo.xcodeproj/project.pbxproj | 4 -- Semo/Extensions/BindingExtension.swift | 12 ---- Semo/Extensions/ViewExtension.swift | 2 + Semo/Views/MainView.swift | 8 +-- .../DeleteSingingListButtonView.swift | 4 +- .../SingingList/SingingListCellView.swift | 12 ++-- Semo/Views/SingingList/SingingListView.swift | 10 ++-- .../SingingListDetailView.swift | 60 +++++++++---------- 8 files changed, 46 insertions(+), 66 deletions(-) delete mode 100644 Semo/Extensions/BindingExtension.swift diff --git a/Semo.xcodeproj/project.pbxproj b/Semo.xcodeproj/project.pbxproj index 9d0a710..d4c63d9 100644 --- a/Semo.xcodeproj/project.pbxproj +++ b/Semo.xcodeproj/project.pbxproj @@ -46,7 +46,6 @@ EEAD17812882E48D009388DD /* SingingListView.swift in Sources */ = {isa = PBXBuildFile; fileRef = EEAD17802882E48D009388DD /* SingingListView.swift */; }; EEAD17842882E4CD009388DD /* SingingListCellView.swift in Sources */ = {isa = PBXBuildFile; fileRef = EEAD17832882E4CD009388DD /* SingingListCellView.swift */; }; EEAD17862882FB6C009388DD /* SongEditButtonView.swift in Sources */ = {isa = PBXBuildFile; fileRef = EEAD17852882FB6C009388DD /* SongEditButtonView.swift */; }; - EEB6BDE228E46BD30017297B /* BindingExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = EEB6BDE128E46BD30017297B /* BindingExtension.swift */; }; EEC3B54A28839F250036BE34 /* TabBarItemView.swift in Sources */ = {isa = PBXBuildFile; fileRef = EEC3B54928839F250036BE34 /* TabBarItemView.swift */; }; EEC3B54C28839FB30036BE34 /* TabBarView.swift in Sources */ = {isa = PBXBuildFile; fileRef = EEC3B54B28839FB30036BE34 /* TabBarView.swift */; }; EEC3B54E2883A79C0036BE34 /* MainView.swift in Sources */ = {isa = PBXBuildFile; fileRef = EEC3B54D2883A79C0036BE34 /* MainView.swift */; }; @@ -98,7 +97,6 @@ EEAD17802882E48D009388DD /* SingingListView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SingingListView.swift; sourceTree = ""; }; EEAD17832882E4CD009388DD /* SingingListCellView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SingingListCellView.swift; sourceTree = ""; }; EEAD17852882FB6C009388DD /* SongEditButtonView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SongEditButtonView.swift; sourceTree = ""; }; - EEB6BDE128E46BD30017297B /* BindingExtension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BindingExtension.swift; sourceTree = ""; }; EEC3B54928839F250036BE34 /* TabBarItemView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TabBarItemView.swift; sourceTree = ""; }; EEC3B54B28839FB30036BE34 /* TabBarView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TabBarView.swift; sourceTree = ""; }; EEC3B54D2883A79C0036BE34 /* MainView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MainView.swift; sourceTree = ""; }; @@ -282,7 +280,6 @@ children = ( EEAD177C2882BE63009388DD /* ColorExtension.swift */, 209E12E42883F1F9006FB3A8 /* ViewExtension.swift */, - EEB6BDE128E46BD30017297B /* BindingExtension.swift */, ); path = Extensions; sourceTree = ""; @@ -467,7 +464,6 @@ 209E12E52883F1F9006FB3A8 /* ViewExtension.swift in Sources */, 3916A1392883AD0500C21828 /* Song+CoreDataClass.swift in Sources */, 3928C5A028A18962006D3D19 /* FinalConfirmButtonView.swift in Sources */, - EEB6BDE228E46BD30017297B /* BindingExtension.swift in Sources */, 39FE869B28828DBD00D0F24F /* TestModel.swift in Sources */, 3916A13B2883AD0500C21828 /* SingingList+CoreDataClass.swift in Sources */, B2983F7228A2C6E50064C79A /* NavigationUtil.swift in Sources */, diff --git a/Semo/Extensions/BindingExtension.swift b/Semo/Extensions/BindingExtension.swift deleted file mode 100644 index 5d20e37..0000000 --- a/Semo/Extensions/BindingExtension.swift +++ /dev/null @@ -1,12 +0,0 @@ -// -// BindingExtension.swift -// Semo -// -// Created by 유정인 on 2022/09/28. -// -// -//import SwiftUI -// -//extension Binding { -// init( -//} diff --git a/Semo/Extensions/ViewExtension.swift b/Semo/Extensions/ViewExtension.swift index 125ad5e..7bf8ee8 100644 --- a/Semo/Extensions/ViewExtension.swift +++ b/Semo/Extensions/ViewExtension.swift @@ -15,6 +15,8 @@ extension View { /// 텍스트 필드 밑줄 커스텀 및 입력 여부에 따라 색이 변화합니다. /// - Parameter isEditing: 텍스트 필드 편집 여부 확인 /// - Parameter isFull: 텍스트 필드 공백 여부 확인 + /// - Parameter inset: 텍스트와 밑줄 간의 간격 + /// - Parameter active: 밑줄 활성화 여부 /// - Returns: 텍스트 필드 뷰 func underlineTextField(isEditing : Bool, isFull: Bool, inset: CGFloat, active: Bool = true) -> some View { var lineColor: Color = Color.grayScale4 diff --git a/Semo/Views/MainView.swift b/Semo/Views/MainView.swift index c120827..ab168c8 100644 --- a/Semo/Views/MainView.swift +++ b/Semo/Views/MainView.swift @@ -9,8 +9,8 @@ import SwiftUI struct MainView: View { @State var currentTab: Int = 0 - @State var songEditButtonTap: Bool = false - @State var listEditButtonTap: Bool = false + @State var songEditButtonTapped: Bool = false + @State var listEditButtonTapped: Bool = false @State var songList: [Song] = CoreDataManager.shared.fetchSongList() ?? [] // MARK: - BODY @@ -22,8 +22,8 @@ struct MainView: View { // MARK: - 상단 탭바 TabView(selection: self.$currentTab) { - SongListView(refresh: $currentTab, songEditButtonTap: $songEditButtonTap).tag(0) - SingingListView(refresh: $currentTab, songEditButtonTap: $songEditButtonTap, listEditButtonTap: $listEditButtonTap).tag(1) + SongListView(refresh: $currentTab, songEditButtonTap: $songEditButtonTapped).tag(0) + SingingListView(refresh: $currentTab, songEditButtonTapped: $songEditButtonTapped, listEditButtonTapped: $listEditButtonTapped).tag(1) } .tabViewStyle(.page(indexDisplayMode: .never)) .edgesIgnoringSafeArea(.all) diff --git a/Semo/Views/SingingList/DeleteSingingListButtonView.swift b/Semo/Views/SingingList/DeleteSingingListButtonView.swift index 025e35e..c883445 100644 --- a/Semo/Views/SingingList/DeleteSingingListButtonView.swift +++ b/Semo/Views/SingingList/DeleteSingingListButtonView.swift @@ -9,7 +9,7 @@ import SwiftUI struct DeleteSingingListButtonView: View { @State var showDeleteAlert: Bool = false - @Binding var listEditButtonTap: Bool + @Binding var listEditButtonTapped: Bool var singingList: SingingList @@ -26,7 +26,7 @@ struct DeleteSingingListButtonView: View { Button("삭제", role: .destructive) { // TODO: - 리스트 삭제 코드 CoreDataManager.shared.deleteSingingList(singingList: singingList) - listEditButtonTap = false + listEditButtonTapped = false } } } diff --git a/Semo/Views/SingingList/SingingListCellView.swift b/Semo/Views/SingingList/SingingListCellView.swift index 21cc912..73b71fd 100644 --- a/Semo/Views/SingingList/SingingListCellView.swift +++ b/Semo/Views/SingingList/SingingListCellView.swift @@ -9,8 +9,8 @@ import SwiftUI struct SingingListCellView: View { @Binding var refresh: Int - @Binding var songEditButtonTap: Bool - @Binding var listEditButtonTap: Bool + @Binding var songEditButtonTapped: Bool + @Binding var listEditButtonTapped: Bool var singingList: SingingList @@ -19,14 +19,14 @@ struct SingingListCellView: View { Button { } label: { HStack { - if listEditButtonTap == true { - DeleteSingingListButtonView(listEditButtonTap: $listEditButtonTap, singingList: singingList) + if listEditButtonTapped == true { + DeleteSingingListButtonView(listEditButtonTapped: $listEditButtonTapped, singingList: singingList) .padding(.trailing, 8) .transition(.move(edge: .leading)) // TODO: - animation(_:value:)로 변경 .animation(.easeInOut) } - NavigationLink(destination: SingingListDetailView(listEditButtonTap: $listEditButtonTap, songEditButtonTap: $songEditButtonTap, singingList: singingList, singingListTitle: singingList.title ?? "제목없음")) { + NavigationLink(destination: SingingListDetailView(listEditButtonTapped: $listEditButtonTapped, songEditButtonTapped: $songEditButtonTapped, singingList: singingList, singingListTitle: singingList.title ?? "제목없음")) { // MARK: - 노래 정보 표시 VStack(alignment: .leading, spacing: 10) { Text(singingList.title ?? "제목없음") @@ -44,7 +44,7 @@ struct SingingListCellView: View { .scaledToFit() .foregroundColor(.grayScale1) } - .disabled(listEditButtonTap) + .disabled(listEditButtonTapped) } .padding(.horizontal, 20) } diff --git a/Semo/Views/SingingList/SingingListView.swift b/Semo/Views/SingingList/SingingListView.swift index fdc5205..316e89d 100644 --- a/Semo/Views/SingingList/SingingListView.swift +++ b/Semo/Views/SingingList/SingingListView.swift @@ -11,8 +11,8 @@ struct SingingListView: View { @Environment(\.managedObjectContext) private var viewContext @FetchRequest(sortDescriptors: [NSSortDescriptor(keyPath: \SingingList.timestamp, ascending: true)], animation: .default) private var singingList: FetchedResults @Binding var refresh: Int - @Binding var songEditButtonTap: Bool - @Binding var listEditButtonTap: Bool + @Binding var songEditButtonTapped: Bool + @Binding var listEditButtonTapped: Bool // MARK: - BODY var body: some View { @@ -25,7 +25,7 @@ struct SingingListView: View { .fontWeight(.medium) Spacer() SongEditButtonView(buttonName: "리스트 편집", buttonWidth: 93) { - self.listEditButtonTap.toggle() + self.listEditButtonTapped.toggle() } } .padding(EdgeInsets(top: 15, leading: 20, bottom: 15, trailing: 30)) @@ -35,7 +35,7 @@ struct SingingListView: View { .background(Color.grayScale6) .frame(width: 350) ForEach(singingList) { - SingingListCellView(refresh: $refresh, songEditButtonTap: $songEditButtonTap, listEditButtonTap: $listEditButtonTap, singingList: $0) + SingingListCellView(refresh: $refresh, songEditButtonTapped: $songEditButtonTapped, listEditButtonTapped: $listEditButtonTapped, singingList: $0) Divider() .background(Color.grayScale6) .frame(width: 350) @@ -46,7 +46,7 @@ struct SingingListView: View { } .padding(.top, 80) .onDisappear { - self.listEditButtonTap = false + self.listEditButtonTapped = false } } } diff --git a/Semo/Views/SingingListDetail/SingingListDetailView.swift b/Semo/Views/SingingListDetail/SingingListDetailView.swift index 51d4711..20334ae 100644 --- a/Semo/Views/SingingListDetail/SingingListDetailView.swift +++ b/Semo/Views/SingingListDetail/SingingListDetailView.swift @@ -12,8 +12,8 @@ struct SingingListDetailView: View { @GestureState private var dragOffset = CGSize.zero @State var isSingingListTitleEditing: Bool = false @State private var showSaveAlert: Bool = false - @Binding var listEditButtonTap: Bool - @Binding var songEditButtonTap: Bool + @Binding var listEditButtonTapped: Bool + @Binding var songEditButtonTapped: Bool var singingList: SingingList @@ -28,47 +28,40 @@ struct SingingListDetailView: View { ZStack { Image("backgroundImage") .edgesIgnoringSafeArea(.vertical) - VStack { - Rectangle() - .edgesIgnoringSafeArea(.all) - .frame(height: UIScreen.main.bounds.height * 0.16) - .foregroundColor(songEditButtonTap == true ? .grayScale7 : .grayScale6) - .opacity(songEditButtonTap == true ? 1 : 0.4) - Spacer() + Rectangle() + .edgesIgnoringSafeArea(.all) + .frame(height: UIScreen.main.bounds.height * 0.16) + .foregroundColor(songEditButtonTapped == true ? .grayScale7 : .grayScale6) + .opacity(songEditButtonTapped == true ? 1 : 0.4) + .padding(.bottom, 700) + TextField("", text: $singingListTitle, onEditingChanged: { changed in + self.isSingingListTitleEditing = changed + }) + .font(.system(size: 28, weight: .semibold)) + .foregroundColor(.white) + .placeholder(when: singingListTitle.isEmpty) { + Text(singingList.title ?? "제목없음") + .font(.system(size: 28, weight: .semibold)) + .foregroundColor(.grayScale2) } - VStack { - HStack { - TextField("", text: $singingListTitle, onEditingChanged: { changed in - self.isSingingListTitleEditing = changed - }) - .font(.system(size: 24, weight: .semibold)) - .foregroundColor(.white) - .placeholder(when: singingListTitle.isEmpty) { - Text("빠른 싱잉리스트") - .font(.system(size: 24, weight: .semibold)) - .foregroundColor(.grayScale2) - } - .disabled(!songEditButtonTap) - } - .underlineTextField(isEditing: isSingingListTitleEditing, isFull: !singingListTitle.isEmpty, inset: 55, active: songEditButtonTap) - .padding(.horizontal, 10) - Spacer() - } - .padding(.top, 65) - SingingListDetailCellView(songEditButtonTap: $songEditButtonTap, singingList: singingList) + .disabled(!songEditButtonTapped) + .underlineTextField(isEditing: isSingingListTitleEditing, isFull: !singingListTitle.isEmpty, inset: 55, active: songEditButtonTapped) + .padding(.horizontal, 10) + .padding(.bottom, 650) + SingingListDetailCellView(songEditButtonTap: $songEditButtonTapped, singingList: singingList) .padding(.top, 35) } .toolbar { ToolbarItem(placement: .navigationBarTrailing) { - SongEditButtonView(buttonName: songEditButtonTap == true ? "완료" : "편집", buttonWidth: 50) { - self.songEditButtonTap.toggle() + SongEditButtonView(buttonName: songEditButtonTapped == true ? "완료" : "편집", buttonWidth: 50) { + self.songEditButtonTapped.toggle() } .padding(.trailing, 20) } } .toolbar { ToolbarItem(placement: .navigationBarLeading) { - if songEditButtonTap == false { + if songEditButtonTapped == false { CustomBackButton(buttonName: "") { self.presentationMode.wrappedValue.dismiss() } @@ -97,11 +90,12 @@ struct SingingListDetailView: View { } .gesture(DragGesture().updating($dragOffset) { (value, state, transaction) in if (value.startLocation.x < 30 && value.translation.width > 100) { + // TODO: - 변경된 값이 있는 경우 swipeback alert 띄우기 self.presentationMode.wrappedValue.dismiss() } }) .onDisappear { - self.songEditButtonTap = false + self.songEditButtonTapped = false } } }