I want to fit an image inside a rectangle that should have a specific aspect ratio. No matter what it is, it should find a form to fit inside the rectangle. I played around in storyboard and got this:
The ones with the dotted border have low priority (250).
This works in the storyboard. However, I need to create these constraints programmatically, so I tried it like this (I'm using SnapKit, which simply provides better AutoLayout
syntax. It should be self-explaining):
let topView = UIView()
topView.translatesAutoresizingMaskIntoConstraints = false
topView.backgroundColor = .gray
view.addSubview(topView)
topView.snp.makeConstraints { (make) in
make.top.equalToSuperview()
make.left.equalToSuperview()
make.trailing.equalToSuperview()
make.height.equalTo(250)
}
// This view should have a specific aspect ratio and fit inside topView
let holderView = UIView()
holderView.translatesAutoresizingMaskIntoConstraints = false
holderView.backgroundColor = .red
topView.addSubview(holderView)
holderView.snp.makeConstraints { (make) in
make.center.equalToSuperview() // If I remove this one, there's no auto-layout issue, but then it's offset
make.edges.equalToSuperview().priority(250) // sets leading, trailing, top and bottom
make.edges.greaterThanOrEqualToSuperview().priority(1000)
make.width.equalTo(holderView.snp.height).multipliedBy(3/2)
}
If you paste this into an empty ViewController and start it up, you get these issues:
2018-03-16 15:38:50.188867+0100 DemoProject[11298:850932] [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.
"<SnapKit.LayoutConstraint:0x6000000a7c80@ViewController.swift#24 UIView:0x7fcd82d12440.left == UIView:0x7fcd82d12640.left>",
"<SnapKit.LayoutConstraint:0x6000000a7ce0@ViewController.swift#25 UIView:0x7fcd82d12440.trailing == UIView:0x7fcd82d12640.trailing>",
"<SnapKit.LayoutConstraint:0x6000000a7d40@ViewController.swift#26 UIView:0x7fcd82d12440.height == 250.0>",
"<SnapKit.LayoutConstraint:0x6000000a7da0@ViewController.swift#35 UIView:0x7fcd8580dad0.centerX == UIView:0x7fcd82d12440.centerX>",
"<SnapKit.LayoutConstraint:0x6000000a7e00@ViewController.swift#35 UIView:0x7fcd8580dad0.centerY == UIView:0x7fcd82d12440.centerY>",
"<SnapKit.LayoutConstraint:0x6000000a8580@ViewController.swift#37 UIView:0x7fcd8580dad0.top >= UIView:0x7fcd82d12440.top>",
"<SnapKit.LayoutConstraint:0x6000000a8a60@ViewController.swift#37 UIView:0x7fcd8580dad0.right >= UIView:0x7fcd82d12440.right>",
"<SnapKit.LayoutConstraint:0x6000000a9360@ViewController.swift#38 UIView:0x7fcd8580dad0.width == UIView:0x7fcd8580dad0.height>",
"<NSLayoutConstraint:0x600000092cf0 'UIView-Encapsulated-Layout-Width' UIView:0x7fcd82d12640.width == 414 (active)>"
Will attempt to recover by breaking constraint <SnapKit.LayoutConstraint:0x6000000a9360@ViewController.swift#38 UIView:0x7fcd8580dad0.width == UIView:0x7fcd8580dad0.height>
This doesn't show up, when I remove the centering constraint make.center.equalToSuperview()
. But then, it's misplaced.
What is different between the storyboard and my code? I don't really understand this. I also tried this using the default swift syntax, the result was exactly the same. So I don't think it's a problem with SnapKit
Any ideas? Thank you guys for any help. Let me know if you need any more infos.
EDIT: I mixed something up. It's not about the image and its aspect ratio. It's just about a UIView
that should maintain a specific aspect ratio while fitting inside a rectangle. The actual image will just be put into that holderView
. Sorry