Intuitive and powerful Auto Layout library

Overview

Screen Shot 2020-06-15 at 23 06 32

Align introduces a better alternative to Auto Layout anchors.

  • Semantic. Align APIs focus on your goals, not the math behind Auto Layout constraints.
  • Powerful. Create multiple constraints with a single line of code.
  • Type Safe. Makes it impossible to create invalid constraints, at compile time.
  • Fluent. Concise and clear API that follows Swift API Design Guidelines.
  • Simple. Stop worrying about translatesAutoresizingMaskIntoConstraints and constraints activation.

To give you a taste of what the semantic APIs look like, here is an example:

view.anchors.edges.pin(insets: 20, alignment: .center)

pin edges with center alignmnet

You can choose to add convenience extensions that you prefer to make it even more concise for select use cases, e.g. view.pin(insets: 20).

Getting Started

The entire library fits in a single file with around 300 lines of code. You can simply drag-n-drop it into your app if you'd like. For more installation options, see Installation Guide.

Introduction

Anchors (Anchor<Type, Axis) represent layout attributes of a view including edges, dimensions, axis, and baselines. You use anchors to create constraints. The Align APIs fit in the following quadrant:

Core API allows you to create constraints by setting relations between one or more anchors, there APIs are similar to what NSLayoutAnchor provides. Semantic API is a high-level API that focus on your goals, such as pinning edges to the container, aligning the view, setting spacing between views, etc.

Both of these types of APIs are designed to be easily discoverable using Xcode code completions. There is also a cheat sheet available, as well as an illustrated guide located in this README.

Align Cheat Sheet

Anchors

Core API

// Align two views along one of the edges
a.anchors.leading.equal(b.anchors.leading)

// Other options are available:
// a.anchors.leading.greaterThanOrEqual(b.anchors.leading)
// a.anchors.leading.greaterThanOrEqual(b.anchors.leading, constant: 10)

// Set height to the given value (CGFloat)
a.anchors.height.equal(30)

pin edges

Align automatically sets translatesAutoresizingMaskIntoConstraints to false for every view that you manipulate using it, so you no longer have to worry about it.

