Summary of a.

During iOS project development, there are two common layout methods: Frame layout and AutoLayout. The Frame layout has nothing to say. It directly sets the horizontal and vertical coordinates of the control and specifies the width and height. AutoLayout is laid out by setting constraints on the relative positions of controls. AutoLayout has a good intention. However, as its grammar is not very friendly, we will not use it much in actual project development. We have to rely on a third-party library like NAVIGATION to use it. The navigation layout is easy to understand, but it takes a lot of code and blocks each control. Flex layouts are particularly common in front end development. Is there a solution for iOS that is similar to Flex layouts? The answer is yes. In addition to the Flex layouts used in Weex and React Native cross-platform projects, AsyncDisplayKit also introduces Flex layouts, which are secondary developments based on Facebook’s Yoga. The same is true of FlexLib today.

Flex layout and related properties

Let’s take a look at Flex layout: Flex layout, also known as elastic layout, is a layout method designed for one-dimensional layout. One-dimensional means you want the content to be laid out in rows or columns. You can usedisplay:flexTo turn elements into elastic layouts. Let’s take a look at the example: horizontal arrangement of 7 items

<! DOCTYPEhtml>
<html>
    <head>
        <title>The flex 2 layout</title>
        <meta charset="UTF-8">
        <style>
            * {
                margin:  0;
                padding: 0;
                box-sizing: border-box;
            }
            .container {
                display: flex;
                flex-direction: row;
                justify-content: flex-start;
                align-items: flex-end;
                background-color: wheat;
                flex-wrap: wrap;
            }
           .item {
               width: 100px;
               height: 100px;
               border: 1px solid royalblue;
               text-align: center;
               line-height: 100px;
               margin: 10px 10px;
           }
           .item6 {
               flex: 1;
           }
           .item7 {
               flex: 2;
           }
        </style>
    </head>

    <body>
        <div class="container">
            <div class="item0 item">item0</div>
            <div class="item1 item">item1</div>
            <div class="item2 item">item2</div>
            <div class="item3 item">item3</div>
            <div class="item4 item">item4</div>
            <div class="item5 item">item5</div>
            <div class="item6 item">item6</div>
            <div class="item7 item">item7</div>
        </div>
    </body>
</html>
Copy the code

This is the front end code, but it’s important to familiarize yourself with some of the common properties of Flex layouts. Flex attributes fall into two categories: those that apply to containers and those that apply to subitems.

  1. Properties that apply to the container
  • display:flexSet:containerThe container has an elastic layout
  • flex-direction: Determine the direction of the main axis, whether items are aligned horizontally or vertically

Values: row | row – reverse | column | column – reverse; Row (default) : The main axis is horizontal and the starting point is on the left. Row-reverse: The main axis is horizontal and the starting point is at the right end. Column: The main axis is in the vertical direction, and the starting point is in the upper edge. Column-reverse: the main axis is vertical and the starting point is at the bottom.

  • justify-content: defines how items are aligned on the main axis.

Values: flex – start | flex – end | center | space – between | space – around; Flex-start (default) : left-align Flex-end: right-align center: center space-between: align both ends with equal intervals between items. Space-around: Equal spacing on both sides of each item. As a result, the spacing between items is twice as large as the spacing between items and the border.

  • align-items: defines how items are aligned on the cross axis.

Values: align – items: flex – start | flex – end | center; Flex-start: Alignment of the starting point of the cross axes. Flex-end: alignment of ends of crossed axes. Center: Aligns the middle point of the cross axis.

  • flex-wrap: not fit on an axis, decide whether to wrap it

Values: nowrap (not a newline) | wrap (wrap)

  • align-content: also controls the alignment of Flex items on the cross axis, but with a full line as the smallest unit. Note that this property does not work if the Flex Item has only one line. Adjust theflex-wrapWrap, the effect is displayed.

Values: flex – start | flex – end | center | space – between | space – around;

  1. Attributes that apply to Item
  • Align-self: Allows a single Flex Item to be aligned differently from other Flex items, overriding the align-items property. The default value is auto, which inherits the align-items property of the Flex container.

  • Flex properties: The flex properties are short for flex-grow, flex-shrink, and flex-basis. The default value is 0 1 Auto.

