【问题标题】:How to center placeholder text in UISearchBar iOS 11如何在 UISearchBar iOS 11 中居中占位符文本
【发布时间】:2020-08-20 19:12:41
【问题描述】:

在 iOS 11 中,搜索栏默认为左对齐文本。虽然这与 iOS 的其他原生更改看起来不错,但它并不真正适合我的设计,我希望它像以前一样成为中心。

我在UISearchBar 上找不到任何此类对齐属性。我错过了什么,还是根本不可能?我是否必须创建自己的自定义搜索栏,例如从 UITextField 派生来实现这一点?

【问题讨论】:

  • 是的,我也想把它放在中间。苹果让我们设置 searchBar.placeHolder.textAlignment = NSTextAlignmentCenter 有多难??

标签: ios cocoa-touch uisearchbar ios11


【解决方案1】:

我遇到了完全相同的问题 - 我很难理解为什么会更改默认对齐方式,而不允许我们轻松地将其设置回居中。

以下对我有用(Swift):

let placeholderWidth = 200 // Replace with whatever value works for your placeholder text
var offset = UIOffset()

override func viewDidLoad() {
    offset = UIOffset(horizontal: (searchBar.frame.width - placeholderWidth) / 2, vertical: 0)
    searchBar.setPositionAdjustment(offset, for: .search)
}

func searchBarShouldBeginEditing(_ searchBar: UISearchBar) -> Bool {
    let noOffset = UIOffset(horizontal: 0, vertical: 0)
    searchBar.setPositionAdjustment(noOffset, for: .search)

    return true
}


func searchBarShouldEndEditing(_ searchBar: UISearchBar) -> Bool {
    searchBar.setPositionAdjustment(offset, for: .search)

    return true
}

【讨论】:

  • 感谢回复。
【解决方案2】:

这是唯一对我有用的,Swift 4.2

extension UISearchBar {
func setCenteredPlaceHolder(){
    let textFieldInsideSearchBar = self.value(forKey: "searchField") as? UITextField

    //get the sizes
    let searchBarWidth = self.frame.width
    let placeholderIconWidth = textFieldInsideSearchBar?.leftView?.frame.width
    let placeHolderWidth = textFieldInsideSearchBar?.attributedPlaceholder?.size().width
    let offsetIconToPlaceholder: CGFloat = 8
    let placeHolderWithIcon = placeholderIconWidth! + offsetIconToPlaceholder

    let offset = UIOffset(horizontal: ((searchBarWidth / 2) - (placeHolderWidth! / 2) - placeHolderWithIcon), vertical: 0)
    self.setPositionAdjustment(offset, for: .search)
}
}


用法:

searchBar.setCenteredPlaceHolder()

结果:

【讨论】:

  • placeHolderWidth 添加 CGFloat 值
  • 这个不错,但是在搜索栏开始写的时候光标还在中间,如果有文字怎么让它从左边开始
【解决方案3】:

这是一种解决方法。

首先你需要获取搜索栏的文本字段,并将文本对齐居中:

let textFieldOfSearchBar = searchController.searchBar.value(forKey: "searchField") as? UITextField textFieldOfSearchBar?.textAlignment = .center

之后,您需要更改占位符的对齐方式。由于某种原因,它不会随着文本字段的对齐方式而改变。您应该通过仅在搜索控制器处于活动状态时向文本字段的左视图添加填充来做到这一点,因此请使用它的委托方法:

func presentSearchController(_ searchController: UISearchController) {
    //Is active
    let width: CGFloat = 100.0 //Calcualte a suitable width based on search bar width, screen size, etc..

    let textfieldOfSearchBar = searchController.searchBar.value(forKey: "searchField") as? UITextField

    let paddingView = UIView(x: 0, y: 0, w: width, h: searchController.searchBar.frame.size.height)
    textfieldOfSearchBar?.leftView = paddingView
    textfieldOfSearchBar?.leftViewMode = .unlessEditing
}

func willDismissSearchController(_ searchController: UISearchController) {
    let textfieldOfSearchBar = searchController.searchBar.value(forKey: "searchField") as? UITextField
    textfieldOfSearchBar?.leftView = nil
}

祝你好运

