iPhone
Xcode
iOS

iOS 11 で UIToolbar にカスタムビューで乗せた UITextField のサイズが暴れるのを「とりあえずなんとかする」方法

この記事を読むにあたって

以下に記載される内容は「とりあえずなんとかする」方法である事に注意。
もっと正しい対応方法があると思いますが、様々な事情により大きな変更を入れられない場合などに使えるかもしれません。

事象

アプリ内のブラウザのURLを表示・編集するために使用していた UITextField をカスタムビューとして生成した UIBarButtonItem の大きさが異常に大きくなってしまう場合があった。
また、サイズを小さくしようとしても小さくならない。

確認した挙動

  • -setFrame: するとツールバー内部の UIStackView サブクラスから -setFrame: が飛んでくる (AutoLayout)
  • AutoLayoutされた結果は UITextField に入力されている text の影響を受ける
  • text 全域が表示できる大きさより小さくできない
  • text 全域が表示できる大きさより大きくできる
  • -setText: のタイミングで大きさが変更されることはない
  • text が長い場合、UITextField の右側にあるアイテムすら画面外に押しのけて自分がツールバー上で最大の大きさにまで広がる場合がある

どうやらツールバーに収まる範囲内で UIBarButtonItem のカスタムビューの -sizeThatFits: 辺りの大きさになるらしい。
※ 具体的には未検証。

対応

UIView の上に UITextField を乗せ、UIView をカスタムビューとして UIBarButtonItem を生成する。

UIView, UITextField の大きさは個々の事情に合わせて変更。
大体は UIView サブクラスを作って -setFrame: を subviews 内の UITextField にも適用する方式や、autoresizingMask の設定で事足りるかと。

試行錯誤段階で UITextField サブクラスを作って -setFrame: が呼ばれた時に text のコピーを作成し、テキストフィールドに空文字列をセットしてから [super setFrame:frame]; した後に コピーしていた text を再セットする方式も試したが、基本的に上手くいくものの完璧とはならなかった。