Home

Awesome

<p align="center"> <a href="https://github.com/layoutBox/FlexLayout"><img src="docs_markdown/images/flexlayout-logo-text.png" alt="FlexLayout" width="210"/></a> </p> <p align="center"> <a href=""><img src="https://img.shields.io/cocoapods/p/FlexLayout.svg?style=flat" /></a> <a href="https://github.com/layoutBox/FlexLayout/actions/workflows/github-actions-ci.yml"><img src="https://github.com/layoutBox/FlexLayout/actions/workflows/github-actions-ci.yml/badge.svg?branch=master" /></a> <!-- <a href='https://coveralls.io/github/layoutBox/FlexLayout?branch=master'><img src='https://coveralls.io/repos/github/layoutBox/FlexLayout/badge.svg?branch=master' alt='Coverage Status' /></a>--> <a href='https://img.shields.io/cocoapods/v/FlexLayout.svg'><img src="https://img.shields.io/cocoapods/v/FlexLayout.svg" /></a> <a href="https://github.com/Carthage/Carthage"><img src="https://img.shields.io/badge/Carthage-compatible-4BC51D.svg?style=flat" /></a> <a href="https://github.com/layoutBox/FlexLayout/issues"><img src="https://img.shields.io/github/issues/layoutBox/FlexLayout.svg?style=flat" /></a> </p></p> <br>

FlexLayout adds a nice Swift interface to the highly optimized Yoga flexbox implementation. Concise, intuitive & chainable syntax.

Flexbox is an incredible improvement over UIStackView. It is simpler to use, much more versatile and amazingly performant.

Yoga is a multiplatform CSS Flexbox implementation (iOS/Android/...). Yoga is also the layout engine of React Native.

Requirements

Content

<br>

:pushpin: FlexLayout is actively updated. So please come often to see latest changes. You can also Star it to be able to retrieve it easily later.

<br>

FlexLayout + PinLayout

<a href="https://github.com/layoutBox/PinLayout"><img src="docs_markdown/images/flexlayout_plus_pinlayout_small.png" alt="FlexLayout" width="250"/></a>

FlexLayout is a companion of PinLayout. They share a similar syntax and method names. PinLayout is a layout framework greatly inspired by CSS absolute positioning, it is particularly useful for greater fine control and animations. It gives you full control by layouting one view at a time (simple to code and debug).

<br>

<a name="intro_usage_example"></a>

FlexLayout Introduction examples

Example 1:

This example will layout multiples views using column and row flexbox containers.

Two steps to use a flexbox container:

  1. Setup the container: Initialize your flexbox structure. Note that it is also possible to alter it later.
  2. Layout the container: The layout of the container should be done from layoutSubviews() (or willTransition(to: UITraitCollection, ...) and viewWillTransition(to: CGSize, ...)).
    1. First you must layout the flexbox container, i.e. position it and optionally set its size.
    2. Then layout the flexbox children using Flex method layout().

<a href="https://github.com/layoutBox/FlexLayout/blob/master/Example/FlexLayoutSample/UI/Examples/Intro/IntroView.swift"><img src="docs_markdown/images/examples/flexlayout_exampleapp_intro_all.png" alt="FlexLayout example"/></a>

fileprivate let rootFlexContainer = UIView()

init() {
   super.init(frame: .zero)
   
   addSubview(rootFlexContainer)
   ...

   // Column container
   rootFlexContainer.flex.direction(.column).padding(12).define { (flex) in
        // Row container
        flex.addItem().direction(.row).define { (flex) in
            flex.addItem(imageView).width(100).aspectRatio(of: imageView)
            
            // Column container
            flex.addItem().direction(.column).paddingLeft(12).grow(1).define { (flex) in
                flex.addItem(segmentedControl).marginBottom(12).grow(1)
                flex.addItem(label)
            }
        }
        
        flex.addItem().height(1).marginTop(12).backgroundColor(.lightGray)
        flex.addItem(bottomLabel).marginTop(12)
    }
}

