Auto Layout made easy

Overview

EasyPeasy Logo

CI Status Version Carthage compatible Coverage

EasyPeasy is a Swift framework that lets you create Auto Layout constraints programmatically without headaches and never ending boilerplate code. Besides the basics, EasyPeasy resolves most of the constraint conflicts for you and also can attach to a constraint conditional closures that are evaluated before applying a constraint, this way you can install an Auto Layout constraint depending on platform, size classes, orientation... or the state of your controller, easy peasy!

In this quick tour through EasyPeasy we assume that you already know the advantages and disadvantages of the different Auto Layout APIs and therefore you won't see here a comparison of the code side by side, just read and decide whether EasyPeasy is for you or not.

A touch of EasyPeasy

The example below is quite simple but shows how effortless its implementation result using EasyPeasy.


First touch

Features

  • Compatible with iOS, tvOS and OS X.
  • Lightweight and easy to use domain specific language.
  • Resolution of Auto Layout conflicts.
  • Fast and hassle-free update of constraints.
  • Conditional application of constraints.
  • UILayoutGuide and NSLayoutGuide support.

Guides

Table of contents

Installation

Swift compatibility

  • To work with Swift 2.2 use EasyPeasy v.1.2.1 or earlier versions of the library.
  • To work with Swift 2.3 use EasyPeasy v.1.3.1.
  • To work with Swift 3 use EasyPeasy v.1.4.2.
  • To work with Swift 4 use EasyPeasy v.1.8.0.
  • To work with Swift 5 use EasyPeasy v.1.9.0 and above. (thanks Bas van Kuijck).

Cocoapods

EasyPeasy is available through CocoaPods. To install it, simply add the following line to your Podfile:

pod "EasyPeasy"

Carthage

EasyPeasy is Carthage compatible. To add EasyPeasy as a dependency to your project, just add the following line to your Cartfile:

github "nakiostudio/EasyPeasy"

And run carthage update as usual.

Compatibility

EasyPeasy is compatible with iOS (8 and above), tvOS (9 and above) and OS X (10.10 and above). The framework has been tested with Xcode 7 and Swift 2.0, however don't hesitate to report any issues you may find with different versions.

Usage

EasyPeasy is a set of position and dimension attributes that you can apply to your views. You can manage these from the easy property available within all the UI classes that work with Auto Layout (view subclasses, layout guides, etc).

For instance, to set a width of 200px to a view you would create an attribute of class Width with a constant value of 200, then the attribute is applied to the view by using the easy.layout(_:) method.

myView.easy.layout(Width(200))

Because our view without height is nothing we can apply multiple attributes at once as follows:

myView.easy.layout(
  Width(200),
  Height(120)
)

In the previous example, two attributes have been applied and therefore two constraints created and added: a width constraint with constant = 200 and a height constraint with constant = 120.

Constants

Without really knowing it, we have just created an EasyPeasy Constant struct containing the constant, multipler and the relation of a NSLayoutConstraint.

Relations

EasyPeasy provides an easy way of creating constants with different NSLayoutRelations:

  • .Equal: it is created like in our previous example Width(200).
  • .GreaterThanOrEqual: it is created as easy as this Width(>=200) and it means that our view has a width greater than or equal to 200px.
  • .LessThanOrEqual: it is created as follows Width(<=200).

Multipliers

There is a custom operator that eases the creation of a NSLayoutConstraint multiplier. You can use it like this Width(*2) and means that the width of our view is two times something, we will mention later how to establish the relationship with that something.

In addition, you can combine multipliers with Equal, .GreaterThanOrEqual and LessThanOrEqual relations. i.e. Width(>=10.0*0.5) creates a NSLayoutConstraint with value = 10.0, relation = .GreaterThanOrEqual and multiplier = 0.5, whereas Width(==10.0*0.5) creates a NSLayoutConstraint with value = 10.0, relation = .Equal and multiplier = 0.5.

Attributes

EasyPeasy provides as many Attribute classes as attributes NSLayoutConstraint have, plus something that we have called CompoundAttributes (we will explain these attributes later).

DimensionAttributes

There are just two dimension attributes Width and Height. You can create an Auto Layout relationship between your view DimensionAttribute and another view by using the method func like(view: UIView) -> Self. Example:

contentLabel.easy.layout(Width().like(headerView))

