MyLayout

MyLayout is a set of iOS interface view layout framework. The MyLayout kernel is implemented by overloading the UIView layoutSubviews method and setting the bounds and center properties of the subview. MyLayout is powerful and easy to use. It integrates the interface layout functions of iOS Autolayout and SizeClass, Android 5 layout systems, HTML/CSS floating positioning technology, flex-Box and Bootstrap framework and other mainstream platforms in the market. At the same time provides a very simple and complete multi-screen size adaptation solution. The Swift version of MyLayout is called TangramKit

English (Simplified): English description

You can join the QQ group: 178573773 or add personal QQ: 156355113 to discuss with me or contact me by email: [email protected].

You can also go to my home page for a detailed description of each layout:

www.jianshu.com/p/4c1eb0dd6… Layout framework and principles introduced blog.csdn.net/yangtiang/a… Linear layout blog.csdn.net/yangtiang/a… Relative layout blog.csdn.net/yangtiang/a… Frame layout blog.csdn.net/yangtiang/a… Table layout www.jianshu.com/p/fbeb37658… Fluid layout www.jianshu.com/p/0c075f2fd… Liquid layout www.jianshu.com/p/4ac229057… Path layout bicyclering.github. IO/grid layout

The advantage of MyLayout

  • MyLayout’s implementation kernel is based on frame Settings, rather than encapsulation of AutoLayout. Therefore, it is not limited by any operating system version.
  • Some articles have shown that the performance of frame layout is better than that of AutoLayout layout, especially when the number of views in the interface increases.
  • AutoLayout’s idea is to complete the layout through the constraint dependence between views, but the result of the constraint dependence is high coupling between views and increases the cost of interface update. MyLayout, in addition to providing constraint dependencies, also provides the ability to automatically create constraints based on the order in which views are added, thereby reducing the problem of display dependency establishment. The end result is a simplified layout code, as well as a reduction in code changes when the layout is updated.
  • AutoLayout is only a relatively constrained layout, and MyLayout in addition to providing a relative layout with the same ability as AutoLayout, but also provides a linear layout, frame layout, table layout, flow layout, floating layout, path layout 7 major layout system. You can choose the easiest layout container to use for your interface. MyLayout also supports Size classes and provides some methods to achieve the perfect screen Size.
  • MyLayout is primarily a solution for layout through code, but the framework also supports layout with XIBS and SBS. It also provides a variety of powerful functions such as automatic trigger layout when view hides and displays, UITableviewCell dynamic height adaptation of layout view, tag cloud implementation, left and right content width adaptation, scale allocation of size and spacing, overall docking control and so on.

Performance comparison of MyLayout and various layout methods

The following two tables list the setup time and layout time for each subview, in milliseconds

create time(ms)/per subview Frame MyLayout AutoLayout Masonry UIStackView
MyLinearLayout 0.08 0.164 0.219 0.304 0.131
MyFrameLayout 0.05 0.149 0.209 0.273 0.131
MyRelativeLayout 0.079 0.182 0.116 0.359 0.131
MyFlowLayout 0.08 0.107 0.198 0.258 0.131
MyFloatLayout 0.044 0.148 0.203 0.250 0.131
layout time(ms)/per subview Frame MyLayout AutoLayout Masonry UIStackView
MyLinearLayout 0 0.049 0.269 0.269 0.272
MyFrameLayout 0 0.042 0.243 0.243 0.272
MyRelativeLayout 0 0.068 0.274 0.274 0.272
MyFlowLayout 0 0.036 0.279 0.279 0.272
MyFloatLayout 0 0.055 0.208 0.208 0.272

The table above can be summarized as follows:

  1. Frame takes the least time to build a view, with an average cost of 0.068ms per view. The layout view is no longer needed when the view’s frame is specified, so the layout time is almost zero.
  2. For AutoLayout layout, the average construction time for each sub-view is about 0.189ms, while the average construction time for the next view is about 0.289ms because it is the encapsulation of AutoLayout. In the layout, it is the same because AutoLayout is used, which takes about 0.255ms.
  3. The implementation of MyLayout is the encapsulation of frame, so the construction time and layout time are better than AutoLayout, but lower than the original frame method. The average construction time of MyLayout is about 0.150ms, which is 2.2 times longer than that of Frame. The average build time of AutoLayout is 1.26 times that of MyLayout. The average build time for navigation was 1.9 times that of MyLayout.
  4. The average layout time for MyLayout is 0.05ms, while AutoLayout is five times longer.
  5. UIStackView takes slightly longer to build than MyLayout’s linear layout, MyLinearLayout. But the layout is 5.5 times longer than MyLinearLayout.
  6. In MyLayout, the build time and layout time of MyFlowLayout are the smallest, while the build and layout time of relative layout are the longest.

