質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.35%
iOS

iOSとは、Apple製のスマートフォンであるiPhoneやタブレット端末のiPadに搭載しているオペレーションシステム(OS)です。その他にもiPod touch・Apple TVにも搭載されています。

Swift

Swiftは、アップルのiOSおよびOS Xのためのプログラミング言語で、Objective-CやObjective-C++と共存することが意図されています

iPhone

iPhoneとは、アップル社が開発・販売しているスマートフォンです。 同社のデジタルオーディオプレーヤーiPodの機能、電話機能、インターネットやメールなどのWeb通信機能の3つをドッキングした機器です。

Q&A

解決済

2回答

1535閲覧

プレビューで書く変数が分からなく困っています

konokarakaua

総合スコア6

iOS

iOSとは、Apple製のスマートフォンであるiPhoneやタブレット端末のiPadに搭載しているオペレーションシステム(OS)です。その他にもiPod touch・Apple TVにも搭載されています。

Swift

Swiftは、アップルのiOSおよびOS Xのためのプログラミング言語で、Objective-CやObjective-C++と共存することが意図されています

iPhone

iPhoneとは、アップル社が開発・販売しているスマートフォンです。 同社のデジタルオーディオプレーヤーiPodの機能、電話機能、インターネットやメールなどのWeb通信機能の3つをドッキングした機器です。

0グッド

0クリップ

投稿2020/04/17 17:11

###プレビューで書く変数が分からなく困っています
SwiftUIを勉強し始めて1週間の者です。
練習としてロック画面を作っていますが
プレビュー画面にエラーが出てここから進みません。
エラー内容としては
[Missing argument for parameter 'handler' in call
Insert 'handler: <#(String, (Bool) -> Void) -> Void#>']
です。
どの様に書けばクリアできるのでしょうか?
教えてください。お願いします。

import SwiftUI // import Introspect public struct Lock: View { var maxDigits: Int = 4 var label = "Enter One Time Password" @State var pin: String = "" @State var showPin = false @State var isDisabled = false var handler: (String, (Bool) -> Void) -> Void public var body: some View { VStack(spacing: 30) { Text(label).font(.title) ZStack { pinDots backgroundField } showPinStack } } private var pinDots: some View { HStack { Spacer() ForEach(0..<maxDigits) { index in Image(systemName: self.getImageName(at: index)) .font(.system(size:30, weight:.ultraLight, design: .default)) Spacer() } } } private var backgroundField: some View { let boundPin = Binding<String>(get: { self.pin }, set: { newValue in self.pin = newValue self.submitPin() }) return TextField("", text: boundPin, onCommit: submitPin) // Introspect library can used to make the textField become first resonder on appearing // if you decide to add the pod 'Introspect' and import it, comment #50 to #53 and uncomment #55 to #61 .accentColor(.clear) .foregroundColor(.clear) .keyboardType(.numberPad) .disabled(isDisabled) // .introspectTextField { textField in // textField.tintColor = .clear // textField.textColor = .clear // textField.keyboardType = .numberPad // textField.becomeFirstResponder() // textField.isEnabled = !self.isDisabled // } } private var showPinStack: some View { HStack { Spacer() if !pin.isEmpty { showPinButton } } .frame(height:30) .padding([.trailing]) } private var showPinButton: some View { Button(action: { self.showPin.toggle() }, label: { self.showPin ? Image(systemName: "eye.slash.fill").foregroundColor(.primary) : Image(systemName: "eye.fill").foregroundColor(.primary) }) } private func submitPin() { guard !pin.isEmpty else { showPin = false return } if pin.count == maxDigits { isDisabled = true handler(pin) { isSuccess in if isSuccess { print("pin matched, go to next page, no action to perfrom here") } else { pin = "" isDisabled = false print("this has to called after showing toast why is the failure") } } } // this code is never reached under normal circumstances. If the user pastes a text with count higher than the // max digits, we remove the additional characters and make a recursive call. if pin.count > maxDigits { pin = String(pin.prefix(maxDigits)) submitPin() } } private func getImageName(at index: Int) -> String { if index >= self.pin.count { return "circle" } if self.showPin { return self.pin.digits[index].numberString + ".circle" } return "circle.fill" } } extension String { var digits: [Int] { var result = [Int]() for char in self { if let number = Int(String(char)) { result.append(number) } } return result } } extension Int { var numberString: String { guard self < 10 else { return "0" } return String(self) } } struct Lock_Previews: PreviewProvider { static var previews: some View { Lock() } }

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答2

0

ベストアンサー

自分で作ったロック画面の使い方が自分でわからないということなのでしょうか?

このコードだと、
var handler: (String, (Bool) -> Void) -> Void
で宣言したhandlerをLock画面呼び出しの引数に指定する必要があると思います。

このhandlerは、 (String, (Bool) -> Void) -> Void 型の
クロージャを指定する引数で、このクロージャの第一引数で
入力されたピンコードを受け取ってそれが正しいか否か判定し、
その判定結果(true/false)を第二引数に指定されたクロージャを
呼び出すことで伝える仕様になっているのだと思います。

このコードが自分で考えて作ったものではなく、何かの記事に書かれてあった
コードをそのまま写して、その動作を試そうとしたのであれば、
記事の中にその辺りの使い方の話も書いてあるのではないのでしょうか?

何か記事を参考にしたのであれば、記事のURLをきちんと示して質問すれば、
もっと的確なアドバイスが得られると思います。


(4/19 追記)

記事の内容を読んでみました。Lock画面のコードについての説明はありますが、それを使うためのコードやその説明はありませんね。それくらいはLock画面のコードを読んで自分で考えろってことなんでしょうね。クロージャのことがちゃんと理解できていれば、さほど難しいことではありませんので。

例えば、次のようなコードを書けばLock画面を呼び出せると思います。
(0000が入力された場合を正解としています。)

swift

1 Lock() { pin,handler in 2 print(pin) 3 if pin == "0000" { 4 handler(true) 5 } else { 6 handler(false) 7 } 8 }

クロージャについてきちんと勉強することをお勧めします。

投稿2020/04/18 05:54

編集2020/04/19 22:17
TakeOne

総合スコア6299

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

konokarakaua

2020/04/18 15:41

ご丁寧にありがとうございます。 練習として下記のサイトを参考にしコードの打ち込みをしたのですがプレビューのところで分からなくなってしまいました。 https://medium.com/flawless-app-stories/swiftui-passcode-field-for-otp-and-pin-entry-b61ba663dc31 こちらが記事のURLです。 TakeOneさんのおかげで理屈は分かりましたがそれをどの様に書けば良いか分かりません。 よろしくお願い致します。
TakeOne

2020/04/19 01:54

回答追記しました。
konokarakaua

2020/04/20 16:09

プレビュー表示されました! ありがとうございました! クロージャ一から勉強します。 本当にありがとうございました!
guest

0

プレビュー表示されました!
ありがとうございました!

クロージャ一から勉強します。
本当にありがとうございました!

投稿2020/04/20 16:07

konokarakaua

総合スコア6

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.35%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問