That line of code will create a constraint that sets a width for contentLabel equal to the headerView width.

PositionAttributes

The table below shows the different position attributes available. Because they behave like the NSLayoutConstraint attributes, you can find a complete description of them in the Apple docs.

Attribute Attribute Attribute Attribute
Left Right Top Bottom
Leading Trailing CenterX CenterY
LeftMargin RightMargin TopMargin BottomMargin
LeadingMargin TrailingMargin CenterXWithinMargins CenterYWithinMargins
FirstBaseline LastBaseline -- --

As well as the DimensionAttributes have the like: method to establish Auto Layout relationships, you can use a similar method to do the same with PositionAttributes. This method is:

func to(view: UIView, _ attribute: ReferenceAttribute? = nil) -> Self

The example below positions contentLabel 10px under headerView with the same left margin as headerView.

contentLabel.easy.layout(
  Top(10).to(headerView),
  Left().to(headerView, .Left)
)

CompoundAttributes

These attributes are the ones that create multiple DimensionAttributes or PositionAttributes under the hood. For example, the Size attribute will create a Width and a Height attributes with their width and height NSLayoutConstraints respectively.

These are the CompoundAttributes available:

  • Size: As mentioned before this attribute will apply a Width and a Height attribute to the view. It can be initialized in many ways and depending on that the result may change. These are some examples:
// Apply width = 0 and height = 0 constraints
view.easy.layout(Size())
// Apply width = referenceView.width and height = referenceView.height constraints
view.easy.layout(Size().like(referenceView))
// Apply width = 100 and height = 100 constraints
view.easy.layout(Size(100))
// Apply width = 200 and height = 100 constraints
view.easy.layout(Size(CGSize(width: 200, height: 100)))
  • Edges: This attribute creates Left, Right, Top and Bottom attributes at once. Examples:
// Apply left = 0, right = 0, top = 0 and bottom = 0 constraints to its superview
view.easy.layout(Edges())
// Apply left = 10, right = 10, top = 10 and bottom = 10 constraints to its superview
view.easy.layout(Edges(10))
// Apply left = 10, right = 10, top = 5 and bottom = 5 constraints to its superview
view.easy.layout(Edges(UIEdgeInsets(top: 5, left: 10, bottom: 5, right: 10)))
  • Center: It creates CenterX and CenterY attributes. Examples:
// Apply centerX = 0 and centerY = 0 constraints to its superview
view.easy.layout(Center())
// Apply centerX = 10 and centerY = 10 constraints to its superview
view.easy.layout(Center(10))
// Apply centerX = 0 and centerY = 50 constraints to its superview
view.easy.layout(Center(CGPoint(x: 0, y: 50)))
  • Margins: This attribute creates LeftMargin, RightMargin, TopMargin and BottomMargin attributes at once. Examples:
// Apply leftMargin = 0, rightMargin = 0, topMargin = 0 and bottomMargin = 0 constraints to its superview
view.easy.layout(Margins())
// Apply leftMargin = 10, rightMargin = 10, topMargin = 10 and bottomMargin = 10 constraints to its superview
view.easy.layout(Margins(10))
// Apply leftMargin = 10, rightMargin = 10, topMargin = 5 and bottomMargin = 5 constraints to its superview
view.easy.layout(Margins(UIEdgeInsets(top: 5, left: 10, bottom: 5, right: 10)))
  • CenterWithinMargins: It creates CenterXWithinMargins and CenterYWithinMargins attributes. Examples:
// Apply centerXWithinMargins = 0 and centerYWithinMargins = 0 constraints to its superview
view.easy.layout(CenterWithinMargins())
// Apply centerXWithinMargins = 10 and centerYWithinMargins = 10 constraints to its superview
view.easy.layout(CenterWithinMargins(10))
// Apply centerXWithinMargins = 0 and centerYWithinMargins = 50 constraints to its superview
view.easy.layout(CenterWithinMargins(CGPoint(x: 0, y: 50)))

Priorities

The Priority enum does the same function as UILayoutPriority and it's shaped by five cases:

  • low: it creates an Auto Layout priority with Float value 1.

  • medium: it creates an Auto Layout priority with Float value 500.

  • high: it creates an Auto Layout priority with Float value 750.

  • required: it creates an Auto Layout priority with Float value 1000.

  • custom: it specifies the Auto Layout priority defined by the developer in the case associated value value. Example: .custom(value: 650.0).

