I want to add a leading, trailing, bottom and width constraint programmatically to a UISearchController. This is my code:
@IBOutlet weak var navigationBar: UIView!
// create search bar
searchBar = UISearchController(searchResultsController: nil)
navigationBar.addSubview(searchBar.searchBar)
searchBar.searchBar.translatesAutoresizingMaskIntoConstraints = false
let leftConstraint = NSLayoutConstraint(item: searchBar.searchBar, attribute: .Leading, relatedBy: .Equal, toItem: navigationBar, attribute: .Leading, multiplier: 1, constant: 0)
let rightConstraint = NSLayoutConstraint(item: searchBar.searchBar, attribute: .Trailing, relatedBy: .Equal, toItem: navigationBar, attribute: .Trailing, multiplier: 1, constant: 0)
let bottomConstraint = NSLayoutConstraint(item: searchBar.searchBar, attribute: .Bottom, relatedBy: .Equal, toItem: navigationBar, attribute: .Bottom, multiplier: 1, constant: 0)
let heightConstraint = NSLayoutConstraint(item: searchBar.searchBar, attribute: .Height, relatedBy: .Equal, toItem: nil, attribute: .NotAnAttribute, multiplier: 1, constant: 44)
navigationBar.addConstraints([leftConstraint, rightConstraint, bottomConstraint, widthConstraint])
When running the app, the search bar appears correctly, but when I press on the search bar, it shrinks, and if I press another time the app crashes. Here is the output:
2015-08-12 20:20:37.696 Contacts++[96997:8547485] The view hierarchy is not prepared for the constraint: <NSLayoutConstraint:0x7fb22580c7a0 UIView:0x7fb225817b20.leading == UIView:0x7fb223449860.leading>
When added to a view, the constraint's items must be descendants of that view (or the view itself). This will crash if the constraint needs to be resolved before the view hierarchy is assembled. Break on -[UIView(UIConstraintBasedLayout) _viewHierarchyUnpreparedForConstraint:] to debug.
2015-08-12 20:20:37.697 Contacts++[96997:8547485] *** Assertion failure in -[UIView _layoutEngine_didAddLayoutConstraint:roundingAdjustment:mutuallyExclusiveConstraints:], /BuildRoot/Library/Caches/com.apple.xbs/Sources/UIKit_Sim/UIKit-3491.2.5/NSLayoutConstraint_UIKitAdditions.m:590
Why do you need to create an instance of 'UISearchController' and get its searchBar?
why not just make the searchBar from UISearchBar?
// create a searchBar from UISearchBar
let searchBar = UISearchBar(frame: CGRectZero)
// add searchBar to navigationBar
navigationController?.navigationBar.addSubview(searchBar)
// call sizeToFit.. this will set the frame of the searchBar to exactly the same as the size of the allowable frame of the navigationBar
searchBar.sizeToFit()
// now reframe the searchBar to add some margins
var frame = searchBar.frame
frame.origin.x = 20
frame.size.width -= 40
searchBar.frame = frame // set new frame with margins
note: you won't need any of those constraint to achieve this.
But if you really prefer the constraint, here's the constraint code without a crash.
let searchBar = UISearchBar(frame: CGRectZero)
navigationController?.navigationBar.addSubview(searchBar)
searchBar.setTranslatesAutoresizingMaskIntoConstraints(false)
let leftConstraint = NSLayoutConstraint(item: searchBar, attribute: .Leading, relatedBy: .Equal, toItem: navigationController?.navigationBar, attribute: .Leading, multiplier: 1, constant: 20) // add margin
let bottomConstraint = NSLayoutConstraint(item: searchBar, attribute: .Bottom, relatedBy: .Equal, toItem: navigationController?.navigationBar, attribute: .Bottom, multiplier: 1, constant: 1)
let topConstraint = NSLayoutConstraint(item: searchBar, attribute: .Top, relatedBy: .Equal, toItem: navigationController?.navigationBar, attribute: .Top, multiplier: 1, constant: 1)
let widthConstraint = NSLayoutConstraint(item: searchBar, attribute: .Width, relatedBy: .Equal, toItem: nil, attribute: .NotAnAttribute, multiplier: 1, constant: self.view.frame.size.width - 40) // - margins from both sides
navigationController?.navigationBar.addConstraints([leftConstraint, bottomConstraint, topConstraint, widthConstraint])
Do you really want to set the width of the navigatinBar to 44 points? Width is horizontal. You already have a width constraint by adding trailing and leading constraints.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With