0
votes

I'm trying to create UISearchController and place its search bar into container view. searchView is outlet. Here's my code:

    let searchController = UISearchController(searchResultsController: nil)
    self.searchController = searchController

    let searchBarBackground = UIImage.roundedImage(UIImage.image(with: #colorLiteral(red: 0.5568627451, green: 0.5568627451, blue: 0.5764705882, alpha: 0.2), size: size), cornerRadius: cornerRadius)
    searchController.searchBar.setSearchFieldBackgroundImage(searchBarBackground, for: .normal)
    searchController.searchBar.searchTextPositionAdjustment = UIOffsetMake(8.0, 0.0)
    searchController.searchBar.searchBarStyle = .minimal
    searchController.searchBar.barStyle = .black
    searchController.searchBar.delegate = self

    searchView.addSubview(searchController.searchBar)

I can't figure out how to make search bar to preserve margins from main view. When I'm trying to add constraints to container view and add search bar as subview, search bar doesn't respect trailing constraint.

enter image description here

Even manual setting of search bar frame equals to content view bounds in viewDidLayoutSubviews doesn't help. It looks OK only when I set leading and trailing constraints to 0 without respecting superview margins. But it has only 8pt margins from sides, I need more.

enter image description here

How can I achieve it? Maybe it's possible to change default margin of search bar? Thanks.

Screenshot from IB if needed (it's just constraints to margin with value -8 to compensate search bar internal margins):

enter image description here

2
Can you show the constraints that you tried?Rakesha Shastri
@RakeshaShastri Added.art-of-dreams
Why are both leading and trailing constants negative? Shouldn't the leading be positive and the trailing negative?Rakesha Shastri
No, constraints is valid. Content view has needed frame, but search bar just stretches to all width of screen when I use it in UISearchController in iOS 11. There are no such problems in lower versions.art-of-dreams

2 Answers

1
votes

I ended up with following solution: update search bar frame after every presenting and dismissing of search controller and in viewDidAppear(_:) for initial setup.

override func viewDidAppear(_ animated: Bool) {
    super.viewDidAppear(animated)
    searchController?.searchBar.frame.size.width = searchView.bounds.width
}

func didPresentSearchController(_ searchController: UISearchController) {
    searchController.searchBar.frame.size.width = self.searchView.bounds.width
}

func didDismissSearchController(_ searchController: UISearchController) {
    searchController.searchBar.frame.size.width = self.searchView.bounds.width
}
0
votes

The problem is that you create view programmatically and use autoresizing mask.

https://developer.apple.com/documentation/uikit/uiview/1622572-translatesautoresizingmaskintoco

By default, the property is set to true for any view you programmatically create.

Example for simple UISearchBar:

class ViewController: UIViewController, UISearchBarDelegate {

    weak var searchBar: UISearchBar?

    override func viewDidLoad() {
        super.viewDidLoad()

        let searchBar = UISearchBar(frame: .zero)
        self.searchBar = searchBar
        searchBar.searchBarStyle = .minimal
        searchBar.barStyle = .black
        searchBar.delegate = self
        searchBar.translatesAutoresizingMaskIntoConstraints = false

        view.addSubview(searchBar)
        NSLayoutConstraint.activate([
            searchBar.topAnchor.constraint(equalTo: view.topAnchor, constant: 50.0),
            searchBar.leadingAnchor.constraint(equalTo: view.leadingAnchor, constant: 40.0),
            view.trailingAnchor.constraint(equalTo: searchBar.trailingAnchor, constant: 40.0),
        searchBar.heightAnchor.constraint(equalToConstant: 36.0)
            ])
    }
}