Align also automatically activates the created constraints. Using (NSLayoutConstraint.active(_:) is typically slightly more efficient than activating each constraint individually. To take advantage of this method, wrap your code into Constrains initializer.

Constraints {       
    // Create constraints in this closure
}

Align has full test coverage. If you'd like to learn about which constraints (NSLayoutConstraint) Align creates each time you call one of its methods, test cases are a great place to start.

Align also allows you to offset and multiply anchors. This is a lightweight operation with no allocations involved.

// Offset one of the anchors, creating a "virtual" anchor
b.anchors.leading.equal(a.anchors.trailing + 20)

// Set aspect ratio for a view
b.anchors.height.equal(a.anchors.width * 2)

pin edges

Semantic API

// Set spacing between two views
a.anchors.bottom.spacing(20, to: b.anchors.top)

// Pin an edge to the superview
a.anchors.trailing.pin(inset: 20)

pin edges

Clamps the dimension of a view to the given limiting range.
a.anchors.width.clamp(to: 40...100)

pin edges

Anchor Collections

With Align, you can manipulate multiple edges at the same time, creating more than one constraint at a time.

Edges

pin() is probably the most powerful and flexible API in Align.

view.anchors.edges.pin(insets: 20)

// Same as the following:
view.anchors.edges.pin(
    to: view.superview!
    insets: EdgeInsets(top: 20, left: 20, bottom: 20, trailing: 20),
    alignment: .fill
)

pin edges

By default, pin() method pin the edges to the superview of the current view. However, you can select any target view or layout guide:

// Pin to superview
view.anchors.edges.pin()

// Pin to layout margins guide
view.anchors.edges.pin(to: container.layoutMarginsGuide)

// Pin to safe area
view.anchors.edges.pin(to: container.safeAreaLayoutGuide)

Align also provides a convenient way to access anchors of the layout guide: view.anchors.safeArea.top.

By default, pin() users .fill alignment. There are variety of other alignments available (81 if you combine all possible options).

view.anchors.edges.pin(insets: 20, alignment: .center)

pin edges with center alignmnet

You can create constraint along the given axis.

view.anchors.edges.pin(insets: 20, axis: .horizontal, alignment: .center)

pin edges with center alignmnet for horizontal axis

Or pin the view to to a corner.

view.anchors.edges.pin(insets: 20, alignment: .topLeading)

pin edges with center alignmnet for horizontal axis

You can create custom alignments (see Alignment type) by providing a vertical and horizontal component.

anchors.edges.pin(insets: 20, alignment: Alignment(vertical: .center, horizontal: .leading))

pin edges with center alignmnet for horizontal axis

Center

a.anchors.center.align()

size equal

Size

a.anchors.size.equal(CGSize(width: 120, height: 40))

greaterThanEqual and lessThanOrEqual options are also available

size equal

a.anchors.size.equal(b)

size equal other view

Advanced

By default, Align automatically activates created constraints. Using Constraints API, constraints are activated all of the same time when you exit from the closure. It gives you a chance to change the priority of the constraints.

Constraints(for: title, subtitle) { title, subtitle in
    // Align one anchor with another
    subtitle.top.spacing(10, to: title.bottom + 10)

    // Manipulate dimensions
    title.width.equal(100)

    // Change a priority of constraints inside a group:
    subtitle.bottom.pin().priority = UILayoutPriority(999)
}

Constraints also give you easy access to Align anchors (notice, there is no .anchors call in the example). And if you want to not activate the constraints, there is an option for that:

Constraints(activate: false) {
    // Create your constraints here
}

Requirements

Align Swift Xcode Platforms
Align 2.0 Swift 5.1 Xcode 11.0 iOS 11.0 / tvOS 11.0 / macOS 10.13
Align 1.1-1.2 Swift 4.2 – 5.0 Xcode 10.1 – 10.2 iOS 10.0 / tvOS 10.0
Align 1.0 Swift 4.0 – 4.2 Xcode 9.2 – 10.1 iOS 9.0 / tvOS 9.0

Why Align

Align strives for clarity and simplicity by following Swift API Design Guidelines. Although most of the APIs are compact, it is a non-goal to enable the most concise syntax possible.

Align is for someone who:

  • Prefers fluent API that follows Swift API Design Guidelines
  • Doesn't want to depend on big, complex libraries
  • Prefers to have as little extensions for native classes as possible, Align only adds one property
  • Doesn't overuse operator overloads, prefers fast compile times
  • Likes NSLayoutAnchor but wishes it had simpler, more fluent API which didn't require manually activating constraints
You might also like...
Very simple swipe-to-dismiss, supporting Auto Layout and dynamic heights
Very simple swipe-to-dismiss, supporting Auto Layout and dynamic heights

PanelPresenter Add swipe-dismiss logic to your view controller, supporting Auto Layout and dynamic heights. Installation Add this package to your proj

A declarative Auto Layout DSL for Swift :iphone::triangular_ruler:
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

Auto Layout made easy
Auto Layout made easy

EasyPeasy is a Swift framework that lets you create Auto Layout constraints programmatically without headaches and never ending boilerplate code. Besi

Lightweight Swift framework for Apple's Auto-Layout
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

An Impressive Auto Layout DSL for  iOS, tvOS & OSX. & It is written in pure swift.
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

A compact but full-featured Auto Layout DSL for Swift
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:

Auto Layout In Swift Made Easy

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

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.

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

Template auto layout cell for automatically UITableViewCell height calculating
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

Comments
  • Extensions, Spacing, IsInverted and Others 🙂

    Extensions, Spacing, IsInverted and Others 🙂

    Hi!

    Thanks for building a small and simple Auto Layout library. I've been integrating it into our project and came up with couple thoughts/questions about the implementation 🙂

    Thanks in advance for having a look at them!

    AddSubview

    I've found this extension in the tests part of the project and I think it's very useful. What was the motivation to remove it from the project itself?

    public extension UIView {
        @discardableResult @nonobjc func addSubview(_ a: UIView, constraints: (LayoutAnchors<UIView>) -> Void) -> Constraints {
            addSubview(a)
            return Constraints(for: a, constraints)
        }
    }
    

    LayoutAnchors

    I've been able to easily pin anchors to the superview, but for the SafeArea I didn't find a simple way to do that. So I've implemented this extension. Though I've been wondering if it fits the Align philosophy. Maybe I don't see some big picture here 🤔

    public extension LayoutAnchors where Base: UIView {
        var superviewSafeArea: LayoutItem? {
            return self.base.superview?.safeAreaLayoutGuide
        }
    
        @discardableResult func toSafeArea(insets: CGFloat = 0.0) -> [NSLayoutConstraint] {
            edges.pin(to: self.base.superview?.safeAreaLayoutGuide, insets: insets)
        }
    }
    

    Combining AddSubview + LayoutAnchors

    Combining the above 2 I've been able to write code like this:

    view.addSubview(loadingView) {
        $0.toSafeArea()
    }
    

    Or this:

    view.addSubview(progressView) {
        $0.top.pin(to: $0.superviewSafeArea)
        $0.leading.pin()
        $0.trailing.pin()
    }
    

    So from my perspective the UIView+AddSubview is super nice addition 🙂

    Align/Spacing -> Pin

    I wanted to have the same interface so I've created couple more extensions:

    public extension AnchorCollectionCenter {
        @discardableResult func pin() -> [NSLayoutConstraint] {
            self.align()
        }
    
        @discardableResult func pin<Item: LayoutItem>(to item: Item) -> [NSLayoutConstraint] {
            self.align(with: item)
        }
    }
    
    public extension Anchor where Type: AnchorType.Center {
        @discardableResult func pin(offset: CGFloat = 0) -> NSLayoutConstraint {
            self.align(offset: offset)
        }
    }
    
    public extension Anchor where Type: AnchorType.Edge {
        @discardableResult func pin(to anchor: Anchor<Type, Axis>, spacing: CGFloat = 0, relation: NSLayoutConstraint.Relation = .equal) -> NSLayoutConstraint {
            self.spacing(spacing, to: anchor, relation: relation)
        }
    }
    

    Is there some specific reasons why you kept spacing and align and didn't rename them to pin?

    IsInverted

    I've been looking at the source code and found that the implementation of the variable isInverted is different in pin and spacing functions. For example spacing has this check:

    (attribute == .trailing && anchor.attribute == .leading)
    

    But doesn't have this one:

    (attribute == .trailing && anchor.attribute == .trailing)
    

    Which in my opinion is also needed to make sure we invert the spacing in this case. So maybe we can simplify it and use the same logic as in the pin?

    let isInverted = [.trailing, .right, .bottom].contains(attribute)
    

    While writing the last point about the IsInverted I've noticed that spacing also inverts the relation. Which is probably the reason why isInverted is calculated differently here.

    But still the spacing function allows to write the following:

    view1.anchors.trailing.spacing(8, to: view2.anchors.trailing)
    

    Which will produce wrong layout 🤔

    opened by wow-such-amazing 4
  • Unable to simultaneously satisfy constraints.

    Unable to simultaneously satisfy constraints.

    Hey,

    addSubview(bgView) {
        $0.edges.pinToSuperview()
    }
    
    addSubview(searchBar) {
        $0.edges(.left, .right, .top).pinToSuperview()
        $0.height.set(44)
    }
    
    addSubview(tableView) {
        $0.edges(.left, .right, .bottom).pinToSuperview()
        $0.height.match(bgView.al.height - 44)
    }
    

    When I run this code, I get the following output, and I'm not sure what I'm doing wrong:

    [LayoutConstraints] Unable to simultaneously satisfy constraints.
    	Probably at least one of the constraints in the following list is one you don't want. 
    	Try this: 
    		(1) look at each constraint and try to figure out which you don't expect; 
    		(2) find the code that added the unwanted constraint or constraints and fix it. 
    (
        "<NSLayoutConstraint:0x6080000944b0 UIImageView:0x7f87650162c0.bottom == Testing.MyTableView:0x7f8765010b70.bottom   (active)>",
        "<NSLayoutConstraint:0x6080000945a0 V:|-(0)-[UIImageView:0x7f87650162c0]   (active, names: '|':Testing.MyTableView:0x7f8765010b70 )>",
        "<NSLayoutConstraint:0x60400008e510 UITableView:0x7f8763865400.height == UIImageView:0x7f87650162c0.height - 44   (active)>",
        "<NSLayoutConstraint:0x608000097110 '_UITemporaryLayoutHeight' Testing.MyTableView:0x7f8765010b70.height == 0   (active)>"
    )
    
    Will attempt to recover by breaking constraint 
    <NSLayoutConstraint:0x6080000944b0 UIImageView:0x7f87650162c0.bottom == Testing.MyTableView:0x7f8765010b70.bottom   (active)>
    
    Make a symbolic breakpoint at UIViewAlertForUnsatisfiableConstraints to catch this in the debugger.
    The methods in the UIConstraintBasedLayoutDebugging category on UIView listed in <UIKit/UIView.h> may also be helpful.
    

    Anybody have an idea how to fix that? Thank you in advance.

    opened by murselturk 3
  • Improvement AnchorCollectionSize

    Improvement AnchorCollectionSize

    Hi, @kean thanks for great library 😀

    I don't know if this ever entered the framework or not, if I have case set size with same width and height like

    view.ancors.size.equal(CGSize(width: 100 height: 100))
    

    Can I just write simple code like this ?

    
    view.ancors.size.equal(100)
    
    

    I'm just giving a suggestion what if AnchorCollectionSize improve like

    public protocol ConstraintSize {}
    extension CGSize: ConstraintSize {}
    extension Int: ConstraintSize {}
    extension Double: ConstraintSize {}
    extension CGFloat: ConstraintSize {}
    
    public struct AnchorCollectionSize {
        /// Set the size of item.
        @discardableResult public func equal(_ size: ConstraintSize) -> [NSLayoutConstraint] {
            switch size {
            case is CGFloat, is Int, is Double:
                let _size: CGFloat = convertSizeToEqual(from: size)
                return [width.equal(_size), height.equal(_size)]
            case let size as CGSize:
                return [width.equal(size.width), height.equal(size.height)]
            default:
                return []
            }
        }
    
        /// Set the size of item.
        @discardableResult public func greaterThanOrEqul(_ size: ConstraintSize) -> [NSLayoutConstraint] {
            switch size {
            case is CGFloat, is Int, is Double:
                let _size: CGFloat = convertSizeToEqual(from: size)
                return [width.greaterThanOrEqual(_size), height.greaterThanOrEqual(_size)]
            case let size as CGSize:
                return [width.greaterThanOrEqual(size.width), height.greaterThanOrEqual(size.height)]
            default:
                return []
            }
        }
    
        /// Set the size of item.
        @discardableResult public func lessThanOrEqual(_ size: ConstraintSize) -> [NSLayoutConstraint] {
            switch size {
            case is CGFloat, is Int, is Double:
                let _size: CGFloat = convertSizeToEqual(from: size)
                return [width.lessThanOrEqual(_size), height.lessThanOrEqual(_size)]
            case let size as CGSize:
                return [width.lessThanOrEqual(size.width), height.lessThanOrEqual(size.height)]
            default:
                return []
            }
        }
    
        /// Makes convert ConstraintSize to CGFloat
        private func convertSizeToEqual(from size: ConstraintSize) -> CGFloat {
            var _size: CGFloat = 0
            
            if let size = size as? Int {
                _size = CGFloat(size)
            } else if let size = size as? Double {
                _size = CGFloat(size)
            } else if let size = size as? CGFloat {
                _size = size
            }
            
            return _size
        }
    }
    
    opened by bagusandinata 2
  • Additional UIView & UIStackView Extensions

    Additional UIView & UIStackView Extensions

    Howdy! This PR adds some additional extensions to the UIView and UIStackView classes, namely:

    UIView

    func insertSubview(_ a: UIView, at index: Int, constraints: (LayoutProxy<UIView>) -> Void) -> Constraints
    func insertSubview(_ a: UIView, aboveSubview siblingSubview: UIView, constraints: (LayoutProxy<UIView>) -> Void) -> Constraints
    func insertSubview(_ a: UIView, belowSubview siblingSubview: UIView, constraints: (LayoutProxy<UIView>) -> Void) -> Constraints
    

    UIStackView

    func addArrangedSubview(_ a: UIView, constraints: (LayoutProxy<UIView>) -> Void) -> Constraints
    func addArrangedSubview(_ a: UIView, _ b: UIView, constraints: (LayoutProxy<UIView>, LayoutProxy<UIView>) -> Void) -> Constraints
    func addArrangedSubview(_ a: UIView, _ b: UIView, _ c: UIView, constraints: (LayoutProxy<UIView>, LayoutProxy<UIView>, LayoutProxy<UIView>) -> Void) -> Constraints
    func addArrangedSubview(_ a: UIView, _ b: UIView, _ c: UIView, _ d: UIView, constraints: (LayoutProxy<UIView>, LayoutProxy<UIView>, LayoutProxy<UIView>, LayoutProxy<UIView>) -> Void) -> Constraints
    func insertArrangedSubview(_ a: UIView, at stackIndex: Int, constraints: (LayoutProxy<UIView>) -> Void) -> Constraints
    
    opened by Chao-Man 1
Releases(3.0.0)
  • 3.0.0(Jul 13, 2022)

    • Breaking Change: The Alignment used in pin() method now works slightly differently by default for the pre-defined .trailing, .leading, .bottom, and .top alignments. Previously, .leading alignment would pin to the view to the .leading horizontal guide and .fill the view vertically. In Align 3.0, it centers the view vertically instead.
    • Add new documentation) created using DocC
    • Increase the minimum required Xcode version to 13.3
    • Increase the minimum supported platforms to iOS 12.0 / tvOS 12.0 / macOS 10.14
    • Rename LayoutAnchors/base to LayoutAnchors/item
    • Move Alignment to AnchorCollectionEdges/Alignment
    • Fix typos
    Source code(tar.gz)
    Source code(zip)
  • 2.4.1(Jun 21, 2020)

  • 2.4.0(Jun 21, 2020)

  • 2.3.0(Jun 21, 2020)

    This release focuses on filling the remaining gaps in the API.

    • Constraints type now conforms to Collection protocol (backed by Array)
    • Add Constraints activate() and deactivate() methods
    • Add clamp(to limit: ClosedRange<CGFloat>) API for dimension anchors
    • Add default insets argument for AnchorCollectionEdges equal method
    • Replace the target parameter of AnchorCollectionEdges equal method with LayoutItem
    • Add AnchorCollectionEdges variant that works with CGFloat
    • Add AnchorCollectionEdges lessThatOrEqual() method
    • Fix AnchorCollectionCenter lessThatOrEqual() method
    • Replace the target parameter of AnchorCollectionCenter method with LayoutItem
    • Performance optimizations
    Source code(tar.gz)
    Source code(zip)
  • 2.2.1(Jun 18, 2020)

  • 2.2.0(Jun 18, 2020)

  • 2.1.0(Jun 18, 2020)

    Use Migraiton Guide included in the repo to ease migration.

    • Remove all deprecated APIs. If you are migrating from the previous version, consider migrating to version 2.0.0 first. It is going to guide you throught the migration.
    Source code(tar.gz)
    Source code(zip)
  • 2.0.0(Jun 18, 2020)

    Use Migraiton Guide included in the repo to ease migration.

    • Add macOS support
    • Add new low-level APIs: equal, greaterThanOrEqual, lessThatOrEqual
    • Add spacing() method for alignments
    • Rename uncler .al to .anchors
    • Remove .al version accepting closure
    • Add constraints property to Constraints type to allow access to all of the constraints created using it
    • Add activate parameter to Constraints initiliazer to optionally disable automatic activation of constraints
    • Deprecated func edges(_ edges: LayoutEdge...), use pin(axis:) insteads
    • pin() methods now use .leading and .trailing anchors intead of absolute .left and .right anchors. To switch to absolute anchors, use absolute(): view.anchors.edges.absolute()
    • Remove addSubview family of APIs
    • Migrate to Swift 5.1
    • Increase minimum required platform versions
    Source code(tar.gz)
    Source code(zip)
  • 1.2.1(Sep 1, 2019)

  • 1.2(Jun 20, 2019)

  • 1.1(Apr 7, 2019)

  • 1.0(Oct 2, 2018)

  • 0.6(May 21, 2018)

    A minor update to make Align a bit more ergonomic.

    • Add iOS 9 and tvOS 9 compatibility (used to require iOS 10 and tvOS 10).
    • Add operators for setting multipliers: view.height.match(view.width * 2).
    • Deprecated align(with:...) and match(:...) methods which had offset and multiplier parameters. Operators are the preferred way to set those (more compact and more obvious what they mean).
    • Move phantom types (e.g. AnchorAxisVertical) into namespaces to reduce clutter in a global namespace.
    Source code(tar.gz)
    Source code(zip)
  • 0.5.1(Mar 2, 2018)

  • 0.5(Jan 10, 2018)

  • 0.4(Dec 29, 2017)

    • pinToSuperviewMargins methods now use margin attributes (e.g. .topMargin) and not layoutMarginsGuide to workaround issues on iOS 10 where layout guides are unpredictable https://stackoverflow.com/questions/32694124/auto-layout-layoutmarginsguide
    • Add pinToSafeArea(of:) family of methods which use safeAreaLayoutGuide on iOS 11 and fall back to topLayoutGuide and bottomLayoutGuide on iOS 10
    • addSubview methods are no longer generic which allows for more extra flexibility when adding constraints (e.g. you can create and operate on an array of layout proxies)
    Source code(tar.gz)
    Source code(zip)
  • 0.3.1(Nov 18, 2017)

    A small update that focuses on improving offsetting(by:) method.

    • offsetting(by:) method now available for all anchors
    • Add an operator that wraps offsetting(by:) method (which wasn't very convenient to use by itself)
    • [Fix] Offsetting anchor which already has an offset now works correctly
    • Split the project into two files
    Source code(tar.gz)
    Source code(zip)
  • 0.3(Nov 15, 2017)

    • With new addSubview(_:constraints:) method you define a view hierarchy and layout views at the same time. It encourages splitting layout code into logical blocks and prevents programmer errors (e.g. trying to add constraints to views not in view hierarchy).

    • Remove standalone fillSuperview(..) and centerInSuperview() family of functions. There were multiple cons of having them (e.g. more terminology to learn, hard to document and explain, inconsistent with center and size manipulations, were not allowing to pin in a corner).

    Now you can manipulate multiple edges at the same time instead:

    view.addSubview(stack) {
        $0.edges.pinToSuperview() // pins the edges to fill the superview
        $0.edges.pinToSuperview(insets: Insets(10)) // with insets
        $0.edges.pinToSuperviewMargins() // or margins
    
        $0.edges(.left, .right).pinToSuperview() // fill along horizontal axis
        $0.centerY.alignWithSuperview() // center along vertical axis
    }
    

    This is a much simpler model which removes entire layer of standalone methods available on LayoutItems. Now you always select either an anchor or collections of anchors, then use their methods to add constraints. Much simpler.

    • Make LayoutProxy's base public to enable adding custom extensions on top of it.
    Source code(tar.gz)
    Source code(zip)
  • 0.2(Nov 13, 2017)

  • 0.1.1(Nov 9, 2017)

  • 0.1(Nov 9, 2017)

Owner
Alexander Grebenyuk
I write kean.blog and like porridge
Alexander Grebenyuk
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
⚓️ 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
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
Auto Layout made easy with the Custom Layout.

Auto Layout made easy with the Custom Layout. Getting started CocoaPods CocoaPods is a dependency manager for Cocoa projects. You can install it with

Malith Nadeeshan 1 Jan 16, 2022
FlexLayout adds a nice Swift interface to the highly optimized facebook/yoga flexbox implementation. Concise, intuitive & chainable syntax.

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

layoutBox 1.7k Dec 30, 2022
SuperLayout is a Swift library that makes using Auto Layout a breeze.

SuperLayout is a library that adds a few custom operators to Swift that makes using the amazing NSLayoutAnchor API for Auto Layout a breeze. SuperLayo

Lionheart Software 53 Oct 12, 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
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
Declarative Auto Layout in Swift, clean and simple

Tails Tails is a take on declarative Auto Layout. If you don't like typing (like me), it might be your kind of thing! Tails is written in Swift and cu

Nick Tymchenko 17 Jan 31, 2019
Fast Swift Views layouting without auto layout. No magic, pure code, full control and blazing fast

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]

layoutBox 2.1k Jan 2, 2023