http://coding.tabasoft.it/ios/ios8-layout-margins/

Margins:单词解释:

The margin of a written or printed page is the empty space at the side of the page. 页边的空白

例:She added her comments in the margin. 她在页边空白处加上了她的评语。

UIView

Swift


var                   layoutMargins         :                   UIEdgeInsets



These 4 values (the UIEdgeInsets

For example, this is the result of an inside view whose leading space to the superview is 0 (relative to margin):

iOS8 Layout Margins 详解_Code


We would expect to see the yellow view attached to the left side of the green view but this is not the case. The leading constraint is relative to the margin, and the margin of every view is, by default, 8 points in length (as of today).







Swift



Default                   Margins          =          UIEdgeInsets         (         top         :                   8         ,                   left         :                   8         ,                   bottom         :                   8         ,                   right         :                   8         )


So the inner view is shifted right by 8 points.

We can change the default behavior modifying the constraint from the Interface Builder menu:

iOS8 Layout Margins 详解_Code_02

Uncheck the “Relative to Margin” item and the constraint will be relative to the left side of the view (not to the left margin of it):

iOS8 Layout Margins 详解_Code_03

When we add a constraint in Interface Builder it can make it relative to margin (this seems to be the default when the main view of the controller is involved). A shortcut to change this behavior is to hold also the ALT key when we insert it (ctrl-alt click and drag).

Programmatically we can change the layout margins of the view with the following code:











Swift


if                   version                   >=                   8                   {


          myView         .         layoutMargins                   =                   UIEdgeInsets         (


            top         :                   0         ,


            left         :                   40         ,


            bottom         :                   0         ,


            right         :                   0         )


}



This code causes the inside view to be more right-shifted:

iOS8 Layout Margins 详解_Code_04

Note the check of the system version since this code is not supported before iOS8. For completeness the system version is so defined:







Swift


let                   version                   =                   (         UIDevice         .         currentDevice         (         )         .         systemVersion                   as                   NSString         )         .         doubleValue



Programmatic Constraints

NSLayoutAttribute











Swift


enum                   NSLayoutAttribute                   :          Int                   {


             case                   Left


             case                   Right


             case                   Top


             case                   Bottom


             case                   Leading


             case                   Trailing


             case                   Width


             case                   Height


             case                   CenterX


             case                   CenterY


             case                   Baseline


    


             case                   FirstBaseline


    


             case                   LeftMargin


             case                   RightMargin


             case                   TopMargin


             case                   BottomMargin


             case                   LeadingMargin


             case                   TrailingMargin


             case                   CenterXWithinMargins


             case                   CenterYWithinMargins


    


             case                   NotAnAttribute


}



If we use visual format, strings like:







Swift


"|-[subview]-|"



are automatically interpreted as relative to margins. As of today we don’t know the visual format syntax to avoid this, but we can always calculate margins and take them in account its effect (waiting for more documentation).

preservesSuperviewLayoutMargins











Swift


var                   preservesSuperviewLayoutMargins         :                   Bool


From the documentation:

A Boolean value indicating whether the current view also respects the margins of its superview.

It took a while to me to understand this property. It is better explained with an example.

In the following figure the red view contains the brown that contains the purple. The red has left margin 40pt. The brown has a leading constraint 0 relative to side (not margin) of superview, so it is attached left. The purple has leading constraint 0 to margin

iOS8 Layout Margins 详解_ios_05

On the other hand if we set preservesSuperviewLayoutMargins of the brown view to true, its subviews (purple) take in account its superview margin, and the result is the following:

iOS8 Layout Margins 详解_ide_06

The usual …didChange

If we implement the following method in our view custom class, it is then called every time its margins change:







Swift


override                   func                   layoutMarginsDidChange         (         )                   {


             println         (         "layoutMarginsDidChange"         )


}



The default implementation does nothing.

Code

XCode LayoutMargins Project