First of all, this is what I want to achieve:
The view needs to be centered, with a height of 200. The trailing an leading anchors should touch the layoutmargins. I am creating my constraints programatically.
import UIKit
class CustomView: UIView {
var dialogView : UIView!
func show()
{
UIApplication.shared.delegate?.window??.rootViewController?.view.addSubview(self)
dialogView = UIView()
dialogView.translatesAutoresizingMaskIntoConstraints = false
dialogView.backgroundColor = .red
addSubview(dialogView)
let dialogViewCenterYConstraint = dialogView.centerYAnchor.constraint(equalTo: self.centerYAnchor)
dialogViewCenterYConstraint.isActive = true
let dialogViewHeightConstraint = dialogView.heightAnchor.constraint(equalToConstant: 200)
dialogViewHeightConstraint.isActive = true
let margins = self.layoutMarginsGuide
let dialogViewLeadingConstraint = dialogView.leadingAnchor.constraint(equalTo: margins.leadingAnchor)
dialogViewLeadingConstraint.isActive = true
let dialogViewTrailingConstraint = dialogView.trailingAnchor.constraint(equalTo: margins.trailingAnchor)
dialogViewTrailingConstraint.isActive = true
}
override func layoutSubviews() {
frame = UIScreen.main.bounds
}
}
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
CustomView().show()
// Do any additional setup after loading the view, typically from a nib.
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
It is working, but it also prints the following warning:
[LayoutConstraints] Unable to simultaneously satisfy constraints.
Probably at least one of the constraints in the following list is one you don't want.
Try this:
(1) look at each constraint and try to figure out which you don't expect;
(2) find the code that added the unwanted constraint or constraints and fix it.
(Note: If you're seeing NSAutoresizingMaskLayoutConstraints that you don't understand, refer to the documentation for the UIView property translatesAutoresizingMaskIntoConstraints)
(
"<NSAutoresizingMaskLayoutConstraint:0x60000009ee60 h=--& v=--& ArtAlertView.CustomView:0x7f9f86c0f770.width == 0 (active)>",
"<NSLayoutConstraint:0x60000009ed20 UIView:0x7f9f86c100d0.leading == UILayoutGuide:0x6000001b8b80'UIViewLayoutMarginsGuide'.leading (active)>",
"<NSLayoutConstraint:0x60000009ed70 UIView:0x7f9f86c100d0.trailing == UILayoutGuide:0x6000001b8b80'UIViewLayoutMarginsGuide'.trailing (active)>",
"<NSLayoutConstraint:0x60000009eb90 'UIView-leftMargin-guide-constraint' H:|-(8)-[UILayoutGuide:0x6000001b8b80'UIViewLayoutMarginsGuide'](LTR) (active, names: '|':ArtAlertView.CustomView:0x7f9f86c0f770 )>",
"<NSLayoutConstraint:0x60000009ec30 'UIView-rightMargin-guide-constraint' H:[UILayoutGuide:0x6000001b8b80'UIViewLayoutMarginsGuide']-(8)-|(LTR) (active, names: '|':ArtAlertView.CustomView:0x7f9f86c0f770 )>"
)
Will attempt to recover by breaking constraint
<NSLayoutConstraint:0x60000009ed70 UIView:0x7f9f86c100d0.trailing == UILayoutGuide:0x6000001b8b80'UIViewLayoutMarginsGuide'.trailing (active)>
Make a symbolic breakpoint at UIViewAlertForUnsatisfiableConstraints to catch this in the debugger.
The methods in the UIConstraintBasedLayoutDebugging category on UIView listed in <UIKit/UIView.h> may also be helpful.
I noticed one of the constraints is an NSAutoresizingMaskLayoutConstraint. I thought setting translatesAutoresizingMaskIntoConstraints to false would get rid of these.
Any thoughts?
Try the following:
func addSubview(_ view: UIView, with height: CGFloat = 200.0)
{
// Check whether superview is non-nil
if view.superview != nil
{
view.removeFromSuperview()
}
// Add self to view as subview
self.addSubview(view)
// translatesAutoresizingMaskIntoConstraints is true by default, which breaks UIView.addConstraints() function
view.translatesAutoresizingMaskIntoConstraints = false
// Create constraints
let centerY = NSLayoutConstraint(item: view,
attribute: .centerY,
relatedBy: .equal,
toItem: self,
attribute: .centerY,
multiplier: 1,
constant: constants.top)
let leading = NSLayoutConstraint(item: view,
attribute: .leading,
relatedBy: .equal,
toItem: self,
attribute: .leading,
multiplier: 1,
constant: constants.leading)
let trailing = NSLayoutConstraint(item: view,
attribute: .trailing,
relatedBy: .equal,
toItem: self,
attribute: .trailing,
multiplier: 1,
constant: constants.trailing)
// Add constraints to superview and return them
self.addConstraints([top, bottom, leading, trailing])
let height = NSLayoutConstraint(item: view,
attribute: .height,
relatedBy: .equal,
toItem: nil,
attribute: nil,
multiplier: 1,
constant: height)
view.addConstraints([height])
}
I'm not sure that this exact text will work however (height constraint in untested). The idea is to create new constraints for leading
, trailing
and centerY
and add those to your CustomView
intance. Height constraint must be added to the dialogView
.
Because you create new CustomView
without frame, when you called show
a new dialogView
will be added to it and layout with |-margin-[dialogView]-margin-|
, this requires CustomView
's width >= 2 * margin
. so you will get this layout warning.
There are 2 way to fix this issue:
1.when you initial a new CustomView
give it a frame where frame.width >= margin * 2.
2.give leading and trailing constraint of dialogView
a lower layout priority.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.