0% found this document useful (0 votes)
250 views30 pages

iOS 6 Auto Layout Guide

This document summarizes part 2 of a tutorial on beginning Auto Layout in iOS 6. It discusses user constraints versus system constraints, and how Interface Builder adds new constraints to ensure a valid layout when constraints are deleted. It also demonstrates connecting views with constraints, changing constant values, and using constraints to make views the same width. Testing the layout by changing button titles at runtime is also covered.
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
250 views30 pages

iOS 6 Auto Layout Guide

This document summarizes part 2 of a tutorial on beginning Auto Layout in iOS 6. It discusses user constraints versus system constraints, and how Interface Builder adds new constraints to ensure a valid layout when constraints are deleted. It also demonstrates connecting views with constraints, changing constant values, and using constraints to make views the same width. Testing the layout by changing button titles at runtime is also covered.
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 30

12/3/2015

BeginningAutoLayoutiniOS6:Part2/2RayWenderlich

Beginning Auto Layout in iOS 6: Part


2/2
MatthijsHollemans onSeptember19,2012

Updatenote:Checkoutournewerversionofthistutorial,updatedto
SwiftandiOS8:BeginningAutoLayoutTutorialinSwift:Part2.
Thistutorialisanabbreviatedversionofoneofthechaptersfromour
newbookiOS6ByTutorials.MatthijsHollemanswrotethisthe
sameguywhowrotetheiOSApprenticeSeries.Enjoy!
Inpart1ofthistutorialyousawthattheoldstrutsandsprings
modelformakinguserinterfacescannoteasilysolvealllayout
problems.ThenewAutoLayoutfeaturefromiOS6isthesolution,
butbecausethistechnologyissopowerfulitisalsoabitmoretricky
touse.
Inthissecondpartandfinalpartofthetutorialseries,youllcontinue
learningallaboutconstraintsandhowtoapplythem!

As bold as a user constraint


MaybeyounoticedthatsomeoftheTbarsinthecanvasarethickerthanothers.Theboldonesarecalleduser
constraints,andunlikethethinonesyoucandeletethem.However,whenyoudeleteauserconstraint,Interface
Builderwilloftenputanondeletableconstraintinitsplace.Youwillsoonseewhy.
IntheDocumentOutline,userconstraintshaveablueicon:

SelecttheVerticalSpace(40)constraintandtaptheDeletekeyonyourkeyboard.TheTbarbetweenthetwobuttons
disappearsandisreplacedbyanewVerticalSpaceconstraintthatgoesallthewaytothebottom:

http://www.raywenderlich.com/20897/beginningautolayoutpart2of2

1/30

12/3/2015

BeginningAutoLayoutiniOS6:Part2/2RayWenderlich

Thisnewconstrainthasapurpleiconanddoesnothaveaboldline,meaningthatyoucannotdeletethisone.Thetwo
buttonsarenolongerconnectedvertically,althoughtheyarestillleftalignedduetotheLeadingAlignmentconstraint.
Whydoesthishappen?WhydoesInterfaceBuilderattachanewVerticalConstrainttothebutton,eventhoughyoujust
toldittodeletesuchaconstraint?Theansweristhis:
Foreachviewtheremustalwaysbeenoughconstraintstodeterminebothitspositionandsize.
ThatisthemostimportantruletorememberwhenitcomestousingAutoLayout.Iftherearentenoughconstraints,then
AutoLayoutwillbeunabletocalculatewhereyourviewsshouldbepositionedorhowbigtheyshouldbe.Suchalayout
isconsideredtobeinvalid.Youwillseeexamplesofsuchinvalidlayoutslateron.
InterfaceBuildertriesveryhardtopreventyoufrommakinglayoutsthatareinvalid.Thesizeofthesetwobuttonsis
knownbecausebuttonsknowhowbigtheyshouldbe,basedontheirtext,backgroundimage,andsoonintrinsic
contentsize,remember?Sothatsnotaproblem.TheXpositionofthetopbuttonisalsoknownbecauseitsleftedgeis
alignedwiththebottombutton,andthebottombuttonisalwayshorizontallycentered.TheonlyunknownistheY
position.
Previously,thetwobuttonswereconnectedwithaVerticalSpace.ThatwasenoughtodeterminetheYpositionofthe
topbutton.ButifyoudeletethatVerticalSpace,thenthetopbuttonhasnothingtoanchoritverticallyintheview.It
cannotjustfloattherebecausethenAutoLayouthasnowaytodeterminewhatitsYcoordinateshouldbe.
Topreventthisfromhappening,InterfaceBuilderneedstopinthebuttonsomewhereandthebottomedgeisclosest.

http://www.raywenderlich.com/20897/beginningautolayoutpart2of2

2/30

12/3/2015

