Autolayout aspect ratio based on `intrinsicContentSize` (not constant)

Can such auto-layout constraints be applied with an aspect ratio calculated on the fly based on intrinsicContentSize

? In the documentation, I only found constraints with a fixed ratio value.

The actual s and height from is intrinsicContentSize

not important in my use case, I want to keep the view's height-to-width ratio, which changes dynamically.

Do I have to provide my own implementation of the constraint? Or is there a better way?

+3


source to share


3 answers


intrinsicContentSize

is not available for entering restrictions. (Logically, there are constraints that enforce priorities intrinsicContentSize

and their associated relationship to content and compression, but these are different.)

If you want to limit the aspect ratio, you'll have to add it yourself. It's easy enough to query intrinsicContentSize

at the moment, make sure it provides real (not NSViewNoInstrinsicMetric

) values for both dimensions, calculates the aspect ratio, and then uses that as a factor in a constraint that binds the element's width to its height.



The hard part knows when intrinsicContentSize

was invalid, so you can remove the old aspect ratio limitation and add a new one. You can do this as a subclass of the view by overriding -invalidateIntrinsicContentSize

. (Make sure to call super!) However, I don't know how to do this with a controller or supervisor.

+1


source


You can find an answer on how to set up relationship constraints here . All you have to do is constrain the width and height together while maintaining the given aspect ratio (in this case 4/3).

We can debate whether this opinion is well aware of this information or whether parents should set such restrictions. I usually prefer parents to set constraints, but if your view doesn't make any sense without this constraint, or all of these views need this constraint, you can safely let these views control their width-to-height ratio.

Finally, intrinsicContentSize

tells Auto Layout the size of the view when the view is single:



Returns the natural size for the resulting view, considering only the properties of the view itself.

I don't know what your view represents, but as the documentation says, you can return CGSizeMake(UIViewNoIntrinsicMetric, UIViewNoIntrinsicMetric)

:

If the custom view does not have its own size for a given dimension, it can return a UIViewNoIntrinsicMetric for that dimension.

0


source


If you have a situation where you want to compute the value of a constraint at runtime, the best option is to CTRLdrag the constraint into .h

your controller file and create an IBOutlet for it. This allows you to change the value of the constraint in your code. You can even animate the change to the limit value.

Then, in your code during installation, or when an action occurs that can change the desired value (for example, loading a new image), you calculate the value you want for the constraint and set its value in code. You usually do this using:

self.myConstraintIBOutlet.constant = <insert your new value>;

      

Then you may need to mark the affected view as a required layout:

// Mark whole view as needing layout. You could do this in a subview if
// only a small area is affected
[self.view setNeedsLayout];
[self.view layoutIfNeeded];

      

If you want a smooth transition, you can place layoutIfNeeded

an animation inside the block, making it animate the constraint change:

[self.view setNeedsLayout];
[UIView animateWithDuration:.25 animations:^{
            [self.view layoutIfNeeded];
        } completion:^(BOOL finished) {
            // Completion code
        }];

      

0


source







All Articles