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

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

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

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

Xcode

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

Swift

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

Q&A

0回答

852閲覧

Swift5 datePicker搭載だけで表示に乱れ

yamchi

総合スコア1

iOS

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

Xcode

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

Swift

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

0グッド

0クリップ

投稿2021/09/12 07:51

前提・実現したいこと

Swift5でアプリを開発していますが、奇妙な事が発生しました。
アプリはUICorrectionViewを使用してセルにキーボードやPickerViewでデータを入力するものです。セルにキーボードから入力される場合で、そのセルが隠れる場合は、View(全てのUICorrectionViewを乗せています)全体を上部にキーボードサイズ分移動しています。(PickerViewはセルが隠れない大きさにしているのでViewの移動は無しです)

これに対し、機能強化のためdatePickerをstoryboardでViewの上に追加しました。
そうしたら、最初に初期画面から移動してきた時は、以前と同様に正常な動作をするのですが、そこで、画面の更新をするとキーボード入力時にViewが直ぐに戻ってしまいセルが隠れてしまうようになってしまいました。

発生している問題・エラーメッセージ

下記がその動きです。
左端の数字はログを取るために設定した各モジュールのIDです。
textFieldDidBeginEditingとtextFieldDidEndEditingはtextFieldのdelegate部分です。
textFieldはUICorrectionViewのセルの中に設定されています。
showKeyboardはviewDidLoad内のNotificationCenter.default.addObserverに設定です。
closeKeyboardもviewDidLoad内のNotificationCenter.default.addObserverに設定です。scrollTableCellはshowKeyboard内とcloseKeyboard内でcallします。
scrollTableCellはViewを上げる時も下げる時も呼ばれます。(フラグにより判断)
datePickerについては@IBOutletの変数定義だけです。

異常な点は以下です。

・なぜ、画面更新されるとキーボード入力開始(ID:20)が2回呼ばれるのか?
・なぜキーボード表示された後にレイアウト変更(ID:4)が呼ばれるのか?

更に不可解な事は、下記の後に初期画面に戻り(show)、再度同じ操作をしても画面更新後と同じになってしまう(Viewが直ぐに戻ってしまう)事です。
また、datePickerを追加したから発生していますが、datePickerを使用する画面を全く表示していないのに発生します。

これでは、datePickerを使用できません。どなたかこの原因や退避方法をご存知の方はいらっしゃいませんでしょうか?

該当のソースコード

ソースは多すぎるので、ログを示します。

<初期画面からshowで移動>

0: viewDidLoad()
1: viewWillAppear
4: viewDidLayoutSubviews
6: collectionView( insetForSectionAt section: Int) x 8
4: viewDidLayoutSubviews
20: textFieldDidBeginEditing
6: collectionView( insetForSectionAt section: Int)
7: showKeyboard(_ notification: Notification)
10: scrollTableCell
8: closeKeyboard
10: scrollTableCell
21: textFieldDidEndEditing
6: collectionView( insetForSectionAt section: Int)
30: collectionView(didSelectItemAt indexPath: IndexPath)

<画面の更新>
self.loadView() 実行
self.viewDidLoad 実行

0: viewDidLoad()
4: viewDidLayoutSubviews
6: collectionView( insetForSectionAt section: Int) x 8
20: textFieldDidBeginEditing
20: textFieldDidBeginEditing
6: collectionView( insetForSectionAt section: Int)
7: showKeyboard(_ notification: Notification)
10: scrollTableCell
7: showKeyboard(_ notification: Notification)
10: scrollTableCell
4: viewDidLayoutSubviews
4: viewDidLayoutSubviews
8: closeKeyboard
10: scrollTableCell
8: closeKeyboard
10: scrollTableCell
21: textFieldDidEndEditing

試したこと

viewDidLayoutSubviewsが問題を発生していると思ったので、キーボード入力中は直ぐにreturnするようにしたのですが効果はありませんでした。

補足情報(FW/ツールのバージョンなど)

ここにより詳細な情報を記載してください。

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

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

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

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

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

yamchi

2021/09/12 08:45

既に半月以上悩んでいます。 何人もの現役プログラマーに聞きましたが、判りませんでした。 開発期限が迫っているので、早く対処方法を知る必要があります。そのため、申し訳ありませんが下記の投稿もしてしまいました。 https://ja.stackoverflow.com/questions/82439/ 解決法が分かればこちらにも投稿します。
hoshi-takanori

2021/09/12 19:03

ソースなしでログだけ見せられても何も答えようがないですね…。
yamchi

2021/09/13 00:18

仰る通りですが、どれが関連するモジュールか分かりません。 (全部で1万行近いので全ては出せません) なお、datePickerに関するソースは@IBOutletの1行だけです。 因みにログに中にある self.loadView() 実行 self.viewDidLoad 実行 を以下に変えるとこの現象は出ません。 let next = self.storyboard?.instantiateViewController(withIdentifier: "この画面のID") as! CalendarController self.show(next, sender: nil)
yamchi

2021/09/13 07:29

そうですね。禁止されている事をやっていたとは... 当初、セル単位で表示更新はreloadItems、correctionView単位で表示更新はreloadData、画面全体は上記と習いました。また、そのように書かれたサイトもありました。 https://tsukader.hatenablog.com/entry/2018/08/20/093414 上記のloadViewをself.view.setNeedsDisplayに変えてみたのですが、画面は変更しませんでした。 どのようにすれば「画面の更新」が出来るのでしょうか? 上記のshowを使用した再描画はメモリをドンドン使ってしまうと聞いたので避けましたが、そのような事はないのでしょうか?
hoshi-takanori

2021/09/13 07:34

show は再描画ではなく画面遷移なので、無駄に画面が積み重なるのでは。 とにかく質問が漠然としすぎて答えようがありません。現象を再現するための最小限のコードを書いて検証することをお勧めします。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

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

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

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

ただいまの回答率
85.35%

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

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

質問する

関連した質問