All Projects → onmyway133 → Easyanchor

onmyway133 / Easyanchor

Licence: other
⚓️ Declarative, extensible, powerful Auto Layout

Programming Languages

swift
15916 projects

Projects that are alternatives of or similar to Easyanchor

Snapkit
A Swift Autolayout DSL for iOS & OS X
Stars: ✭ 18,091 (+4087.73%)
Mutual labels:  autolayout, constraints
Uicollectionview Layouts Kit
📐 A set of custom layouts for UICollectionView with examples [Swift 5.3, iOS 12].
Stars: ✭ 410 (-5.09%)
Mutual labels:  autolayout, constraints
Kvconstraintkit
An Impressive Auto Layout DSL for iOS, tvOS & OSX. & It is written in pure swift.
Stars: ✭ 91 (-78.94%)
Mutual labels:  autolayout, constraints
Easyswiftlayout
Lightweight Swift framework for Apple's Auto-Layout
Stars: ✭ 345 (-20.14%)
Mutual labels:  autolayout, constraints
Driftwood
Driftwood is a DSL to make Auto Layout easy on iOS, tvOS and macOS.
Stars: ✭ 14 (-96.76%)
Mutual labels:  constraints, autolayout
Align
Intuitive and powerful Auto Layout library
Stars: ✭ 261 (-39.58%)
Mutual labels:  autolayout, constraints
Fluid For Sketch
[Sketch Plugin] Sketch-flavored Auto Layout-like Constraints
Stars: ✭ 2,408 (+457.41%)
Mutual labels:  autolayout, constraints
Swiftautolayout
Write constraints in a concise, expressive, Swifty way.
Stars: ✭ 83 (-80.79%)
Mutual labels:  autolayout, constraints
Stevia
🍃 Concise Autolayout code
Stars: ✭ 3,182 (+636.57%)
Mutual labels:  autolayout, constraints
VanillaConstraints
🍦 Simplified and chainable AutoLayout constraints for iOS.
Stars: ✭ 42 (-90.28%)
Mutual labels:  constraints, autolayout
Tangramkit
TangramKit is a powerful iOS UI framework implemented by Swift. 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,LayoutSizeClass to build your App 自动布局 UIView UITableView UICollectionView
Stars: ✭ 984 (+127.78%)
Mutual labels:  autolayout, constraints
EZAnchor
An easier and faster way to code Autolayout
Stars: ✭ 25 (-94.21%)
Mutual labels:  constraints, autolayout
Core Layout
Flexbox & CSS-style Layout in Swift.
Stars: ✭ 215 (-50.23%)
Mutual labels:  autolayout, constraints
StoryboardConstraint
A simple way to use programmatically Autolayout Constraint created in Storyboard.
Stars: ✭ 25 (-94.21%)
Mutual labels:  constraints, autolayout
wwlayout
Swifty DSL for programmatic Auto Layout in iOS
Stars: ✭ 46 (-89.35%)
Mutual labels:  constraints, autolayout
Mylinearlayout
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 UITab…
Stars: ✭ 4,152 (+861.11%)
Mutual labels:  autolayout, constraints
Cupcake
An easy way to create and layout UI components for iOS (Swift version).
Stars: ✭ 273 (-36.81%)
Mutual labels:  constraints
Dry Struct
Typed struct and value objects
Stars: ✭ 263 (-39.12%)
Mutual labels:  constraints
Nerdyui
An easy way to create and layout UI components for iOS.
Stars: ✭ 381 (-11.81%)
Mutual labels:  constraints
DailyNews
Daily News is a news app with good looking user interface ! Apps architecture is MVVM and used RxSwift for binding.
Stars: ✭ 31 (-92.82%)
Mutual labels:  autolayout

EasyAnchor

❤️ Support my apps ❤️

❤️❤️😇😍🤘❤️❤️

Version Carthage Compatible License Platform Swift

Table of contents

Story

I like to build view in code, so Auto Layout is my definite choice. The syntax has improved over the years, but I always want to do it with minimum effort. More repetitive code makes you tend to do copy paste and produce more bugs.

Read more How to make Auto Layout more convenient in iOS

Auto Layout APIs history

How new APIs were introduced over the years, so you know to set your deployment target

  • NSLayoutConstraint since iOS 6, macOS 10.7
  • isActive since iOS 8, macOS 10.10
  • NSLayoutAnchor, UI|NSLayoutGuide since iOS 9, macOS 10.11

Do you need another Auto Layout framework?

All the Auto Layout frameworks you see are just convenient ways to build NSLayoutConstraint, in fact these are what you normally need

  • Call addSubview so that view is in hierarchy
  • Set translatesAutoresizingMaskIntoConstraints = false
  • Set isActive = true to enable constraints

