はじめに
iOS アプリを使用している際に、ログインを求められることがあると思います。基本的には UI/UX は似たり寄ったりになると思いますが、今回はその UI 等についてまとめていきます。今回も素敵なクリエイターの方が上げてくれている動画を参考にしました
本記事は UI のみまとめています。機能に関しては別の記事にまとめます
参考動画
ソースコード
ログインページ (親View)
import SwiftUI
// ログインページ
struct LoginView: View {
@State private var email: String = ""
@State private var password: String = ""
var body: some View {
VStack(alignment:.leading , spacing: 10){
VStack(alignment:.leading , spacing: 8){
Text("ログインページです")
.font(.largeTitle)
Text("ログインフォームを表示します")
.font(.callout)
}
.fontWeight(.medium)
.padding(10)
CustomTextField(hint:"Eメール アドレス" , symbol : "mail" , value : $email)
.padding(.top, 10)
.padding(.horizontal,10)
CustomTextField(hint:"パスワード" , symbol : "key" , isPassword: true , value : $password)
.padding(.top, 10)
.padding(.horizontal,10)
// パスワードを忘れた際のボタンを記載
Button("パスワードを忘れましたか?") {
//content
}
.tint(.primary)
.frame(maxWidth: .infinity , alignment: .trailing)
.padding(.top , 10)
.padding(.horizontal , 10)
// Sign In ボタン
SignInView(title: "Sign In"){
} onStatusChange : { isLogin in
}
.padding(.top, 20)
.padding(.horizontal , 10)
HStack{
Text("パスワードをお忘れですか?")
Button{
// content
} label: {
Text("Sign Up")
.underline()
}
}
.fontWeight(.medium)
.padding(.top, 10)
.foregroundStyle(Color.primary)
.frame(maxWidth: .infinity)
}
.frame(maxWidth: .infinity, maxHeight: .infinity , alignment: .topLeading)
.padding(.top, 20)
}
}
ログインボタン
import SwiftUI
struct SignInView: View {
var title : String
var onTask : () async -> () // 非同期で実行する処理を外から注入できるトリガー用の変数
var onStatusChange: (Bool) -> () = { _ in }
@State private var isLogin: Bool = false
var body: some View {
Button {
Task{
isLogin = true
await onTask()
// 若干のスリープ処理
try? await Task.sleep(for: .seconds(0.1))
isLogin = false
}
} label: {
Text(title)
.font(.callout)
.fontWeight(.semibold)
.frame(maxWidth: .infinity)
.padding(.vertical, 10)
}
.buttonStyle(.borderedProminent)
.buttonBorderShape(.capsule)
.tint(Color.primary)
.disabled(isLogin)
}
}
メアド , パスワード入力欄
import SwiftUI
// 入力情報の構造体
struct CustomTextField: View {
var hint: String
var symbol: String
var isPassword: Bool = false
@Binding var value: String
var body: some View {
HStack(spacing: 12) {
Image(systemName: symbol)
.font(.callout)
.foregroundStyle(.gray)
.frame(width: 30)
Group {
if isPassword {
SecureField(hint, text: $value) // ⚫️ 表示になる
} else {
TextField(hint, text: $value)
}
}
}
.padding(.horizontal, 15)
.padding(.vertical, 12)
.background(.ultraThinMaterial)
.clipShape(.capsule)
}
}
実際の画面
終わりに
今回はわかりやすく、 UI のみにフォーカスしてまとめましたが、処理についてもまとめた方が良いと判断した際にはまとめます