In order to apply any of these priorities to an Attribute, the method .with(priority: Priority) must be used. The following example gives an UILayoutPriority of 500 to the Top Attribute applied to view:

view.easy.layout(Top(>=50).with(.medium))

You can also apply a Priority to an array of Attributes (this operation will override the priorities previously applied to an Attribute).

view.easy.layout([
  Width(200),
  Height(200)
].with(.medium))

Conditions

One of the peculiarities of EasyPeasy is the usage of Conditions or closures that evaluate whether a constraint should be applied or not to the view.

The method when(condition: Condition) sets the Condition closure to an Attribute.

There is plenty of use cases, the example below shows how to apply different constraints depending on a custom variable:

var isCenterAligned = true
...
view.easy.layout(
  Top(10),
  Bottom(10),
  Width(250),
  Left(10).when { !isCenterAligned },
  CenterX(0).when { isCenterAligned }
)

Condition re-evaluation

These Condition closures can be re-evaluated during the lifecycle of a view, to do so you just need to call the convenience method easy.reload().

view.easy.reload()

Bare in mind that these Condition closures are stored in properties therefore you need to capture those variables you access within the closure. For example:

descriptionLabel.easy.layout(
  Height(100).when { [weak self] in
    return self?.expandDescriptionLabel ?? false
  }
)

You can also apply a Condition to an array of Attributes (this operation will override the Conditions previously applied to an Attribute).

view.easy.layout([
  Width(200),
  Height(240)
].when { isFirstItem })

view.easy.layout([
  Width(120),
  Height(140)
].when { !isFirstItem })

ContextualConditions

This iOS only feature is a variant of the Condition closures that receive no parameters and return a boolean value. Instead, a Context struct is passed as parameter providing some extra information based on the UITraitCollection of the UIView the Attributes are going to be applied to.

The properties available on this Context struct are:

  • isPad: true if the current device is iPad.
  • isPhone: true if the current device is iPhone.
  • isHorizontalVerticalCompact: true if both horizontal and vertical size classes are .Compact.
  • isHorizontalCompact: true if the horizontal size class is .Compact.
  • isVerticalCompact: true if the vertical size class is .Compact.
  • isHorizontalVerticalRegular: true if both horizontal and vertical size classes are .Regular.
  • isHorizontalRegular: true if the horizontal size class is .Regular.
  • isVerticalRegular: true if the vertical size class is .Regular.

This is an example of ContextualConditions applied to an array of Attributes:

view.easy.layout([
  Size(250),
  Center(0)
].when { $0.isHorizontalRegular })

view.easy.layout([
  Top(0),
  Left(0),
  Right(0),
  Height(250)
].when { $0.isHorizontalCompact })
ContextualCondition re-evaluation

As we have seen before, you can re-evaluate a Condition closure by calling the easy.reload() convenience method. This also applies to ContextualConditions, therefore if you want your constraints to be updated upon a change on your view UITraitCollection then you need to call the easy.reload() method within traitCollectionDidChange(_:).

Alternatively, EasyPeasy can do this step for you automatically. This is disabled by default as it requires method swizzling; to enable it simply compile the framework adding the compiler flags -D EASY_RELOAD.

UILayoutGuides

Since the version v.0.2.3 (and for iOS 9 projects and above) EasyPeasy integrates UILayoutGuides support.

Applying constraints

Applying a constraint to an UILayoutGuide is as easy as we have discussed in the previous sections, just apply the EasyPeasy attributes you want using the easy.layout(_:) method.

func viewDidLoad() {
  super.viewDidLoad()

  let layoutGuide = UILayoutGuide()
  self.view.addLayoutGuide(layoutGuide)

  layoutGuide.easy.layout(
    Top(10),
    Left(10),
    Right(10),
    Height(100).when { Device() == .iPad },
    Height(60).when { Device() == .iPhone }
  )
}

As you can see, all the different attributes and goodies EasyPeasy provides for UIViews are also applicable to UILayoutGuides.

Connecting UILayoutGuides and UIViews

As mentioned in the Attributes section you can create constraint relationships between an UIView attribute and other UIViews attributes using the methods to(_:_) and like(_:_). Now you can take advantage of those methods to create a relationship between your UIView attributes and an UILayoutGuide.