BeginningAutoLayoutiniOS6:Part2/2RayWenderlich

Funnilyenough,ifyouruntheappandfliptolandscape,itstillseemstowork.Thescreenlooksexactlythesameasit
didbefore.Thatistrue,butyourdesignisfundamentallydifferent:bothbuttonsarenowconnectedtothebottomofthe
window.Thismeansthatifthebottombuttonmoves,thetoponedoesntmovewithit.(Notethateithersolutionisfine,it
justdependsonwhatyouwantyourapptodo.Butinthisexample,youwanttohaveaverticalconnectionbetweenthe
twobuttons.)
Toillustratethis,selecttheVerticalSpaceconstraintbetweenthelowerbuttonandthescreensedge.Gointothe
Attributesinspector.ItsConstantshouldcurrentlyreadAuto,andStandardischeckedbecausethisisastandard
marginspace.Changeitto40.
Becausethebuttonsarenotconnected,onlythelowerbuttonmovesupwardthetopbuttonstaysput:

NoticethatchangingtheConstantvalueoftheconstraintpromotedittoabolduserconstraint.

Needles and pins


Letsconnectthetwobuttonsagain.Sofaryouhavemadeconstraintsbydraggingthebuttonsonthecanvas,butyou
canalsomakethemafterwards.HolddowntheCmdkeyandclickbothbuttonstoselectthem.FromtheEditormenu,
choosePin\VerticalSpacing.
Youcanalsousethelittlepanelinthebottomrightcornertomakethisconstraint:

Itpopsupthefollowingmenu:

http://www.raywenderlich.com/20897/beginningautolayoutpart2of2

3/30

12/3/2015

BeginningAutoLayoutiniOS6:Part2/2RayWenderlich

Regardlessofthemethodyouchoose,thisaddsanewconstraintbetweenthetwobuttons:

ThenewconstraintisaVerticalSpaceconstraintwithaConstantof20points.Thatisbecausethedistancebetweenthe
twobuttonswas20pointsatthetimeyoumadethisconnection.
NoticethattheoldVerticalSpacefromtheuppermostbuttontothebottomedgeisstillthere.Thisconstrainttheone
thatsaysVerticalSpace(104)isnolongerneeded,sodeleteit.
Previouslywhenyoudeletedablueconstraint,apurpleonetookitsplace.Nowthatdoesnothappen,becausethe
remainingconstraintsaresufficienttopositionalltheviews.InterfaceBuilderonlyaddsnewconstraintswhenthe
existingonesarenolongeradequate.
Youshouldnowhavethefollowingconstraints:

http://www.raywenderlich.com/20897/beginningautolayoutpart2of2

4/30

12/3/2015

BeginningAutoLayoutiniOS6:Part2/2RayWenderlich

SelectthebottomVerticalSpace(byclickingonthecanvas)andchangeitsConstantfrom40backtoStandard.This
shouldnotonlymovethebottombuttondownwards,butthetopbuttonaswell,becausetheyareconnectedagain.

A little runtime excursion


Youveseenabitofthebasicsnow:youknowhowtoplacecontrolsusingtheguides,howtoalignthemrelativetoone
another,andhowtoputspacebetweencontrols.Overthecourseofthistutorialyouwillalsousetheotheroptionsfrom
theAlignandPinmenus.
PlayingwiththisinInterfaceBuilderisallwellandgood,butletsseehowthisworksatruntime.Addthefollowing
methodtoViewController.m:
- (IBAction)buttonTapped:(UIButton *)sender
{
if ([[sender titleForState:UIControlStateNormal] isEqualToString:@"X"])
[sender setTitle:@"A very long title for this button"
forState:UIControlStateNormal];
else
[sender setTitle:@"X" forState:UIControlStateNormal];
}
Thissimplytogglesbetweenalongtitleandashorttitleforthebuttonthattriggeredtheevent.Connectthisaction
methodtobothofthebuttonsinInterfaceBuilder:CtrldragfromeachbuttontoFilesOwnerandselectbuttonTapped:in
thepopup.
Runtheappandtapthebuttonstoseehowitbehaves.Performthetestinbothportraitandlandscapeorientations.

http://www.raywenderlich.com/20897/beginningautolayoutpart2of2

5/30

12/3/2015

BeginningAutoLayoutiniOS6:Part2/2RayWenderlich

Regardlessofwhichbuttonhasthelongtitleandwhichhastheshorttitle,thelayoutalwayssatisfiestheconstraintsyou
havegivenit:
Thelowerbuttonisalwayscenteralignedinthewindow,horizontally.
Thelowerbuttonalwayssits20pointsfromthebottomofthewindow.
Thetopbuttonisalwaysleftalignedwiththelowerbutton.
Thatistheentirespecificationforyouruserinterface.
Forfun,selectbothbuttonsinInterfaceBuilderandfromtheAlignmenupickRightEdges.Nowruntheappagainand
noticethedifferences.
Repeat,butnowchooseAlign\HorizontalCenters.Thatwillalwayscenterthetopbuttonwithrespecttothebottom
button.Runtheappandseehowthebuttonsactwhenyoutapthem.