Most of the time, NSLayoutAnchor is what you need. But if you need more, EasyAnchor can be your choice.

Examples

Tetris

Well, you can use Auto Layout to make Tetris. Auto Layout plays well with affine transform too. See code




activate(
  lineBlock.anchor.left.bottom
)

// later
activate(
  firstSquareBlock.anchor.left.equal.to(lineBlock.anchor.right),
  firstSquareBlock.anchor.bottom
)

// later
activate(
  secondSquareBlock.anchor.right.bottom
)

Piano

This is how to make a piano using apply and fixed spacing. See code

activate(
  c.anchor.left,
  b.anchor.right,
  c.anchor.top.bottom,
  c.anchor.top.bottom.width.apply(to: [d, e, f, g, a, b]),
  c.anchor.fixedSpacingHorizontally(togetherWith: [d, e, f, g, a, b], spacing: 0)
)

activate(
  cd.anchor.top,
  cd.anchor.size.equal.to(c.anchor.size).multiplier(2/3),
  cd.anchor.top.size.apply(to: [de, fg, ga, ab]),
  cd.anchor.centerX.equal.to(c.anchor.right),
  de.anchor.centerX.equal.to(d.anchor.right),
  fg.anchor.centerX.equal.to(f.anchor.right),
  ga.anchor.centerX.equal.to(g.anchor.right),
  ab.anchor.centerX.equal.to(a.anchor.right)
)

More

More example can be found in Example

Features

  • [x] Fluent builder syntax
  • [x] Easy to customize with protocol based
  • [x] Support iOS, macOS
  • [x] Support LayoutGuide
  • [x] Update and reset constraints
  • [x] Find existing constraints
  • [ ] Debug constraints
  • [ ] Visualize constraints

Basic with Anchor

Access Anchor

Prefer composition over extension, this is how you access anchor. Support View, LayoutGuide, LayoutSupport

let view = UIView()
view.anchor.left.right

let guide = UILayoutGuide()
guide.anchor.width.height

topLayoutGuide.anchor.bottom
bottomLayoutGuide.anchor.top

Activate constraints

Use activate which accepts variadic parameters. This is important, no matter how you create constraints, they don't have any effect until you activate it ❗❗❗❗❗

activate(
  a.anchor.top.left,
  b.anchor.top.right,
  c.anchor.bottom.left,
  d.anchor.bottom.right
)

Attributes

Supports all attributes you can think of

anchor.top.left.bottom.right
  .leading.trailing
  .topMargin.bottomMargin.leftMargin.rightMargin
  .centerX.centerY
  .centerXWithinMargins.centerXWithinMargins
  .lastBaseline.firstBaseline
  .width.height

Relation

a.anchor.top.equal.to(b.bottom)
a.anchor.width.greaterThanOrEqual.to(b.anchor.height)
a.anchor.width.lessThanOrEqual.to(b.anchor)

Configuration

This is how to apply constant, multiplier, priority, identifier

a.anchor.top.equal.to(b.anchor.bottom)
  .constant(10).multiplier(1.5).priority(999)
  .id("verticalSpacingBetweenA-B")

Reference

Get references to constraints to modify it later on. In the ref closure, we get access to all the created constraints

var constraint: NSLayoutConstraint?
activate(
  view.anchor.center.constant(10).ref({ constraint = $0.first })
)

Convenient attributes

Use convenient attributes which combine multiple inner attributes

a.anchor.center  // centerX, centerY
a.anchor.size  // width, height
a.anchor.edges  // top, right, bottom, left

Convenient methods

Insets

a.anchor.edges.insets(EdgeInsets(top: 1, left: 2, bottom: 3, right: 4))  // top+1, left+2, bottom+3, right+4
a.anchor.edges.insets(5)  // top+5, left+5, bottom-5, right-5

Padding

a.anchor.paddingHorizontally(20) // leading+20, trailing-20
b.anchor.paddingVertically(20)	// top+20, bottom-20

Size

Size to another anchor

a.anchor.height.equal.to(b.anchor.width)
c.anchor.size.equal.to(d.anchor)

Size to a constant

a.anchor.height.equal.to(20)  // height==20
b.anchor.size.equal.to(20)  // width==20, height==20

You can't just use constant because EasyAnchor will infer to the superview

c.anchor.width.constant(20)  // width==superview.width+20

Ratio

a.anchor.height.equal.to(a.anchor.width)  // height==width

Alternatively, you can just use ratio

a.anchor.width.constant(10)
a.anchor.height.ratio(2) // height==width*2
a.anchor.height.constant(10)
a.anchor.width.ratio(2) // width==height*2

Inference