override func layoutSubviews() {
    super.layoutSubviews() 

    // 1) Layout the flex container. This example use PinLayout for that purpose, but it could be done 
    //    also by setting the rootFlexContainer's frame:
    //       rootFlexContainer.frame = CGRect(x: 0, y: 0, 
    //                                        width: frame.width, height: rootFlexContainer.height)
    rootFlexContainer.pin.top().left().width(100%).marginTop(topLayoutGuide)

    // 2) Then let the flexbox container layout itself. Here the container's height will be adjusted automatically.
    rootFlexContainer.flex.layout(mode: .adjustHeight)
}

:pushpin: This example is available in the Examples App. See complete source code

</br>

<a name="intro_usage_example_raywenderlich"></a>

Example 2:

The example implements the Ray Wenderlich Yoga Tutorial screen using FlexLayout.

<a href="https://github.com/layoutBox/FlexLayout/blob/master/Example/FlexLayoutSample/UI/Examples/RaywenderlichTutorial/RaywenderlichTutorialView.swift"><img src="docs_markdown/images/examples/flexlayout_exampleapp_ray_wenderlich_tutorial.png" width=200/></a>

init() {
   ...

   rootFlexContainer.flex.define { (flex) in
        // Image
        flex.addItem(episodeImageView).grow(1).backgroundColor(.gray)
        
        // Summary row
        flex.addItem().direction(.row).padding(padding).define { (flex) in
            flex.addItem(summaryPopularityLabel).grow(1)
            
            flex.addItem().direction(.row).justifyContent(.spaceBetween).grow(2).define { (flex) in
                flex.addItem(yearLabel)
                flex.addItem(ratingLabel)
                flex.addItem(lengthLabel)
            }
            
            flex.addItem().width(100).height(1).grow(1)
        }
        
        // Title row
        flex.addItem().direction(.row).padding(padding).define { (flex) in
            flex.addItem(episodeIdLabel)
            flex.addItem(episodeTitleLabel).marginLeft(20)
        }
        
        // Description section
        flex.addItem().paddingHorizontal(paddingHorizontal).define { (flex) in
            flex.addItem(descriptionLabel)
            flex.addItem(castLabel)
            flex.addItem(creatorsLabel)
        }
        
        // Action row
        flex.addItem().direction(.row).padding(padding).define { (flex) in
            flex.addItem(addActionView)
            flex.addItem(shareActionView)
        }
        
        // Tabs row
        flex.addItem().direction(.row).padding(padding).define { (flex) in
            flex.addItem(episodesTabView)
            flex.addItem(moreTabView)
        }
        
        // Shows TableView
        flex.addItem(showsTableView).grow(1)
    }
}

override func layoutSubviews() {
    super.layoutSubviews() 

    // 1) Layout the contentView & rootFlexContainer using PinLayout
    contentView.pin.top().bottom().left().right()
    rootFlexContainer.pin.top().left().right()

    // 2) Let the flexbox container layout itself and adjust the height
    rootFlexContainer.flex.layout(mode: .adjustHeight)
    
    // 3) Adjust the scrollview contentSize
    contentView.contentSize = rootFlexContainer.frame.size
}

:pushpin: This example is available in the Examples App. See complete source code

<br>

<a name="introduction"></a>

FlexLayout principles and philosophy

NOTE: FlexLayout wraps facebook/yoga implementation and expose all its features. So note that on this documentation we will refer to FlexLayout, but this also applies to Yoga.

<br>

<a name="performance"></a>

FlexLayout's Performance

FlexLayout's performance has been measured using the Layout Framework Benchmark. FlexLayout and PinLayout has been added to this benchmark to compare their performance.

As you can see in the following chart, FlexLayout and PinLayout's performance are faster or equal to manual layouting. FlexLayout and PinLayout are between 8x and 12x faster than UIStackViews, and this for all types of iPhone (5S/6/6S/7/8/X)

See here more complete details, results and explanation of the benchmark.