Fixing the width


ThePinmenuhasanoptionforWidthsEqually.Ifyousetthisconstraintontwoviews,thenAutoLayoutwillalways
makebothviewsequallywide,basedonwhichoneisthelargest.Letsplaywiththatforaminute.
SelectbothbuttonsandchoosePin\WidthsEqually.Thisaddsanewconstrainttobothbuttons:

http://www.raywenderlich.com/20897/beginningautolayoutpart2of2

6/30

12/3/2015

BeginningAutoLayoutiniOS6:Part2/2RayWenderlich

Note:Ifyougetanextraunintendedconstraintbetweenoneofthebuttonsandthesuperview,selectthetwo
buttonsandselectAlign\HorizontalCentersagain.

Youhaveseenthistypeofconstraintbefore,inthefirstpartofthistutorial.ItlooksliketheusualTbarbutinthemiddleit
hasacirclewithanequalsign.
IntheDocumentOutlinethisshowsupasasingleEqualWidthsconstraint:

Changingthelabeltextononebuttonwillnowchangethesizeoftheotheroneaswell.
ChangethebottombuttonslabeltoX,justtomakeitreallysmall.Youwillnoticethatthetopbuttonnolongerfitsits
text:

SohowdoesInterfaceBuilderknowwhichbuttonssizetouseforbothofthem?Ifyoupaycloseattention,youllseethat
aWidthconstraintwasaddedtothebuttonwiththetruncatedtext:

http://www.raywenderlich.com/20897/beginningautolayoutpart2of2

7/30

12/3/2015

BeginningAutoLayoutiniOS6:Part2/2RayWenderlich

InterfaceBuilderdoesthistoforcethebuttontobecomesmallerthanwhatitwouldideallybe,inordertocomplywiththe
EqualWidthsconstraint.
Obviouslythisisnotwhatyouwant,soselectthetopbuttonandchooseSizetoFitContentfromtheEditormenu(or
pressCmd=).Nowthetextfitsinsidethebuttonagainorrather,thebuttonfitsaroundthetextandtheWidth
constraintisgone.
Runtheappandtapthebuttons.Thebuttonsalwayshavethesamewidth,regardlessofwhichonehasthelargest
label:

http://www.raywenderlich.com/20897/beginningautolayoutpart2of2

8/30

12/3/2015

BeginningAutoLayoutiniOS6:Part2/2RayWenderlich

Ofcourse,whenbothlabelsareveryshort,bothbuttonswillshrinkequally.Afterall,unlessthereisaconstraintthat
prevents,buttonswillsizethemselvestofittheircontentexactly,nomore,noless.Whatwasthatcalledagain?Right,the
intrinsiccontentsize.

IntrinsicContentSize
BeforeAutoLayout,youalwayshadtotellbuttonsandothercontrolshowbigtheyshouldbe,eitherbysettingtheir
frameorboundspropertiesorbyresizingtheminInterfaceBuilder.Butitturnsoutthatmostcontrolsareperfectly
capableofdetermininghowmuchspacetheyneed,basedontheircontent.
Alabelknowshowwideandtallitisbecauseitknowsthelengthofthetextthathasbeensetonit,aswellasthe
fontsizeforthattext.Likewiseforabutton,whichmightcombinethetextwithabackgroundimageandsome
paddingfortheroundedcorners.
Thesameistrueforsegmentedcontrols,progressbars,andmostothercontrols,althoughsomemayonlyhavea
predeterminedheightbutanunknownwidth.
Thisisknownastheintrinsiccontentsize,anditisanimportantconceptinAutoLayout.Youhavealreadyseenit
inactionwiththebuttons.AutoLayoutasksyourcontrolshowbigtheyneedtobeandlaysoutthescreenbased
onthatinformation.
YoucanpreventthisbysettinganexplicitWidthorHeightconstraintonacontrol.Ifyouresizethecontrolbyhand,
thenInterfaceBuilderwillsetsuchanexplicitconstraintforyou.WiththeSizetoFitContentcommand,you
removeanyfixedWidthorHeightconstraintsandletthecontroldetermineitsintrinsiccontentsizeagain.
Usuallyyouwanttousetheintrinsiccontentsize,buttherearesomecaseswhereyoumaynotwanttodothat.
ImaginewhathappenswhenyousetanimageonaUIImageViewifthatimageismuchlargerthanthescreen.You
usuallywanttogiveimageviewsafixedwidthandheightandscalethecontent,unlessyouwanttheviewtoresize
tothedimensionsoftheimage.