You know what you mostly want to do. So does EasyAnchor 🎉. It does its best to infer so don't have to write "obvious" code

Most of the time, you want to constraint to the superview

a.anchor.top.left // a.top == a.superview.top, a.left == a.superview.left

Most of the time, you want to constraint to the same attributes

a.anchor.top.bottom.width.equal.to(b.anchor) // a.top == b.top, a.bottom == b.bottom, a.width == b.width

Find existing constraints

You don't need to declare variables to store constraints, you can just retrieve them back

a.anchor.find(.height)?.constant = 100

// later
b.anchor.find(.height)?.constant = 100

// later
c.anchor.find(.height)?.constant = 100

Animation

Animation is simple. You just change your constraint 's isActive or constant properties, then layoutIfNeeded in an animation block. You can use UIView.animate or UIViewPropertyAnimator

// Change constraint
a.anchor.find(.height)?.constant = 100
loginButtonHeightConstraint.isActive = false

let animator = UIViewPropertyAnimator(duration: 1, dampingRatio: 0.7)
animator.addAnimations { [weak self] in
  self?.view.layoutIfNeeded()
}

animator.startAnimation(afterDelay: 1)

Update constraints with Group

activate is just a convenient way to produce group, then set isActive on the Group. If you just want to group a set of constraints, then set isActive later on, use function group

In this example, we have 4 groups, then take turn to toggle which group gets activated

func toggle(_ group: Group) {
  [g1, g2, g3, g4].forEach { g in
    guard let g = g else {
      return
    }

    g.isActive = (g == group)
  }
}

g1 = group(a.anchor.top.left)
g2 = group(a.anchor.top.right)
g3 = group(a.anchor.bottom.right)
g4 = group(a.anchor.bottom.left)

g1.isActive = true

animator = Animator(view: self, animations: [
  {
    self.toggle(self.g2)
  },
  {
    self.toggle(self.g3)
  },
  {
    self.toggle(self.g4)
  },
  {
    self.toggle(self.g1)
  }
  ])

animator.start()

Extensible with ConstraintProducer

Group is a set of NSLayoutConstraint, which are produced by ConstraintProducer

public protocol ConstraintProducer {
  func constraints() -> [NSLayoutConstraint]
}

For now, there is Anchor and Builder which conforms to ConstraintProducer, you can extend EasyAnchor easily by conform to ConstraintProducer. For example

// This accepts a list of views, and build constraints
class MyAwesomeLayout: ConstraintProducer {
  init(views: [UIView]) {
    // Your code goes here
  }

  func constraints() -> [NSLayoutConstraint] {
    // Your code goes here
    return []
  }
}

let awesomeLayout = MyAwesomeLayout(views: [view1, view2])
activate(awesomeLayout)

Build quickly with Builder

Well, Anchor is for making constraints between 2 views. If you want to make constraints for multiple views at once, you can use multiple Anchor. There are some tasks that you do often, let Builder help you. These method below use Builder under the hood

EasyAnchor has a set of builders to help you avoid repetitive tasks and build UIs quickly 😎

Apply

Apply the same anchor to other views

a.anchor.left.height.apply(to: [b, c]),

Paging

Build a paging scrollView horizontally

addSubview(scrollView)
[a, b, c, d].forEach {
  scrollView.addSubview($0)
}

activate(
  scrollView.anchor.edges.insets(8),
  a.anchor.pagingHorizontally(togetherWith: [b, c, d], in: scrollView)
)

Fixed spacing

Add fixed spacing. The views will resize

activate(
  container.anchor.edges.insets(8),
  a.anchor.left.top.bottom,
  c.anchor.right,
  a.anchor.top.bottom.width.apply(to: [b, c]),
  a.anchor.fixedSpacingHorizontally(togetherWith: [b, c], spacing: 50)
)

Dynamic spacing

Add dynamic spacing using LayoutGuide. The spacing will resize

activate(
  container.anchor.edges.insets(8),
  a.anchor.size.equal.to(30),
  b.anchor.size.equal.to(30),
  c.anchor.size.equal.to(30),
  a.anchor.left.centerY,
  a.anchor.centerY.apply(to: [b, c]),
  c.anchor.right,
  a.anchor.dynamicSpacingHorizontally(togetherWith: [b, c])
)

Debug Auto Layout

Support multiple screen sizes

Installation

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

pod 'EasyAnchor'

EasyAnchor is also available through Carthage. To install just write into your Cartfile:

github "onmyway133/EasyAnchor"

EasyAnchor can also be installed manually. Just download and drop Sources folders in your project.

Author

Khoa Pham, [email protected]

Contributing

We would love you to contribute to EasyAnchor, check the CONTRIBUTING file for more info.

License

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

Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].