Demo renderings

Application scenarios

The following application scenario is an example:

  • There’s A container view S that has A width of 100 and the height is the sum of the heights of the four subviews A,B,C, and D that are arranged from top to bottom.
  • The left margin of view A takes up 20% of the width of the superview, the right margin takes up 30% of the width of the superview, and the height is equal to its own width.
  • The left margin of view B is 40, and the width takes up the rest of the width of the parent view, and the height is 40.
  • The width of view C takes up all of the width of the superview, which is 40.
  • The right margin of view D is 20, the width is 50% of the width of the superview, and the height is 40.

The final effect is as follows:

MyLinearLayout *S = [MyLinearLayout linearLayoutWithOrientation:MyOrientation_Vert]; S.subviewSpace = 10; S.widthSize.equalTo(@100); UIView *A = UIView.new; A. eftPos. EqualTo (@ 0.2); A.r ightPos. EqualTo (@ 0.3); A.heightSize.equalTo(A.widthSize); [S addSubview:A]; UIView *B = UIView.new; B.leftPos.equalTo(@40); B.widthSize.equalTo(@60); B.heightSize.equalTo(@40); [S addSubview:B]; UIView *C = UIView.new; C.leftPos.equalTo(@0); C.rightPos.equalTo(@0); C.heightSize.equalTo(@40); [S addSubview:C]; UIView *D = UIView.new; D.rightPos.equalTo(@20); D.w idthSize. EqualTo (s. idthSize). Multiply (0.5); D.heightSize.equalTo(@40); [S addSubview:D];Copy the code

The system structure

The layout location class MyLayoutPos

The MyLayoutPos class is a class that describes the location of a view. UIView in extending out of the leftPos topPos, bottomPos, rightPos, centerXPos, centerYPos the six variables to achieve the positioning operation view. You can use the equalTo methods of these variables to set the margins and spacing between views. The equalTo method can set NSNumber, MyLayoutPos, and NSArray

for different scenarios. The system provides 6 simple variables myLeft, myTop, myBottom, myRight, myCenterX, and mYCenterY to set values of NSNumber type, such as A.leftpos. EqualTo (@10); Equivalent to a.myleft = 10; .
*>

The layout size class MyLayoutSize

The MyLayoutSize class is a class that describes the size of a view. UIView extends the widthSize and heightSize variables to set the width and height of the view. You can use the equalTo method to set the width and height of the view. The equalTo method can set NSNumber, MyLayoutSize, and NSArray

for different scenarios. The system also provides two simple variables myWidth,myHeight to set the value of type NSNumber, such as a.widthsize.equalto (@10); Equivalent to a.myWidth = 10; .
*>

Linear layout MyLinearLayout

Equivalent to iOS UIStackView and Android LinearLayout.

A linear layout is a single-column (single-row) layout in which the subviews are arranged from top to bottom or left to right in the order in which they are added, so that the subviews establish constraints and dependencies by the order in which they are added. A linear layout view with subviews arranged from top to bottom is called a vertical linear layout view, while a linear layout view with subviews arranged from left to right is called a horizontal linear layout.

Sample code:

-(void)loadView
{
    [super loadView];
    
    MyLinearLayout *S = [MyLinearLayout linearLayoutWithOrientation:MyOrientation_Vert];
    S.myWidth = 120;
    S.subviewSpace = 10;
    
    UIView *A = [UIView new];
    A.myLeft = A.myRight = 5;
    A.myHeight = 40;
    [S addSubview:A];
    
    UIView *B = [UIView new];
    B.myLeft = 20;
    B.myWidth = B.myHeight = 40;
    [S addSubview:B];
    
    UIView *C = [UIView new];
    C.myRight = 40;
    C.myWidth = 50;
    C.myHeight = 40;
    [S addSubview:C];
    
    UIView *D = [UIView new];
    D.myLeft = D.myRight = 10;
    D.myHeight = 40;
    [S addSubview:D];
    
    [self.view addSubview:S];
    S.backgroundColor = [UIColor redColor];
    A.backgroundColor = [UIColor greenColor];
    B.backgroundColor = [UIColor blueColor];
    C.backgroundColor = [UIColor orangeColor];
    D.backgroundColor = [UIColor cyanColor];
 }
Copy the code

Relative layout MyRelativeLayout

Equivalent to AutoLayout on iOS and RelativeLayout on Android.

