Swift5.1.2 Xcode11.2.1 SwiftUI
- 自作アプリにUserDefaultsでパスワードを記録します
- if文でパスワードの正誤判断し画面ロックを解除します
- Sheetの機能を利用して写真をカバーします
「以下は動画のハイライトです。」
SwiftUIではデータの記録を行うUserDefaultsの使い方に少し手こずります。まずButtonをTapしてTapした回数をUserDefaultsに記録する方法からおさらいします。
@State var tapCount = UserDefaults.standard.string(forKey: "Taps")
?? ""
Button("Tap count:" + tapCount) {
var tapInt = Int(self.tapCount) ?? 0
tapInt += 1
self.tapCount = "\(tapInt)"
UserDefaults.standard.set(self.tapCount, forKey: "Taps")
// let idDomain = Bundle.main.bundleIdentifier!
// UserDefaults.standard.removePersistentDomain(forName: idDomain)
// UserDefaults.standard.synchronize()
// print("UserDefaults Reset")
}
後にStringでパスワードを保存することを想定しているため、あえてstandard.stringを利用してStringとIntの変換を行なっております。これをビルドして再起動後もTap回数が保存されるのをご確認ください。
ちなみに上記のコメントアウトしている箇所はUserDefaultsに記録した変数を初期化する働きがあります。UserDefaultsをリセットしたい時に適宜コメントアウトして使ってください。
次にプライベートな写真をiPhoneに取り込みます。取り込み方法は23回の動画で詳しく解説しているためこちらもご査収ください。
Image("180")
.resizable()
.aspectRatio(contentMode: .fit)
この写真をカバーするためのSheet Viewは以下になります。
struct SheetView: View {
@State var btnTitle:String
@State var showTrigger = true
var body: some View {
VStack {
Button(self.btnTitle) {
self.showTrigger = true
if self.btnTitle == "パスワード再設定" {
UserDefaults.standard.set("", forKey: "pass")
UserDefaults.standard.set("新しいパスワードを決めてください", forKey: "message")
}
}
}.sheet(isPresented: $showTrigger, onDismiss: {
print("sheet action")
}) {
LockView()
}
}
}
この中でUserDefaultsにforKeyを"pass"としてユーザーが入力したパスワードを記録します。一方、パスワードの設定の有無によってメッセージを変える文字列もforKeyに"message"として記録します。if文の中はパスワードを再設定するために作ったものです。
それではいよいよメインとなるロック画面のSheetを実装します。コードは以下となります。
struct LockView: View {
@State private var text: String = ""
@State private var titleMessage = UserDefaults.standard.string(forKey:
"message") ?? "新しいパスワードを決めてください"
@State private var keyPass = UserDefaults.standard.string(forKey: "pass")
?? ""
@State var errorMessage = ""
var body: some View {
VStack {
Spacer()
Text(self.errorMessage).foregroundColor(.red)
Text(self.titleMessage).font(.headline)
TextField("パスワード入力欄", text: $text).textFieldStyle(RoundedBorderTextFieldStyle())
Button(action: {
if self.keyPass == self.text {
print("パスワード一致")
UIApplication.shared.windows[0].rootViewController?.dismiss(animated:
false, completion: {})
print("done with", self.text)
} else if self.keyPass == "" {
print("初回設定")
UserDefaults.standard.set(self.text, forKey: "pass")
UserDefaults.standard.set("設定したパスワードを入力してください", forKey: "message")
UIApplication.shared.windows[0].rootViewController?.dismiss(animated:
false, completion: {})
} else {
print("パスワード不一致")
self.errorMessage = "パスワードが不一致です"
}
}) {
Text("Done")
}
Spacer()
}.font(.custom("SFProText-Bold", size: 25))
}
}
UserDefaultsからパスワードを取り出し変数のkeyPassに代入します。初期値は空文字の""です。初回起動時にパスワードの新規設定を呼ぶためにif文で判定するように作りました。keyPassとTextField入力された文字列が一致していればSheetのカバーを外すような仕組みになっております。また不一致の場合はエラーメッセージも赤字で表示するように設計しております。
このStructはContentViewで以下のように2種類呼びます。
SheetView(btnTitle: "パスワード再設定", showTrigger: false)
SheetView(btnTitle: "画面ロック", showTrigger: true)
btnTitleの引数は作成されるButtonのタイトルを指定しております。showTriggerの引数はここをtrueにすることで起動直後にSheetのカバーを作動させるようにしているものです。ここをtrueにすることでアプリを落として再起動をかけたとしてもUserDefaultsのforKey:"pass"にパスワードが設定されていれば即座にカバーがかかる動作をします。パスワード再設定の方もtrueにしてしまうとSheetが2回呼ばれてしまうため片方は便宜上falseにしました。
以上動画でないとなかなか説明が難しいところもありますので動きで理解していただければと思います。
ソースコードは YouTubeのコメント欄 に記載します。
目次へ戻る