TinyConstraints is the syntactic sugar that makes Auto Layout sweeter for human use.

Overview

TinyConstraints is the syntactic sugar that makes Auto Layout sweeter for human use.

TinyConstraints TinyConstraints

Features

  • Pure Swift 5 sweetness.
  • Everything you can do with Auto Layout, but shorter.
  • Constraints are active by default.
  • 100% compatible with other Auto Layout code.
  • Optionally store your constraints.
  • Set constraint priorities upon creation.
  • Constrain directly to the superview.
  • Stack views together with one line of code.
  • No need to set translatesAutoresizingMaskIntoConstraints because TinyConstraints does it for you.

Examples

Edges

Attaching a view to its superview with NSLayoutConstraint:

NSLayoutConstraint.activate([
    view.topAnchor.constraint(equalTo: superview.topAnchor, constant: 0),
    view.leadingAnchor.constraint(equalTo: superview.leadingAnchor, constant: 0),
    view.bottomAnchor.constraint(equalTo: superview.bottomAnchor, constant: 0),
    view.trailingAnchor.constraint(equalTo: superview.trailingAnchor, constant: 0)
])

with TinyConstraints:

view.edgesToSuperview()

or:

view.edgesToSuperview(insets: .top(10) + .left(10))

Center

Constraining the center of a view to its superview with NSLayoutConstraint:

NSLayoutConstraint.activate([
    view.centerXAnchor.constraint(equalTo: superview.centerXAnchor, constant: 0)
    view.centerYAnchor.constraint(equalTo: superview.centerYAnchor, constant: 0)
])

with TinyConstraints:

view.center(in: superview)

or:

view.center(in: superview, offset: CGPoint(x: 10, y: 10))

Basic Use

Typealiases

TinyConstraints gives you convenient and tiny typealiases for handling constraints.

  • Constraint = NSLayoutConstraint
  • Constraints = [NSLayoutConstraint]

Equal and Unequal Anchors

This constraints the top-anchor of the view to the top-anchor of the superview:

view.top(to: superview)

This constraints the top-anchor of firstView to the bottom-anchor of secondView:

firstView.topToBottom(of: secondView)

Constrain to Superview

Often you need to constrain a view to it's superview, with TinyConstraints you can do this super easy:

view.edgesToSuperview()

Or only one edge:

view.topToSuperview()

Or you can attach all edges except one, like this:

view.edgesToSuperview(excluding: .bottom)

Relation and Priority

For almost all constraints you can set the relation and priority properties. The default relation is .equal and the default priority is .required:

container.width(150, relation: .equalOrLess, priority: .high)

Storing Constraints

Here we create a set of inactive constraints and store these to our property:

let constraints = view.size(CGSize(width: 100, height: 100), isActive: false)

Activation and Deactivation

Besides the default NSLayoutConstraint activation, TinyConstraints also provides a way to activate a set of constraints:

constraints.activate()

You can also do this in an animation:

oldConstraints.deActivate()

constraints.activate()
UIViewPropertyAnimator(duration: 1, dampingRatio: 0.4) {
    self.layoutIfNeeded()
}.startAnimation()

Animating Constraint Constants

Here we add a height constraint to a view, store it and animate it later:

let height = view.height(100)

height.constant = 200
UIViewPropertyAnimator(duration: 1, dampingRatio: 0.4) {
    self.layoutIfNeeded()
}.startAnimation()

Stack

Stack provides a way of constraining views together in a superview:

let views = [logo, title, description]
superview.stack(views, axis: .vertical, spacing: 10)
Find these examples and more in the Example Project.

Installation

CocoaPods

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

pod "TinyConstraints"

Carthage

TinyConstraints is available through Carthage. To install it, simply add the following line to your Cartfile:

github "roberthein/TinyConstraints"

Swift Package Manager

TinyConstraints is available through Swift Package Manager. To install it, in Xcode 11.0 or later select File > Swift Packages > Add Package Dependency... and add TinyConstraints repository URL:

https://github.com/roberthein/TinyConstraints.git

Tutorials

Here are some video tutorials made by Alex Nagy.

Suggestions or feedback?

Feel free to create a pull request, open an issue or find me on Twitter.