Flex-grow: property defines the zoom scale of the project. Default is 0, or no zoom if there is free space. The larger the value is, the more space it occupies. Flex-shrink: The flex-shrink attribute defines the scale by which the project shrinks. The default is 1, that is, if there is insufficient space, the project shrinks. Flex-basis: Property specifies the initial size of a Flex element along the main axis

The flex values of Item6 and Item7 are set to 1 and 2, indicating that the remaining space of the current axis is 1/3 for Item6 and 2/3 for Item7. More information about Flex properties can be found here: Flex Layout

Use of FlexLib

1. Usage

CocoaPods introduced FlexLib:

pod 'FlexLib'
Copy the code

Use:

  • Create view controller inheritanceFlexBaseVCOr create view inheritanceFlexCustomBaseView
  • Create an XML file with the same name as the view controller or view
  • Add controls to the XML file for layout

Example:

TestLoginVC.h

@interface TestLoginVC : FlexBaseVC
@end
Copy the code

TestLoginVC.m

#import "TestLoginVC.h" @interface TestLoginVC () { UIScrollView* scroll; UIView* close; } @end @implementation TestLoginVC - (void)viewDidLoad { [super viewDidLoad]; self.navigationItem.title = @"Touch Demo"; } - (void)tapTouchAction { UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"" message:@"You pressed" delegate:nil cancelButtonTitle:@"Cancel" otherButtonTitles:@"OK",nil]; [alert show]; } - (void)didReceiveMemoryWarning { [super didReceiveMemoryWarning]; } @endCopy the code

TestLoginVC.xml


      
<UIView
    layout=" flex:1, alignItems:center"
    attr="bgColor:white">
    <FlexScrollView name="scroll"  layout="padding:50,flex:1,width:100%,alignItems:center" attr="bgColor:white,vertScroll:true,">
        <FlexTouchView onPress="tapTouchAction" attr="underlayColor:blue">
            <UIImageView layout="width:100,height:100" attr="borderRadius:50,clipsToBounds:true,source:qrcode.png">
                <FlexTouchMaskView attr="BgColor: red, alpha: 0.7"/>
            </UIImageView>
        </FlexTouchView>
        <UIView layout="height:20"/>
        <FlexTouchView onPress="tapTouchAction" layout="height:100,width:100%,alignItems:center,justifyContent:center" attr="bgColor:#e5e5e5,borderRadius:8,underlayColor:darkGray">
            <UILabel layout="width:100%" attr="FontSize: 16, textAlign: center, color: red, text: both Please touch me, and move \ \ r \ n this is test the touch function controls, linesNum: 0"/>
        </FlexTouchView>
        <UIView layout="height:20"/>
        <UILabel layout="width:100%" attr="fontSize:20,linesNum:0,color:#333333,text:You can press the buttons above to see the effect. We use FlexTouchView to provide more powerful function and better flexibility than button."/>
    </FlexScrollView>
</UIView> 

Copy the code

Description:

  • The default views are arranged from top to bottom, and adding other views to the view TAB is equivalent to adding child views to the view

  • FlexLib supports two types of properties: Layout and View properties. Layout properties are the same as those supported by yoga, and view properties can be extended using FLEXSET macros in addition to those listed in the document. You can see the layout Attributes and View Attributes it supports here

  • FlexScrollView(a subclass of UIScrollView) can automatically manage the scrolling range. FlexTouchView is similar to UIButton with built-in onPress property, and you can set its trigger method.

  • You can set the name property of the control. The value of the name property automatically binds to member variables with the same name in your code, and you can use it directly in your code.

  • You can pre-define some attribute values, put them in a global XML file, and initialize them in the AppDelegate

The global XML file system.style is formatted like this:


      
<styles>
    <style name="buttonAttrStyle">
        <attr name="bgColor">black</attr>
        <attr name="color">white</attr>
        <attr name="borderRadius">4</attr>
        <attr name="underlayColor">darkGray</attr>
        <attr name="shadowColor">red</attr>
        <attr name="shadowOffset">5/5</attr>
        <attr name="shadowOpacity">0.2</attr>
        <attr name="shadowRadius">3</attr>
    </style >
    <style name="buttonLayoutStyle">
        <attr name="height">44</attr>
        <attr name="width">150</attr>
        <attr name="alignItems">center</attr>
        <attr name="justifyContent">center</attr>
        <attr name="margin">20</attr>
    </style>
</styles>
Copy the code

Import the system style file

