How to use saveesSuperviewLayoutMargins in nested views

I'm trying to use preservesSuperviewLayoutMargins through a hierarchy of nested views, but I encounter a lot of problems with UIKit and wonder what I'm doing wrong (or is this a real mistake).

I am trying to lay out a few views (some next to each other, some above each other):

 // Various combinations here will create different visual results (it will either work or won't) let i1 = ImageView() //let i1 = LabelView() let i2 = ImageView() //let i2 = LabelView() let i3 = ImageView() //let i3 = LabelView() let view = LeftRight(left: i1, right: TopBottom(top: i2, bottom: i3)) //let view = LeftRight(left: TopBottom(top: i2, bottom: i3), right: i1) 

With some layout, I can make it work as shown below. You can see that the images on the right correctly retreat from the green view, which, in turn, correctly retreats from the white view.

Properly built

But with others I struggle:

Black screen!

Running code like this in the application, I can get a full lock and memory.

Indentation is done using layoutMargins as follows:

 let masterView = UIView(frame: CGRect(x: 0, y: 0, width: 500, height: 500)) masterView.translatesAutoresizingMaskIntoConstraints = false masterView.layoutMargins = UIEdgeInsets(top: 5.0, left: 5.0, bottom: 5.0, right: 5.0) let subView = UIView(frame: CGRect(x: 0, y: 0, width: 500, height: 500)) subView.translatesAutoresizingMaskIntoConstraints = false subView.layoutMargins = UIEdgeInsets(top: 5.0, left: 5.0, bottom: 5.0, right: 5.0) 

Here is a sample layout image from the playground. The full project of the playground can be found here , and it can be easily downloaded and run in Xcode to understand what I mean.

 class ImageView: UIView { init() { super.init(frame: CGRect(x: 0, y: 0, width: 1000, height: 1000)) self.preservesSuperviewLayoutMargins = true self.layoutMargins = .zero let imageView = UIImageView(image: UIImage(named: "jesus")) imageView.contentMode = .center imageView.translatesAutoresizingMaskIntoConstraints = false imageView.clipsToBounds = true self.clipsToBounds = true imageView.backgroundColor = UIColor.red self.addSubview(imageView) imageView.leftAnchor.constraint(equalTo: self.layoutMarginsGuide.leftAnchor).isActive = true imageView.rightAnchor.constraint(equalTo: self.layoutMarginsGuide.rightAnchor).isActive = true imageView.topAnchor.constraint(equalTo: self.layoutMarginsGuide.topAnchor).isActive = true imageView.bottomAnchor.constraint(equalTo: self.layoutMarginsGuide.bottomAnchor).isActive = true } } 
+5
source share
2 answers

Ok Found your problem. In your main view and your view there is both a frame size of 500x500 and a marginLayout of 5 points to the edge. If you create instances with the .zero frame, then everything should be fine.

Update

After being on the playground a bit, I also added this to ImageView:

 private var imageView: UIImageView! override var intrinsicContentSize: CGSize { return imageView?.intrinsicContentSize ?? .zero } 

and LabelView:

 private var textLabel: UILabel! override var intrinsicContentSize: CGSize { return textLabel?.intrinsicContentSize ?? .zero } 

Now in your init methods, both ImageView and LabelView use these instance properties instead of a local variable. After that, it seems that all possible combinations work. If you had one particular combination that you knew didn’t like, let me know so that I can test it.

0
source

I believe that you have forgotten something that is required.

  • Implementing intrinsicContentSize in ImageView and Label
  • Missing restrictions that make both subspecies the same in width and height in these two UIView subclasses (TopBottom and LeftRight)
  • The correct view (LeftRight) has not yet been set for the translatesAutoresizingMaskIntoConstraints property to false
  • Add constraint for bottom from frame appearance
  • Call layoutIfNeeded() on frame view

    top.widthAnchor.constraint (equalTo: bottom.widthAnchor) .isActive = true top.heightAnchor.constraint (equalTo: bottom.heightAnchor) .isActive = true

0
source

Source: https://habr.com/ru/post/1264458/


All Articles