個人で開発しているオープンソースのMacアプリMizuameでTextFieldに数値の入力制限を設けたのですが、間抜けな実装をしてしまったのでうまく動作せず、バグありのままAppStoreにリリースしてしまいました。macOS 13.xのときは動作していたはずなのですが、macOS 14.0で動作していませんでした。
その間抜けな実装は以下の通りです。
TextField("Value", value: $inputValue) .onChange(of: inputValue) { val in if val < minVal { inputValue = minVal } if val > maxVal { inputValue = maxVal } }
onChange()を使うと、入力や削除があるたびに最大値・最小値のチェックができます。一見問題なさそうですが、1文字を入力または削除した瞬間に最大値または最小値を超えてしまうと現在値が訂正されてしまうので、望む値に変更できません。
例えば、最小値minValに100、最大値maxValに500が設定されていて現在値inputValが200の場合、現在値を300に変更しようとして 2 を削除すると、その瞬間に現在値が「00」となり最小値minVal(=100)を下回るので、入力制限により現在値inputValueが100に設定されてしまいます。
実際の間抜けなコードはこちらです
https://github.com/3colorr/Mizuame/blob/v1.1.2/Mizuame/Settings/TabStickyNote.swift#L85github.com
つまるところ、どうすべきだったか?というと、NumberFormatterを使うべきでした。
private var valueFormatter = NumberFormatter() init() { valueFormatter.minimum = 100 valueFormatter.maximum = 500 } TextField("Value", value: $inputValue, formatter: valueFormatter)
これでTextFieldに入力制限を掛けられます。
実際のソースコードはこちらです。
ブログ中で使ったソースコードは個人開発しているMac向けのメニューバーからアクセスするノートアプリMizuameのものです。MITライセンスのオープンソースですので、実際のソースコードはこちらから確認できます。
AppStoreにも公開しています。
広告は好きではないので付いてません。