NSString *path = [[NSBundle mainBundle]pathForResource:@"system" ofType:@"style"];
[[FlexStyleMgr instance] loadClassStyle:path];
Copy the code

Use:

<UILabel attr="@:system/buttonAttrStyle" layout="@:system/buttonLayoutStyle" />
Copy the code
  • FlexLib supports a runtime update interface, which you can configure here

  • FlexLib supports a high degree of automatic Cell computation and works with models like the iPhone X, In practice, custom UITableViewCell needs to inherit FlexBaseTableCell, and custom UICollectionViewCell needs to inherit FlexCollectionCell.

2. Use of FlexXmlBaseView, FlexFrameView and FlexCustomBaseView

When using XML for layout, it is inevitable to use a custom view. If the custom view also wants to use XML for layout, it needs to inherit one of the three views: FlexXmlBaseView, FlexFrameView, and FlexCustomBaseView.

(1) Custom views use XML layout

  • Views inherited from FlexXmlBaseView: can be used in XML files, can be created from initWithRootView, but not from initWithFrame, and cannot be directly set to frame. The advantage is that it is more lightweight and does not add additional view hierarchy.

  • Views that inherit from FlexFrameView: You can set frames directly, but not in XML files. For example,

FlexFrameView *frameView = [[FlexFrameView alloc] initWithFlex:@"CustomFrameView" Frame:CGRectMake(0, 0, [UIScreen mainScreen].bounds.size.width, 0) Owner:self]; frameView.flexibleHeight = YES; [_scrollView addSubview:frameView];Copy the code

Customframeview.xml is the CORRESPONDING XML layout file for this view

  • inheritanceFlexCustomBaseViewView: can be used either in XML or as a traditional UIView-derived classinitWithFrameCreate, with the disadvantage of adding extra layers of view.

Note: Views that inherit from FlexCustomBaseView or FlexFrameView must have the following two properties set

// Are the width and height variable? The default value is NO @property(nonatomic,assign) BOOL flexibleWidth; @property(nonatomic,assign) BOOL flexibleHeight;Copy the code

(2) Custom views do not use XML layouts, but want to use them in XML files

At this point, our custom view needs to meet the following two conditions to be used in the XML file:

  • All initializations must be ininitMethod. Any otherinitFunction, for exampleInitWith...Will not be called.
  • You can useFLEXSETMacros extend view properties, which you can then set in an XML file.

Use it directly in the superview


      
<UIView layout="flex:1,alignItems:center" attr="bgColor:white">
  <! -- No XML corresponding, custom View like this -->
  <ComplateCustomView layout="width:100%,height:80"/>
</UIView>

Copy the code

3. Other Settings

  • The zoom factor

In page layout, if you want different screen sizes to share the same design, the page controls will scale as the screen size changes, this is used in this case. Set the scaling factor:

// Set the scaling factor, using the method in the XML layout *16 ==> 16*factor + 1 float factor = [UIScreen mainScreen].bounds.size.width/375; FlexSetScale(factor, 1);Copy the code

Used in layout XML, preceded by *

<UILabel attr="fontSize: *16"/>
Copy the code

The fontSize of the Label is 16*factor + 1

  • Use expressions in attributes

Add an expression to the layout and view properties with $before the property name. ScreenWidth is a predefined macro, or you can use custom macros. Currently supported operators +, -, *, /, (,),

<UIView layout="$width: ScreenWidth * 0.6, height: 50, alignItems: center, justifyContent: center" attr="bgColor:#e5e5e5,borderRadius:6">
     <UILabel attr="@:system/buttonText,text: expression calculation, 60% of screen width"/>
</UIView>
Copy the code
  • FlexTextView

It is a class provided by another system that automatically adjusts its height based on input text and ensures that its height does not exceed minHeight and maxHeight.

 <FlexTextView layout="flex:1,minHeight:40,maxHeight:95" attr="BorderRadius borderColor: red, borderWidth: 1:4, fontSize: 18, color: darkGray, text: this is a highly can adjust automatically according to the word of text input box, placeholder: I am a placeholder, PLA ceholderColor:red"/>
Copy the code

4. To summarize

FlexLib may be friendly to those who have experience in front-end development, but for those who are native developers, it doesn’t hurt to learn its syntax. In daily development, we can use this layout selectively, and once we are familiar with this layout, we can greatly improve the efficiency of our page layout, allowing us to focus on more core functions.

Reference: github.com/zhenglibao/…