let layoutGuide = UILayoutGuide()
let separatorView: UIView
let label: UILabel

func setupLabel() {
  self.label.easy.layout(
    Top(10).to(self.layoutGuide),
    CenterX(0),
    Size(60)
  )

  self.separatorView.easy.layout(
    Width(0).like(self.layoutGuide),
    Height(2),
    Top(10).to(self.label),
    CenterX(0).to(self.label)
  )
}

Lastly

Finally but not less important in this section we will explain how to interact with Attributes once they have been applied to an UIView using the easy.layout(_:) method.

Updating constraints

We briefly mentioned in the introductory section that EasyPeasy solves most of the constraint conflicts and it's true. Usually, in order to update a constraint or the constant of a constraint you have to keep a reference to your NSLayoutConstraint and update the constant when needed. With EasyPeasy you just need to apply another Attribute to your UIView of the same or different type. In the example below we have two methods, the one in which we setup our constraints viewDidLoad() and a method in which we want to update the Top attribute of our headerView.

func viewDidLoad() {
  super.viewDidLoad()

  headerView.easy.layout(
    Top(0),
    Left(0),
    Right(0),
    Height(60)
  )
}

func didTapButton(sender: UIButton?) {
  headerView.easy.layout(Top(100))
}

That's it! we have updated our Top constraint without caring about keeping references or installing/uninstalling new constraints.

However, there is some cases in which EasyPeasy cannot prevent a conflict (at least for now). This is when multiple constraints cannot be satisfied, i.e. existing a Left and Right constraints it's also applied a Width constraint (all of them with the same priority). But EasyPeasy is smart enough to prevent conflicts, i.e. when replacing a Left and Right attributes with a CenterX attribute.

Clearing constraints

EasyPeasy provides a method extending UIView that clears all the constraints installed in an UIView by the framework. This method is func easy.clear().

view.easy.clear()

Animating constraints

Animating constraints with EasyPeasy is very straightforward, just apply one or more Attributes to your view within an animation block and you are ready to go, without worrying about constraint conflicts. Example:

UIView.animateWithDuration(0.3) {
  view.easy.layout(Top(10))
  view.layoutIfNeeded()
}

Example projects

Don't forget to clone the repository and run the iOS and OS X example projects to see EasyPeasy in action.

Demo iOS Demo macOS

Note: the messages in the demo app aren't real and the appearance of those Twitter accounts no more than a tribute to some kickass developers :)

EasyPeasy playground

Alternatively, you can play with EasyPeasy cloning the Playground project available here.

Playground

Autogenerated documentation

EasyPeasy is a well documented framework and therefore all the documented classes and methods are available in Cocoadocs.

Author

Carlos Vidal - @nakiostudio

License

EasyPeasy is available under the MIT license. See the LICENSE file for more info.

