Implementing Auto Layout for Views Generated Programmatically

AutoLayout in programmatically created UIControl doesn't appear to work

The behaviour of TestButton view will depend on how it is constrained within its superview.

In NSLayoutConstraints both participating attributes (or anchors) are equal "partners": with just those four constraints you have, imageView will take full frame of it's parent (TestButton), but at the same time TestButton will be expanded to be big enough for a full-size image.

You can apply other constraints to TestButton view to prevent the latter.

To understand why standard views behave like that, look at intrinsicContentSize property (docs). It is implemented by standard controls, and tells the auto layout system how big the view should be, purely based on it's content (UIButton or UISwitch are auto-sized like that, for example). UIImageView's intrinsicContentSize is the size of its image, that's why it expands full-size if nothing is preventing it.

3 equal height views using autolayout programmatically

Have you tried using a UIStackView?

lazy var stackView: UIStackView = {
let stackView: UIStackView = UIStackView(arrangedSubviews: [self.firstView, self.secondView, self.thirdView])
stackView.axis = UILayoutConstraintAxis.vertical
stackView.distribution = UIStackViewDistribution.fillEqually
stackView.alignment = UIStackViewAlignment.fill
stackView.spacing = 10.0
return stackView
}()

Then use autolayout to make the height of one of the view's height. The stackView will take care of the other two views' height

Align a programmatically created UIView's center with an auto-layout view's center

You need to override the following method in your view controller:

- (void)viewDidLayoutSubviews 
{
[super viewDidLayoutSubviews];
self.smallView.frame.center = self.largeView.frame.center;
}

Auto Layout programmatically (NSLayoutConstraint): center inner view in outer view and constrain to min(width, height)

First, it's a bit weird that you are setting the inner.widthAnchor constraint twice in your code. Set it only once.

Also, you need to select the outer anchor for the inner view's dimensions based on the actual outer view's frame. If the smallest outer dimension is width, then you constrain the width of the inner view to outer.widthAnchor * imageScale. Otherwise, when the smallest outer dimension is height, you constrain to outer.heightAnchor * imageScale.

This works for me to get the layout you're looking for (I just created a simple single-view project):

class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()

let inner = UIView()
inner.backgroundColor = .yellow
inner.translatesAutoresizingMaskIntoConstraints = false

let outer = UIView()
outer.backgroundColor = .blue
outer.translatesAutoresizingMaskIntoConstraints = false

view.addSubview(outer)
view.addSubview(inner)

// get these from somewhere, e.g. outerWidth.frame.size
let outerWidth = CGFloat(200)
let outerHeight = CGFloat(400)
let outerAnchor: NSLayoutDimension

if outerWidth >= outerHeight {
outerAnchor = outer.heightAnchor
} else {
outerAnchor = outer.widthAnchor
}

let imageScale = CGFloat(0.5)

NSLayoutConstraint.activate([
outer.widthAnchor.constraint(equalToConstant: outerWidth),
outer.heightAnchor.constraint(equalToConstant: outerHeight),
outer.centerXAnchor.constraint(equalTo: view.centerXAnchor),
outer.centerYAnchor.constraint(equalTo: view.centerYAnchor),

inner.centerXAnchor.constraint(equalTo: outer.centerXAnchor),
inner.centerYAnchor.constraint(equalTo: outer.centerYAnchor),
inner.widthAnchor.constraint(equalTo: outerAnchor, multiplier: imageScale),
inner.heightAnchor.constraint(equalTo: inner.widthAnchor)
])
}
}


Related Topics



Leave a reply



Submit