LayoutKit is a fast view layout library for iOS, macOS, and tvOS.

Overview

🚨 UNMAINTAINED 🚨

This project is no longer used by LinkedIn and is currently unmaintained.

LayoutKit

CocoaPods GitHub release Build Status codecov

LayoutKit is a fast view layout library for iOS, macOS, and tvOS.

Motivation

LinkedIn created LayoutKit because we have found that Auto Layout is not performant enough for complicated view hierarchies in scrollable views. For more background, read the blog post.

Benefits

LayoutKit has many benefits over using Auto Layout:

  • Fast: LayoutKit is as fast as manual layout code and is significantly faster than Auto Layout.
  • Asynchronous: Layouts can be computed in a background thread so user interactions are not interrupted.
  • Declarative: Layouts are declared with immutable data structures. This makes layout code easier to develop, document, code review, test, debug, profile, and maintain.
  • Cacheable: Layout results are immutable data structures so they can be precomputed in the background and cached to increase user perceived performance.

LayoutKit also provides benefits that make it as easy to use as Auto Layout:

  • UIKit friendly: LayoutKit produces UIViews and also provides an adapter that makes it easy to use with UITableView and UICollectionView.
  • Internationalization: LayoutKit automatically adjusts view frames for right-to-left languages.
  • Swift: LayoutKit can be used in Swift applications and playgrounds.
  • Tested and production ready: LayoutKit is covered by unit tests and is being used inside of recent versions of the LinkedIn and LinkedIn Job Search iOS apps.
  • Open-source: Not a black box like Auto Layout.
  • Apache License (v2): Your lawyers will be happy that there are no patent shenanigans.

Hello world

let image = SizeLayout<UIImageView>(width: 50, height: 50, config: { imageView in
    imageView.image = UIImage(named: "earth.jpg")
})

let label = LabelLayout(text: "Hello World!", alignment: .center)

let stack = StackLayout(
    axis: .horizontal,
    spacing: 4,
    sublayouts: [image, label])

let insets = UIEdgeInsets(top: 4, left: 4, bottom: 4, right: 8)
let helloWorld = InsetLayout(insets: insets, sublayout: stack)
helloWorld.arrangement().makeViews(in: rootView)

Hello world example layout

Limitations

We have found LayoutKit to be a useful tool, but you should be aware of what it is not.

  • LayoutKit is not a constraint based layout system. If you wish to express a constraint between views, then those views need to be children of a single layout that implements code to enforce that constraint.
  • LayoutKit is not flexbox, but you may find similarities.

Installation

LayoutKit can be installed with CocoaPods or Carthage.

CocoaPods

Add this to your Podspec:

pod 'LayoutKit'

Then run pod install.

Carthage

Add this to your Cartfile:

github "linkedin/LayoutKit"

Then run carthage update.

Documentation

Now you are ready to start building UI.