Comments
  • ISSUE-69 Deprecate apply operator

    ISSUE-69 Deprecate apply operator

    #69: Some fresh air for the library discontinuing the usage of the <- operator. For now the operator itself and other methods are marked as deprecated.

    Apply operator <- replaced with:

    myView.easy.layout(
      Width(200),
      Height(120)
    )
    
    view.easy.layout([
      Width(200),
      Height(240)
    ].when { isFirstItem })
    

    The helper method easy_clear() is now:

    view.easy.clear()
    

    And also easy_reload() has changed:

    view.easy.reload()
    

    Thanks to @muukii for the ideas 🙌

    opened by nakiostudio 8
  • Add workflows that enable to create release automatically in CocoaPods

    Add workflows that enable to create release automatically in CocoaPods

    • Add workflows that run on GitHub Actions.
    • These are:
      • Check podspec is valid (linting)
      • Push to cocoapods repo automatically when we create a tag.

    TODO

    • [x] Set a secure variable COCOAPODS_TRUNK_TOKEN to create cocoapods release from GitHub Actions.
    opened by muukii 4
  • Contextual conditions

    Contextual conditions

    Motivation

    As per #18, using EasyPeasy along with size classes is not trivial

    Goals

    Facilitate activation/deactivation of NSLayoutConstraints based on size classes and device.

    The final result should allow the following:

    Width(50).when { $0.isVerticalCompact }
    Width(50).when { $0.isHorizontalVerticalCompact }
    Width(50).when { $0.isPad }
    

    In addition, if the compiler flag EASY_RELOAD is defined, easy_reload will be automatically triggered when the trait collections change.

    Tasks

    • [x] ContextualCondition implementation
    • [x] Compiler flag to enable swizzling of traitCollectionDidChange(_:)
    • [x] Write more unit test
    • [x] Update documentation
    opened by nakiostudio 4
  • ISSUE-28 Extend multipliers usage

    ISSUE-28 Extend multipliers usage

    Motivation

    Achieve what @lipka describes in #28.

    Goals

    Enable the use of multipliers alongside Equal, LessThanOrEqual and GreaterThanOrEqual relation attributes.

    The final result should allow the following:

    Width(50)
    Width(*0.5)
    Width(==50)
    Width(>=50)
    Width(<=50)
    Width(==50*0.5)
    Width(<=50*0.5)
    Width(<=50*0.5)
    

    Tasks

    • [x] Enable multipliers use alongside LessThanOrEqual and GreaterThanOrEqual constants
    • [x] Update unit test
    • [x] Write more unit test
    • [x] Update documentation
    opened by nakiostudio 3
  • Add Edges().to(_:) - Enables to attach the edge of the view to another view or LayoutGuide.

    Add Edges().to(_:) - Enables to attach the edge of the view to another view or LayoutGuide.

    PR adds methods to enable to attach edges of view to other layout-guide or view.

    Motivation

    I often write the following code in order to attach the edges of the view to UILayoutGuide. This code is a bit verbosity, and we could have a shorthand if we could add a method to Edges.

    Before:

     myOverlayView.easy.layout([
        Top().to(overlayViewLayoutGuide, .top),
        Left().to(overlayViewLayoutGuide, .left),
        Right().to(overlayViewLayoutGuide, .right),
        Bottom().to(overlayViewLayoutGuide, .bottom),
      ])
    

    After:

     myOverlayView.easy.layout(
       Edges().to(overlayViewLayoutGuide)
     )
    
    opened by muukii 2
  • Solution for Nakiostudio EasyPeasy issue #75

    Solution for Nakiostudio EasyPeasy issue #75

    Changing compatibility setting of the Xcode project file to "Xcode 11", changing deployment targets to 10.15 and manually creating a build scheme EasyPeasy-macOS (again) solves the Carthage build problem for me. Now the build for macOS succeeds again.

    opened by ikemuc 2
  • Swift 4.2 / Xcode10 compatible

    Swift 4.2 / Xcode10 compatible

    Still had to set the build system to legacy, because I got some build errors with the new build system:

    error: Build input file cannot be found: '/Users/bvkuijck/Library/Developer/Xcode/DerivedData/EasyPeasy-dixwhwxfapeplzbbpahtbzhnavfn/Build/Products/Debug/Demo macOS.app/Contents/PlugIns/Tests macOS.xctest/Contents/MacOS/Tests macOS'

    Which I haven't figured out how to fix.

    opened by basvankuijck 2
  • Cleanup Directory Projects

    Cleanup Directory Projects

    For Cleanup and Fix https://github.com/nakiostudio/EasyPeasy/issues/73

    @dkalachov @nakiostudio

    I have experience about this problem. In that time, I've fixed this with removing xcworkspace. So, I've cleanup EasyPeasy like it. What do you think?

    Reveal

    screen shot 2017-10-12 at 01 50 30 screen shot 2017-10-12 at 01 51 07 screen shot 2017-10-12 at 01 57 15 screen shot 2017-10-12 at 01 52 11
    opened by muukii 2
  • Say no to commas: add array builder to layout

    Say no to commas: add array builder to layout

    Result builder hit the swift 5.4. Array result builder allows to refuse from commas when you create an array. The example of usage:

    self.thumbnailImageView.easy.layout {
        Size(52)
        Top(12)
        Left(12)
    }
    
    opened by onsissond 1
  • Rename Context to EasyContext and View to EasyView for SwiftUI compatibility

    Rename Context to EasyContext and View to EasyView for SwiftUI compatibility

    SwiftUI introduces the structs View and Context. EasyPeasy's own structs of the same name conflict with this, which leads to errors in files where you include both SwiftUI and EasyPeasy.

    This PR renames EasyPeasy's View and Context to EasyView and EasyContext. This fixes the incompatibility. I've decided not to rename file names, so Context.swift remains Context.swift, as that felt more in line with the other filenames.

    opened by tcwalther 2
  • Fix reload()

    Fix reload()

    For some reason activateConstraints and deactivateConstraints might contain same constraints. That requires further investigation but deactivating after activating solves the consequences of the issue in my case.

    opened by aspcartman 2
  • Bump excon from 0.68.0 to 0.71.0

    Bump excon from 0.68.0 to 0.71.0

    Bumps excon from 0.68.0 to 0.71.0.

    Changelog

    Sourced from excon's changelog.

    0.71.0 2019-12-12

    fix for leftover data with interrupted persistent connections

    0.70.0 2019-12-02

    Update bundled certificates

    0.69.1 2019-11-21

    Fix mistake in proxy connection error handling

    0.69.0 2019-11-21

    Raise better proxy connection errors

    Commits
    • 1149d44 v0.71.0
    • ccb57d7 fix for leftover data with interrupted persistent connections
    • f8de8cf v0.70.0
    • 93f4a21 v0.69.1
    • e89bbb7 Merge pull request #709 from jasquat/fix_response_status_check
    • 5647437 fixed response status check when making a request with a valid proxy is set
    • f769176 v0.69.0
    • 20c0748 define ProxyConnectionError
    • f44106a raise on failed proxy connect
    • d7ed5fe be thorough in unsubscribing to notifications in instrumentation tests
    • Additional commits viewable in compare view

    Dependabot compatibility score

    Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting @dependabot rebase.


    Dependabot commands and options

    You can trigger Dependabot actions by commenting on this PR:

    • @dependabot rebase will rebase this PR
    • @dependabot recreate will recreate this PR, overwriting any edits that have been made to it
    • @dependabot merge will merge this PR after your CI passes on it
    • @dependabot squash and merge will squash and merge this PR after your CI passes on it
    • @dependabot cancel merge will cancel a previously requested merge and block automerging
    • @dependabot reopen will reopen this PR if it is closed
    • @dependabot ignore this [patch|minor|major] version will close this PR and stop Dependabot creating any more for this minor/major version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this dependency will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
    • @dependabot use these labels will set the current labels as the default for future PRs for this repo and language
    • @dependabot use these reviewers will set the current reviewers as the default for future PRs for this repo and language
    • @dependabot use these assignees will set the current assignees as the default for future PRs for this repo and language
    • @dependabot use this milestone will set the current milestone as the default for future PRs for this repo and language

    You can disable automated security fix PRs for this repo from the Security Alerts page.

    dependencies 
    opened by dependabot[bot] 1
  • Fix * operator which would set value not just for multiplier but also for constant

    Fix * operator which would set value not just for multiplier but also for constant

    We've found an issue in one of the project that is using EasyPeasy. When you create a constraint using * operator (e.g. Width(*1.5)), it would set not just the multiplier to 1.5 but also the constant. As a workaround we're currently always explicitly providing a constant: Width(==0 *1.5).

    opened by kean 2
