如何设置iOS 13 UISearchTextField
的占位符颜色?
我尝试了以下操作,但没有成功:
searchField.attributedPlaceholder = NSAttributedString(string: "Some placeholder", attributes: [NSAttributedString.Key.foregroundColor: UIColor.red])
这是当前Beta中的错误,还是我错过了什么?我正在使用Xcode 11,Beta 7。
答案 0 :(得分:5)
您可以使用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 }
}
使用:
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)
答案 1 :(得分:1)
我发现以下代码段有效:
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)
}
答案 2 :(得分:1)
使用自定义搜索栏。
当UISearchController
内UINavigationItem
的一部分(带有hidesSearchBarWhenScrolling = true
)时,这也适用。
我们希望在应用UIAppearance
代理后立即应用更改,因为这是最可能的根本原因:
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() {
super.didMoveToSuperview() // important! - system colors will not apply correctly on ios 11-12 without this
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 }
}
答案 3 :(得分:0)
这对我来说适用于XCode 11.1的占位符颜色,删除搜索图标:
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)
答案 4 :(得分:0)
UiSearch
栏不会更新viewDidLoad
和viewWillAppear
中的占位符颜色,因此请在viewDidAppear
中编写以下代码:
let textField = searchbar.value(forKey: "searchField") as? UITextField
let placeholderAttributes = [NSAttributedString.Key.foregroundColor : UIColor.white.withAlphaComponent(0.6)]
let attributedPlaceholder = NSAttributedString(string: "SearchTextPlaceholer".localized(), attributes: placeholderAttributes)
textField?.attributedPlaceholder = attributedPlaceholder