14

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

我在UISearchBar. 我错过了什么,还是根本不可能?我是否必须创建自己的自定义搜索栏,例如从 a 派生UITextField来实现这一点?

4

7 回答 7

9

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

以下对我有用(斯威夫特):

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
}
于 2017-11-14T09:45:38.740 回答
4

这是唯一对我有用的,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()

结果:
在此处输入图像描述

于 2019-07-31T09:04:54.833 回答
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
}

祝你好运

于 2017-06-18T19:26:34.627 回答
1

没有官方的方法可以做到这一点。尝试使用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)
于 2018-11-06T17:53:26.247 回答
0

我在@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)")
于 2020-08-20T11:12:41.947 回答
0

对于 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
    }
}
于 2018-10-01T20:24:20.570 回答
0

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

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

于 2017-10-23T22:01:29.247 回答