Releases(v1.10.0)
  • v1.10.0(Jan 14, 2021)

    • Add Edges().to(_:) - Enables to attach the edge of the view to another view or LayoutGuide. #106 by @muukii
    • Solution for Nakiostudio EasyPeasy issue #75 #99 by @ikemuc
    • Bump mini_magick from 4.5.1 to 4.9.5 #98 by @dependabot
    • Bump rubyzip from 1.2.2 to 1.3.0 #97 by @dependabot
    • Add workflows that enable to create release automatically in CocoaPods #107 by @muukii

    Generated by chglog Source code(tar.gz)
    Source code(zip)
Owner
Carlos Vidal
Carlos Vidal
Auto Layout In Swift Made Easy

Swiftstraints Swiftstraints can turn verbose auto-layout code: let constraint = NSLayoutConstraint(item: blueView, attr

null 119 Jan 29, 2022
Auto Layout (and manual layout) in one line.

Auto Layout (and manual layout) in one line. Quick Look view.bb.centerX().below(view2).size(100) It’s equivalent to iOS 9 API: view.centerXAnchor.cons

Javier Zhang 74 Oct 19, 2022
Written in pure Swift, QuickLayout offers a simple and easy way to manage Auto Layout in code.

QuickLayout QuickLayout offers an additional way, to easily manage the Auto Layout using only code. You can harness the power of QuickLayout to align

Daniel Huri 243 Oct 28, 2022
Easy Auto Layout

RKAutoLayout Easy AutoLayout TL;DR let view1: UIView = UIView() let view2: UIView = UIView() view1.addSubview(view2) /// Add all view1.rk_alAdd(

Roman Kotov 1 Mar 24, 2019
Fast Swift Views layouting without auto layout. No magic, pure code, full control and blazing fast. Concise syntax, intuitive, readable & chainable. [iOS/macOS/tvOS/CALayer]

Extremely Fast views layouting without auto layout. No magic, pure code, full control and blazing fast. Concise syntax, intuitive, readable & chainabl

layoutBox 2.1k Dec 22, 2022
A declarative Auto Layout DSL for Swift :iphone::triangular_ruler:

Cartography ?? ?? Using Cartography, you can set up your Auto Layout constraints in declarative code and without any stringly typing! In short, it all

Robb Böhnke 7.3k Jan 4, 2023
Lightweight Swift framework for Apple's Auto-Layout

I am glad to share with you a lightweight Swift framework for Apple's Auto-Layout. It helps you write readable and compact UI code using simple API. A

null 349 Dec 20, 2022
An Impressive Auto Layout DSL for iOS, tvOS & OSX. & It is written in pure swift.

KVConstraintKit KVConstraintKit is a DSL to make easy & impressive Auto Layout constraints on iOS, tvOS & OSX with Swift Installation Using CocoaPods

Keshav Vishwkarma 90 Sep 1, 2022
A compact but full-featured Auto Layout DSL for Swift

Mortar allows you to create Auto Layout constraints using concise, simple code statements. Use this: view1.m_right |=| view2.m_left - 12.0 Instead of:

Jason Fieldman 83 Jan 29, 2022
The ultimate API for iOS & OS X Auto Layout — impressively simple, immensely powerful. Objective-C and Swift compatible.

The ultimate API for iOS & OS X Auto Layout — impressively simple, immensely powerful. PureLayout extends UIView/NSView, NSArray, and NSLayoutConstrai

PureLayout 7.6k Jan 6, 2023
TinyConstraints is the syntactic sugar that makes Auto Layout sweeter for human use.

TinyConstraints is the syntactic sugar that makes Auto Layout sweeter for human use. Features Pure Swift 5 sweetness. Everything you can do with Auto

Robert-Hein Hooijmans 3.8k Jan 5, 2023
Intuitive and powerful Auto Layout library

Align introduces a better alternative to Auto Layout anchors. Semantic. Align APIs focus on your goals, not the math behind Auto Layout constraints. P

Alexander Grebenyuk 338 Oct 18, 2022
⚓️ Declarative, extensible, powerful Auto Layout

EasyAnchor ❤️ Support my apps ❤️ Push Hero - pure Swift native macOS application to test push notifications PastePal - Pasteboard, note and shortcut m

Khoa 449 Nov 10, 2022
Harness the power of AutoLayout NSLayoutConstraints with a simplified, chainable and expressive syntax. Supports iOS and OSX Auto Layout

Masonry Masonry is still actively maintained, we are committed to fixing bugs and merging good quality PRs from the wider community. However if you're

null 18k Jan 5, 2023
Template auto layout cell for automatically UITableViewCell height calculating

UITableView-FDTemplateLayoutCell Overview Template auto layout cell for automatically UITableViewCell height calculating. Basic usage If you have a se

null 10k Dec 31, 2022
Yet Another Swift Auto Layout DSL

FormationLayout Documentation FormationLayout is the top level layout class for one root view. FormationLayout takes a UIView as its rootView. transla

Evan Liu 53 Mar 31, 2022
Lightweight declarative auto-layout framework for Swift

SwiftyLayout SwiftyLayout is a framework that allows to describe layout constraints (ie NSLayoutConstraint) as a simple mathematical formula in a Swif

Hisakuni Fujimoto 15 Nov 7, 2017
Minimal Auto Layout in Swift

Restraint Restraint is a very very small library to help make your use of NSLayoutConstraint in Swift more legible & declarative. Like programmatic vi

The Puffin Supply Project 80 Aug 23, 2022
Swift microframework for declaring Auto Layout constraints functionally

Relayout Relayout is a Swift microframework to make using Auto Layout easier with static and dynamic layouts. Why? If you want to build a UI using App

Steve Streza 560 Nov 19, 2022