Comments
  • Not an issue but a question

    Not an issue but a question

    Hello!

    I could not find another way of contacting you so I had to create an issue... I just have a quick newbie question:

    How do I, for example, set top and bottom alignment of a button to another button? It seems to be quite easy in IB, but whenever I say, for example button.top (to: anotherButton), Xcode crashes with finding nil while unwrapping an optional value.

    I add those constraints to UIButton after I added it into my subview. I know I am missing something out but I cannot quite get what. Here is an example of my code:

        cancelButton = UIButton(frame: CGRect(x: 10.0, y: 10.0, width: 50.0, height: 50.0))
        cancelButton.layer.shadowOpacity = 0.7
        cancelButton.layer.shadowOffset = CGSize(width: 0.0, height: 0.0)
        cancelButton.layer.shadowRadius = 5.0
        cancelButton.showsTouchWhenHighlighted = true
        cancelButton.setImage(#imageLiteral(resourceName: "Close"), for: UIControlState())
        cancelButton.addTarget(self, action: #selector(cancel), for: .touchUpInside)
        view.addSubview(cancelButton)
    
        cancelButton.height(50)
        cancelButton.width(50)
        cancelButton.leading(to: saveButton)
        
        saveButton = UIButton (frame: CGRect(x: 10.0, y: 506.0, width: 50, height: 50))
        saveButton.layer.shadowOpacity = 0.7
        saveButton.layer.shadowOffset = CGSize(width: 0.0, height: 0.0)
        saveButton.layer.shadowRadius = 5.0
        saveButton.showsTouchWhenHighlighted = true
        saveButton.setImage(#imageLiteral(resourceName: "Save"), for: UIControlState())
        saveButton.addTarget(self, action: #selector(save), for: .touchUpInside)
        view.addSubview(saveButton)
        
        saveButton.height(50)
        saveButton.width(50)
        saveButton.edges(to: cancelButton)`
    
    opened by Andriyas123 9
  • Feature request: stack views of different size

    Feature request: stack views of different size

    In my case I have 3 views placed in vertical order. The problem is it is enough hard to setup them because the are all different but must fill the whole space given to them with predefined height proportion.

    opened by gerchicov-bp 8
  • Improving view.edgesToSuperview(excluding:)

    Improving view.edgesToSuperview(excluding:)

    A very common case is when a view is stretched horizontally in superview, but top and bottom are tied to sibling views. E.g.

            // stretching horizontally
            myView.leadingToSuperview()
            myView.trailingToSuperview()
            myView.topToBottom(of: sibling1)
            myView.bottomToTop(of: sibling2)
            
            // stretching vertically
            myView.topToSuperview()
            myView.bottomToSuperview()
            myView.leadingToTrailing(of: sibling1)
            myView.trailingToLeading(of: sibling2)
    

    It would be very cool to have a method like stretchHorizontallyInSuperview() and stretchVerticallyInSuperview because this operation is very frequent.

    But while these methods are desirable, one of the side ways we can implement it is by improving edgesToSuperview(excluding:) by making LayoutEdge conform to OptionSetType, so that we could do something like this

            // stretching horizontally
            myView.edgesToSuperview(excluding: [.top, .bottom])
            myView.topToBottom(of: sibling1)
            myView.bottomToTop(of: sibling2)
            
            // stretching vertically
            myView.edgesToSuperview(excluding: [.leading, .trailing])
            myView.leadingToTrailing(of: sibling1)
            myView.trailingToLeading(of: sibling2)
    

    While this is a very tiny improvement, I feel like it would still be needed for this great library.

    opened by xinatanil 6
  • Arbitrary ConstraintPriority?

    Arbitrary ConstraintPriority?

    What is the purpose of ConstraintPriority, meaning why it exists? It's used in all the methods but is limited to a handful of values which is really limiting. I often need to use values like 999 to resolve issues when container is temporary smaller than content (but will be fine at the end of the animation).

    For example, this is impossible:

    v.edges(to: pv, priority: ConstraintPriority(rawValue: UILayoutPriority(999))!)
    
    opened by radianttap 6
  • Improve code completion for constraints that need offsets and insets

    Improve code completion for constraints that need offsets and insets

    TinyConstraints is using a lot of methods with default parameters, unfortunately Xcode's code completion follows an all or nothing approach; it either shows the method with all the default parameters, or the method without any defaults, not the in between ones.

    Current behavior Because of this, creating a constraint that needs an offset is a bit tedious: current code completion

    Desired behavior It would be nice and faster if there would be code completions available that include the offsets and insets: preferred code completion

    How to approach this To make sure, the right code completions become available, you'd have to add some convenience methods for the completions you'd like to support. I've been doing this extensively for the public api of Zoomy.

    opened by lvnkmn 4
  • Unexpected layouting problem once using with UICollectionViewCell

    Unexpected layouting problem once using with UICollectionViewCell

    When I used NSLayoutAnchor to fit any view(named, myview) to contentView of UICollectionViewCell by using edges method like the following, myview is not resized but contentView is actually resized to fit to myview.

    cell.contentView.addSubview(myview)
    myview.edges(to: cell.contentView)
    

    As I mention above, I expected that myview has same size of contentView. On the contrary, a size of contentView is affected by a size of myview.

    On the other hand, using NSLayoutConstraint with Visual Format works well.

    Is there anything what I don't know about NSLayoutAnchor?

    opened by fullc0de 4
  • Possibility of Joining Forces

    Possibility of Joining Forces

    Hey all,

    I have been working on a similar constraints library currently called Constraid your friendly constraints aid. We have the same ideals/goals as this project but are a little further along.

    We are definitely early on so are willing shift and adjust the naming of the methods in the API as we come up with better terminology for representing these concepts. Anyways, we have evolved this library after using it in a number of apps.

    Was wondering if you would be interested in possibly joining forces to reduce the noise in the constraints library space, and to focus efforts and energy to try and build an extremely valuable constraints framework?

    https://github.com/uptech/Constraid

    opened by drewdeponte 4
  • Naming suggestion...

    Naming suggestion...

    I like TinyConstraints but the naming makes it a little awkward to discover the methods by stumbling through syntax completion... For an extension like this maybe consider having all of these methods start with a verb prefix like "constrain" or "anchor"? Just a suggestion. Thanks.

    opened by patniemeyer 3
  • Enhancement Request: Add ability to exclude edges when pinning to any constrainable

    Enhancement Request: Add ability to exclude edges when pinning to any constrainable

    Right now, you can do this:

    someView.edgesToSuperview(excluding: .bottom)
    

    And you can do

    someView.edges(to: anotherView.safeAreaLayoutGuide)
    

    But you can't do what I'd like to be able to do, which is:

    someView.edges(to: anotherView.safeAreaLayoutGuide, excluding: .bottom)
    

    Would it be possible to add an optional excluding parameter for any Constrainable.edges(to: call?

    opened by designatednerd 3
  • Weird temp error in Xcode 9 b5

    Weird temp error in Xcode 9 b5

    If you are getting this:

    TinyConstraints/Classes/Constraints.swift:40:33: 
    Raw type 'LayoutPriority' (aka 'UILayoutPriority') is not expressible by any literal
    

    on

    public enum ConstraintPriority: LayoutPriority
    

    then make sure your TinyConstraints CocoaPods target is marked to use Swift 3.2 and not Swift 4 which is default (SWIFT_VERSION in build settings).

    I want my hour back. 😒

    opened by radianttap 3
  • Adding support to ignore the Ascender/Descender in views that display text

    Adding support to ignore the Ascender/Descender in views that display text

    Not really sure how you would like to implement this in the main project, but I wrote an extension that allows you to easily align the top and bottom edges of UILabel and UITextView so that they line up visually with the top/bottom of the text instead of being off a little due to ascender/descender.

    https://pastebin.com/hYum9uLf

    opened by GoldenJoe 3
  • Fails to build for simulator running an Apple Silicon-based Mac

    Fails to build for simulator running an Apple Silicon-based Mac

    Installing TinyConstraints using SPM on an M1 Pro MacBook Pro, Xcode 13.4 - building for any iOS simulator will fail. It works fine on an Intel-based Mac.

    Error:

    Could not find module 'TinyConstraints' for target 'x86_64-apple-ios-simulator'; found: arm64-apple-ios-simulator, at: /Users/will/Library/Developer/Xcode/DerivedData/<APP>/Build/Products/Debug-iphonesimulator/TinyConstraints.swiftmodule
    

    I used to use CocoaPods and having the following in my Podfile worked for TinyConstraints and other pods:

    post_install do |installer|
      installer.pods_project.build_configurations.each do |config|
        config.build_settings["EXCLUDED_ARCHS[sdk=iphonesimulator*]"] = "arm64"
      end
    end
    

    I have tried modifying Universal-Target-Base.xcconfig to add

    EXCLUDED_ARCHS[sdk=iphonesimulator*] = arm64
    

    and/or removing the VALID_ARCHS settings, but to no avail.

    With SPM the only fix I've found is to run Xcode in Rosetta, which really isn't ideal.

    opened by SwiftArtery 2
  • TinyConstraints cannot run in x86_64 simulator on Xcode 12/13 due to VALID_ARCHS built setting

    TinyConstraints cannot run in x86_64 simulator on Xcode 12/13 due to VALID_ARCHS built setting

    e.g. Source.swift:9:8: Could not find module 'TinyConstraints' for target 'arm64-apple-ios-simulator'; found: i386, x86_64-apple-ios-simulator, x86_64, i386-apple-ios-simulator, at: ~Library/Developer/Xcode/DerivedData/APP_BUILD_DIR/Build/Products/Debug-iphonesimulator/TinyConstraints.framework/Modules/TinyConstraints.swiftmodule

    The solution is to remove VALID_ARCHS, which has been deprecated.

    https://developer.apple.com/documentation/xcode-release-notes/xcode-12-release-notes

    The Build Settings editor no longer includes the Valid Architectures build setting (VALID_ARCHS), and its use is discouraged. Instead, there is a new Excluded Architectures build setting (EXCLUDED_ARCHS). If a project includes VALID_ARCHS, the setting is displayed in the User-Defined section of the Build Settings editor. (15145028)

    Patch in #101

    You may also want to remove your custom ENABLE_BITCODE setting, in case it breaks something down the road.

    opened by eliburke 0
  • remove VALID_ARCHS (deprecated since XCode 12 i think)

    remove VALID_ARCHS (deprecated since XCode 12 i think)

    I was unable to run in an x86_64 simulator until removing this build setting.

    https://developer.apple.com/documentation/xcode-release-notes/xcode-12-release-notes

    The Build Settings editor no longer includes the Valid Architectures build setting (VALID_ARCHS), and its use is discouraged. Instead, there is a new Excluded Architectures build setting (EXCLUDED_ARCHS). If a project includes VALID_ARCHS, the setting is displayed in the User-Defined section of the Build Settings editor. (15145028)

    opened by eliburke 0
  • Add activate/deactivate extension for Constraint.

    Add activate/deactivate extension for Constraint.

    Before

    let constraint: Constraint? = view.leadingToSuperview()
    
    ...
    
    if let c = constraint {
        Constraint.deactivate([c])
    }
    

    After

    let constraint: Constraint? = view.leadingToSuperview()
    
    ...
    
    constraint?.deactivate()
    
    opened by kitwtnb 0
  • add a 'dynamic library' product to swift package

    add a 'dynamic library' product to swift package

    Hello!

    I have a project with mulitple frameworks and many of the frameworks use TinyConstraints via Carthage. When trying to migrate to SPM, I bumped into an issue where it always embeds the library in every module, resulting in issues when trying to archive the app and sending to the App Store.

    ERROR ITMS-90685: "CFBundleIdentifier Collision. There is more than one bundle with the CFBundleIdentifier value 'TinyConstraints' under the iOS application '<MyApp>.app'."
    ERROR ITMS-90205: "Invalid Bundle. The bundle at '<MyApp>.app/Frameworks/<MyFramework>.framework' contains disallowed nested bundles."
    ERROR ITMS-90206: "Invalid Bundle. The bundle at '<MyApp>.app/Frameworks/<MyFramework>.framework' contains disallowed file 'Frameworks'."
    

    To solve that I added another product that forces the library to be dynamic. With a dynamic library I have the option to not embed the library in my modules, only in the app target, which solves my problem.

    opened by alephao 1
  • M1 MacBook Air - Not able to locate the module

    M1 MacBook Air - Not able to locate the module

    Any one having issues with TiknyConstraints on ARM chip M1 macbook air?

    App runs fine on an intel chip machine but on the M1 machine, I keep getting the error No such module TinyConstraints (pod install successfully)

    opened by domainxh 0
Releases(2.0.0)
Owner
Robert-Hein Hooijmans
iOS Developer
Robert-Hein Hooijmans
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
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
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
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

Carlos Vidal 1.9k Dec 23, 2022
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
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
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