Auto Layout: layoutMarginsGuide

How to rewrite visual format

addConstraints(NSLayoutConstraint.constraintsWithVisualFormat("|-[label]-|", options: .AlignAllBaseline, metrics: nil, views: ["label": label])) addConstraints(NSLayoutConstraint.constraintsWithVisualFormat("V:|-[label]-|", options: .AlignAllCenterX, metrics: nil, views: ["label": label])) 

going to layout guides (with margins)?

I tried it with

 label.topAnchor.constraintEqualToAnchor(layoutMarginsGuide.topAnchor).active = true label.leftAnchor.constraintEqualToAnchor(layoutMarginsGuide.leftAnchor).active = true label.bottomAnchor.constraintEqualToAnchor(layoutMarginsGuide.bottomAnchor).active = true label.rightAnchor.constraintEqualToAnchor(layoutMarginsGuide.rightAnchor).active = true 

but does not work. Even layoutMarginsGuide.layoutFrame does not have the expected value (yes, I call it in layoutSubviews after doing super ). The limits are set, but act as a zero margin. It is a layout and gives the expected layoutFrame only when the layout is set to negative; which is clearly not what I want, but demonstrates that constraints are set using guide fields. Looks like I missed something ...

+6
source share
3 answers

It seems to me that layoutMarginsGuide is not ready in the init method of the UIView. I am also having similar problems when setting constraints in updateConstraints only works. Still exploring why.

UPDATE: what I was trying to do was set the layouts of the layouts before the view was added to the supervisor (in init). This did not work. Which worked with setting limits in init compared to layoutMarginsGuide, but actually setting layoutMargins to viewDidMoveToSuperView.

+11
source

I did another study since I now have iOS 10. Here is what I found:

  • It still does not work reliably. I mean setting restrictions on the guide fields of the layout in the designated initializer without further action.
  • It works fine if frame size> = layout layouts for a specific size.
  • If you call layoutMarginsGuide (even only in print , we are still talking about calls in the initializer), you will damage this manual so that even in a later call (for example, in didMoveToWindow ) it will not work then. You can repair it by installing a new layoutMargins (but the new value should be different from the old one).

I consider this a mistake and filed it (please indicate it also so that it can be set as a priority for correction).

+4
source

Reuse that contains a workaround addressed to layoutMarginsGuide (Swift 4).

 open class View: UIView { public override init(frame: CGRect) { var adjustedFrame = frame if frame.size.width == 0 { adjustedFrame.size.width = CGFloat.greatestFiniteMagnitude } if frame.size.height == 0 { adjustedFrame.size.height = CGFloat.greatestFiniteMagnitude } super.init(frame: adjustedFrame) #if !TARGET_INTERFACE_BUILDER initializeView() #endif } public required init?(coder aDecoder: NSCoder) { super.init(coder: aDecoder) } open override func awakeFromNib() { super.awakeFromNib() initializeView() } open func initializeView() { // Do something in child classes. } } 
0
source

All Articles