<p align="center"> <a href="docs_markdown/benchmark.md"> <img src="docs_markdown/benchmark/benchmark_comparison_all_small.png" width=660/> </a> </p> <br/>

Variation from CSS flexbox

NOTE: FlexLayout doesn't support the flexbox order property. The order is determined by the flex container's UIView.subviews array.

<br>

<a name="documentation"></a>

Documentation

Flexbox is pretty easy and straightforward to use. The defining aspect of the flexbox is the ability to alter its items, width, height to best fill the available space on any display device. A flex container expands its items to fill the available free space or shrinks them to prevent overflow.

The flex layout is constituted of parent container referred as flex container and its immediate children which are called flex items. A flex item can also be a flex container, i.e. it is possible to add other flex items to it.

Axes

When working with StackViews you need to think in terms of two axes — the main axis and the cross axis. The main axis is defined by StackView's direction property, and the cross axis runs perpendicular to it.

StackView directionAxes
column (default)<img src="docs_markdown/images/axis-column.png" width="200"/>
row<img src="docs_markdown/images/axis-row.png" width="200"/>
Sections

In the following sections we will see:

  1. How to create, modify and defines flex containers and items.
  2. Flexbox container's properties
  3. Flexbox item's properties

:pushpin: This document is a guide that explains how to use FlexLayout. You can also checks the FlexLayout's API documentation.

<br>

<a name="create_modify_define_containers"></a>

1. Creation, modification and definition of flexbox items

addItem(:UIView)

Method:

Usage examples:
  view.flex.addItem(imageView).width(100).aspectRatio(1)
<br>

addItem()

Method:

Usage examples:
  view.flex.addItem().direction(.row).padding(10)
<br>

define()

Method:

Usage examples:
  view.flex.addItem().define { (flex) in
      flex.addItem(imageView).grow(1)
		
      flex.addItem().direction(.row).define { (flex) in
          flex.addItem(titleLabel).grow(1)
          flex.addItem(priceLabel)
      }
  }

The same results can also be obtained without using the define() method, but the result is not as elegant:

  let columnContainer = UIView()
  columnContainer.flex.addItem(imageView).grow(1)
  view.flex.addItem(columnContainer)
		
  let rowContainer = UIView()
  rowContainer.flex.direction(.row)
  rowContainer.flex.addItem(titleLabel).grow(1)
  rowContainer.flex.addItem(priceLabel)
  columnContainer.flex.addItem(rowContainer)

Advantages of using define():

<br>

<a name="accessing_flexbox_view"></a>

Accessing flex item's UIView

It is possible to access the flex items's UIView using flex.view. This is particularly useful when using flex.define() method.

Example:

This example creates a flexbox container and sets its alpha to 0.8.

    view.flex.direction(.row).padding(20).alignItems(.center).define { (flex) in
        flex.addItem().width(50).height(50).define { (flex) in
            flex.view?.alpha = 0.8
        }
    }

Another possible solution:

    view.flex.direction(.row).padding(20).alignItems(.center).define { (flex) in
        let container = UIView()
        container.alpha = 0.8
        
        flex.addItem(container).width(50).height(50)
    }
<br>

layout()

Method:

Usage examples:
  rootFlexContainer.flex.layout(mode: .adjustHeight)
<br>

<a name="containers_properties"></a>

2. Flexbox containers properties

This section describes all flex container's properties.

direction()

Property:

Method:

ValueResultDescription
column (default)<img src="docs_markdown/images/flexlayout-direction-column.png" width="100"/>Top to bottom
columnReverse<img src="docs_markdown/images/flexlayout-direction-columnReverse.png" width="100"/>Bottom to top
row<img src="docs_markdown/images/flexlayout-direction-row.png" width="190"/>Same as text direction
rowReverse<img src="docs_markdown/images/flexlayout-direction-rowReverse.png" width="190"/>opposite to text direction
Usage examples:
  view.flex.direction(.column)  // Not required, default value. 
  view.flex.direction(.row)
Example 1:

This example center three buttons with a margin of 10 pixels between them.
Example source code