A relative layout is a layout view in which the sub-views are laid out and positioned through constraints and dependencies on each other. The placement of subviews in the relative layout has nothing to do with the order in which they are added. Instead, they are positioned and laid out by setting the relative dependencies of the subviews.

Sample code:

-(void)loadView { [super loadView]; MyRelativeLayout *S = [MyRelativeLayout new]; S.widthSize.equalTo(@170); S.heightSize.equalTo(@280); UIView *A = [UIView new]; A.leftPos.equalTo(@20); A.topPos.equalTo(@20); A.widthSize.equalTo(@40); A.heightSize.equalTo(A.widthSize); [S addSubview:A]; UIView *B = [UIView new]; B.leftPos.equalTo(A.centerXPos); B.topPos.equalTo(A.bottomPos).offset(10); B.widthSize.equalTo(@60); B.heightSize.equalTo(A.heightSize); [S addSubview:B]; UIView *C = [UIView new]; C.leftPos.equalTo(B.rightPos).offset(10); C.bottomPos.equalTo(B.bottomPos); C.widthSize.equalTo(@40); C. eightSize. EqualTo (B.h eightSize). Multiply (0.5); [S addSubview:C]; UIView *D = [UIView new]; D.bottomPos.equalTo(C.topPos).offset(10); D.rightPos.equalTo(@15); D.heightSize.equalTo(A.heightSize); D.widthSize.equalTo(D.heightSize); [S addSubview:D]; UIView *E = [UIView new]; E.centerYPos.equalTo(@0); E.centerXPos.equalTo(@0); E.heightSize.equalTo(@40); E.widthSize.equalTo(S.widthSize).add(-20); [S addSubview:E]; / /.. F, G [self.view addSubview:S]; S.backgroundColor = [UIColor redColor]; A.backgroundColor = [UIColor greenColor]; B.backgroundColor = [UIColor blueColor]; C.backgroundColor = [UIColor orangeColor]; D.backgroundColor = [UIColor cyanColor]; E.backgroundColor = [UIColor magentaColor]; }Copy the code

Frame layout MyFrameLayout

Equivalent to Android’s FrameLayout layout.

A frame layout is a layout view in which the child views are anchored in a particular position and can overlap with the parent view. The layout position of the child views in the frame layout does not depend on the order in which they are added. Frame layout will be vertical direction is divided into up, middle and lower three directions, and horizontal direction is divided into left, middle and right three directions, any sub-view can only be located in the vertical direction and horizontal direction on a azimuth.

Sample code:

-(void)loadView { [super loadView]; MyFrameLayout *S = [MyFrameLayout new]; S.m ySize = CGSizeMake (320500); UIView *A = [UIView new]; Arjun ySize = CGSizeMake (40, 40); [S addSubview:A]; UIView *B = [UIView new]; B.m ySize = CGSizeMake (40, 40); B.myRight = 0; [S addSubview:B]; UIView *C = [UIView new]; C. ySize = CGSizeMake (40, 40); C.myCenterY = 0; [S addSubview:C]; UIView *D = [UIView new]; D.m ySize = CGSizeMake (40, 40); D.myCenter = CGPointZero; [S addSubview:D]; / /.. E, F,G [self.view addSubview:S]; S.backgroundColor = [UIColor redColor]; A.backgroundColor = [UIColor greenColor]; B.backgroundColor = [UIColor blueColor]; C.backgroundColor = [UIColor orangeColor]; D.backgroundColor = [UIColor cyanColor]; }Copy the code

Table layout MyTableLayout

Equivalent to the Android table layout layout and the HTML table element.

A table layout is a layout view in which the subviews can be arranged as many rows and columns as a table. Before adding a child view to a table layout view, you must create and add a row view, and then add the child view to the row view. If row views are arranged from top to bottom in a table layout, the table layout is a vertical table layout, and the child views in a vertical table layout are arranged from left to right in a row view; If row views are arranged left to right in a table layout, the table layout is a horizontal table layout. The child views in a horizontal table layout are arranged top to bottom in the row view.

Sample code:

-(void)loadView { [super loadView]; MyTableLayout *S = [MyTableLayout tableLayoutWithOrientation:MyOrientation_Vert]; S.wrapContentWidth = YES; S.subviewHSpace = 10; S.subviewVSpace = 10; [S addRow:MTLSIZE_WRAPCONTENT colSize:MTLSIZE_WRAPCONTENT]; UIView *A = [UIView new]; Arjun ySize = CGSizeMake (50, 40); [S addSubview:A]; UIView *B = [UIView new]; B.m ySize = CGSizeMake (100, 40); [S addSubview:B]; UIView *C = [UIView new]; C. ySize = CGSizeMake (30, 40); [S addSubview:C]; [S addRow:MTLSIZE_WRAPCONTENT colSize:MTLSIZE_WRAPCONTENT]; UIView *D = [UIView new]; D.m ySize = CGSizeMake (200, 40); [S addSubview:D]; / /... E,F [self.view addSubview:S]; S.backgroundColor = [UIColor redColor]; A.backgroundColor = [UIColor greenColor]; B.backgroundColor = [UIColor blueColor]; C.backgroundColor = [UIColor orangeColor]; D.backgroundColor = [UIColor cyanColor]; }Copy the code