http://www.raywenderlich.com/20897/beginningautolayoutpart2of2

9/30

12/3/2015

BeginningAutoLayoutiniOS6:Part2/2RayWenderlich

SowhathappenswhenoneofthebuttonshasafixedWidthconstraintonit?Buttonscalculatetheirownsize,butyou
canoverridethisbygivingthemafixedwidth.SelectthetopbuttonandchoosePin\Widthfromthemenu.Thisaddsa
solidTbarbelowthebutton:

Becausethissortofconstraintonlyappliestothebuttonitself,nottoitssuperview,itislistedintheDocumentOutline
belowthebuttonobject.Inthiscase,youhavefixedthebuttontoawidthof73points.
Runtheappandtapthebuttons.Whathappens?Thebuttontextdoeschange,butitgetstruncatedbecausethereisnot
enoughroom:

Becausethetopbuttonhasafixedwidthconstraintandbothbuttonsarerequiredtobethesamesize,theywillnever
shrinkorgrow.

Note:YouprobablywouldntsetaWidthconstraintonabuttonbydesignitisbesttoletthebuttonuseitsintrinsic
sizebutifyoueverrunintoalayoutproblemwhereyouexpectyourcontrolstochangesizeandtheydont,then
http://www.raywenderlich.com/20897/beginningautolayoutpart2of2

10/30

12/3/2015

BeginningAutoLayoutiniOS6:Part2/2RayWenderlich

doublechecktomakesureInterfaceBuilderdidntsneakafixedWidthconstraintinthere.

Playaroundwiththisstuffforabittogetthehangofpinningandaligningviews.Getafeelforit,becausenoteverything
isimmediatelyobvious.JustrememberthattheremustalwaysbeenoughconstraintssothatAutoLayoutcandetermine
thepositionandsizeforallviews.

Gallery example
Youshouldnowhaveanideaofwhatconstraintsareandhowyoucanbuildupyourlayoutsbyforgingrelationships
betweenthedifferentviews.Inthefollowingsections,youwillseehowtouseAutoLayoutandconstraintstocreate
layoutsthatmeetrealworldscenarios.
Letspretendyouwanttomakeanappthathasagalleryofyourfavoriteprogrammers.Itlookslikethisinportraitand
landscape:

http://www.raywenderlich.com/20897/beginningautolayoutpart2of2

11/30

12/3/2015

BeginningAutoLayoutiniOS6:Part2/2RayWenderlich

Thescreenisdividedintofourequalquarters.Eachquarterhasanimageviewandalabel.Howwouldyouapproach
this?
Letsstartbysettingupthebasicapp.YoucanuseyourexistingConstraintsappbydeletingthebuttonsandreusing
theview.
Or,youcancreateanewprojectusingtheSingleViewApplicationtemplateandnameitasyoulike,forinstance,
Gallery.Thiswilljustuseanib,sodisablethestoryboardsoption.
OpenViewController.xib.FromtheObjectLibrary,dragaplainviewobjectontothecanvas.Resizetheviewsothatitis
160by230points,andchangeitsbackgroundcolortobesomethingotherthanwhite(Imademinegreen):

http://www.raywenderlich.com/20897/beginningautolayoutpart2of2

12/30

12/3/2015

BeginningAutoLayoutiniOS6:Part2/2RayWenderlich

Thisviewhasfourconstraintstokeepitinplace.Unlikeabuttonorlabel,aplainUIViewdoesnothaveanintrinsic
contentsize.Theremustalwaysbeenoughconstraintstodeterminethepositionandsizeofeachview,sothisviewalso
needsconstraintstotellitwhatsizeitneedstobe.
Youmaywonder,wherearethesesizeconstraints?Inthiscase,thesizeoftheviewisimpliedbythesizeofthe
superview.TheconstraintsinthislayoutaretwoHorizontalSpacesandtwoVerticalSpaces,andtheseallhavefixed
lengths.YoucanseethisintheDocumentOutline:

Thewidthofthegreenviewiscalculatedbytheformulawidthofsuperviewminus(109+51)anditsheightbythe
formulaheightofsuperviewminus(153+77).Thespaceconstraintsarefixed,sotheviewhasnochoicebuttoresize.
http://www.raywenderlich.com/20897/beginningautolayoutpart2of2

13/30

12/3/2015

BeginningAutoLayoutiniOS6:Part2/2RayWenderlich

Whenyourotatetheapp,thedimensionsofthesuperviewchangefrom320460to480300.Plugthisnewwidthand
heightintotheseformulas,andyoullgetthenewsizeofthegreenview.
Youcanseethisforyourselfwhenyouruntheappandfliptolandscape,butyoucanalsosimulateitdirectlyinInterface
Builder.
SelectthetopmostviewinthenibandgototheAttributesinspector.UndertheSimulatedMetricssection,change
OrientationtoLandscape:

Thisgivesyouaninstantpreviewofwhatthenibslayoutwilllooklikeinlandscapeorientation.Thegreenviewhas
resizedinordertosatisfyitsHorizontalandVerticalSpaceconstraints.
Switchbacktoportraitorientation.

Note:TherearetwomainreasonswhyyouwoulddropaplainUIViewontoanib:a)Youregoingtouseitasa
containerforotherviews,whichhelpswithorganizingthecontentofyournibsorb)Itisaplaceholderforacustom
vieworcontrol,andyouwillalsosetitsClassattributetothenameofyourownUIVieworUIControlsubclass.

YoumaynotalwayswantyourUIViewtoresizewhenthedevicerotates,soyoucanuseconstraintstogivetheviewa
fixedwidthand/orheight.Letsdothatnow.SelectthegreenviewandfromthePinmenu,chooseWidth.Selecttheview
againandchoosePin\Height.
Youhavenowaddedtwonewconstraintstotheview,a160pointWidthconstraintanda230pointHeightconstraint:

http://www.raywenderlich.com/20897/beginningautolayoutpart2of2

14/30

12/3/2015

BeginningAutoLayoutiniOS6:Part2/2RayWenderlich

BecauseWidthandHeightapplytojustthisview,theyarelocatedintheDocumentOutlineundertheViewitself.
Usually,constraintsexpressarelationshipbetweentwodifferentviewsforexample,theHorizontalandVerticalSpace
constraintsarebetweenthegreenviewanditsgraysuperviewbutyoucanconsidertheWidthandHeightconstraints
tobearelationshipbetweentheviewanditself.
Runtheapp.Yup,looksgoodinportrait.Nowflipovertolandscape.Whoops!Notonlydoesitnotlooklikeyouwanted
theviewhaschangedsizeagainbuttheXcodedebugpanehasdumpedanastyerrormessage:
Gallery[68932:11303] 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. (Note: If
you're seeing NSAutoresizingMaskLayoutConstraints that you don't understand, refer to the
documentation for the UIView property translatesAutoresizingMaskIntoConstraints)
(
"<NSLayoutConstraint:0x754dac0 V:[UIView:0x754e510(230)]>",
"<NSLayoutConstraint:0x754eac0 V:|-(77)-[UIView:0x754e510]
(Names:
'|':UIView:0x754e3a0 )>",
"<NSLayoutConstraint:0x754ea40 V:[UIView:0x754e510]-(153)-|
(Names:
'|':UIView:0x754e3a0 )>",
"<NSAutoresizingMaskLayoutConstraint:0x7558cd0 h=-&- v=-&- UIView:0x754e3a0.width ==
UIWindow:0x71156e0.width - 20>",
"<NSAutoresizingMaskLayoutConstraint:0x74128b0 h=--- v=--- H:
[UIWindow:0x71156e0(320)]>"
)

Will attempt to recover by breaking constraint


http://www.raywenderlich.com/20897/beginningautolayoutpart2of2

15/30

12/3/2015

BeginningAutoLayoutiniOS6:Part2/2RayWenderlich

<NSLayoutConstraint:0x754dac0 V:[UIView:0x754e510(230)]>

Break on objc_exception_throw to catch this in the debugger.


The methods in the UIConstraintBasedLayoutDebugging category on UIView listed in
<UIKit/UIView.h> may also be helpful.
RememberwhenIsaidthattheremustbeenoughconstraintssothatAutoLayoutcancalculatethepositionsandsizes
ofalltheviews?Well,thisisanexamplewheretherearetoomanyconstraints.WheneveryougettheerrorUnableto
simultaneouslysatisfyconstraints,itmeansthatyourconstraintsareconflictingsomewhere.
Letslookatthoseconstraintsagain:

Therearesixconstraintssetonthegreenview,thefourSpacingconstraintsyousawearlierandthenewWidthand
Heightconstraintsthatyouhavejustsetonit.Sowhereistheconflict?
Well,inportraitmodethereshouldntbeaproblembecausethemathaddsup.Thewidthofthesuperviewis320points.
IfyouaddthelengthsoftheHorizontalSpaceconstraintsandtheWidthoftheview,thenyoushouldalsoendupat320.
ThewayIhavepositionedtheview,thatis:51+160+109=320indeed.Likewise,theverticalconstraintsshouldadd
upto460.
Butwhenyourotatethedevicetolandscape,thewindow(andthereforethesuperview)is480pointswide.Thatmeans
51+160+109+?=480.Thereare160extrapointsthatneedtogosomewhereinthatequationandAutoLayout
doesntknowwheretogetthem.Likewisefortheverticalaxis.
http://www.raywenderlich.com/20897/beginningautolayoutpart2of2

