酢ろぐ!

カレーが嫌いなスマートフォンアプリプログラマのブログ。

UISearchBarのTextFieldの背景色を変更する(iOS 13以降ではAPIが変わるらしい)

UISearchBarのTextField部分の背景色を変更できなくて頭をひねった……

f:id:ch3cooh393:20200501143149p:plain

UISearchBarのTextFieldの背景色を変更する

下記のコードで対応することができた。

extension UISearchBar {

    var textField: UITextField? {
        return value(forKey: "searchField") as? UITextField
    }
    
    func setSearchTextFieldBackgroundColor(color: UIColor) {
        guard let textField = textField else {
            return
        }
        switch searchBarStyle {
        case .minimal:
            textField.layer.backgroundColor = color.cgColor
            textField.layer.cornerRadius = 6
        case .prominent, .default:
            textField.backgroundColor = color
        @unknown default:
            break
        }
    }
}

参照元

まず、UISearchBarのUITextField部分の背景色を変更する、で検索にかかったのはこの記事。UISearchBarからTextFieldに直接触る方法がないことがわかった。valueForKey(:)を使う。

ただし、この方法で取得した TextFieldに対して背景色を設定しても反映されることはなかった。searchBarStyle が.minimalの時には背景色の設定方法が異なることがわかった。

iOS 13以降でのUISearchBarのTextFieldの背景色を変更する方法

さらに調べたところ、iOS 13では直接TextFieldに触れられるプロパティが追加されたためか、_searchTextField に触れるとクラッシュするようになった。

'NSGenericException', reason: 'Access to UISearchBar's _searchField ivar is prohibited. This is an application bug'

Xcode 10.3(10G8) ではビルドが通らなかったので、下記のように書き換えた。

extension UISearchBar {

    var textField: UITextField? {
        if #available(iOS 13.0, *) {
            return searchTextField
        } else {
            return value(forKey: "searchField") as? UITextField
        }
    }
    
    func setSearchTextFieldBackgroundColor(color: UIColor) {
        guard let textField = textField else {
            return
        }
        switch searchBarStyle {
        case .minimal:
            textField.layer.backgroundColor = color.cgColor
            textField.layer.cornerRadius = 6
        case .prominent, .default:
            textField.backgroundColor = color
        @unknown default:
            break
        }
    }
}