FlowLayout MyFlowLayout

Equivalent to CSS3’s Flex-Box.

A streaming layout is a multi-row layout in which the subviews are arranged in the order they are added and then rearranged on another row when certain constraints are encountered. There are mainly two kinds of constraint restrictions, quantity constraint and content size constraint, and the direction of newline is divided into vertical and horizontal direction, so the flow layout has a total of vertical quantity constraint flow layout, vertical content constraint flow layout, horizontal quantity constraint flow layout, horizontal content constraint flow layout. Streaming layout is mainly used in scenarios where subviews are arranged regularly and can be used to some extent as an alternative to UICollectionView.

Sample code:

   
  -(void)loadView
{
    [super loadView];
    
    MyFlowLayout *S = [MyFlowLayout flowLayoutWithOrientation:MyOrientation_Vert arrangedCount:4];
    S.wrapContentHeight = YES;
    S.myWidth = 300;
    S.padding = UIEdgeInsetsMake(10, 10, 10, 10);
    S.gravity = MyGravity_Horz_Fill;
    S.subviewSpace = 10;
    
    for (int i = 0; i < 10; i++)
    {
        UIView *A = [UIView new];
        A.heightSize.equalTo(A.widthSize);
        [S addSubview:A];
        
        A.backgroundColor = [UIColor greenColor];

    }
    
    
    [self.view addSubview:S];
    S.backgroundColor = [UIColor redColor];
}

   
   
Copy the code

Floating layout MyFloatLayout

Equivalent to float positioning in CSS.

A floating layout is a layout view in which the subviews float and dock in the agreed direction and automatically find the best place to float and dock when the size is insufficient to accommodate them. The idea of floating layouts comes from HTML/CSS floating positioning techniques, so floating layouts can be used specifically for layouts that are irregular or wrapped around text. Different according to floating direction, floating layout can be divided into around floating layout and fluctuation floating layout.

Sample code:

-(void)loadView { [super loadView]; MyFloatLayout *S = [MyFloatLayout floatLayoutWithOrientation:MyOrientation_Vert]; S.wrapContentHeight = YES; S.padding = UIEdgeInsetsMake(10, 10, 10, 10); S.subviewSpace = 10; S.myWidth = 300; UIView *A = [UIView new]; Arjun ySize = CGSizeMake (80); [S addSubview:A]; UIView *B = [UIView new]; B.m ySize = CGSizeMake (150, 40); [S addSubview:B]; UIView *C = [UIView new]; C. ySize = CGSizeMake (70, 40); [S addSubview:C]; UIView *D = [UIView new]; D.m ySize = CGSizeMake (100140); [S addSubview:D]; UIView *E = [UIView new]; E.m ySize = CGSizeMake (150, 40); E.reverseFloat = YES; [S addSubview:E]; UIView *F = [UIView new]; F. may ySize = CGSizeMake (120 '); [S addSubview:F]; [self.view addSubview:S]; S.backgroundColor = [UIColor redColor]; A.backgroundColor = [UIColor greenColor]; B.backgroundColor = [UIColor blueColor]; C.backgroundColor = [UIColor orangeColor]; D.backgroundColor = [UIColor cyanColor]; E.backgroundColor = [UIColor blackColor]; F.backgroundColor = [UIColor whiteColor]; }Copy the code

Path layout MyPathLayout

Layout library unique

A path layout is a layout view in which the subviews are laid out based on a path formed by a particular curve function that you provide. You need to provide a function to implement the curve path, a specific coordinate system, and a specific subview distance Settings on the curve to implement the interface layout. When the curve path is formed, the subviews are arranged around the curve at equal distances. Path layouts are mainly used for interface layouts that have a certain pattern of irregular arrangement and the effect is very cool.

Sample code:

-(void)loadView { [super loadView]; MyPathLayout *S = [MyPathLayout new]; S.m ySize = CGSizeMake (320320); S.coordinateSetting.isReverse = YES; S.c oordinateSetting. Origin = CGPointMake (0.5, 0.2); S.polarEquation = ^(CGFloat angle) { return 80 * (1 + cos(angle)); }; for (int i = 0; i < 4; i++) { UIView *A = [UIView new]; Arjun ySize = CGSizeMake (40, 40); [S addSubview:A]; A.backgroundColor = [UIColor greenColor]; } [self.view addSubview:S]; S.backgroundColor = [UIColor redColor]; }Copy the code

Grid layout MyGridLayout

Layout library unique

Grid layout is a layout mechanism in which a rectangular view area is divided into subareas in rows or columns. Subareas can be divided recursively according to the requirements of the layout. The subviews in the grid layout will be filled into the corresponding leaf areas in the order of addition. Grid layout uses a set of custom layout system to divide the location and size. The subviews added to the grid layout will no longer need to specify the location and size but will be completed by the subgrids in the grid layout, so the layout structure can be easily adjusted to achieve the dynamic layout capability.

Sample code:

-(void)loadView { [super loadView]; MyGridLayout *S = [MyGridLayout new]; S.m ySize = CGSizeMake (320320); S.backgroundColor = [UIColor redColor]; [self.view addSubview:S]; //add grids [S addRow:50]; id<MyGrid> g2 = [S addRow:MyLayoutSize.fill]; [g2 addCol: 0.2]; [g2 addCol: 0.2]; Id <MyGrid> g23 = [g2 addCol:0.6]; [g23 addRow: 0.5]; [g23 addRow: 0.5]; //add subviews UIView *A = [UIView new]; A.backgroundColor = [UIColor greenColor]; [S addSubview:A]; UIView *B = [UIView new]; B.backgroundColor = [UIColor blueColor]; [S addSubview:B]; UIView *C = [UIView new]; C.backgroundColor = [UIColor orangeColor]; [S addSubview:C]; UIView *D = [UIView new]; D.backgroundColor = [UIColor cyanColor]; [S addSubview:D]; UIView *E = [UIView new]; E.backgroundColor = [UIColor blackColor]; [S addSubview:E]; }Copy the code

SizeClass support

Equivalent to iOS Size Classes

MyLayout supports SIZECLASS to accommodate devices with different screen sizes. You can use SIZECLASS with any of the six layouts mentioned above to create a perfect fit for each device interface. The system provides two UIView extension methods:

-(instancetype)fetchLayoutSizeClass:(MySizeClass)sizeClass;
-(instancetype)fetchLayoutSizeClass:(MySizeClass)sizeClass copyFrom:(MySizeClass)srcSizeClass;
Copy the code

To implement support for Size Classes. Take the following example:

// Default Settings for all devices. MyLinearLayout *rootLayout = [MyLinearLayout linearLayoutWithOrientation:MyOrientation_Vert]; rootLayout.padding = UIEdgeInsetsMake(10, 10, 10, 10); rootLayout.wrapContentHeight = NO; rootLayout.gravity = MyGravity_Horz_Fill; / / MySizeClass_wAny | MySizeClass_hCompact landscape show the iPhone devices. MyLinearLayout *lsc = [rootLayout fetchLayoutSizeClass:MySizeClass_wAny | MySizeClass_hCompact copyFrom:MySizeClass_wAny  | MySizeClass_hAny]; lsc.orientation = MyOrientation_Horz; lsc.wrapContentWidth = NO; lsc.gravity = MyGravity_Vert_Fill;Copy the code

Method of use

Direct copy

  1. Copy all the files in the Lib folder of the Github project into your project.
  2. will#import "MyLayout.h"The header file is placed in your PCH file or in the source code location where you need to use the interface layout.

CocoaPods installation

If you have not installed Cocoapods, run the following command:

$ gem install cocoapods
Copy the code

To integrate MyLayout into your Xcode project using CocoaPods, create the following Podfile:

The source 'https://github.com/CocoaPods/Specs.git' platform: ios, '7.0' pod 'MyLayout'Copy the code

Then run the following command:

$ pod install
Copy the code

useCarthage

1. Create a Cartfile file with the following contents:

github "youngsoft/MyLinearLayout"
Copy the code

2. The terminal executes the Carthage Update.

3. Click on the “General” button, and then put the Carthage/Build/iOS/MyLayout framework drag and drop to “Linked Frameworks and Libraries” column.

4. Click the “Build Phases” button, then click the “+” in the upper left corner to select “New Run Script Phase”, and fill in the following under the Shell:

/usr/local/bin/carthage copy-frameworks
Copy the code

Then in the “Input Files” column add:

$(SRCROOT)/Carthage/Build/iOS/MyLayout.framework
Copy the code

Version history

For details, see Changelog.md