16/30

12/3/2015

BeginningAutoLayoutiniOS6:Part2/2RayWenderlich

Theconflicthereisthateitherthewidthoftheviewisfixedandoneofthemarginsmustbeflexible,orthemarginsare
fixedandthewidthmustbeflexible.Sooneoftheseconstraintshastogo.Intheaboveexample,youwanttheviewto
havethesamewidthinbothportraitandlandscape,sothetrailingHorizontalSpacehasgottogo.
RemovetheHorizontalSpaceattherightandtheVerticalSpaceatthebottom.Thenibshouldlooklikethis:

Nowtheviewhasjusttherightnumberofconstraintstodetermineitssizeandposition,nomore,noless.Runtheapp
andverifythattheerrormessageisgoneandthattheviewstaysthesamesizeafterrotating.

Note:EventhoughInterfaceBuilderdoesitsbesttopreventyoufrommakinginvalidlayouts,itcannotperform
miracles.AtleastAutoLayoutspitsoutadetailederrormessagewhensomethingiswrong.Youwilllearnmore
aboutanalyzingtheseerrormessagesanddiagnosinglayoutproblemsinIntermediateAutoLayoutiniOS6by
Tutorials.

Painting the portraits


Dragalabelontothegreenview.Noticethatnowtheguidesappearwithinthatgreenview,becauseitwillbethe
superviewforthelabel.

http://www.raywenderlich.com/20897/beginningautolayoutpart2of2

17/30

12/3/2015

BeginningAutoLayoutiniOS6:Part2/2RayWenderlich

Positionthelabelinthetopleftcorneragainsttheguides.ThiswilladdtwoSpaceconstraintstoanchorthelabelinthe
topleftcornerofthegreenview:

http://www.raywenderlich.com/20897/beginningautolayoutpart2of2

18/30

12/3/2015

BeginningAutoLayoutiniOS6:Part2/2RayWenderlich

NoticethatthesetwonewHorizontalandVerticalSpaceconstraintsarelistedunderthegreenviewsConstraints
section,notinthemainview.
Nowmovethegreenviewaroundabit.Youllseethatonlytheconstraintsbetweenthegreenviewanditssuperview
change,butthoseforthelabeldont.Thelabelalwaysstaysputinthesameplace,relativetothegreenview.
Selectthelabelandplaceitagainstthebottommargin,horizontallycentered.Thendraganewimageviewobjectonto
thenib,andmakethelayoutlooklikethis:

http://www.raywenderlich.com/20897/beginningautolayoutpart2of2

19/30

12/3/2015

BeginningAutoLayoutiniOS6:Part2/2RayWenderlich

Theimageviewispinnedtothetop,leftandrightedgesofitssuperview,butitsbottomisconnectedtothetopofthe
labelwithastandardspacing.
Downloadtheresourcesforthistutorialandunzipthefile.YouwillfindanImagesfolderaddthisfolderintoyour
project.SetRay.pngastheimagefortheimageview,changetheimageviewsmodetoAspectFitandsetits
backgroundcolortowhite.ChangethelabelstexttosayRay.
Yourlayoutshouldnowlooklikethis:

http://www.raywenderlich.com/20897/beginningautolayoutpart2of2

20/30

12/3/2015

BeginningAutoLayoutiniOS6:Part2/2RayWenderlich

NoticethatInterfaceBuilderhasplacedaHeightconstraintonthelabelnow.Thishappenedthemomentyousetthe
imageontheimageview.

InterfaceBuildertriestopreventwhatareknownasambiguouslayouts.Ifneithertheimageviewnorthelabelhasa
http://www.raywenderlich.com/20897/beginningautolayoutpart2of2

21/30

12/3/2015

BeginningAutoLayoutiniOS6:Part2/2RayWenderlich

fixedheight,thenAutoLayoutdoesntknowbyhowmuchtoscaleeachiftheheightofthegreenviewshouldchange.
(InterfaceBuilderseemstoignorefornowthatthegreenviewactuallyhasafixedHeightconstraintsetonit.)
Letssayatsomepointinyourappthegreenviewbecomes100pointstaller.HowshouldAutoLayoutdistributethese
new100pointsamongthelabelandtheimageview?Doestheimageviewbecome100pointstallerwhilethelabel
staysthesamesize?Ordoesthelabelbecometallerwhiletheimageviewstaysthesame?Dotheybothget50points
extra,orisitsplit25/75,40/60,orinsomeotherpossiblecombination?
AutoLayoutisnotgoingtoguess,soInterfaceBuilderfixesthisproblemforusbygivingthelabelafixedheight.It
couldalsohavegiventheimageviewafixedheight,butthelabelmakesmoresense.
Fornow,letsjustlivewiththeHeightconstraintonthelabel.

