Search code examples
swiftuinavigationbaruisearchbarnslayoutconstraintpure-layout

UISearchBar not getting centered when pinned below a UINavigationBar


I have this code below who configures the constraints of the view:

func configNavigationBarConstraints() {
    navigationBar.autoPinEdge(toSuperviewEdge: .leading)
    navigationBar.autoPinEdge(toSuperviewEdge: .trailing)
    if #available(iOS 11.0, *) {
        navigationBar.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor).isActive = true
        return
    }
    navigationBar.topAnchor.constraint(equalTo: topLayoutGuide.bottomAnchor).isActive = true
}

func configSearchBarConstraints() {
    searchBar.autoPinEdge(.top, to: .bottom, of: navigationBar)
    //    taskHistorySearchBar.autoPinEdge(.top, to: .bottom, of: navigationBar, withOffset: 6) //This is a solution but no ideal, the height diff varies by device
    searchBar.autoPinEdge(toSuperviewEdge: .left)
    searchBar.autoPinEdge(toSuperviewEdge: .right)
}

This results into this view:

enter image description here

Note that the UISearchBar is not aligned, any idea of what I can do? Even if I set it to have a high height value by constraint, the center is offset.


Solution

  • You probably set the UINavigationBar's delegate and UISearchBar's delegate, both extends UIBarPositioningDelegate, so you need to do this:

    extension ViewController: UINavigationBarDelegate {
      func position(for bar: UIBarPositioning) -> UIBarPosition {
        if bar is UINavigationBar {
          return .topAttached
        }
        return .any
      }
    }
    

    This will only apply the .topAttached setting for the UINavigationBar.