<img src="docs_markdown/images/flexlayout_example_column_center.png" width="160"/>
    rootFlexContainer.flex.justifyContent(.center).padding(10).define { (flex) in
        flex.addItem(button1)
        flex.addItem(button2).marginTop(10)
        flex.addItem(button3).marginTop(10)
    }
<br/>

justifyContent()

Method:

direction(.column)direction(.row)
start (default)<img src="docs_markdown/images/flexlayout-justify-column-flexstart.png" width="140"/><img src="docs_markdown/images/flexlayout-justify-row-flexstart.png" width="160"/>Items are packed at the beginning of the main-axis.
end<img src="docs_markdown/images/flexlayout-justify-column-flexend.png" width="140"/><img src="docs_markdown/images/flexlayout-justify-row-flexend.png" width="160"/>Items are packed at the end of the main-axis.
center<img src="docs_markdown/images/flexlayout-justify-column-center.png" width="140"/><img src="docs_markdown/images/flexlayout-justify-row-center.png" width="160"/>items are centered along the main-axis.
spaceBetween<img src="docs_markdown/images/flexlayout-justify-column-spacebetween.png" width="140"/><img src="docs_markdown/images/flexlayout-justify-row-spacebetween.png" width="160"/>Items are evenly distributed in the main-axis; first item is at the beginning, last item at the end.
spaceAround<img src="docs_markdown/images/flexlayout-justify-column-spacearound.png" width="140"/><img src="docs_markdown/images/flexlayout-justify-row-spacearound.png" width="160"/>Items are evenly distributed in the main-axis with equal space around them.
spaceEvenly<img src="docs_markdown/images/flexlayout-justify-column-spaceevenly.png" width="140"/><img src="docs_markdown/images/flexlayout-justify-row-spaceevenly.png" width="160"/>Items are evenly distributed in the main-axis with equal space around them.
Usage examples:
  view.flex.justifyContent(.start)  // default value. 
  view.flex.justifyContent(.center)
<br/>

alignItems()

Method:

direction(.column)direction(.row)
stretch (default)<img src="docs_markdown/images/flexlayout-align-column-stretch.png" width="140"/><img src="docs_markdown/images/flexlayout-align-row-stretch.png" width="160"/>
start<img src="docs_markdown/images/flexlayout-align-column-flexStart.png" width="140"/><img src="docs_markdown/images/flexlayout-align-row-flexStart.png" width="160"/>
end<img src="docs_markdown/images/flexlayout-align-column-flexEnd.png" width="140"/><img src="docs_markdown/images/flexlayout-align-row-flexEnd.png" width="160"/>
center<img src="docs_markdown/images/flexlayout-align-column-center.png" width="140"/><img src="docs_markdown/images/flexlayout-align-row-center.png" width="160"/>
<br/>

alignSelf()

Method:

The auto value means use the flex container alignItems property. See alignItems for documentation of the other values.

<br/>

wrap()

Method:

By default, the flex container fits all flex items into one line. Using this property we can change that. We can tell the container to lay out its items in single or multiple lines, and the direction the new lines are stacked in

Reminder: the cross axis is the axis perpendicular to the main axis. Its direction depends on the main axis direction.

direction(.column)direction(.row)Description
noWrap (default)<img src="docs_markdown/images/flexlayout-wrap-column-nowrap.png" width="130"/><img src="docs_markdown/images/flexlayout-wrap-row-nowrap.png" width="180"/>Single-line which may cause the container to overflow. NEW: Flex items are displayed in one row and by default they are shrunk to fit the flex container’s width
wrap<img src="docs_markdown/images/flexlayout-wrap-column-wrap.png" width="130"/><img src="docs_markdown/images/flexlayout-wrap-row-wrap.png" width="180"/>Multi-lines, direction is defined by direction(). NEW: Flex items are displayed in multiple rows if needed from left-to-right and top-to-bottom
wrapReverse<img src="docs_markdown/images/flexlayout-wrap-column-wrapReverse.png" width="130"/><img src="docs_markdown/images/flexlayout-wrap-row-wrapReverse.png" width="180"/>Multi-lines, opposite to direction defined by direction(). NEW: Flex items are displayed in multiple rows if needed from left-to-right and bottom-to-top
Usage examples:
  view.flex.wrap(.nowrap)  // Not required, default value. 
  view.flex.wrap(.wrap)
