ios - Emulating aspect-fit behaviour using AutoLayout constraints in Xcode 6 -


i want use autolayout size , layout view in manner reminiscent of uiimageview's aspect-fit content mode.

i have subview inside container view in interface builder. subview has inherent aspect ratio wish respect. container view's size unknown until runtime.

if container view's aspect ratio wider subview, want subview's height equal parent view's height.

if container view's aspect ratio taller subview, want subview's width equal parent view's width.

in either case wish subview centered horizontally , vertically within container view.

is there way achieve using autolayout constraints in xcode 6 or in previous version? ideally using interface builder, if not perhaps possible define such constraints programmatically.

you're not describing scale-to-fit; you're describing aspect-fit. (i have edited question in regard.) subview becomes large possible while maintaining aspect ratio , fitting entirely inside parent.

anyway, can auto layout. can entirely in ib of xcode 5.1. let's start views:

some views

the light green view has aspect ratio of 4:1. dark green view has aspect ratio of 1:4. i'm going set constraints blue view fills top half of screen, pink view fills bottom half of screen, , each green view expands as possible while maintaining aspect ratio , fitting in container.

first, i'll create constraints on 4 sides of blue view. i'll pin nearest neighbor on each edge, distance of 0. make sure turn off margins:

blue constraints

note don't update frame yet. find easier leave room between views when setting constraints, , set constants 0 (or whatever) hand.

next, pin left, bottom, , right edges of pink view nearest neighbor. don't need set top edge constraint because top edge constrained bottom edge of blue view.

pink constraints

i need equal-heights constraint between pink , blue views. make them each fill half screen:

enter image description here

if tell xcode update frames now, this:

containers laid out

so constraints i've set far correct. undo , start work on light green view.

aspect-fitting light green view requires 5 constraints:

  • a required-priority aspect ratio constraint on light green view. can create constraint in xib or storyboard xcode 5.1 or later.
  • a required-priority constraint limiting width of light green view less or equal width of container.
  • a high-priority constraint setting width of light green view equal width of container.
  • a required-priority constraint limiting height of light green view less or equal height of container.
  • a high-priority constraint setting height of light green view equal height of container.

let's consider 2 width constraints. less-than-or-equal constraint, itself, not sufficient determine width of light green view; many widths fit constraint. since there's ambiguity, autolayout try choose solution minimizes error in other (high-priority not required) constraint. minimizing error means making width close possible container's width, while not violating required less-than-or-equal constraint.

the same thing happens height constraint. , since aspect-ratio constraint required, can maximize size of subview along 1 axis (unless container happens have same aspect ratio subview).

so first create aspect ratio constraint:

top aspect

then create equal width , height constraints container:

top equal size

i need edit these constraints less-than-or-equal constraints:

top less or equal size

next need create set of equal width , height constraints container:

top equal size again

and need make these new constraints less required priority:

top equal not required

finally, asked subview centered in container, i'll set constraints:

top centered

now, test, i'll select view controller , ask xcode update frames. get:

incorrect top layout

oops! subview has expanded fill container. if select it, can see in fact it's maintained aspect ratio, it's doing aspect-fill instead of aspect-fit.

the problem on less-than-or-equal constraint, matters view @ each end of constraint, , xcode has set constraint opposite expectation. select each of 2 constraints , reverse first , second items. instead, i'll select subview , change constraints greater-than-or-equal:

fix top constraints

xcode updates layout:

correct top layout

now same things dark green view on bottom. need make sure aspect ratio 1:4 (xcode resized in weird way since didn't have constraints). won't show steps again since they're same. here's result:

correct top , bottom layout

now can run in iphone 4s simulator, has different screen size ib used, , test rotation:

iphone 4s test

and can test in in iphone 6 simulator:

iphone 6 test

i've uploaded final storyboard this gist convenience.


Comments

Popular posts from this blog

javascript - how to protect a flash video from refresh? -

visual studio 2010 - Connect to informix database windows form application -

android - Associate same looper with different threads -