Note:ThepropersolutiontothissmalllayoutproblemistochangetheContentCompressionResistancePriority
ofthelabel.Youwilllearnmoreaboutthatlateron.Ifyoucantwait,thengointotheSizeinspectorforthelabel
andsettheverticalContentCompressionResistancePriorityto751.TheHeightconstraintonthelabelshouldnow
disappear.

Adding the other heads


Movethegreenviewontothemainviewstopleftcorner.RecallthatthegreenviewhadHorizontalSpaceandVertical
Spaceconstraintsthatdetermineditspositionintheparentview.Itstillhasthose,buttheyarenowsettoavalueof0
theyarerepresentedbythethickbluelines(withwhiteborders)atthetopandleftedgesofthewindow:

http://www.raywenderlich.com/20897/beginningautolayoutpart2of2

22/30

12/3/2015

BeginningAutoLayoutiniOS6:Part2/2RayWenderlich

Soeventhoughtheviewsitscompletelyinthecorner,itstillneedsconstraintstoanchoritthere.Thinkoftheseas
marginswithavalueof0.
SelectthegreenviewandtapCmdDtoduplicateit.Movetheduplicateintothetoprightcorner:

http://www.raywenderlich.com/20897/beginningautolayoutpart2of2

23/30

12/3/2015

BeginningAutoLayoutiniOS6:Part2/2RayWenderlich

Duplicatetwomoretimesandputthesecopiesinthebottomleftandbottomrightcorners,respectively.
Changethescreendesigntothefollowing:

http://www.raywenderlich.com/20897/beginningautolayoutpart2of2

24/30

12/3/2015

BeginningAutoLayoutiniOS6:Part2/2RayWenderlich

Thosearesomegoodlookingprogrammers!:)
Runtheapp.Itlooksgoodinportrait,butnotsomuchinlandscape:

http://www.raywenderlich.com/20897/beginningautolayoutpart2of2

25/30

12/3/2015

BeginningAutoLayoutiniOS6:Part2/2RayWenderlich

Itshouldbeprettyobviouswhatwentwrong:youvesetafixedwidthandheightonthefourbrightlycoloredcontainer
views,sotheywillalwayshavethosesizes,regardlessofthesizeoftheirsuperview.
SelecttheWidth(160)andHeight(230)constraintsfromallfourviewsanddeletethem.Ifyouruntheappnow,youllget
somethinglikethis.Alsonotverygood:

Thislooksverymuchliketheproblemwesolvedintheintroduction,soifyouthinkbacktohowwesolvedthat,youll
recallthatwegavetheviewsequalwidthsandheights.
SelectallfourcoloredviewsandchoosePin\WidthsEqually.SelecttheviewsagainandchoosePin\HeightsEqually.
Runtheappagainandrotatethedevice.Hmmitstilllooksexactlythesameasbefore.Why?
Well,ifyoulookatthescreenshotyoullseethatalltheviewsdohavethesameheight,andtheyalsoappeartohavethe
samewidth(thegreenandbrownviewsarepartiallyobscuredbytheyellowandblueones),soourconstraintsare
beingmet.Itsjustnotthewidthandheightthatyouwantthemtohave.Theremustbeotherconstraintsthataregetting
intheway.
Sureenough,ifyoulookattheconstraintsontheseviews,youllseethattheyalsohaveHorizontalandVerticalSpace
constraintsthatforcethemintoplace(lookatlistofconstraintsonthemainview,notthefoursubviews):

http://www.raywenderlich.com/20897/beginningautolayoutpart2of2

26/30

12/3/2015

BeginningAutoLayoutiniOS6:Part2/2RayWenderlich

Whatsworse,youcantevendeletethatconstraint.ItsTbarisnotboldandtheconstraintisnotblue,soInterface
Builderputitthereinordertopreventalayoutproblem.
Sowhydoesitdothat?Justsayingthatallfourviewsmusthaveequalsizesisnotenoughtodeterminewhatthose
sizesshouldactuallybe,becauseAutoLayoutdoesnotknowhowthesefourviewsareconnectedtoeachother.They
appearsidebysideinthedesign,buttherearenoactualconstraintsbetweenthem.AutoLayoutdoesnotknowthatit
needstosplitthewindowwidthbetweentheRayandMatthijsboxes.
IfAutoLayoutcantfigurethisoutbyitself,youhavetotellit.

http://www.raywenderlich.com/20897/beginningautolayoutpart2of2

27/30

12/3/2015

BeginningAutoLayoutiniOS6:Part2/2RayWenderlich