<br/>

alignContent()

Method:

Note, alignContent has no effect when the flexbox has only a single line.

direction(.column)direction(.row)
start (default)<img src="docs_markdown/images/flexlayout-alignItems-column-flexStart.png" width="140"/><img src="docs_markdown/images/flexlayout-alignItems-row-flexStart.png" width="160"/>
end<img src="docs_markdown/images/flexlayout-alignItems-column-flexEnd.png" width="140"/><img src="docs_markdown/images/flexlayout-alignItems-row-flexEnd.png" width="160"/>
center<img src="docs_markdown/images/flexlayout-alignItems-column-center.png" width="140"/><img src="docs_markdown/images/flexlayout-alignItems-row-center.png" width="160"/>
stretch<img src="docs_markdown/images/flexlayout-alignItems-column-stretch.png" width="140"/><img src="docs_markdown/images/flexlayout-alignItems-row-stretch.png" width="160"/>
spaceBetween<img src="docs_markdown/images/flexlayout-alignItems-column-spaceBetween.png" width="160"/><img src="docs_markdown/images/flexlayout-alignItems-row-spaceBetween.png" width="160"/>
spaceAround<img src="docs_markdown/images/flexlayout-alignItems-column-spaceAround.png" width="160"/><img src="docs_markdown/images/flexlayout-alignItems-row-spaceAround.png" width="160"/>
spaceEvenly
<br/>

layoutDirection()

FlexLayout supports left-to-right (LTR) and right-to-left (RTL) languages.

