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

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

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

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

Q&A

解決済

2回答

208閲覧

swiftで繰り返し処理を行う際の画面更新について

snowman2

総合スコア3

Swift

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

0グッド

0クリップ

投稿2024/01/10 04:11

実現したいこと

whileにて繰り返し処理を行う際,1回の処理ごとに画面を更新させて計算値を表示させたい。

発生している問題・分からないこと

StoryBoardにLabelを配置し,その中に計算された値が表示されるようにコードを書きました。
ボタンを押すとランダムな数値が選ばれ,その数値が配列の中の数値と一致するごとに当たり用のカウント数が1つ増え,一致しなかった場合はハズレ用の数値が1つ増えるようにしています。
これをTextFieldに入力した回数分繰り返されるよう,Whileにて繰り返し処理を行っています。
Printにて表示させると適切にコードの実行が行われているようですが,シミュレーションで動作させてみると全ての処理が終わってからのみ画面の更新が行われ,一気に結果が表示される状況になってしまいました。
これを,1回の処理ごとに画面の数値が更新されるようにしたいのですが,どのようにすればよろしいでしょうか?

該当のソースコード

swift

1class ViewController: UIViewController, UITextFieldDelegate { 2 3 @IBOutlet weak var testCountSet: UITextField! 4 @IBOutlet weak var execButton: UIButton! 5 override func viewDidLoad() { 6 super.viewDidLoad() 7 // Do any additional setup after loading the view. 8 testCountSet.keyboardType = UIKeyboardType.numberPad 9 testCountSet.delegate = self 10 11 testCountNum.text = String(testCount) 12 kakuhenCountNum.text = String(kakuhenCount) 13 normalCountNum.text = String(normalCount) 14 hazureCountNum.text = String(hazureCount) 15 16 execButton.isEnabled = false 17 } 18 19 override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) { 20 view.endEditing(true) 21 } 22 23 @IBOutlet weak var testCountNum: UILabel! 24 @IBOutlet weak var kakuhenCountNum: UILabel! 25 @IBOutlet weak var normalCountNum: UILabel! 26 @IBOutlet weak var hazureCountNum: UILabel! 27 28 var testCount = 0 29 var kakuhenCount = 0 30 var normalCount = 0 31 var hazureCount = 0 32 let kakuhenArray = [10, 24, 36, 68, 103, 104, 210, 253, 286, 289, 296, 409, 637, 715, 747, 912, 1046, 1048, 1356, 1827, 2846, 3096, 3784, 5060, 5283, 5475, 5876, 6106, 7777, 9037, 11303, 11586, 11867, 12486, 14869, 18576, 18764, 18978, 19284, 19384, 20193, 22222, 22857, 23487, 23867, 25049, 25867, 26157, 27373, 28345, 30938, 31000] 33 let normalArray = [3, 16, 20, 64, 105, 158, 179, 236, 247, 295, 314, 376, 736, 799, 1175, 1657, 1659, 1688, 2186, 2367, 2646, 3263, 3948, 4857, 4938, 5338, 6456, 6873, 6874, 7041, 8456, 9285, 10374, 15364, 17366, 17684, 19867, 23136, 23183, 23456, 23576, 25676, 27756, 29173, 29465, 30124, 30476, 31900] 34 35 @IBAction func checkText(_ sender: Any) { 36 if testCountSet.text?.count == 0 { 37 execButton.isEnabled = false 38 } else { 39 execButton.isEnabled = true 40 } 41 } 42 43 @IBAction func startCount(_ sender: UIButton) { 44 let setTestCountText = testCountSet.text! 45 print(setTestCountText) 46 let setTestCount = Int(setTestCountText)! 47 print(setTestCount) 48 49 testCount = 0 50 kakuhenCount = 0 51 normalCount = 0 52 hazureCount = 0 53 54 while testCount < setTestCount { 55 testCount += 1 56 print(testCount) 57 testCountNum.text = String(testCount) 58 let pickNum = Int.random(in: 1...31960) 59 print(pickNum) 60 if kakuhenArray.contains(pickNum) == true { 61 kakuhenCount += 1 62 kakuhenCountNum.text = String(kakuhenCount) 63 }else if normalArray.contains(pickNum) == true { 64 normalCount += 1 65 normalCountNum.text = String(normalCount) 66 }else { 67 hazureCount += 1 68 print(hazureCount) 69 hazureCountNum.text = String(hazureCount) 70 } 71 72 sleep(1) 73 } 74 75 } 76 77} 78

試したこと・調べたこと

  • teratailやGoogle等で検索した
  • ソースコードを自分なりに変更した
  • 知人に聞いた
  • その他
上記の詳細・結果

調べたのですが,該当記事を見つけることが出来ませんでした。

補足

特になし

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

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

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

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

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

guest

回答2

0

自己解決

こちらは,whileの中のコードをtimerにて行う事で解決することが出来ました

投稿2024/01/27 12:15

snowman2

総合スコア3

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

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

0

あまり詳しくないのですが、まだ回答がついていないようでしたので、回答してみます。

whileの処理中は画面の数値が更新されないですので、
考え方を変えないといけなそうですね。

何秒後にどのような数値を表示するかをあらかじめ登録して、
whileの中ではsleepせずに、すぐにfuncを終了するような感じはいかがでしょうか?

下のサンプルコードでは10回ループして
1回目は0秒後に0を表示、
2回目は1秒後に1を表示、
...
10回目は9秒後に9を表示しています。

swift

1class ViewController: UIViewController { 2 @IBOutlet var label: UILabel! 3 4 override func viewDidLoad() { 5 super.viewDidLoad() 6 // Do any additional setup after loading the view. 7 } 8 9 @IBAction func startCount(_ sender: UIButton) { 10 for i in 0..<10 { 11 DispatchQueue.main.asyncAfter(deadline: .now() + Double(i)) { 12 self.label.text = "\(i)" 13 } 14 } 15 } 16}

このままだと続けて何度もボタンをタップすると
表示の制御が重複しておかしくなってしまいます。
全体的な制御も踏まえて対処する必要があると思います。
(場合によってはDispatchQueue.main.asyncAfterを使わない方が良いのかもしれません・・)

投稿2024/01/12 14:56

退会済みユーザー

退会済みユーザー

総合スコア0

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

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

snowman2

2024/01/19 08:22

ご回答ありがとうございます。 秒数毎にカウントアップをするのではなくランダム関数によって値がランダムに選択され,配列の中の数値と一致しているか,それとも一致していないかを判断した上でカウントアップを行いたいと思っております。 こちらは,whileの中のコードをtimerにて行う事で解決することが出来ました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.46%

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

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

質問する

関連した質問