SelecttheRayandMatthijsboxesandchoosePin\HorizontalSpacing.Becausetheboxesaresidebyside,thisaddsa
HorizontalSpaceconstraintwithsize0betweenthem,andthatisenoughtoletAutoLayoutknowhowthesetwoviews
arerelated.
Important:InterfaceBuilderdoesnotautomaticallyremovetheleadingHorizontalSpacebetweenthesuperviewand
theyellowbox(theonefromthescreenshotabove),butitdidpromoteittoauserconstraint(afatbar).Youcannow
deletethisspace.Ifyoudont,youwillgetanUnabletosimultaneouslysatisfyconstraintserrorduringruntimewhen
youfliptolandscape.
Runtheapp.Itshouldnowlooklikethis:

Thatlooksabitbetteralready.Thefourboxesnowhaveequalwidths,buttheheightsarestillwrong.Thesolutionis
similar:putaVerticalSpacebetweentheRayandDennisRitchieboxesandremovetheVerticalSpacebetweenthe
DennisRitchieboxandthetopofthewindow.

http://www.raywenderlich.com/20897/beginningautolayoutpart2of2

28/30

12/3/2015

BeginningAutoLayoutiniOS6:Part2/2RayWenderlich

Runtheappagain,andthistimeitlooksallright:

NoticethattheDennisRitchielabelisnotcenteredbelowitsimageview.ThisoriginallyhappenedtomewhenItyped
thattextintothelabel.Thelabelwasinitiallycenteredintheview,butInterfaceBuilderdecideditknewbetterand
replacedthatcenteringconstraintwithaHorizontalSpace.Ifthishappenedtoyou,too,thenselectthatlabelandchoose
Align\HorizontalCenterinContainertofixit.
Aquicknoteontheimageviews:theystretchoutbecauseyouhavenotgiventhemafixedsize.Youmaynotknowit,but
thatsintentionalonyourpart. Theimageviewswouldntfitinlandscapemodeotherwise.However,ifyouwantan
imageviewtokeepitsoriginalaspectratio,thenyoureoutofluck.Youcannotachievethefollowingeffectusing
InterfaceBuilder:

Unfortunately,InterfaceBuilderdoesnotcurrentlyprovideawaytomakeconstraintsthatkeeptheaspectratioofaview
intact.Todothat,youneedtocreateandsettheconstraintsprogrammatically.Youwilllearnhowtodothatin
IntermediateAutoLayoutiniOS6byTutorials.
Tip:YouhaveseenthatyoucanpreviewwhattheUIwilllooklikeinlandscapebychangingtheOrientationsetting
underSimulatedMetrics.YoucanalsotesttheresizingbehaviorofyourviewsdirectlyinInterfaceBuilder.
Selectthemainview.UnderSimulatedMetrics,setSizetoFreeform.Thisaddsresizehandlesaroundyournibthatyou
canusetomolditintoanyshapeyouwant.AutoLayoutwillrecalculatethelayoutonthefly:

http://www.raywenderlich.com/20897/beginningautolayoutpart2of2

29/30

12/3/2015

BeginningAutoLayoutiniOS6:Part2/2RayWenderlich

However,becarefulwiththis.SometimesInterfaceBuilderwillinsertnewconstraintsofitsownwhenyoureresizing,as
itdidhereinthebottomrightcorner(itaddedaHorizontalSpace).Itmayalsodeleteexistingconstraintswhentheyfall
outsideofthenibbounds.

Where To Go From Here?


Ifyouvemadeitthisfar,congratulationsyounowknowwhatAutoLayoutisallabout,andhaveexperimentedwiththe
basics!Buttheresalotlefttolearn
ThetutorialyouhavejustreadisonlythefirsthalfoftheBeginningAutoLayoutchapterfromthebookiOS6byTutorials.
ThesecondhalfteacheshowtouseAutoLayouttocreatemorerealworldscreenlayouts,andeverythingelseyou
needtoknowaboutusingAutoLayoutfromInterfaceBuilder.
Butlikeanyvisualdesigntool,InterfaceBuilderhasitslimitationsandsometimesitjustmakesmoresensetoworkwith
theNSLayoutConstraintobjectsdirectlyfromcode.iOS6byTutorialsdedicatesanentirechaptertothistopic,
IntermediateAutoLayout.SoifyouwanttogettothebottomofAutoLayout,getthebook!

MatthijsHollemans
MatthijsHollemansisanindependentiOSdeveloperanddesignerwholivestocreate
awesomesoftware.HisfocusisoniPadappsbecausehethinkstabletsarewaycooler
thanphones.Wheneverheisnotgluedtohisscreen,Matthijsplaysthepiano,isinto
healthyandnaturalliving,andgoesoutbarefootrunning.Visithiswebsiteat
http://www.hollance.com.

http://www.raywenderlich.com/20897/beginningautolayoutpart2of2

30/30

You might also like