【问题标题】:iOS 13 Set UISearchTextField placeholder coloriOS 13 设置 UISearchTextField 占位符颜色
【发布时间】:2020-01-09 05:35:52
【问题描述】:

iOS 13的UISearchTextField的占位符颜色怎么设置?

我尝试了以下但没有成功:

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

这是当前测试版中的错误还是我遗漏了什么?我正在使用 Xcode 11,测试版 7。

【问题讨论】:

  • 您找到解决问题的方法了吗?我遇到了同样的问题。我认为它一定是 beta 错误。
  • 还没有找到解决办法...一有问题就写更新
  • 好的,我找到了解决方案。这是一个时间问题。确保在 viewDidAppear 中设置了属性占位符。将等待 iOS 13 的公开发布以获得官方答案。
  • 你是对的。不幸的是,这意味着颜色变化非常明显。一个无赖。它适用于 iOS 12 中的 viewDidLoad。
  • iOS 13.1.2 中仍然存在

标签: ios xcode placeholder ios13


【解决方案1】:

iOS 13

使用自定义搜索栏。

这也适用于UISearchControllerUINavigationItem 中的一部分(带有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 }
}

Copy of my answer from here

【讨论】:

  • 这是唯一干净的答案,现在是 2020 年,只需使用它,忘记 iOS 9
【解决方案2】:

UiSearch bar 未更新 viewDidLoadviewWillAppear 中的占位符颜色,因此请在 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

【讨论】:

    【解决方案3】:

    这对我有用 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】:

      我发现以下代码 sn-p 有效:

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

      【讨论】:

      • 太棒了!我发现我不必等待很长时间,我可以这样做 DispatchQueue.main.async { ... } 以便它在下一个事件循环中发生。
      • 杰普。 DispatchQueue.main.async {...} 也为我工作。就我而言,自 iOS 14.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)
      

      【讨论】:

      • 这个答案使用 setValue(_, forKey:),这是一个私有 API,使用它可能会被应用商店禁止。
      • Matt,它不是私有的,它的标准可可方法
      猜你喜欢
      • 2020-01-06
      • 1970-01-01
      • 2013-09-12
      • 2014-06-03
      • 2018-01-29
      • 2019-01-03
      • 2020-02-22
      • 1970-01-01
      • 2011-08-15
      相关资源
      最近更新 更多