web-dev-qa-db-fra.com

iOS 13 Définir la couleur de l'espace réservé UISearchTextField

Comment définissez-vous la couleur de l'espace réservé du UISearchTextField d'iOS 13?

J'ai essayé ce qui suit sans succès:

searchField.attributedPlaceholder = NSAttributedString(string: "Some placeholder", attributes: [NSAttributedString.Key.foregroundColor: UIColor.red])

Est-ce un bug dans la version bêta actuelle ou est-ce que je manque quelque chose? J'utilise Xcode 11, beta 7.

17
Renato Stauffer

Vous pouvez essayer ceci avec Xcode 11, iOS 1

 extension UISearchBar {

        func getTextField() -> UITextField? { return value(forKey: "searchField") as? UITextField }
        func set(textColor: UIColor) { if let textField = getTextField() { textField.textColor = textColor } }
        func setPlaceholder(textColor: UIColor) { getTextField()?.setPlaceholder(textColor: textColor) }
        func setClearButton(color: UIColor) { getTextField()?.setClearButton(color: color) }

        func setTextField(color: UIColor) {
            guard let textField = getTextField() else { return }
            switch searchBarStyle {
            case .minimal:
                textField.layer.backgroundColor = color.cgColor
                textField.layer.cornerRadius = 8
            case .prominent, .default: textField.backgroundColor = color
            @unknown default: break
            }
        }

        func setSearchImage(color: UIColor) {
            guard let imageView = getTextField()?.leftView as? UIImageView else { return }
            imageView.tintColor = color
            imageView.image = imageView.image?.withRenderingMode(.alwaysTemplate)
        }
    }

    private extension UITextField {

    private class Label: UILabel {
        private var _textColor = UIColor.lightGray
        override var textColor: UIColor! {
            set { super.textColor = _textColor }
            get { return _textColor }
        }

        init(label: UILabel, textColor: UIColor = .lightGray) {
            _textColor = textColor
            super.init(frame: label.frame)
            self.text = label.text
            self.font = label.font
        }

        required init?(coder: NSCoder) { super.init(coder: coder) }
    }


    private class ClearButtonImage {
        static private var _image: UIImage?
        static private var semaphore = DispatchSemaphore(value: 1)
        static func getImage(closure: @escaping (UIImage?)->()) {
            DispatchQueue.global(qos: .userInteractive).async {
                semaphore.wait()
                DispatchQueue.main.async {
                    if let image = _image { closure(image); semaphore.signal(); return }
                    guard let window = UIApplication.shared.windows.first else { semaphore.signal(); return }
                    let searchBar = UISearchBar(frame: CGRect(x: 0, y: -200, width: UIScreen.main.bounds.width, height: 44))
                    window.rootViewController?.view.addSubview(searchBar)
                    searchBar.text = ""
                    searchBar.layoutIfNeeded()
                    _image = searchBar.getTextField()?.getClearButton()?.image(for: .normal)
                    closure(_image)
                    searchBar.removeFromSuperview()
                    semaphore.signal()
                }
            }
        }
    }

    func setClearButton(color: UIColor) {
        ClearButtonImage.getImage { [weak self] image in
            guard   let image = image,
                let button = self?.getClearButton() else { return }
            button.imageView?.tintColor = color
            button.setImage(image.withRenderingMode(.alwaysTemplate), for: .normal)
        }
    }

    var placeholderLabel: UILabel? { return value(forKey: "placeholderLabel") as? UILabel }

    func setPlaceholder(textColor: UIColor) {
        guard let placeholderLabel = placeholderLabel else { return }
        let label = Label(label: placeholderLabel, textColor: textColor)
        placeholderLabel.removeFromSuperview() // To remove existing label. Otherwise it will overwrite it if called multiple times.
        setValue(label, forKey: "placeholderLabel")
    }

    func getClearButton() -> UIButton? { return value(forKey: "clearButton") as? UIButton }

}

tilisez:

    searchBarObj.placeholder = "placeholder text"
    searchBarObj.set(textColor: .blue)
    searchBarObj.setTextField(color: UIColor.gray)
    searchBarObj.setPlaceholder(textColor: .red)
    searchBarObj.setSearchImage(color: .black)
    searchBarObj.setClearButton(color: .red)
6
Nick

J'ai trouvé l'extrait de code suivant fonctionnel:

DispatchQueue.main.asyncAfter(deadline: .now()+0.5) {
    // Stackoverflow said the above doesn't work on viewDidLoad style methods, so running it async after a 0.5s delay to workaround.  Works.
    searchField.attributedPlaceholder = NSAttributedString(string:"Search", attributes: attributesDictionary)
}
4
chrisoneiota

Cela fonctionne pour moi XCode 11.1 pour la couleur de l'espace réservé, supprimez l'icône de recherche:

  let textFieldInsideSearchBar = searchbar.value(forKey: "searchField") as? UITextField
    textFieldInsideSearchBar!.attributedPlaceholder = NSAttributedString(string: Constant.Text.search_currency.localized, attributes: [NSAttributedString.Key.foregroundColor: UIColor.white])
    textFieldInsideSearchBar?.textColor = UIColor.white
    textFieldInsideSearchBar?.leftViewMode = UITextField.ViewMode.never
    searchbar.setImage(UIImage(), for: .search, state: .normal)
    searchbar.setPositionAdjustment(UIOffset(horizontal: -20, vertical: 0), for: .search)
0
Baibhav Singh

iOS 13

Lorsqu'une partie d'un UISearchController à l'intérieur d'un UINavigationItem (avec hidesSearchBarWhenScrolling = true):

class MySearchBar : UISearchBar {
    // Appearance proxies are applied when a view is added to a view hierarchy, so apply your tweaks after that:
    override func didMoveToSuperview() {
        let placeholderColor = UIColor.white.withAlphaComponent(0.75)
        let placeholderAttributes = [NSAttributedString.Key.foregroundColor : placeholderColor]
        let attributedPlaceholder = NSAttributedString(string: "My custom placeholder", attributes: placeholderAttributes)
        self.searchTextField.attributedPlaceholder = attributedPlaceholder

        // Make the magnifying glass the same color
        (self.searchTextField.leftView as? UIImageView)?.tintColor = placeholderColor
    }
}

// Override `searchBar` as per the documentation
private class MySearchController : UISearchController {
    private lazy var customSearchBar = MySearchBar()
    override var searchBar: UISearchBar { customSearchBar }
}

Copie de ma réponse d'ici

0
Andreas