How to set the NSLayoutAnchor to generate an centered subview with aspect ratio 1:1

ぃ、小莉子 提交于 2019-12-30 05:27:05

问题


It doesn't sound too difficult, but after hours of trying I couldn't get a proper solution.

Problem: I want to set constraints (with class NSLayoutAnchor) to get a subview (colorImageView) beeing centered in the superview, with a aspect ratio of 1:1 AND always at the maximum size possible in a superview that sometimes has a width > height OR height > width.

Example 1: SuperViewSize = width : 80, height = 100 -> subview should get a height and width of 80 and centered at (40/50)

Example 2: SuperviewSize = width : 60, height = 50 -> subview should get a height and width of 50 and centered at (30/25)

I dont want /and it does not solve the problem / to hardcode a widthConstraint = min(superviewWidth, superviewHeight) because at the moment of creation the subview, the superviews bounds are not finally defined -> so I need a constraint.

This is my attempt so far (still missing constraints to set height and width at the maximum possible within a varying superview:

// CREATE CONSTRAINTS(center in SuperView)
colorImageView.centerXAnchor.constraint(equalTo: self.centerXAnchor).isActive = true
colorImageView.centerYAnchor.constraint(equalTo: self.centerYAnchor).isActive = true

// CREATE CONSTRAINTS (ratio 1:1)
colorImageView.widthAnchor.constraint(equalTo: colorImageView.heightAnchor, multiplier: 1.0).isActive = true

I'd really appreciate a hint, how to do that. Thanks in advance :))


回答1:


The key to making this work is to set the width of the colorImageView equal to the width of its superview but with a priority of 750 (instead of the default 1000).

Then set the height of the colorImageView to be lessThanOrEqualTo the height of its superview.

Auto Layout will do its best to satisfy these two new constraints.

When the view's width is greater than its height, it won't be able to make the colorImageViews width equal to the view's width, but that's OK since the priority is 750. It will make it as big as possible without violating the other full priority constraints.

When the view's height is greater than its width, it will be able to satisfy all constraints because the colorView's height is lessThanOrEqualTo the view's height.

import UIKit

let view = UIView(frame: CGRect(x: 0, y: 0, width: 80, height: 100))
view.backgroundColor = .red

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

view.addSubview(colorImageView)

// CREATE CONSTRAINTS(center in SuperView)
colorImageView.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true
colorImageView.centerYAnchor.constraint(equalTo: view.centerYAnchor).isActive = true

// CREATE CONSTRAINTS (ratio 1:1)
colorImageView.widthAnchor.constraint(equalTo: colorImageView.heightAnchor, multiplier: 1.0).isActive = true

let widthConstraint = colorImageView.widthAnchor.constraint(equalTo: view.widthAnchor)
widthConstraint.priority = UILayoutPriority(rawValue: 750)
widthConstraint.isActive = true

colorImageView.heightAnchor.constraint(lessThanOrEqualTo: view.heightAnchor).isActive = true

view.layoutIfNeeded()

view.frame = CGRect(x: 0, y: 0, width: 60, height: 50)
view.layoutIfNeeded()

Here it is running in a Playground:



来源:https://stackoverflow.com/questions/40455046/how-to-set-the-nslayoutanchor-to-generate-an-centered-subview-with-aspect-ratio

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!