iOS 13 Set UISearchTextField placeholder color

后端 未结 5 1719
执笔经年
执笔经年 2020-12-10 02:20

How do you set the placeholder color of iOS 13\'s UISearchTextField?

I tried the following with no success:

searchField.attributedPlaceh         


        
5条回答
  •  心在旅途
    2020-12-10 02:26

    You can try this with Xcode 11, iOS 13

     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 }
    
    }
    

    Use:

        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)
    

提交回复
热议问题