SkillAgentSearch skills...

FlexLayout

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

Install / Use

/learn @layoutBox/FlexLayout

README

<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

  • iOS 13.0+
  • Xcode 13.0+
  • Swift 5.5

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).

  • A view can be layouted using FlexLayout, PinLayout, or both!
  • PinLayout can layout anything, but in situations where you need to layout many views but don't require PinLayout's finest control nor complex animations, FlexLayout is best fitted.
  • A view layouted using PinLayout can be embedded inside a FlexLayout's container and reversely. You choose the best layout framework for your situation.
<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

  • Flexbox layouting is simple, powerful and fast.
  • FlexLayout syntax is concise and chainable.
  • FlexLayout/yoga is incredibly fast, it's even faster than manual layout. See Performance.
  • The source code structure matches the flexbox structure, making it easier to understand and modify. Flex containers are defined on one line, and its items (children) are imbricated. This makes the flexbox structure much more visual and easy to understand.
  • Supports left-to-right (LTR) and right-to-left (RTL) languages.

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](https

View on GitHub
GitHub Stars2.1k
CategoryDevelopment
Updated2d ago
Forks236

Languages

Swift

Security Score

100/100

Audited on Mar 26, 2026

No findings