Comments
  • Remove shared example layouts scheme so as not to be built by carthage

    Remove shared example layouts scheme so as not to be built by carthage

    @nicksnyder I would like to remove ExampleLayouts from the shared schemes, since it builds when you specify LayoutKit as a Carthage dependency, which is undesirable as it takes additional build time.

    If we are to have LayoutKit, which is swift-based, as a dependency, when building on ci without a pre-built artifact, we would like to minimize the build time for swift dependencies.

    Swift dependencies can't really be stored as pre-built artifacts AFAIK due to the lack of ABI stability.

    enhancement 
    opened by stowy 14
  • BatchUpdates reloadItems has slow performance

    BatchUpdates reloadItems has slow performance

    I have built a horizontally scrolling control that uses a fixed number of fixed-size cells using LayoutKit. When the user taps a cell, I'd like to reload the previously selected cell and the newly selected cell in order to move the selection indicator. I attempted to do this by using BatchUpdates and setting the reloadItems property, but the performance is very slow.

    Once I build BatchUpdates, I call layoutAdapter.reload() with a fixed width and height, passing in the BatchUpdates I just built, and returning a cached array of Layout items to the layoutProvider (with the 2 indexPaths already rebuilt and updated in the cache).

    To work around this, I've instead just fetched each cell manually (cellForItemAtIndexPath), built the new layout, and arranged/made in the cell.contentView. This shows much faster performance. What's the intended use of BatchUpdates, and is there a way to get better performance out of it?

    defect question needs clarification 
    opened by stephensilber 14
  • Swift 3 branch without any API changes

    Swift 3 branch without any API changes

    Hello, LayoutKit is awesome, but I would like to develop apps with Swift 3, unfortunately LayoutKit has no Swift 3 support yet, so I create a new branch for that reason. It's migrated by Xcode 8 beta, I don't touch any API names but I'm not sure if the migrations affect the API names, and fix some un-migratable errors manualy.

    opened by cxa 10
  • ReloadableViewLayoutAdapter batchUpdates animation style

    ReloadableViewLayoutAdapter batchUpdates animation style

    Hi. I am finding ReloadableViewLayoutAdapter quite useful, but most of the methods are not open making it hard to use it for anything but the simplest of cases. Is there any reason for this?

    For example, I need to change UITableView batchUpdates animation style. Method public func perform(batchUpdates: BatchUpdates) in extension UITableView: ReloadableView uses .automatic and cannot be overridden.

    open func reload<T: Collection, U: Collection> in ReloadableViewLayoutAdapter is open but var currentArrangement is internal(set) because of which it is needed to call super. reload. As such it is not possible custom reload and call custom batchUpdates.

    I ended up implementing custom ReloadableViewLayoutAdapter. Any better ideas? Would it be possible to make open some of the methods?

    enhancement 
    opened by Rep2 8
  • LayoutKit CI build is broken

    LayoutKit CI build is broken

    As of https://github.com/linkedin/LayoutKit/pull/132/files#diff-0b83f9dedf40d7356e5ca147a077acb4 the build script that runs on Travis no longer builds or runs tests for the main LayoutKit target.

    Before (tests run): https://travis-ci.org/linkedin/LayoutKit/builds/223716700 After (no tests run): https://travis-ci.org/linkedin/LayoutKit/builds/225308216 Current (no tests run): https://travis-ci.org/linkedin/LayoutKit/builds/225442466

    The build script used to be a chain of commands linked with && so that any failure would cause the whole script to fail. As it is now, the first command fails, but the next two commands still run and the build script (erroneously) passes.

    Please do not merge or commit any more changes to master until this is fixed.

    defect 
    opened by nicksnyder 7
  • Should the config block execute at last?

    Should the config block execute at last?

    For instance: https://github.com/linkedin/LayoutKit/blob/master/LayoutKit/Layouts/LabelLayout.swift#L129-L137

    Sometimes I want to change some property when configuration, it will be override by the initial setup.

    Should the config block execute after initial setup will be better?

    question 
    opened by RoCry 7
  • Clips to bounds is not respected

    Clips to bounds is not respected

    I'm trying to add a drop shadow to a view spawned from an inset layout. In the config handler, I'm setting:

            view.layer.shadowColor = kShadowColor
            view.layer.shadowRadius = kShadowRadius
            view.layer.shadowOffset = kShadowOffset
            view.layer.masksToBounds = false
            view.clipsToBounds = false
    

    But the shadow is not showing up. If I set the border color, however, that appears to work fine. What's going on here?

    question 
    opened by AttilaTheFun 6
  • UIButton Layout

    UIButton Layout

    Hey there Is there something equivalent to LabelLayout for views such as UIButton (or any other view that define an intrinsicContentSize)?

    Right now I am using a SizeLayout but I am forced to define the size of my button

    SizeLayout<UIButton>(
      width: 100, height: 50,
      alignment: .centerTrailing,
      flexibility: .flexible,
      config: { button in
        button.backgroundColor = UIColor.blue
        button.setTitle("Button", for: .normal)
        button.setTitleColor(.black, for: .normal)
      }
    )
    
    screen shot 2016-10-13 at 3 19 47 pm enhancement 
    opened by pgherveou 6
  • Make LayoutKit extension safe

    Make LayoutKit extension safe

    This line is not compatible with today extension. https://github.com/linkedin/LayoutKit/blob/master/LayoutKit/LayoutArrangement.swift#L105

    Could this get checked like http://stackoverflow.com/questions/29246656/ios-sharedapplication-is-unavailable-in-today-extension to add support for extensions as well?

    enhancement 
    opened by FabianTerhorst 6
  • Adding an Objective-C compatible API to LayoutKit

    Adding an Objective-C compatible API to LayoutKit

    This is related to issue #178 regarding adding support for Objective-C consumers. This objc-api branch is now ready for review.

    Two of the open questions are:

    1. How do we make these long initializers more convenient for use from Objective-C? I have several options in mind.
    2. Should we make these new classes unavailable from Swift somehow? My understanding is that there's a way to use pods to exclude some directories at import time?

    The builders for (1) can be added as a separate follow-up change. Currently working on figuring out what we can do for (2).

    opened by staguer 5
  • Fix StackLayout fillEqualSpacing distribution with spacing

    Fix StackLayout fillEqualSpacing distribution with spacing

    Updates StackLayout.distributionConfig and calculates the axisSpacing taking into account the spaces that were already added during the measurement phase. Actual excessAxisLength for .fillEqualSpacing is increased by numberOfSpaces * spacing so it can be redistrubuted.

    See issue https://github.com/linkedin/LayoutKit/issues/159

    opened by domasn 5
  • Update ButtonLayout sizeOf(image:) for iOS13+

    Update ButtonLayout sizeOf(image:) for iOS13+

    iOS13+ has different CGSize for some button types: .contactAdd, .infoLight, .infoDark, .detailDisclosure

    Tests were failing when testing with simulators iOS13+

    opened by robinbonin 0
  • Remove UIView.init() is called in outside of the main thread

    Remove UIView.init() is called in outside of the main thread

    In class LabelLayoutDefaults, UILabel.init() is called on static stored property declaration. This leads [UIView init] must be used from main thread only warning on Xcode. Moreover, it breaks on runtime some cases (e.g. XCUITest tests layout built with using LabelLayout)

    This PR fixes this problem.

    image

    opened by getogrand 0
  • Make the designated initializers with a viewClass argument public

    Make the designated initializers with a viewClass argument public

    Hi there,

    Is there any reason why the initializers, containing the viewClass argument, are marked internal? It would be extremely useful if they were exposed as public.

    Reason: Let's say for example you want to define a SizeLayout and you want to determine what UITextField.Type you want to use at runtime, the current public initializers for SizeLayout prevents you from doing so.

    func createSizeLayout<T: UITextField>(type: T.Type) -> SizeLayout<T> {
        .... logic for creation here ...
    }
    
    let textFieldLayout = createSizeLayout(type: YourCustomTextField.self) // this inferred as SizeLayout<UITextField> 
    
    // if you follow the initialization steps, the used initializer in BaseLayout is:
    public init(alignment: Alignment, flexibility: Flexibility, viewReuseId: String? = nil, config: ((V) -> Void)?) {
        self.alignment = alignment
        self.flexibility = flexibility
        self.viewReuseId = viewReuseId
        self.viewClass = V.self
        self.config = config
    }
    
    // instead of:
    init(alignment: Alignment, flexibility: Flexibility, viewReuseId: String? = nil, viewClass: V.Type, config: ((V) -> Void)?) {
        self.alignment = alignment
        self.flexibility = flexibility
        self.viewReuseId = viewReuseId
        self.viewClass = viewClass
        self.config = config
    }
    

    Using the latter will still yield an inferred type of SizeLayout<UITextField> BUT if you set breakpoints in the config closure it will be a YourCustomTextField instance.

    opened by hooliooo 0
  • Update SwiftPM manifest to work with Accio

    Update SwiftPM manifest to work with Accio

    This updates support for SwiftPM manifest based dependency managers. Specifically this adds support for installing via Accio but will probably also work with SwiftPM once it's integrated into Xcode.

    Please note that this project is part of Accio's official integration tests within the Demo project.

    opened by Jeehut 0
