I've got a UIView that I'm adding programmatically with the following code in viewDidLoad
dropMenuView = YNDropDownMenu(frame: CGRect(x: 0.0, y: 0, width: UIScreen.main.bounds.width, height: 40.0), dropDownViews: [typeView, brandView, priceView], dropDownViewTitles:["Type", "Brand", "Price"])
self.view.addSubview(dropMenuView)
The above code creates a view with the correct width for the current orientation, but if a user changes their device orientation, the width of the view does not update. I've tried adding a new constraint in viewWillTransitionTo:
override func viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator) {
let widthConstraint = NSLayoutConstraint(item: dropMenuView, attribute: NSLayoutAttribute.width, relatedBy: NSLayoutRelation.equal, toItem: self.view, attribute: NSLayoutAttribute.notAnAttribute, multiplier: 1, constant: 100)
dropMenuView.addConstraints([widthConstraint])
dropMenuView.layoutIfNeeded()
}
I've tried a number of mutations on the above code trying to get it to work. Generally the error I get is: 'NSLayoutConstraint for >: Unknown layout attribute'
I can't help but think I'm going about this in the wrong way. Is adding new constraints upon orientation change the way to go? I tried just adding the equal width constraint after I add the subview, but I get the same error. I've never really added constraints programmatically before, so these are uncharted waters for me. What would be the best approach here?
Adding constraints during an orientation change is not a good idea. If you were to do it, you'd need to remove the previously added constraints to avoid over constraining your view.
The constraint you are trying to create isn't correct. You only use .notAnAttrubute
when you are passing nil
as the second view.
I suggest you use layout anchors instead. They're easier to write and read:
dropMenuView = YNDropDownMenu(frame: CGRect.zero, dropDownViews: [typeView, brandView, priceView], dropDownViewTitles:["Type", "Brand", "Price"])
self.view.addSubview(dropMenuView)
// you need to set this if you are adding your own constraints and once
// yet set it, the frame is ignored (which is why we just passed CGRect.zero
// when creating the view)
dropMenuView.translatesAutoresizingMaskIntoConstraints = false
// Create the constraints and activate them. This will set `isActive = true`
// for all of the constraints. iOS knows which views to add them to, so
// you don't have to worry about that detail
NSLayoutConstraint.activate([
dropMenuView.topAnchor.constraint(equalTo: view.topAnchor),
dropMenuView.leadingAnchor.constraint(equalTo: view.leadingAnchor),
dropMenuView.trailingAnchor.constraint(equalTo: view.trailingAnchor),
dropMenuView.heightAnchor.constraint(equalToConstant: 40)
])