はじめに
どうもこんにちは、TOSHです。
UITextFieldを使用したときに、textColorはそのままセットできるのに、なぜか、placeHolderの色はそのままセットできないって感じた人ことある人は多いと思います。
ということで、placeHolderについてもTextColorと同じようにセットできるようなExtensionを考えてみました。
通常の方法
通常、placeHolderの色を変更する場合は、
let color: UIColor = ~ここで任意の色を指定する~
textField.attributedPlaceholder = NSAttributedString(
string: "placeHolderの中の文字",
attributes: [NSAttributedString.Key.foregroundColor : color])
まあ、別にそんなに大変ではないが、NSAttibutedStringを使うのかといった感じですよね。
Extensionを用いた実装方法
extension UITextField {
var placeHolderColor: UIColor {
set {
self.attributedPlaceholder = NSAttributedString(
string: self.placeholder ?? "",
attributes: [NSAttributedString.Key.foregroundColor : newValue])
}
get {
let defaultPlaceHolderGray = UIColor(red: 0, green: 0, blue: 0.0980392, alpha: 0.22)
guard self.attributedPlaceholder?.length != 0,
let placeHolderColor = self.attributedPlaceholder?.attribute(.foregroundColor, at: 0, effectiveRange: nil) as? UIColor else {
return defaultPlaceHolderGray
}
return placeHolderColor
}
}
}
extensionのなかで、Stored Propertyはできないので、Computed Propertyを使用します。
setterは簡単なのですが、意外と苦戦したのは、getter。
Place Holderのなかに文字が入っていない可能性もあるので、self.attributedPlaceholder?.length != 0でガードをする必要があります。あと、あくまで、attributedPlaceholderの1文字目を取っているだけなので、1文字目以降で文字が変わるようなAttributedString出会った場合は、うまく動いていないと思っていいでしょう。
ただ、セットすることはあってもなかなか取ってくることはないと思われるのでこれについてはあまり深く考えなくてもいい気がします。。。
まとめ
実装していて気づいたことは、そもそも、Place Holderの色をセットしたが、中身をセットしないということはないので、textのセットと同時に行うことのできるNSAttributedStringを使用しているののだなと思いました。(Textの場合は、ユーザーが文字を入力するので、初期状態で、色を指定しておいて、Textを指定しないということがメインの使い方)
なので、せっかく作ったはいいんですけど、あまり使用されないようなExtensionだなーという感覚です。