From 762d6e96113fb271833de89c65ca3f69c44347d0 Mon Sep 17 00:00:00 2001 From: zekuta-x Date: Mon, 20 Feb 2023 13:22:16 +0900 Subject: [PATCH 1/6] =?UTF-8?q?[fix]=20atom/textfield=E3=81=AE=E4=BF=AE?= =?UTF-8?q?=E6=AD=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../View/Atom/TextField.swift | 52 +++++++++++++------ 1 file changed, 35 insertions(+), 17 deletions(-) diff --git a/portfolio-ios-swiftui/portfolio-ios-swiftui/View/Atom/TextField.swift b/portfolio-ios-swiftui/portfolio-ios-swiftui/View/Atom/TextField.swift index 1c5f210..35237d7 100644 --- a/portfolio-ios-swiftui/portfolio-ios-swiftui/View/Atom/TextField.swift +++ b/portfolio-ios-swiftui/portfolio-ios-swiftui/View/Atom/TextField.swift @@ -4,28 +4,46 @@ // // Created by fun_massu on 2022/09/26. // + import SwiftUI + struct TextBox: View { - @State private var inputText = "" - let text: String + + let fieldHide: Bool + let titleText: String + let descriptionText: String + + @Binding var inputText: String + var body: some View { - VStack(alignment: .leading) { - Text(text) - .foregroundColor(Color.text) - TextField("入力してください", text: $inputText) - .frame(width: 240, height: 40) - .padding(.leading, 15) - .overlay(RoundedRectangle(cornerRadius: 20) - .stroke(Color.grayBottonColor, lineWidth: 2) - ) - .padding(.leading, 25) + TextView(text: titleText, textPattern: 0) + + if fieldHide { + SecureField(descriptionText, text: $inputText) + .frame(width: 294, height: 48) + .padding(.leading, 15) + .overlay(RoundedRectangle(cornerRadius: 15) + .stroke(Color.grayBottonColor, lineWidth: 2) + ) + .padding(.leading, 25) + } else { + TextField(descriptionText, text: $inputText) + .frame(width: 294, height: 48) + .padding(.leading, 15) + .overlay(RoundedRectangle(cornerRadius: 15) + .stroke(Color.grayBottonColor, lineWidth: 2) + ) + .padding(.leading, 25) + } } } } -struct TextBox_Previews: PreviewProvider { - static var previews: some View { - TextBox(text: "メールアドレス") - } -} +//struct TextBox_Previews: PreviewProvider { +// @State private var test = "" +// +// static var previews: some View { +// TextBox(titleText: "メールアドレス", inputText: $test) +// } +//} From c5775bdfdd254f7cd02c835e72849d200a49a405 Mon Sep 17 00:00:00 2001 From: zekuta-x Date: Mon, 20 Feb 2023 16:13:52 +0900 Subject: [PATCH 2/6] =?UTF-8?q?[add]=20pulldown=E3=81=AE=E3=83=86=E3=83=B3?= =?UTF-8?q?=E3=83=97=E3=83=AC=E8=BF=BD=E5=8A=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../View/Atom/PullDownSelectView.swift | 42 +++++++++++++++++++ 1 file changed, 42 insertions(+) create mode 100644 portfolio-ios-swiftui/portfolio-ios-swiftui/View/Atom/PullDownSelectView.swift diff --git a/portfolio-ios-swiftui/portfolio-ios-swiftui/View/Atom/PullDownSelectView.swift b/portfolio-ios-swiftui/portfolio-ios-swiftui/View/Atom/PullDownSelectView.swift new file mode 100644 index 0000000..6a9edd9 --- /dev/null +++ b/portfolio-ios-swiftui/portfolio-ios-swiftui/View/Atom/PullDownSelectView.swift @@ -0,0 +1,42 @@ +// +// PullDownSelectView.swift +// portfolio-ios-swiftui +// +// Created by 鳥山英峻 on 2023/02/20. +// + +import SwiftUI + +struct PullDownSelectView: View { + + var labelName: String + + @State var selectList = [""] + @State var startSelection = "" + + var body: some View { + VStack(alignment: .leading) { + TextView(text: labelName, textPattern: 0) + + Picker("", selection: $startSelection) { + ForEach($selectList, id: \.self) { item in + // @Stateで参照しているためwrappedValueを用いる + Text(item.wrappedValue) + } + } + .accentColor(.black) + .frame(width: 294, height: 48) + .padding(.leading, 15) + .overlay(RoundedRectangle(cornerRadius: 15) + .stroke(Color.grayBottonColor, lineWidth: 2) + ) + .padding(.leading, 25) + } + } +} + +// struct PullDownSelectView_Previews: PreviewProvider { +// static var previews: some View { +// PullDownSelectView(labelName: "あああああ", selectList: ["aaa", "bbb", "ccc", "ddd"], startSelection: "") +// } +// } From 8dd652e514a3682d09e52e867c2873d1781ae4da Mon Sep 17 00:00:00 2001 From: zekuta-x Date: Mon, 20 Feb 2023 16:15:11 +0900 Subject: [PATCH 3/6] =?UTF-8?q?[add]=20signup=E3=83=9A=E3=83=BC=E3=82=B8?= =?UTF-8?q?=E3=81=AE=E3=83=AF=E3=82=A4=E3=83=A4=E3=83=95=E3=83=AC=E3=83=BC?= =?UTF-8?q?=E3=83=A0=E4=BD=9C=E6=88=90?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../project.pbxproj | 21 ++++- .../userIcon_plus.imageset/Contents.json | 21 +++++ .../userIcon_plus.imageset/userIcon_plus.png | Bin 0 -> 15547 bytes .../Assets.xcassets/userIcon_plus.png | Bin 0 -> 15547 bytes .../SignUp/SignUpPage.swift | 89 ++++++++++++++++++ 5 files changed, 128 insertions(+), 3 deletions(-) create mode 100644 portfolio-ios-swiftui/portfolio-ios-swiftui/Assets.xcassets/userIcon_plus.imageset/Contents.json create mode 100644 portfolio-ios-swiftui/portfolio-ios-swiftui/Assets.xcassets/userIcon_plus.imageset/userIcon_plus.png create mode 100644 portfolio-ios-swiftui/portfolio-ios-swiftui/Assets.xcassets/userIcon_plus.png create mode 100644 portfolio-ios-swiftui/portfolio-ios-swiftui/SignUp/SignUpPage.swift diff --git a/portfolio-ios-swiftui/portfolio-ios-swiftui.xcodeproj/project.pbxproj b/portfolio-ios-swiftui/portfolio-ios-swiftui.xcodeproj/project.pbxproj index 26e7fb9..08ce14b 100644 --- a/portfolio-ios-swiftui/portfolio-ios-swiftui.xcodeproj/project.pbxproj +++ b/portfolio-ios-swiftui/portfolio-ios-swiftui.xcodeproj/project.pbxproj @@ -12,8 +12,10 @@ AA31E7F828EAD00B00DCE061 /* FloatingActionButtonView.swift in Sources */ = {isa = PBXBuildFile; fileRef = AA31E7F728EAD00B00DCE061 /* FloatingActionButtonView.swift */; }; AA31E7FA28F542C700DCE061 /* TestView1.swift in Sources */ = {isa = PBXBuildFile; fileRef = AA31E7F928F542C700DCE061 /* TestView1.swift */; }; AA31E7FC28F542D900DCE061 /* TestView2.swift in Sources */ = {isa = PBXBuildFile; fileRef = AA31E7FB28F542D900DCE061 /* TestView2.swift */; }; - AADD20EC292B6A45008EE02E /* PublishingSettingToggleButtonView.swift in Sources */ = {isa = PBXBuildFile; fileRef = AADD20EB292B6A45008EE02E /* PublishingSettingToggleButtonView.swift */; }; AA31E800290F9C9F00DCE061 /* TabBarView.swift in Sources */ = {isa = PBXBuildFile; fileRef = AA31E7FF290F9C9F00DCE061 /* TabBarView.swift */; }; + AADD20EC292B6A45008EE02E /* PublishingSettingToggleButtonView.swift in Sources */ = {isa = PBXBuildFile; fileRef = AADD20EB292B6A45008EE02E /* PublishingSettingToggleButtonView.swift */; }; + AB2187C829A21CBF00B54172 /* SignUpPage.swift in Sources */ = {isa = PBXBuildFile; fileRef = AB2187C729A21CBF00B54172 /* SignUpPage.swift */; }; + AB2187CA29A3412600B54172 /* PullDownSelectView.swift in Sources */ = {isa = PBXBuildFile; fileRef = AB2187C929A3412600B54172 /* PullDownSelectView.swift */; }; ABAE5BEB28604E4A008ED665 /* .swiftlint.yml in Resources */ = {isa = PBXBuildFile; fileRef = ABAE5BEA28604E4A008ED665 /* .swiftlint.yml */; }; ABAF1D1B283B78F100F890BC /* ContentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = ABAF1D1A283B78F100F890BC /* ContentView.swift */; }; ABAF1D1D283B78F800F890BC /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = ABAF1D1C283B78F800F890BC /* Assets.xcassets */; }; @@ -36,8 +38,10 @@ AA31E7F728EAD00B00DCE061 /* FloatingActionButtonView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FloatingActionButtonView.swift; sourceTree = ""; }; AA31E7F928F542C700DCE061 /* TestView1.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TestView1.swift; sourceTree = ""; }; AA31E7FB28F542D900DCE061 /* TestView2.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TestView2.swift; sourceTree = ""; }; - AADD20EB292B6A45008EE02E /* PublishingSettingToggleButtonView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PublishingSettingToggleButtonView.swift; sourceTree = ""; }; AA31E7FF290F9C9F00DCE061 /* TabBarView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TabBarView.swift; sourceTree = ""; }; + AADD20EB292B6A45008EE02E /* PublishingSettingToggleButtonView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PublishingSettingToggleButtonView.swift; sourceTree = ""; }; + AB2187C729A21CBF00B54172 /* SignUpPage.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SignUpPage.swift; sourceTree = ""; }; + AB2187C929A3412600B54172 /* PullDownSelectView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PullDownSelectView.swift; sourceTree = ""; }; ABAE5BEA28604E4A008ED665 /* .swiftlint.yml */ = {isa = PBXFileReference; lastKnownFileType = text.yaml; path = .swiftlint.yml; sourceTree = ""; }; ABAF1D15283B78F100F890BC /* portfolio-ios-swiftui.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "portfolio-ios-swiftui.app"; sourceTree = BUILT_PRODUCTS_DIR; }; ABAF1D1A283B78F100F890BC /* ContentView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContentView.swift; sourceTree = ""; }; @@ -74,6 +78,14 @@ path = Organism; sourceTree = ""; }; + AB2187C629A21C9300B54172 /* SignUp */ = { + isa = PBXGroup; + children = ( + AB2187C729A21CBF00B54172 /* SignUpPage.swift */, + ); + path = SignUp; + sourceTree = ""; + }; ABAF1D0C283B78F100F890BC = { isa = PBXGroup; children = ( @@ -94,6 +106,7 @@ ABAF1D17283B78F100F890BC /* portfolio-ios-swiftui */ = { isa = PBXGroup; children = ( + AB2187C629A21C9300B54172 /* SignUp */, ABB3AD30284DEA84004C012E /* View */, ABC44B162918F62D00BBE1A6 /* Login */, ABAF1D1A283B78F100F890BC /* ContentView.swift */, @@ -170,6 +183,7 @@ AA31E7F928F542C700DCE061 /* TestView1.swift */, AA31E7FB28F542D900DCE061 /* TestView2.swift */, AADD20EB292B6A45008EE02E /* PublishingSettingToggleButtonView.swift */, + AB2187C929A3412600B54172 /* PullDownSelectView.swift */, ); path = Atom; sourceTree = ""; @@ -269,16 +283,17 @@ ABC44B232918F62D00BBE1A6 /* User.swift in Sources */, ABDA951F286996FA00C7C735 /* TextView.swift in Sources */, 0483FA3C290669BC001866C9 /* IconView.swift in Sources */, + AB2187CA29A3412600B54172 /* PullDownSelectView.swift in Sources */, ABAF1D1B283B78F100F890BC /* ContentView.swift in Sources */, AA31E800290F9C9F00DCE061 /* TabBarView.swift in Sources */, AA31E7F828EAD00B00DCE061 /* FloatingActionButtonView.swift in Sources */, AA31E7FA28F542C700DCE061 /* TestView1.swift in Sources */, 0CFE7BC3286A2A6500CA5119 /* ButtonView.swift in Sources */, ABC44B212918F62D00BBE1A6 /* LoginPage.swift in Sources */, + AB2187C829A21CBF00B54172 /* SignUpPage.swift in Sources */, ABC44B252918F62D00BBE1A6 /* LoginService.swift in Sources */, FC7EC30D28EAC89300600302 /* TextField.swift in Sources */, AADD20EC292B6A45008EE02E /* PublishingSettingToggleButtonView.swift in Sources */, - ABAF1D19283B78F100F890BC /* portfolio_ios_swiftuiApp.swift in Sources */, ABC44B242918F62D00BBE1A6 /* APIServiceError.swift in Sources */, FC06F9E9288E85110016E401 /* ColorExtension.swift in Sources */, ABC44B202918F62D00BBE1A6 /* LoginViewModel.swift in Sources */, diff --git a/portfolio-ios-swiftui/portfolio-ios-swiftui/Assets.xcassets/userIcon_plus.imageset/Contents.json b/portfolio-ios-swiftui/portfolio-ios-swiftui/Assets.xcassets/userIcon_plus.imageset/Contents.json new file mode 100644 index 0000000..c27d044 --- /dev/null +++ b/portfolio-ios-swiftui/portfolio-ios-swiftui/Assets.xcassets/userIcon_plus.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "userIcon_plus.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/portfolio-ios-swiftui/portfolio-ios-swiftui/Assets.xcassets/userIcon_plus.imageset/userIcon_plus.png b/portfolio-ios-swiftui/portfolio-ios-swiftui/Assets.xcassets/userIcon_plus.imageset/userIcon_plus.png new file mode 100644 index 0000000000000000000000000000000000000000..86db47d967675ddd8f1e34012ecdb3ced686f2e7 GIT binary patch literal 15547 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 literal 0 HcmV?d00001 diff --git a/portfolio-ios-swiftui/portfolio-ios-swiftui/Assets.xcassets/userIcon_plus.png b/portfolio-ios-swiftui/portfolio-ios-swiftui/Assets.xcassets/userIcon_plus.png new file mode 100644 index 0000000000000000000000000000000000000000..86db47d967675ddd8f1e34012ecdb3ced686f2e7 GIT binary patch literal 15547 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 literal 0 HcmV?d00001 diff --git a/portfolio-ios-swiftui/portfolio-ios-swiftui/SignUp/SignUpPage.swift b/portfolio-ios-swiftui/portfolio-ios-swiftui/SignUp/SignUpPage.swift new file mode 100644 index 0000000..5e527b8 --- /dev/null +++ b/portfolio-ios-swiftui/portfolio-ios-swiftui/SignUp/SignUpPage.swift @@ -0,0 +1,89 @@ +// +// SignupPage.swift +// portfolio-ios-swiftui +// +// Created by 鳥山英峻 on 2023/02/19. +// + +import SwiftUI + +struct SignUpPage: View { + + @State private var input = "" + @State private var ikkk = "" + + var body: some View { + ScrollView { + VStack { + VStack { + HStack { + TextView(text: "表示名", textPattern: 0) + TextField("", text: $input) + .frame(width: 140, height: 50) + .padding(.leading, 15) + .overlay(RoundedRectangle(cornerRadius: 15) + .stroke(Color.grayBottonColor, lineWidth: 2) + ) + .padding(.leading, 10) + + Image("userIcon_plus") + .resizable() + .scaledToFit() + .frame(width: 90, height: 90) + .padding(.leading, 25) + } + Text("※ '表示名'は第三者に公開されます") + .foregroundColor(.gray) + } + .padding(.bottom, 20) + + VStack(spacing: 15) { + HStack { + TextView(text: "姓", textPattern: 0) + TextField("", text: $input) + .frame(width: 240, height: 48) + .padding(.leading, 15) + .overlay(RoundedRectangle(cornerRadius: 15) + .stroke(Color.grayBottonColor, lineWidth: 2) + ) + .padding(.leading, 25) + } + + HStack { + TextView(text: "名", textPattern: 0) + TextField("", text: $input) + .frame(width: 240, height: 48) + .padding(.leading, 15) + .overlay(RoundedRectangle(cornerRadius: 15) + .stroke(Color.grayBottonColor, lineWidth: 2) + ) + .padding(.leading, 25) + } + } + .padding(.bottom, 20) + + VStack(spacing: 20) { + TextBox(fieldHide: false, titleText: "メールアドレス", descriptionText: "学内メールを入力してください", inputText: $ikkk) + TextBox(fieldHide: true, titleText: "パスワード", descriptionText: "", inputText: $ikkk) + TextBox(fieldHide: true, titleText: "パスワード確認", descriptionText: "", inputText: $ikkk) + PullDownSelectView(labelName: "学年", selectList: ["学部1年", "学部2年", "学部3年", "学部4年"], startSelection: "学部1年") + PullDownSelectView(labelName: "所属コース", selectList: ["aaa", "bbb", "ccc", "ddd"], startSelection: "bbb") + } + .padding(.bottom, 40) + + BaseButtonView( + action: {}, + labelText: "新規会員登録", + foregroundColor: Color.white, + backgroundColor: Color.subPink, radius: 25 + ) + } + } + } +} + +struct SignUpPage_Previews: PreviewProvider { + static var previews: some View { + SignUpPage() + } +} From aa5d78a09e2d312be51c41c2762e73d840a2a5f9 Mon Sep 17 00:00:00 2001 From: zekuta-x Date: Mon, 27 Feb 2023 13:06:20 +0900 Subject: [PATCH 4/6] =?UTF-8?q?[fix]=20LoginPage=E3=81=8B=E3=82=89SignUpPa?= =?UTF-8?q?ge=E3=81=B8=E3=81=AE=E9=81=B7=E7=A7=BB=E5=87=A6=E7=90=86?= =?UTF-8?q?=E8=BF=BD=E5=8A=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../project.pbxproj | 24 +++++++++++++++++++ .../Login/LoginPage.swift | 10 +++++++- 2 files changed, 33 insertions(+), 1 deletion(-) diff --git a/portfolio-ios-swiftui/portfolio-ios-swiftui.xcodeproj/project.pbxproj b/portfolio-ios-swiftui/portfolio-ios-swiftui.xcodeproj/project.pbxproj index 08ce14b..eb53649 100644 --- a/portfolio-ios-swiftui/portfolio-ios-swiftui.xcodeproj/project.pbxproj +++ b/portfolio-ios-swiftui/portfolio-ios-swiftui.xcodeproj/project.pbxproj @@ -81,6 +81,9 @@ AB2187C629A21C9300B54172 /* SignUp */ = { isa = PBXGroup; children = ( + ABBB849529AC45E50066B787 /* ViewModel */, + ABBB849729AC45F50066B787 /* Service */, + ABBB849629AC45EE0066B787 /* Model */, AB2187C729A21CBF00B54172 /* SignUpPage.swift */, ); path = SignUp; @@ -135,6 +138,27 @@ path = View; sourceTree = ""; }; + ABBB849529AC45E50066B787 /* ViewModel */ = { + isa = PBXGroup; + children = ( + ); + path = ViewModel; + sourceTree = ""; + }; + ABBB849629AC45EE0066B787 /* Model */ = { + isa = PBXGroup; + children = ( + ); + path = Model; + sourceTree = ""; + }; + ABBB849729AC45F50066B787 /* Service */ = { + isa = PBXGroup; + children = ( + ); + path = Service; + sourceTree = ""; + }; ABC44B162918F62D00BBE1A6 /* Login */ = { isa = PBXGroup; children = ( diff --git a/portfolio-ios-swiftui/portfolio-ios-swiftui/Login/LoginPage.swift b/portfolio-ios-swiftui/portfolio-ios-swiftui/Login/LoginPage.swift index a74eea1..e718806 100644 --- a/portfolio-ios-swiftui/portfolio-ios-swiftui/Login/LoginPage.swift +++ b/portfolio-ios-swiftui/portfolio-ios-swiftui/Login/LoginPage.swift @@ -10,6 +10,9 @@ import SwiftUI struct LoginPage: View { @ObservedObject var login = LoginViewModel() + @State var new_login: Bool = false + @State var new_register: Bool = false + var body: some View { VStack { VStack(alignment: .leading) { @@ -55,12 +58,17 @@ struct LoginPage: View { .padding(.top, 30) BaseButtonView( - action: {}, + action: { + self.new_register.toggle() + }, labelText: "新規会員登録", foregroundColor: Color.text, backgroundColor: Color.grayBottonColor, radius: 25 ) + .fullScreenCover(isPresented: self.$new_register) { + SignUpPage() + } .padding(.top, 60) } } From a20848df4537984ef2f3dbb0fead55c3a0dc0cd7 Mon Sep 17 00:00:00 2001 From: zekuta-x Date: Mon, 27 Feb 2023 13:07:22 +0900 Subject: [PATCH 5/6] =?UTF-8?q?[add]=20Signuppage=E3=81=8B=E3=82=89Loginpa?= =?UTF-8?q?ge=E3=81=AB=E6=88=BB=E3=82=8B=E5=87=A6=E7=90=86=E8=BF=BD?= =?UTF-8?q?=E5=8A=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../SignUp/SignUpPage.swift | 140 ++++++++++-------- 1 file changed, 82 insertions(+), 58 deletions(-) diff --git a/portfolio-ios-swiftui/portfolio-ios-swiftui/SignUp/SignUpPage.swift b/portfolio-ios-swiftui/portfolio-ios-swiftui/SignUp/SignUpPage.swift index 5e527b8..7f67b0d 100644 --- a/portfolio-ios-swiftui/portfolio-ios-swiftui/SignUp/SignUpPage.swift +++ b/portfolio-ios-swiftui/portfolio-ios-swiftui/SignUp/SignUpPage.swift @@ -12,71 +12,95 @@ struct SignUpPage: View { @State private var input = "" @State private var ikkk = "" + @State var end_register: Bool = false + var body: some View { - ScrollView { - VStack { + VStack { + Button(action: { + var transaction = Transaction() + transaction.disablesAnimations = true + withTransaction(transaction) { + end_register = true + } + }) { + Image(systemName: "chevron.backward") + .resizable() + .scaledToFit() + .font(.system(size: 20, weight: .bold)) + .frame(height: 20.0) + .frame(maxWidth: .infinity, alignment: .leading) + .padding(.leading, 20) + .foregroundColor(.gray) + } + .fullScreenCover(isPresented: $end_register) { + LoginPage() + } + + ScrollView { VStack { - HStack { - TextView(text: "表示名", textPattern: 0) - TextField("", text: $input) - .frame(width: 140, height: 50) - .padding(.leading, 15) - .overlay(RoundedRectangle(cornerRadius: 15) - .stroke(Color.grayBottonColor, lineWidth: 2) - ) - .padding(.leading, 10) - - Image("userIcon_plus") - .resizable() - .scaledToFit() - .frame(width: 90, height: 90) - .padding(.leading, 25) + VStack { + HStack { + TextView(text: "表示名", textPattern: 0) + TextField("", text: $input) + .frame(width: 140, height: 50) + .padding(.leading, 15) + .overlay(RoundedRectangle(cornerRadius: 15) + .stroke(Color.grayBottonColor, lineWidth: 2) + ) + .padding(.leading, 10) + + Image("userIcon_plus") + .resizable() + .scaledToFit() + .frame(width: 90, height: 90) + .padding(.leading, 25) + } + Text("※ '表示名'は第三者に公開されます") + .foregroundColor(.gray) } - Text("※ '表示名'は第三者に公開されます") - .foregroundColor(.gray) - } - .padding(.bottom, 20) - - VStack(spacing: 15) { - HStack { - TextView(text: "姓", textPattern: 0) - TextField("", text: $input) - .frame(width: 240, height: 48) - .padding(.leading, 15) - .overlay(RoundedRectangle(cornerRadius: 15) - .stroke(Color.grayBottonColor, lineWidth: 2) - ) - .padding(.leading, 25) + .padding(.bottom, 20) + + VStack(spacing: 15) { + HStack { + TextView(text: "姓", textPattern: 0) + TextField("", text: $input) + .frame(width: 240, height: 48) + .padding(.leading, 15) + .overlay(RoundedRectangle(cornerRadius: 15) + .stroke(Color.grayBottonColor, lineWidth: 2) + ) + .padding(.leading, 25) + } + + HStack { + TextView(text: "名", textPattern: 0) + TextField("", text: $input) + .frame(width: 240, height: 48) + .padding(.leading, 15) + .overlay(RoundedRectangle(cornerRadius: 15) + .stroke(Color.grayBottonColor, lineWidth: 2) + ) + .padding(.leading, 25) + } } + .padding(.bottom, 20) - HStack { - TextView(text: "名", textPattern: 0) - TextField("", text: $input) - .frame(width: 240, height: 48) - .padding(.leading, 15) - .overlay(RoundedRectangle(cornerRadius: 15) - .stroke(Color.grayBottonColor, lineWidth: 2) - ) - .padding(.leading, 25) + VStack(spacing: 20) { + TextBox(fieldHide: false, titleText: "メールアドレス", descriptionText: "学内メールを入力してください", inputText: $ikkk) + TextBox(fieldHide: true, titleText: "パスワード", descriptionText: "", inputText: $ikkk) + TextBox(fieldHide: true, titleText: "パスワード確認", descriptionText: "", inputText: $ikkk) + PullDownSelectView(labelName: "学年", selectList: ["学部1年", "学部2年", "学部3年", "学部4年"], startSelection: "学部1年") + PullDownSelectView(labelName: "所属コース", selectList: ["aaa", "bbb", "ccc", "ddd"], startSelection: "bbb") } + .padding(.bottom, 40) + + BaseButtonView( + action: {}, + labelText: "新規会員登録", + foregroundColor: Color.white, + backgroundColor: Color.subPink, radius: 25 + ) } - .padding(.bottom, 20) - - VStack(spacing: 20) { - TextBox(fieldHide: false, titleText: "メールアドレス", descriptionText: "学内メールを入力してください", inputText: $ikkk) - TextBox(fieldHide: true, titleText: "パスワード", descriptionText: "", inputText: $ikkk) - TextBox(fieldHide: true, titleText: "パスワード確認", descriptionText: "", inputText: $ikkk) - PullDownSelectView(labelName: "学年", selectList: ["学部1年", "学部2年", "学部3年", "学部4年"], startSelection: "学部1年") - PullDownSelectView(labelName: "所属コース", selectList: ["aaa", "bbb", "ccc", "ddd"], startSelection: "bbb") - } - .padding(.bottom, 40) - - BaseButtonView( - action: {}, - labelText: "新規会員登録", - foregroundColor: Color.white, - backgroundColor: Color.subPink, radius: 25 - ) } } } From 86fc47b14790b133df9a07dd96edb101b72dc130 Mon Sep 17 00:00:00 2001 From: zekuta-x Date: Mon, 27 Feb 2023 16:11:35 +0900 Subject: [PATCH 6/6] =?UTF-8?q?[add]=20=E6=96=B0=E8=A6=8F=E7=99=BB?= =?UTF-8?q?=E9=8C=B2=E3=81=AEAPI=E5=87=A6=E7=90=86=E3=82=92=E8=BF=BD?= =?UTF-8?q?=E5=8A=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- portfolio-ios-swiftui/.swiftlint.yml | 4 +- .../project.pbxproj | 30 +++++++---- .../Login/LoginPage.swift | 2 +- .../SignUp/Model/Register.swift | 13 +++++ .../SignUp/Service/SignupService.swift | 44 ++++++++++++++++ .../{SignUpPage.swift => SignupPage.swift} | 38 ++++++++------ .../SignUp/ViewModel/SignupViewModel.swift | 52 +++++++++++++++++++ .../View/Atom/PullDownSelectView.swift | 6 +-- 8 files changed, 160 insertions(+), 29 deletions(-) create mode 100644 portfolio-ios-swiftui/portfolio-ios-swiftui/SignUp/Model/Register.swift create mode 100644 portfolio-ios-swiftui/portfolio-ios-swiftui/SignUp/Service/SignupService.swift rename portfolio-ios-swiftui/portfolio-ios-swiftui/SignUp/{SignUpPage.swift => SignupPage.swift} (74%) create mode 100644 portfolio-ios-swiftui/portfolio-ios-swiftui/SignUp/ViewModel/SignupViewModel.swift diff --git a/portfolio-ios-swiftui/.swiftlint.yml b/portfolio-ios-swiftui/.swiftlint.yml index afebedd..e82fe3f 100644 --- a/portfolio-ios-swiftui/.swiftlint.yml +++ b/portfolio-ios-swiftui/.swiftlint.yml @@ -10,6 +10,8 @@ disabled_rules: - force_cast # closureが返す値を明示しておきたい場合があるため - unused_closure_parameter +# パラメータの個数制限を解除 +- function_parameter_count # デフォルト無効のルールのうち、有効にするもの opt_in_rules: @@ -39,7 +41,7 @@ excluded: - Carthage/ # 1行あたりの文字数制限変更 -line_length: 120 +line_length: 200 # 変数名に関する制約 identifier_name: diff --git a/portfolio-ios-swiftui/portfolio-ios-swiftui.xcodeproj/project.pbxproj b/portfolio-ios-swiftui/portfolio-ios-swiftui.xcodeproj/project.pbxproj index eb53649..c32bf11 100644 --- a/portfolio-ios-swiftui/portfolio-ios-swiftui.xcodeproj/project.pbxproj +++ b/portfolio-ios-swiftui/portfolio-ios-swiftui.xcodeproj/project.pbxproj @@ -14,12 +14,15 @@ AA31E7FC28F542D900DCE061 /* TestView2.swift in Sources */ = {isa = PBXBuildFile; fileRef = AA31E7FB28F542D900DCE061 /* TestView2.swift */; }; AA31E800290F9C9F00DCE061 /* TabBarView.swift in Sources */ = {isa = PBXBuildFile; fileRef = AA31E7FF290F9C9F00DCE061 /* TabBarView.swift */; }; AADD20EC292B6A45008EE02E /* PublishingSettingToggleButtonView.swift in Sources */ = {isa = PBXBuildFile; fileRef = AADD20EB292B6A45008EE02E /* PublishingSettingToggleButtonView.swift */; }; - AB2187C829A21CBF00B54172 /* SignUpPage.swift in Sources */ = {isa = PBXBuildFile; fileRef = AB2187C729A21CBF00B54172 /* SignUpPage.swift */; }; + AB2187C829A21CBF00B54172 /* SignupPage.swift in Sources */ = {isa = PBXBuildFile; fileRef = AB2187C729A21CBF00B54172 /* SignupPage.swift */; }; AB2187CA29A3412600B54172 /* PullDownSelectView.swift in Sources */ = {isa = PBXBuildFile; fileRef = AB2187C929A3412600B54172 /* PullDownSelectView.swift */; }; ABAE5BEB28604E4A008ED665 /* .swiftlint.yml in Resources */ = {isa = PBXBuildFile; fileRef = ABAE5BEA28604E4A008ED665 /* .swiftlint.yml */; }; ABAF1D1B283B78F100F890BC /* ContentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = ABAF1D1A283B78F100F890BC /* ContentView.swift */; }; ABAF1D1D283B78F800F890BC /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = ABAF1D1C283B78F800F890BC /* Assets.xcassets */; }; ABAF1D20283B78F800F890BC /* Preview Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = ABAF1D1F283B78F800F890BC /* Preview Assets.xcassets */; }; + ABBB849929AC67D80066B787 /* SignupViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = ABBB849829AC67D80066B787 /* SignupViewModel.swift */; }; + ABBB849C29AC781B0066B787 /* Register.swift in Sources */ = {isa = PBXBuildFile; fileRef = ABBB849B29AC781B0066B787 /* Register.swift */; }; + ABBB849E29AC7AA20066B787 /* SignupService.swift in Sources */ = {isa = PBXBuildFile; fileRef = ABBB849D29AC7AA20066B787 /* SignupService.swift */; }; ABC44B202918F62D00BBE1A6 /* LoginViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = ABC44B182918F62D00BBE1A6 /* LoginViewModel.swift */; }; ABC44B212918F62D00BBE1A6 /* LoginPage.swift in Sources */ = {isa = PBXBuildFile; fileRef = ABC44B192918F62D00BBE1A6 /* LoginPage.swift */; }; ABC44B222918F62D00BBE1A6 /* Auth.swift in Sources */ = {isa = PBXBuildFile; fileRef = ABC44B1B2918F62D00BBE1A6 /* Auth.swift */; }; @@ -40,13 +43,16 @@ AA31E7FB28F542D900DCE061 /* TestView2.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TestView2.swift; sourceTree = ""; }; AA31E7FF290F9C9F00DCE061 /* TabBarView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TabBarView.swift; sourceTree = ""; }; AADD20EB292B6A45008EE02E /* PublishingSettingToggleButtonView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PublishingSettingToggleButtonView.swift; sourceTree = ""; }; - AB2187C729A21CBF00B54172 /* SignUpPage.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SignUpPage.swift; sourceTree = ""; }; + AB2187C729A21CBF00B54172 /* SignupPage.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SignupPage.swift; sourceTree = ""; }; AB2187C929A3412600B54172 /* PullDownSelectView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PullDownSelectView.swift; sourceTree = ""; }; ABAE5BEA28604E4A008ED665 /* .swiftlint.yml */ = {isa = PBXFileReference; lastKnownFileType = text.yaml; path = .swiftlint.yml; sourceTree = ""; }; ABAF1D15283B78F100F890BC /* portfolio-ios-swiftui.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "portfolio-ios-swiftui.app"; sourceTree = BUILT_PRODUCTS_DIR; }; ABAF1D1A283B78F100F890BC /* ContentView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContentView.swift; sourceTree = ""; }; ABAF1D1C283B78F800F890BC /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; ABAF1D1F283B78F800F890BC /* Preview Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = "Preview Assets.xcassets"; sourceTree = ""; }; + ABBB849829AC67D80066B787 /* SignupViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SignupViewModel.swift; sourceTree = ""; }; + ABBB849B29AC781B0066B787 /* Register.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Register.swift; sourceTree = ""; }; + ABBB849D29AC7AA20066B787 /* SignupService.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SignupService.swift; sourceTree = ""; }; ABC44B182918F62D00BBE1A6 /* LoginViewModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = LoginViewModel.swift; sourceTree = ""; }; ABC44B192918F62D00BBE1A6 /* LoginPage.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = LoginPage.swift; sourceTree = ""; }; ABC44B1B2918F62D00BBE1A6 /* Auth.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Auth.swift; sourceTree = ""; }; @@ -81,10 +87,10 @@ AB2187C629A21C9300B54172 /* SignUp */ = { isa = PBXGroup; children = ( + ABBB849A29AC77F60066B787 /* Model */, ABBB849529AC45E50066B787 /* ViewModel */, ABBB849729AC45F50066B787 /* Service */, - ABBB849629AC45EE0066B787 /* Model */, - AB2187C729A21CBF00B54172 /* SignUpPage.swift */, + AB2187C729A21CBF00B54172 /* SignupPage.swift */, ); path = SignUp; sourceTree = ""; @@ -141,22 +147,25 @@ ABBB849529AC45E50066B787 /* ViewModel */ = { isa = PBXGroup; children = ( + ABBB849829AC67D80066B787 /* SignupViewModel.swift */, ); path = ViewModel; sourceTree = ""; }; - ABBB849629AC45EE0066B787 /* Model */ = { + ABBB849729AC45F50066B787 /* Service */ = { isa = PBXGroup; children = ( + ABBB849D29AC7AA20066B787 /* SignupService.swift */, ); - path = Model; + path = Service; sourceTree = ""; }; - ABBB849729AC45F50066B787 /* Service */ = { + ABBB849A29AC77F60066B787 /* Model */ = { isa = PBXGroup; children = ( + ABBB849B29AC781B0066B787 /* Register.swift */, ); - path = Service; + path = Model; sourceTree = ""; }; ABC44B162918F62D00BBE1A6 /* Login */ = { @@ -307,6 +316,7 @@ ABC44B232918F62D00BBE1A6 /* User.swift in Sources */, ABDA951F286996FA00C7C735 /* TextView.swift in Sources */, 0483FA3C290669BC001866C9 /* IconView.swift in Sources */, + ABBB849929AC67D80066B787 /* SignupViewModel.swift in Sources */, AB2187CA29A3412600B54172 /* PullDownSelectView.swift in Sources */, ABAF1D1B283B78F100F890BC /* ContentView.swift in Sources */, AA31E800290F9C9F00DCE061 /* TabBarView.swift in Sources */, @@ -314,8 +324,9 @@ AA31E7FA28F542C700DCE061 /* TestView1.swift in Sources */, 0CFE7BC3286A2A6500CA5119 /* ButtonView.swift in Sources */, ABC44B212918F62D00BBE1A6 /* LoginPage.swift in Sources */, - AB2187C829A21CBF00B54172 /* SignUpPage.swift in Sources */, + AB2187C829A21CBF00B54172 /* SignupPage.swift in Sources */, ABC44B252918F62D00BBE1A6 /* LoginService.swift in Sources */, + ABBB849E29AC7AA20066B787 /* SignupService.swift in Sources */, FC7EC30D28EAC89300600302 /* TextField.swift in Sources */, AADD20EC292B6A45008EE02E /* PublishingSettingToggleButtonView.swift in Sources */, ABC44B242918F62D00BBE1A6 /* APIServiceError.swift in Sources */, @@ -324,6 +335,7 @@ ABC44B272918F93200BBE1A6 /* portfolio_ios_swiftuiApp.swift in Sources */, AA31E7FC28F542D900DCE061 /* TestView2.swift in Sources */, ABC44B222918F62D00BBE1A6 /* Auth.swift in Sources */, + ABBB849C29AC781B0066B787 /* Register.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; diff --git a/portfolio-ios-swiftui/portfolio-ios-swiftui/Login/LoginPage.swift b/portfolio-ios-swiftui/portfolio-ios-swiftui/Login/LoginPage.swift index e718806..934d15d 100644 --- a/portfolio-ios-swiftui/portfolio-ios-swiftui/Login/LoginPage.swift +++ b/portfolio-ios-swiftui/portfolio-ios-swiftui/Login/LoginPage.swift @@ -67,7 +67,7 @@ struct LoginPage: View { radius: 25 ) .fullScreenCover(isPresented: self.$new_register) { - SignUpPage() + SignupPage() } .padding(.top, 60) } diff --git a/portfolio-ios-swiftui/portfolio-ios-swiftui/SignUp/Model/Register.swift b/portfolio-ios-swiftui/portfolio-ios-swiftui/SignUp/Model/Register.swift new file mode 100644 index 0000000..a4b77c1 --- /dev/null +++ b/portfolio-ios-swiftui/portfolio-ios-swiftui/SignUp/Model/Register.swift @@ -0,0 +1,13 @@ +// +// SignupModel.swift +// portfolio-ios-swiftui +// +// Created by 鳥山英峻 on 2023/02/27. +// + +import Foundation + +struct Register: Codable { + let userID: String +// let oneTimePass: String +} diff --git a/portfolio-ios-swiftui/portfolio-ios-swiftui/SignUp/Service/SignupService.swift b/portfolio-ios-swiftui/portfolio-ios-swiftui/SignUp/Service/SignupService.swift new file mode 100644 index 0000000..bfcbd00 --- /dev/null +++ b/portfolio-ios-swiftui/portfolio-ios-swiftui/SignUp/Service/SignupService.swift @@ -0,0 +1,44 @@ +// +// SignupService.swift +// portfolio-ios-swiftui +// +// Created by 鳥山英峻 on 2023/02/27. +// + +import Foundation + +final class SignupAPIService { + + static let shared = SignupAPIService() + private init() {} + + public func fetchSignupService(displayName: String, userIcon: String, familyName: String, firstName: String, mail: String, password: String, grade: String, course: String) async throws -> Register { + + let body: [String: String] = [ + "icon": "\(userIcon)", + "familyName": "\(familyName)", + "firstName": "\(firstName)", + "mail": "\(mail)", + "password": "\(password)", + "grade": "\(grade)", + "course": "\(course)", + "displayName": "\(displayName)" + ] + + // MARK: - 1.API取得先URLの作成 + // 本番環境ではURLを変更する + let baseURL: URL = .init(string: "http://localhost:9000/sign/up")! + var request = URLRequest(url: baseURL) + + // MARK: - 2.URLリクエストの作成 + request.httpMethod = "POST" + request.setValue("application/json", forHTTPHeaderField: "Content-Type") + request.httpBody = try? JSONSerialization.data(withJSONObject: body, options: .fragmentsAllowed) + + // MARK: - 3.TASKの作成 + let data = try await URLSession.shared.data(for: request) + let response = try JSONDecoder().decode(Register.self, from: data.0) + + return response + } +} diff --git a/portfolio-ios-swiftui/portfolio-ios-swiftui/SignUp/SignUpPage.swift b/portfolio-ios-swiftui/portfolio-ios-swiftui/SignUp/SignupPage.swift similarity index 74% rename from portfolio-ios-swiftui/portfolio-ios-swiftui/SignUp/SignUpPage.swift rename to portfolio-ios-swiftui/portfolio-ios-swiftui/SignUp/SignupPage.swift index 7f67b0d..20192d1 100644 --- a/portfolio-ios-swiftui/portfolio-ios-swiftui/SignUp/SignUpPage.swift +++ b/portfolio-ios-swiftui/portfolio-ios-swiftui/SignUp/SignupPage.swift @@ -7,16 +7,19 @@ import SwiftUI -struct SignUpPage: View { - - @State private var input = "" - @State private var ikkk = "" +struct SignupPage: View { + @ObservedObject var signup = SignupViewModel() @State var end_register: Bool = false + let gradeList = ["学部1年", "学部2年", "学部3年", "学部4年","修士1年","修士2年","博士1年","博士2年","博士3年"] + let courseList = ["情報システムコース","情報デザインコース","複雑系コース","知能システムコース","情報アーキテクチャ領域","高度ICT領域","メディアデザイン領域","複雑系情報科学領域","知能情報科学領域"] + var body: some View { VStack { + // MARK: - backbutton処理 Button(action: { + // アニメーションを削除する処理 var transaction = Transaction() transaction.disablesAnimations = true withTransaction(transaction) { @@ -35,13 +38,14 @@ struct SignUpPage: View { .fullScreenCover(isPresented: $end_register) { LoginPage() } + // MARK: - 入力フォーム処理 ScrollView { VStack { VStack { HStack { TextView(text: "表示名", textPattern: 0) - TextField("", text: $input) + TextField("", text: $signup.displayName) .frame(width: 140, height: 50) .padding(.leading, 15) .overlay(RoundedRectangle(cornerRadius: 15) @@ -63,7 +67,7 @@ struct SignUpPage: View { VStack(spacing: 15) { HStack { TextView(text: "姓", textPattern: 0) - TextField("", text: $input) + TextField("", text: $signup.familyName) .frame(width: 240, height: 48) .padding(.leading, 15) .overlay(RoundedRectangle(cornerRadius: 15) @@ -74,7 +78,7 @@ struct SignUpPage: View { HStack { TextView(text: "名", textPattern: 0) - TextField("", text: $input) + TextField("", text: $signup.firstName) .frame(width: 240, height: 48) .padding(.leading, 15) .overlay(RoundedRectangle(cornerRadius: 15) @@ -86,16 +90,20 @@ struct SignUpPage: View { .padding(.bottom, 20) VStack(spacing: 20) { - TextBox(fieldHide: false, titleText: "メールアドレス", descriptionText: "学内メールを入力してください", inputText: $ikkk) - TextBox(fieldHide: true, titleText: "パスワード", descriptionText: "", inputText: $ikkk) - TextBox(fieldHide: true, titleText: "パスワード確認", descriptionText: "", inputText: $ikkk) - PullDownSelectView(labelName: "学年", selectList: ["学部1年", "学部2年", "学部3年", "学部4年"], startSelection: "学部1年") - PullDownSelectView(labelName: "所属コース", selectList: ["aaa", "bbb", "ccc", "ddd"], startSelection: "bbb") + TextBox(fieldHide: false, titleText: "メールアドレス", descriptionText: "学内メールを入力してください", inputText: $signup.mail) + TextBox(fieldHide: true, titleText: "パスワード", descriptionText: "", inputText: $signup.password) + TextBox(fieldHide: true, titleText: "パスワード確認", descriptionText: "", inputText: $signup.checkPassword) + PullDownSelectView(labelName: "学年", selectList: gradeList, selectionLabel: $signup.grade) + PullDownSelectView(labelName: "所属コース", selectList: courseList, selectionLabel: $signup.course) } .padding(.bottom, 40) + // MARK: - 登録処理 + BaseButtonView( - action: {}, + action: { + signup.fetchSignupService() + }, labelText: "新規会員登録", foregroundColor: Color.white, backgroundColor: Color.subPink, radius: 25 @@ -106,8 +114,8 @@ struct SignUpPage: View { } } -struct SignUpPage_Previews: PreviewProvider { +struct SignupPage_Previews: PreviewProvider { static var previews: some View { - SignUpPage() + SignupPage() } } diff --git a/portfolio-ios-swiftui/portfolio-ios-swiftui/SignUp/ViewModel/SignupViewModel.swift b/portfolio-ios-swiftui/portfolio-ios-swiftui/SignUp/ViewModel/SignupViewModel.swift new file mode 100644 index 0000000..e1a654a --- /dev/null +++ b/portfolio-ios-swiftui/portfolio-ios-swiftui/SignUp/ViewModel/SignupViewModel.swift @@ -0,0 +1,52 @@ +// +// SignupViewModel.swift +// portfolio-ios-swiftui +// +// Created by 鳥山英峻 on 2023/02/27. +// + +import Foundation + +class SignupViewModel: ObservableObject { + @Published var register: Register + + @Published var displayName: String + @Published var userIcon: String + @Published var familyName: String + @Published var firstName: String + @Published var mail: String + @Published var password: String + @Published var checkPassword: String + + @Published var grade: String + @Published var course: String + + init() { + self.register = Register(userID: "") + + self.displayName = "" + self.userIcon = "aaaa" + self.familyName = "" + self.firstName = "" + self.mail = "" + self.password = "" + self.checkPassword = "" + self.grade = "" + self.course = "" + + fetchSignupService() + } + + func fetchSignupService() { + // MARK: - dispatchを使う理由はfetchに時間がかかるから、アプリの裏側で実行する + Task.detached { + do { + let response = try await SignupAPIService.shared.fetchSignupService(displayName: self.displayName, userIcon: self.userIcon, familyName: self.familyName, firstName: self.firstName, mail: self.mail, password: self.password, grade: self.grade, course: self.course) + // エラーがなければ必ず通る + print(response) + } catch { + print(error.localizedDescription) + } + } + } +} diff --git a/portfolio-ios-swiftui/portfolio-ios-swiftui/View/Atom/PullDownSelectView.swift b/portfolio-ios-swiftui/portfolio-ios-swiftui/View/Atom/PullDownSelectView.swift index 6a9edd9..0a62486 100644 --- a/portfolio-ios-swiftui/portfolio-ios-swiftui/View/Atom/PullDownSelectView.swift +++ b/portfolio-ios-swiftui/portfolio-ios-swiftui/View/Atom/PullDownSelectView.swift @@ -11,14 +11,14 @@ struct PullDownSelectView: View { var labelName: String - @State var selectList = [""] - @State var startSelection = "" + @State var selectList: [String] + @Binding var selectionLabel: String var body: some View { VStack(alignment: .leading) { TextView(text: labelName, textPattern: 0) - Picker("", selection: $startSelection) { + Picker("", selection: $selectionLabel) { ForEach($selectList, id: \.self) { item in // @Stateで参照しているためwrappedValueを用いる Text(item.wrappedValue)