如何在UISearchBar iOS 11中居中占位符文本

时间:2017-06-18 17:24:06

标签: ios cocoa-touch uisearchbar ios11

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

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

7 个答案:

答案 0 :(得分:8)

我遇到了完全相同的问题 - 我很难理解为什么默认路线会被改变而不允许我们轻松地将其设置回中心。

以下适用于我(斯威夫特):

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
}

答案 1 :(得分: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
}
祝你好运

答案 2 :(得分: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)

答案 3 :(得分:0)

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

如果您想要在栏处于活动状态时使用其他位置,则必须在相应的委托方法中重置此位置

答案 4 :(得分:0)

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

答案 5 :(得分:0)

这是唯一为我工作的人, 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()

结果:
enter image description here

答案 6 :(得分: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)")