Using start or end properties, you can position views without having to think about whether your item will show up on the left or the right side of the screen (depending on the person’s language

Method:

<br>

<a name="intems_properties"></a>

3. Flexbox items properties

This section describe all flex items's properties.

:pushpin: Remembers that flex containers are also flex items, so all these properties also apply to containers.

grow

Method:

For example, if all items have grow set to 1, every child will set to an equal size inside the container. If you were to give one of the children a value of 2, that child would take up twice as much space as the others.

<br>

shrink

Method:

<br>

basis

Method:

<br>

gap

Method:

<br/>

isIncludedInLayout()

Method:

FlexLayout automatically includes the UIView when:

<br>

display

Method:

Set the item display or not, with none value, the item will be hidden and not included in the layout.

<br>

markDirty()

Method:

Usage examples:

In the case where a UILabel's text is updated, it is needed to mark the label as dirty and relayout the flex container.

    // 1) Update UILabel's text
    label.text = "I love FlexLayout"
     
    // 2) Mark the UILabel as dirty
    label.flex.markDirty()
    
    // 3) Then force a relayout of the flex container.
    rootFlexContainer.flex.layout()
    OR
    setNeedsLayout()
<br>

sizeThatFits()

Method:

Usage Example:

Get the size of view when layouted in a container with a width of 200 pixels.

    let layoutSize = viewA.flex.sizeThatFits(size: CGSize(width: 200, height: CGFloat.greatestFiniteMagnitude))
<br>

intrinsicSize

Property:

<br>

<a name="positioning"></a>

4. Positioning

Method:

Usage examples:
  view.flex.position(.relative).top(10).left(10).size(50)

  view.flex.position(.absolute).top(10).left(10).size(50)

top(), bottom(), left(), right(), start(), end(), vertically(), horizontally(), all()

A flex item with position set to .relative is positioned relative to its normal position within its flex container. Only one property can be applied in each direction, either vertical or horizontal. If both top and bottom properties are set, top takes precedence. If both left and right properties are set, left takes precedence.

A flex item with position set to .absolute is positioned absolutely with respect to its containing block. Using these properties you can control the size and position of an absolute item within its parent. Because absolutely positioned children don’t affect their sibling's layout. Absolute position can be used to create overlays and stack children in the Z axis.

This is done through the following methods:

Methods:

Usage examples:
  view.flex.position(.relative).top(10).right(10).width(100).height(50)

  view.flex.position(.absolute).top(10).right(10).width(100).height(50)
  view.flex.position(.absolute).left(20%).right(20%)

:pushpin: See the "Yoga C" example in the Examples App. Source code

<br>

<a name="adjusting_size"></a>

5. Adjusting the size

<a name="width_height_size"></a>

Width and height and size

FlexLayout has methods to set the view’s height and width.

Methods:

Usage examples:
  view.flex.width(100)	
  view.flex.width(50%)	
  view.flex.height(200)
	
  view.flex.size(250)
<br>

<a name="minmax_width_height_size"></a>

minWidth(), maxWidth(), minHeight(), maxHeight()

FlexLayout has methods to set the view’s minimum and maximum width, and minimum and maximum height.

Using minWidth, minHeight, maxWidth, and maxHeight gives you increased control over the final size of items in a layout. By mixing these properties with grow, shrink, and alignItems(.stretch), you are able to have items with dynamic size within a range which you control.

An example of when Max properties can be useful is if you are using alignItems(.stretch) but you know that your item won’t look good after it increases past a certain point. In this case, your item will stretch to the size of its parent or until it is as big as specified in the Max property.

Same goes for the Min properties when using shrink. For example, you may want children of a container to shrink to fit on one row, but if you specify a minimum width, they will break to the next line after a certain point (if you are using wrap(.wrap).

Another case where Min and Max dimension constraints are useful is when using aspectRatio.

Methods:

Usage examples:
  view.flex.maxWidth(200)
  view.flex.maxWidth(50%)
  view.flex.width(of: view1).maxWidth(250)
	
  view.flex.maxHeight(100)
  view.flex.height(of: view1).maxHeight(30%)
<br>

<a name="aspect_ratio"></a>

aspectRatio()

AspectRatio is a property introduced by Yoga that don't exist in CSS. AspectRatio solves the problem of knowing one dimension of an element and an aspect ratio, this is very common when it comes to images, videos, and other media types. AspectRatio accepts any floating point value > 0, the default is undefined.

Usage examples:
  imageView.flex.aspectRatio(16/9)
<br/>

<a name="margins"></a>

6. Margins

By applying Margin to an item you specify the offset a certain edge of the item should have from it’s closest sibling or parent.

Methods:

Usage examples:
  view.flex.margin(20)
  view.flex.marginTop(20%).marginLeft(20%)
  view.flex.marginHorizontal(20)
  view.flex.margin(safeAreaInsets)
  view.flex.margin(10, 12, 0, 12)
<br>

<a name="paddings"></a>

7. Paddings

Padding specify the offset children should have from a certain edge on the container.

Methods:

Usage examples:
  view.flex.padding(20)
  view.flex.paddingTop(20%).paddingLeft(20%)
  view.flex.paddingBottom(20)
  view.flex.paddingHorizontal(20)
  view.flex.padding(10, 12, 0, 12)
<br>

<a name="uiview_methods"></a>

9. Extra UIView methods

FlexLayout also adds methods to set common UIView properties.

Methods:

Usage examples:
  // Create a gray column container and add a black horizontal line separator 
  flex.addItem().backgroundColor(.gray).define { (flex) in
      flex.addItem().height(1).backgroundColor(.black)
  }
  // Set rounded corner
  flex.addItem().cornerRadius(12)
  // Set border
  flex.addItem().border(1, .black)
<br>

<a name="api_documentation"></a>

FlexLayout API Documentation

The complete FlexLayout API is available here.

<br>

<a name="examples_app"></a>

Example App

The FlexLayout's Example App exposes some usage example of FlexLayout.
See the Example App section to get more information.

<a href="https://github.com/layoutBox/FlexLayout/blob/master/Example/FlexLayoutSample/UI/Examples/Intro/IntroView.swift"><img src="docs_markdown/images/examples/flexlayout_exampleapp_intro_portrait.png" width=90/></a> <a href="https://github.com/layoutBox/FlexLayout/blob/master/Example/FlexLayoutSample/UI/Examples/RaywenderlichTutorial/RaywenderlichTutorialView.swift"><img src="docs_markdown/images/examples/flexlayout_exampleapp_ray_wenderlich_tutorial.png" width=90/></a> <a href="https://github.com/layoutBox/FlexLayout/blob/master/Example/FlexLayoutSample/UI/Examples/TableViewExample"><img src="docs_markdown/images/examples/flexlayout_exampleapp_uitableview.png" width=90/></a> <a href="https://github.com/layoutBox/FlexLayout/blob/master/Example/FlexLayoutSample/UI/Examples/CollectionViewExample/HouseCell.swift"><img src="docs_markdown/images/examples/flexlayout_example_collectionview.png" width=90/></a> <a href="https://github.com/layoutBox/FlexLayout/blob/master/Example/FlexLayoutSample/UI/Examples/YogaExampleA/YogaExampleAView.swift"><img src="docs_markdown/images/examples/flexlayout_exampleapp_yoga_c.png" width=90/></a> <a href="https://github.com/layoutBox/FlexLayout/blob/master/Example/FlexLayoutSample/UI/Examples/YogaExampleB/YogaExampleBView.swift"><img src="docs_markdown/images/examples/flexlayout_exampleapp_yoga_objc.png" width=90/></a> <a href="https://github.com/layoutBox/FlexLayout/blob/master/Example/FlexLayoutSample/UI/Examples/YogaExampleC/YogaExampleCView.swift"><img src="docs_markdown/images/examples/flexlayout_exampleapp_yoga_java.png" width=90/></a> <a href="https://github.com/layoutBox/FlexLayout/blob/master/Example/FlexLayoutSample/UI/Examples/YogaExampleD/YogaExampleDView.swift"><img src="docs_markdown/images/examples/flexlayout_exampleapp_yoga_csharp.png" width=90/></a> <a href="https://github.com/layoutBox/FlexLayout/blob/master/Example/FlexLayoutSample/UI/Examples/YogaExampleE/YogaExampleEView.swift"><img src="docs_markdown/images/examples/flexlayout_exampleapp_yoga_android.png" width=90/></a>

<br>

<a name="faq"></a>

FAQ

   view.flex.shrink(1)
<br/>

Flexbox interesting external links

<br/>

<a name="comments"></a>

Contributing, comments, ideas, suggestions, issues, ....

For any comments, ideas, suggestions, simply open an issue.

For issues, please have a look at Yoga's issues. Your issue may have been already reported. If not, it may be a FlexLayout issue. In this case open an issue and we'll let you know if the issue is related to Yoga's implementation.

If you find FlexLayout interesting, thanks to Star it. You'll be able to retrieve it easily later.

If you'd like to contribute, you're welcome!

<br>

<a name="installation"></a>

Installation

CocoaPods

To integrate FlexLayout into your Xcode project using CocoaPods, specify it in your Podfile:

  pod 'FlexLayout'

Then, run pod install.

Carthage

To integrate FlexLayout into your Xcode project using Carthage:

  1. Specify in your Cartfile:
github "layoutBox/FlexLayout"
  1. Run carthage update to build frameworks.
  2. Add built FlexLayout.framework in your Xcode project in the Embedded Binaries section.

Swift Package Manager

Another Swift Package

To integrate FlexLayout into another Swift Package, add it as a dependency:

.package(url: "https://github.com/layoutBox/FlexLayout.git", from: "1.3.18")

In an Xcode target

To integrate FlexLayout into an Xcode target, use the File -> Swift Packages -> Add Package Dependency menu item.

<br/>

Changelog

FlexLayout recent history is available in the are documented in the CHANGELOG.

<br>

License

MIT License