🖥️
【AppKit】NSSecureTextFieldのAuto Fillの挙動とバグ
概要
Projectでパスワード等セキュアな入力に使うNSSecureTextFieldを使った際、動きに翻弄されたので、調査し判明したことを内容として記載する
Auto Fillの表示条件
NSSecureTextFieldは、特定の配置において、パスワードのAuto Fillのpopupが表示され使える挙動をする。以下の画像が、正常な時の表示。
正常
⭕️ 正常縦並び | ⭕️ 正常横並び |
---|---|
画像のように、EditableなNSTextFieldの次にNSSecureTextFieldを配置することで、Auto Fillのpopupが表示されるように仕組まれている。
不適合
❌ NSSecureTextFiledを連続配置 | ❌ NSSecureTextFiled単体配置 |
---|---|
❌ NSSecureTextFiled後にNSTextField(縦) | ❌ NSSecureTextFiled後にNSTextField(横) |
---|---|
❌ EditableでないNSTextFiled後に配置1 | ❌ EditableでないNSTextFiled後に配置2 |
---|---|
isFlippedによるAuto Fillのバグ
Macの座標は、左下が原点となっているため、人によっては扱いづらく、isFlipped = true
にして左上を原点としている人も少なからずいる。
ただその際、Macの各種Objectが正しく動くとは限らず、NSSecureTextFieldのAuto Fillのpopupもこれに該当する。
isFlipped = true
にしているviewの上に配置されたNSSecureTextFieldのAuto Fillのpopupは、以下の画像のようにNSSecureTextFieldと重なった状態で表示される。
回避策としては、NSSecureTextFiledをラップしたviewを作って配置してやるか、その画面だけStoryboardやXIBを使ったGUIで画面を作るのが無難なとこだろうか。
WrapSecureTextField
class WrapSecureTextField: NSView {
override var isFlipped: Bool { false }
var placeholderString: String? {
get { textField.placeholderString }
set { textField.placeholderString = newValue }
}
var stringValue: String {
get { textField.stringValue }
set { textField.stringValue = newValue }
}
private var textField: NSSecureTextField
init(string: String) {
textField = .init(string: string)
super.init(frame: .zero)
addSubview(textField)
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
override func layout() {
super.layout()
textField.frame = bounds
}
}
Discussion