Releases(10.1.0)
  • 10.1.0(Jan 30, 2019)

    Adding support for nested view trees that are produced by different makeViews calls. (One example is a collection view that is created by calling makeViews on a Layout object and its cells that are also similarly populated from their own specific Layout objects.)

    Source code(tar.gz)
    Source code(zip)
  • 10.0.1(Oct 16, 2018)

    Bugfix version fixes handling of flexibility on Overlay and Inset layouts.

    • OverlayLayout now has an optional flexibility parameter, and defaults to the flexibility of the first primary layout.
    • InsetLayout now has an optional flexibility parameter, and the corresponding builder’s flexibility parameter is now hooked up whereas it had no effect before.
    Source code(tar.gz)
    Source code(zip)
  • 10.0.0(Oct 5, 2018)

    • On OverlayLayout the primary layout parameter is now an array of layouts rather than a single layout.
    • The view recycling mechanism in the makeViews method now resets the transform and anchorPoint for recycled views before handing them off to client code for configuration.
    • Minor warnings and playgrounds fixes.
    Source code(tar.gz)
    Source code(zip)
  • 9.0.0(Aug 7, 2018)

    Major change in this release is that LayoutKit now builds cleanly with Swift 4.1 (Xcode 9.3).

    For the Objective-C side, the configureView: method on the LOKLayout protocol is no longer optional. It is valid to provide an empty implementation if it is legitimately not needed for a particular layout implementation.

    Source code(tar.gz)
    Source code(zip)
  • 8.0.2(Jul 18, 2018)

    Exposing a few more APIs to Objective-C that previously were available to Swift only.

    • UserInterfaceLayoutDirection parameter added to LOKLayoutArrangement makeViews method
    • on LOKBaseLayout making needsView and configure open for overriding
    • adding horizontallyHighlyFlexible to LOKFlexibility
    Source code(tar.gz)
    Source code(zip)
  • 8.0.1(Jun 12, 2018)

    Added initializers to the ObjC builders in addition to their static methods. This change allows people to subclass these builders, which previously was not possible.

    Source code(tar.gz)
    Source code(zip)
  • 8.0.0(Jun 6, 2018)

    If you use this library from Swift, there are no changes!

    There are no changes to the Swift version of the library. The changes in this release are breaking changes to the builder objects created for Objective-C compatibility. We have changed those builders so that the chainable block properties no longer have the with prefix. Also, the properties that you could also set directly are now private so that the chainable way is the only way available now.

    Source code(tar.gz)
    Source code(zip)
  • 7.0.3(Apr 23, 2018)

    The Objective C layout wrapper builder classes now support a more succinct syntax for initializing layouts. Getting a bit closer to the convenient default parameter values we have in Swift.

    Also adding Objective C wrappers for the animation support API and for flexibility values that are flexible only on one of the horizontal or vertical axis.

    Source code(tar.gz)
    Source code(zip)
  • 7.0.1(Mar 5, 2018)

    Some fixes for the Objective-C wrappers:

    • For LOKReloadableViewLayoutAdapter, adding batch update support.
    • For LOKSizeLayout, adding a configure block parameter.
    • For LOKFlexibility, making its values public.
    • Making Objective-C API wrapper classes open for subclassing.
    Source code(tar.gz)
    Source code(zip)
  • 7.0.0(Feb 15, 2018)

    Adding an Objective-C compatible API.

    This API is in the new LayoutKitObjC pod and not in the pre-existing pod.

    Also, adding a lineHeight parameter to LabelLayout to support custom line heights for line limit height calculation according to the numberOfLines parameter.

    Source code(tar.gz)
    Source code(zip)
  • 6.0.0(Oct 11, 2017)

    • Swift 4 Migration
    • Use max size for measuring overlay sublayouts
    • Incremental update is changed to use chunking
    • Fix StackLayout fillEqualSpacing distribution with spacing
    • Fixing async issue on completion callback for perform batch updates
    • Fix to make custom view for UITableViewHeaderFooterView in its contentView
    • Allow isSelectable to be overridden in TextViewLayout Configure
    Source code(tar.gz)
    Source code(zip)
  • 5.0.0(Jul 19, 2017)

    Added TextViewLayout and OverlayLayout.

    Swift 3.1 and Xcode 8.3 support.

    Open ReloadableViewLayoutAdapter for extension.

    Open ReloadableView and BatchUpdates for extension.

    BatchUpdates becomes a class. (BatchUpdates changing from struct to class is technically a breaking change, hence the major version increment.)

    Source code(tar.gz)
    Source code(zip)
  • 4.0.2(Mar 31, 2017)

  • 4.0.1(Jan 12, 2017)

    View recycling no longer removes views that it didn't create (#85 @inamiy)

    It is now possible to override registerViews on ReloadableView to use custom UICollectionViewCell/UITableViewCell with ReloadableViewLayoutAdapter (#86)

    Source code(tar.gz)
    Source code(zip)
  • 4.0.0(Nov 24, 2016)

    This release contains some new features and backward incompatible changes.

    Features

    • New ButtonLayout for UIButton. Please read the class documentation before using.
    • Layouts now support views whose initializers require arguments (i.e. UIButton).
    • BatchUpdates now supports reloading sections and items (thanks @RoCry).

    Backward incompatible changes

    • LabelLayoutTextType renamed to Text now that it is shared with ButtonLayout.
    • LabelLayout initializer parameter textType renamed to text.
    • needsView was moved from ConfigurableLayout to Layout.
    • func makeView(from recycler: ViewRecycler) -> View? changed to func makeView() -> View. LayoutKit now handles view recycling internally and only calls makeView() if needsView is true.
    • ViewRecycler is no longer public (it doesn't need to be anymore).

    Behavior changes

    • A non-nil viewReuseId no longer forces a Layout to generate a view. If you want to force a Layout to generate a view when it otherwise wouldn't, provide a configuration block (which may be empty).
    • Subview order is now deterministic and matches what you would expect.

    Other LayoutKitExampleLayouts target renamed to ExampleLayouts so that it isn't inadvertently pulled in by Carthage. ExampleLayouts is for experimentation and not part of the supported or documented public API of LayoutKit.

    Source code(tar.gz)
    Source code(zip)
  • 3.1.0(Oct 26, 2016)

  • 3.0.1(Oct 18, 2016)

  • 3.0.0(Sep 19, 2016)

  • 2.1.0(Sep 12, 2016)

  • 2.0.1(Aug 24, 2016)

  • 2.0.0(Aug 22, 2016)

    This release contains new features and backwards incompatible API changes.

    Features

    LayoutKit now supports:

    • Animating between two different layouts (documentation)
    • macOS and tvOS
    • min/max height/width constraints on SizeLayout
    • Incremental updates with ReloadableViewLayoutAdapter

    Backward incompatible changes

    • All base layout now expose a generic view parameter, similar to SizeLayout in 1.x.

      InsetLayout<V: UIView>
      LabelLayout<L: UILabel>
      SizeLayout<V: UIView>
      StackLayout<V: UIView>
      

      Subclasses of these layouts should use this generic parameter to customize the view created instead of overriding makeView.

    • Due to generic parameters, some nested types needed to be renamed

      StackLayout.Distribution -> StackLayoutDistribution
      LabelLayout.TextType -> LabelLayoutTextType
      
    • New ConfigurableLayout protocol that all custom layouts should implement (instead of just Layout).

    • Layout protocol's makeView function now requires a viewRecycler parameter to support animations. ConfigurableLayout provides an implementation for this method.

    • Layout protocol now requires a configure method. Previously creating a view and configuring it happened in makeView but now it has been split into two functions. ConfigurableLayout provides an implementation for this method.

    • Layout protocol now requires a viewReuseId to help with animations and view reuse.

    • PositioningLayout is now BaseLayout

    • LayoutAxis renamed to Axis

    • Certain APIs have been updated to be consistent with Swift 3 style guidelines

      makeViews(inView view: UIView) -> makeViews(in view: UIView)
      position(size size: CGSize, inRect rect: CGRect) -> position(size size: CGSize, in rect: CGRect)
      
    • There are some new shim types to help support multiple platforms

      View -> UIView or NSView
      Application -> UIApplication or NSApplication
      EdgeInsets -> UIEdgeInsets or NSEdgeInsets
      etc
      
    Source code(tar.gz)
    Source code(zip)
  • 1.1.0(Jun 23, 2016)

  • 1.0.0(Jun 23, 2016)

Owner
LinkedIn's Attic
The OSS projects that LinkedIn no longer maintains live here.
LinkedIn's Attic
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
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
BrickKit is a delightful layout library for iOS and tvOS. It is written entirely in Swift!

BrickKit is a delightful layout library for iOS and tvOS. It is written entirely in Swift! Deprecated BrickKit is being phased out at Wayfair, and the

Wayfair Tech – Archive 608 Sep 15, 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
AppStoreClone - Understanding the complex layout of app store using UICompositional layout in swift

AppStoreClone Understanding the complex layout of app store using UICompositiona

Dheeraj Kumar Sharma 8 Dec 28, 2022
A custom layout built on top of SwiftUI's Layout API that lays elements out in multiple lines. Similar to flex-wrap in CSS, CollectionViewFlowLayout.

WrapLayout A custom layout built on top of SwiftUI's Layout API that lays elements out in multiple lines. Similar to flex-wrap in CSS, CollectionViewF

Hiroshi Kimura 6 Sep 27, 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
MyLayout is a simple and easy objective-c framework for iOS view layout

MyLayout is a powerful iOS UI framework implemented by Objective-C. It integrates the functions with Android Layout,iOS AutoLayout,SizeClass, HTML CSS float and flexbox and bootstrap. So you can use LinearLayout,RelativeLayout,FrameLayout,TableLayout,FlowLayout,FloatLayout,PathLayout,GridLayout,LayoutSizeClass to build your App 自动布局 UIView UITableView UICollectionView RTL

欧阳大哥2013 4.2k Dec 30, 2022
Flow layout / tag cloud / collection view in SwiftUI.

SwiftUIFlowLayout A Flow Layout is a container that orders its views sequentially, breaking into a new "line" according to the available width of the

Gordan Glavaš 115 Dec 28, 2022
Programmatic view layout for the rest of us.

Façade Important Facade is no longer under active development, and as such if you create any issues or submit pull requests, it's not very likely to b

Mike 696 Aug 3, 2022
A Code challenge I solved leveraging a lot on Composite collection view layout written in swift

AsthmApp Mobile app designed as a support aid for people with Asthma Accounts Google and Firebase [email protected] dICerytiMPSI Facebook asthmp.ap

null 0 Dec 13, 2021
A Code challenge I solved leveraging a lot on Composite collection view layout...written in swift

Space44 Code Challenge Space44 Code Challenge iOS application for Space 44 hiring process, it leverages on Image download and composite collection vie

null 0 Dec 16, 2021
A flexible collection view with proper horizontal layout flow

FlexCollection A very simple flexible collection view using SwiftUI that automat

null 1 Dec 29, 2021
A grid layout view for SwiftUI

Update July 2020 - latest SwiftUI now has built-in components to do this, which should be used instead. FlowStack FlowStack is a SwiftUI component for

John Susek 147 Nov 10, 2022
✂ Easy to use and flexible library for manually laying out views and layers for iOS and tvOS. Supports AsyncDisplayKit.

ManualLayout Table of Contents Installation Usage API Cheat Sheet Installation Carthage Add the following line to your Cartfile. github "isair/ManualL

Baris Sencan 280 Sep 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
FrameLayoutKit is a super fast and easy to use autolayout kit

FrameLayoutKit FrameLayout is a super fast and easy to use layout library for iOS and tvOS. For Objective-C version: NKFrameLayoutKit (Deprecated, not

Nam Kennic 57 Jun 24, 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