【讨论】:

  • 让 paddingView = UIView(frame: CGRect(x: 0, y: 0, width: width, height: self.frame.size.height))
  • 有效,但在更改设备方向后会切断搜索图标并中断
【解决方案4】:

没有官方的方法可以做到这一点。尝试使用UISearchBarDelegate 方法和您自己的UILabel

extension YourViewController: UISearchBarDelegate {
    func searchBarTextDidBeginEditing(_ searchBar: UISearchBar) {
        placeholderLabel.isHidden = true
    }

    func searchBarTextDidEndEditing(_ searchBar: UISearchBar) {
        placeholderLabel.isHidden = false
    }
}

别忘了隐藏标准的左对齐图标(使用空白图片):

    searchBar.setImage(UIImage.imageWithColor(.clear), for: .search, state: .normal)

【讨论】:

    【解决方案5】:

    让 placeHolderOffSet = UIOffset(水平: 100, 垂直: 0) setPositionAdjustment(placeHolderOffSet, for: .search)

    如果您在栏处于活动状态时想要一个不同的位置,您必须在相应的委托方法中重置它

    【讨论】:

      【解决方案6】:

      对于 swift 4.0+

      由于您的问题并没有真正指定占位符,我将对占位符和文本给出答案。在我的项目中,我需要两个文本始终居中,而不仅仅是在我不编辑文本字段时。您可以使用他们所说的委托将其返回到与本文中的一些答案左对齐。

      我也不使用 SearchController,而是使用 SearchBar 插座,无论哪种方式,如果您使用控制器,它都可以轻松地为您的项目修复。 (只需替换 searchController.searchBar 而不是 searchBar)。

      所以只需要在需要的地方调用下一个函数。

      func searchBarCenterInit(){
          if let searchBarTextField = searchBar.value(forKey: "searchField") as? UITextField {
      
              //Center search text
              searchBarTextField.textAlignment = .center
      
              //Center placeholder
              let width = searchBar.frame.width / 2 - (searchBarTextField.attributedPlaceholder?.size().width)!
              let paddingView = UIView(frame: CGRect(x: 0, y: 0, width: width, height: searchBar.frame.height))
              searchBarTextField.leftView = paddingView
              searchBarTextField.leftViewMode = .unlessEditing
          }
      }
      

      【讨论】:

      • 这不被认为是“非法的”,因为您正在访问私人未公开的子视图?此外,在 ViewDidLoad 中调用它不会考虑视图的变化,例如旋转。也许它应该在 viewDidLayoutSubviews 中?
      • @Sti 不完全是,但我仍然更改了内置函数的子视图中的迭代,该内置函数像其他一些答案一样直接返回 searchField。
      • 这会隐藏搜索图标。
      【解决方案7】:

      我在@Danny182 的回答中做了一些修改。这是更新版本,它将适用于所有操作系统版本。

      extension UISearchBar {
          func setPlaceHolder(text: String?) {
              self.layoutIfNeeded()
              self.placeholder = text
              var textFieldInsideSearchBar:UITextField?
              if #available(iOS 13.0, *) {
                  textFieldInsideSearchBar = self.searchTextField
              } else {
                  for view : UIView in (self.subviews[0]).subviews {
                      if let textField = view as? UITextField {
                          textFieldInsideSearchBar = textField
                      }
                  }
              }
              
              //get the sizes
              let searchBarWidth = self.frame.width
              let placeholderIconWidth = textFieldInsideSearchBar?.leftView?.frame.width
              let placeHolderWidth = textFieldInsideSearchBar?.attributedPlaceholder?.size().width
              let offsetIconToPlaceholder: CGFloat = 8
              let placeHolderWithIcon = placeholderIconWidth! + offsetIconToPlaceholder
              
              let offset = UIOffset(horizontal: ((searchBarWidth / 2) - (placeHolderWidth! / 2) - placeHolderWithIcon), vertical: 0)
              self.setPositionAdjustment(offset, for: .search)
          }
      }
      

      你只需要打电话:

      searchBar.setPlaceHolder(text: "Search \(name)")
      

      【讨论】:

        猜你喜欢
        • 2018-06-07
        • 2020-03-27
        • 2013-12-21
        • 2016-02-02
        • 1970-01-01
        • 1970-01-01
        • 2019-10-02
        • 2012-07-12
        • 2012-01-23
        相关资源
        最近更新 更多