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

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

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

Xcodeはソフトウェア開発のための、Appleの統合開発環境です。Mac OSXに付随するかたちで配布されています。

Swift

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

Q&A

0回答

581閲覧

【Swift】UILabelのtextに思ったように値が反映されない

konchan_exbaka

総合スコア2

Xcode

Xcodeはソフトウェア開発のための、Appleの統合開発環境です。Mac OSXに付随するかたちで配布されています。

Swift

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

0グッド

0クリップ

投稿2021/04/30 06:05

環境
Xcode 12.2
swift 5
build端末 ipad air(4th)

とあるプリンターに印刷処理を送る際に、通信エラーが発生したり、紙切れが発生した場合に、再びプリンターが動き出せるようになるまで、sleep(10)をかけながら無限ループさせるようなロジックを作成しようと考えています。(無限ループから強制的に抜ける方法も後ほど考える)

storybordで配置したlabelにエラーメッセージを反映させたいのですが、以下のような事象が起きてしまいうまく実現することができていません。
1,1回目のループの際にエラーが出たとしてもエラーメッセージが表示されない(labelに反映されない)
2,エラーメッセージが表示されるタイミングがワンループ分遅れる(printErrorにエラー判定が入った場合にそのループのうちにエラーメッセージを表示させたい)

swift

1while count <= numberOfPrintedSheets { 2 currentPrintCount.text = String(count) + "枚目" 3 let printError = printerDriver.printImage(with: url as URL, settings: printSettings) 4 switch printError.code { 5 case.noError: count += 1; errorFlag = 0 6 default: 7 if errorFlag == 0 { count += 1; errorFlag = 1} 8 printStatusLabel.text = { 9 switch printError.code { 10 case .printerStatusErrorPaperEmpty: return "紙切れが発生しました。近くにいるスタッフにお声がけください。" 11 case .printerStatusErrorCoverOpen: return "プリンターのカバーが空いています。「カチッ」と音がするようしっかり閉めてください。" 12 default: return "通信エラーが発生しました。以下の中断ボタンで印刷を中断するか、時間を置いてもう一度お試しください。" 13 } 14 }() 15 sleep(10) 16 } 17}

試しにループの頭の部分に

swift

1print(printStatusLabel.text)

と出力してみると、画面には表示されていませんが、きちんとエラーメッセージが代入されていることがわかりました。

出力→Optional("紙切れが発生しました。近くにいるスタッフにお声がけください。")

何かロジックに問題があるのかそれともswift独特のUI描画の条件等あるのでしょうか?
わかる方いらっしゃればご教授いただけますと幸いです。

よろしくお願い致します。

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

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

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

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

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

tomato879241

2021/04/30 06:28

そもそもsleepを何のために使っているのでしょうか?10秒間アプリの作業を停止して、何か意味がありますか?それだったら作業が終わるまで、画面の全面にUIActivityIndicatorViewを付けた白いviewを表示した方がいいのでは?
konchan_exbaka

2021/04/30 06:36

質問ありがとうございます。 エラーが発生した場合のみ呼び出されるsleep自体はループの回数を圧倒的に減らすことができるので使用しています。(紙の入れ替え等が遅くなった場合にかなり負荷がかかるためとクラッシュが怖いため) UIActivityIndicatorViewも使用していたのですが、ユーザーに対し何が起因してプリンターが止まっているのかを明示的に示す上ではメッセージも必須だと思い、このような実装になっています。
tomato879241

2021/04/30 06:38

きっと10秒待ちたいと言うのであれば、sleepを使うのではなくて、以下のようにDispatchQueue.main.asyncAfterを使った方はいいのではないでしょうか? DispatchQueue.main.asyncAfter(deadline: .now() + 10.0) { }
konchan_exbaka

2021/04/30 06:48

ご指摘ありがとうございます。 お恥ずかしながらDispatchQueue.main.asyncAfterを知らなかったので勉強になりました。ありがとうございます。 今回の本筋であるLabelにテキストが反映されないという部分にsleepが起因している可能性もあるのでしょうか?
tomato879241

2021/04/30 06:53

>今回の本筋であるLabelにテキストが反映されないという部分にsleepが起因している可能性もあるのでしょうか? わかりません。自分はkonchan_exbakaがどこにそのコードを書いているかも知りません。自分が相手に見せたいコードだけ書いて、何になりますか?まずはクラスの名前から初めて、上から下までのコードを全て書いたらどうでしょうか?最初に説明しましたが、sleepはアプリを止めるだけなので、それを使う意味はないのではないでしょうか?
hoshi-takanori

2021/04/30 07:21

> 今回の本筋であるLabelにテキストが反映されないという部分にsleepが起因している可能性もあるのでしょうか? はい。 UILabel の text などを変更した場合、実際に変更した内容が画面に表示されるのは、メインスレッドの制御を OS に戻した後 (例えば @IBAction などから return した後) になります。メインスレッドの処理を sleep などで止めてしまうと、その間は描画は更新されませんし、画面タップなどのイベントにも反応しなくなります。(macOS では虹色カーソルが出現しますが、iOS では画面が固まるだけかな…。) DispatchQueue.main.asyncAfter などの非同期処理を使うと、いったん現在の処理を終了して、指定した時間後に (または、例えば API の結果が返ってきた後で) 処理を再開することができますし、その間に OS は画面を更新したり、他のイベントの処理を行うことができます。 なお、今年の WWDC で発表されることが期待されている Swift 5.5 には async/await という機能が入り、この辺のコードがさらに書きやすくなると思います。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだ回答がついていません

会員登録して回答してみよう

アカウントをお持ちの方は

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

ただいまの回答率
85.46%

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

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

質問する

関連した質問