mirror of https://github.com/SnapKit/SnapKit
318 lines
9.7 KiB
Markdown
318 lines
9.7 KiB
Markdown
---
|
||
layout: default
|
||
permalink: /docs/
|
||
id: docs
|
||
---
|
||
## Requirements
|
||
|
||
* iOS 7.0+ / OS X 10.9+
|
||
* Xcode 6.3+
|
||
|
||
> While SnapKit supports iOS 7.0, frameworks are not supported for iOS 7.0 so you must manually embed the framework for non app store apps or integrate the source files directly.
|
||
|
||
## Installing
|
||
|
||
The first thing you’ll need to do with SnapKit is get it installed into your project. We support three different integrations:
|
||
|
||
### Cocoapods
|
||
|
||
[CocoaPods](http://cocoapods.org) is a dependency manager for Cocoa projects.
|
||
|
||
CocoaPods 0.36 adds supports for Swift and embedded frameworks. You can install it with the following command:
|
||
|
||
```bash
|
||
$ gem install cocoapods
|
||
```
|
||
|
||
To integrate SnapKit into your Xcode project using CocoaPods, specify it in your `Podfile`:
|
||
|
||
```ruby
|
||
source 'https://github.com/CocoaPods/Specs.git'
|
||
platform :ios, '8.0'
|
||
use_frameworks!
|
||
|
||
pod 'SnapKit', '~> 0.12.0'
|
||
```
|
||
|
||
Then, run the following command:
|
||
|
||
```bash
|
||
$ pod install
|
||
```
|
||
|
||
### Carthage
|
||
|
||
Carthage is a decentralized dependency manager that automates the process of adding frameworks to your Cocoa application.
|
||
|
||
You can install Carthage with [Homebrew](http://brew.sh/) using the following command:
|
||
|
||
```bash
|
||
$ brew update
|
||
$ brew install carthage
|
||
```
|
||
|
||
To integrate SnapKit into your Xcode project using Carthage, specify it in your `Cartfile`:
|
||
|
||
```
|
||
github "SnapKit/SnapKit" >= 0.12.0
|
||
```
|
||
|
||
### Embedded Framework
|
||
|
||
- Add SnapKit as a [submodule](http://git-scm.com/docs/git-submodule) by opening the Terminal, `cd`-ing into your top-level project directory, and entering the following command:
|
||
|
||
```bash
|
||
$ git submodule add https://github.com/SnapKit/SnapKit.git
|
||
```
|
||
|
||
- Open the `SnapKit` folder, and drag `SnapKit.xcodeproj` into the file navigator of your app project.
|
||
- In Xcode, navigate to the target configuration window by clicking on the blue project icon, and selecting the application target under the "Targets" heading in the sidebar.
|
||
- Ensure that the deployment target of `SnapKit.framework` matches that of the application target.
|
||
- In the tab bar at the top of that window, open the "Build Phases" panel.
|
||
- Expand the "Target Dependencies" group, and add `SnapKit.framework`.
|
||
- Click on the `+` button at the top left of the panel and select "New Copy Files Phase". Rename this new phase to "Copy Frameworks", set the "Destination" to "Frameworks", and add `SnapKit.framework`.
|
||
|
||
## Usage
|
||
|
||
SnapKit is designed to be extremely easy to use. Let's say we want to layout a box that is constrained to it's superview's edges with 20pts of padding.
|
||
|
||
```swift
|
||
let box = UIView()
|
||
superview.addSubview(box)
|
||
|
||
box.snp_makeConstraints { (make) -> Void in
|
||
make.top.equalTo(superview).offset(20)
|
||
make.left.equalTo(superview).offset(20)
|
||
make.bottom.equalTo(superview).offset(-20)
|
||
make.right.equalTo(superview).offset(-20)
|
||
}
|
||
```
|
||
|
||
Or even shorter:
|
||
|
||
```swift
|
||
let box = UIView()
|
||
superview.addSubview(box)
|
||
|
||
box.snp_makeConstraints { (make) -> Void in
|
||
make.edges.equalTo(superview).inset(UIEdgeInsetsMake(20, 20, 20, 20))
|
||
}
|
||
```
|
||
|
||
Not only does this greatly shorten and increase the readability of constraints SnapKit is also taking care of a few crucial steps in the process:
|
||
|
||
- Determining the best common superview to install the constraints on.
|
||
- Keeping track of the constrainted installed so they can easily be removed later.
|
||
- Ensuring `setTranslatesAutoresizingMaskIntoConstraints(false)` is called on all appropriate views.
|
||
|
||
### Not all things are created equal
|
||
|
||
> `.equalTo` equivalent to **NSLayoutRelation.Equal**
|
||
|
||
> `.lessThanOrEqualTo` equivalent to **NSLayoutRelation.LessThanOrEqual**
|
||
|
||
> `.greaterThanOrEqualTo` equivalent to **NSLayoutRelation.GreaterThanOrEqual**
|
||
|
||
These three equality constraints accept one argument which can be any of the following:
|
||
|
||
#### 1. ViewAttribute
|
||
|
||
```swift
|
||
make.centerX.lessThanOrEqualTo(view2.snp_left)
|
||
```
|
||
|
||
ViewAttribute | NSLayoutAttribute
|
||
------------------------- | --------------------------
|
||
view.snp_left | NSLayoutAttribute.Left
|
||
view.snp_right | NSLayoutAttribute.Right
|
||
view.snp_top | NSLayoutAttribute.Top
|
||
view.snp_bottom | NSLayoutAttribute.Bottom
|
||
view.snp_leading | NSLayoutAttribute.Leading
|
||
view.snp_trailing | NSLayoutAttribute.Trailing
|
||
view.snp_width | NSLayoutAttribute.Width
|
||
view.snp_height | NSLayoutAttribute.Height
|
||
view.snp_centerX | NSLayoutAttribute.CenterX
|
||
view.snp_centerY | NSLayoutAttribute.CenterY
|
||
view.snp_baseline | NSLayoutAttribute.Baseline
|
||
|
||
|
||
#### 2. UIView/NSView
|
||
|
||
if you want view.left to be greater than or equal to label.left:
|
||
|
||
```swift
|
||
// these two constraints are exactly the same
|
||
make.left.greaterThanOrEqualTo(label)
|
||
make.left.greaterThanOrEqualTo(label.snp_left)
|
||
```
|
||
|
||
#### 3. Strict Checks
|
||
|
||
Auto Layout allows width and height to be set to constant values.
|
||
if you want to set view to have a minimum and maximum width you could pass a primitive to the equality blocks:
|
||
|
||
```swift
|
||
// width >= 200 && width <= 400
|
||
make.width.greaterThanOrEqualTo(200)
|
||
make.width.lessThanOrEqualTo(400)
|
||
```
|
||
|
||
However Auto Layout does not allow alignment attributes such as left, right, centerY etc to be set to constant values.
|
||
So if you pass a primitive for these attributes SnapKit will turn these into constraints relative to the view's superview ie:
|
||
|
||
```swift
|
||
// creates view.left <= view.superview.left + 10
|
||
make.left.lessThanOrEqualTo(10)
|
||
```
|
||
|
||
You can also use other primitives and structs to build your constraints, like so:
|
||
|
||
```swift
|
||
make.top.equalTo(42)
|
||
make.height.equalTo(20)
|
||
make.size.equalTo(CGSizeMake(50, 100))
|
||
make.edges.equalTo(UIEdgeInsetsMake(10, 0, 10, 0))
|
||
make.left.equalTo(view).offset(UIEdgeInsetsMake(10, 0, 10, 0))
|
||
```
|
||
|
||
### Learn to prioritize
|
||
|
||
> `.prority` allows you to specify an exact priority
|
||
|
||
> `.priorityHigh` equivalent to **UILayoutPriority.DefaultHigh**
|
||
|
||
> `.priorityMedium` is half way between high and low
|
||
|
||
> `.priorityLow` equivalent to **UILayoutPriority.DefaultLow**
|
||
|
||
Priorities are can be tacked on to the end of a constraint chain like so:
|
||
|
||
```swift
|
||
make.left.greaterThanOrEqualTo(label.snp_left).priorityLow()
|
||
make.top.equalTo(label.snp_top).priority(600)
|
||
```
|
||
|
||
### Composition, composition, composition
|
||
|
||
SnapKit also gives you a few convenience methods to create multiple constraints at the same time.
|
||
|
||
#### edges
|
||
|
||
```swift
|
||
// make top, left, bottom, right equal view2
|
||
make.edges.equalTo(view2);
|
||
|
||
// make top = superview.top + 5, left = superview.left + 10,
|
||
// bottom = superview.bottom - 15, right = superview.right - 20
|
||
make.edges.equalTo(superview).insets(UIEdgeInsetsMake(5, 10, 15, 20))
|
||
```
|
||
|
||
#### size
|
||
|
||
```swift
|
||
// make width and height greater than or equal to titleLabel
|
||
make.size.greaterThanOrEqualTo(titleLabel)
|
||
|
||
// make width = superview.width + 100, height = superview.height - 50
|
||
make.size.equalTo(superview).offset(CGSizeMake(100, -50))
|
||
```
|
||
|
||
#### center
|
||
|
||
```swift
|
||
// make centerX and centerY = button1
|
||
make.center.equalTo(button1)
|
||
|
||
// make centerX = superview.centerX - 5, centerY = superview.centerY + 10
|
||
make.center.equalTo(superview).offset(CGPointMake(-5, 10))
|
||
```
|
||
|
||
You can chain view attributes for increased readability:
|
||
|
||
```swift
|
||
// All edges but the top should equal those of the superview
|
||
make.left.right.bottom.equalTo(superview)
|
||
make.top.equalTo(otherView)
|
||
```
|
||
|
||
### Hold on for dear life
|
||
|
||
Sometimes you need modify existing constraints in order to animate or remove/replace constraints.
|
||
In SnapKit there are a few different approaches to updating constraints.
|
||
|
||
#### 1. References
|
||
You can hold on to a reference of a particular constraint by assigning the result of a constraint make expression to a local variable or a class property.
|
||
You could also reference multiple constraints by storing them away in an array.
|
||
|
||
```swift
|
||
var topConstraint: Constraint? = nil
|
||
|
||
...
|
||
|
||
// when making constraints
|
||
view1.snp_makeConstraints { (make) -> Void in
|
||
self.topConstraint = make.top.equalTo(superview).offset(padding.top).constraint
|
||
make.left.equalTo(superview).offset(padding.left)
|
||
}
|
||
|
||
...
|
||
// then later you can call
|
||
self.topConstraint.uninstall()
|
||
|
||
// or if you want to update the constraint
|
||
self.topConstraint.updateOffset(5)
|
||
```
|
||
|
||
### 2. snp_updateConstraints
|
||
|
||
Alternative if you are only updating the **constant** value of the constraint you can use the method `snp_updateConstraints` instead of `snp_makeConstraints`
|
||
|
||
```swift
|
||
// this is Apple's recommended place for adding/updating constraints
|
||
// this method can get called multiple times in response to setNeedsUpdateConstraints
|
||
// which can be called by UIKit internally or in your code if you need to trigger an update to your constraints
|
||
override func updateConstraints() {
|
||
self.growingButton.snp_updateConstraints { (make) -> Void in
|
||
make.center.equalTo(self);
|
||
make.width.equalTo(self.buttonSize.width).priorityLow()
|
||
make.height.equalTo(self.buttonSize.height).priorityLow()
|
||
make.width.lessThanOrEqualTo(self)
|
||
make.height.lessThanOrEqualTo(self)
|
||
}
|
||
|
||
// according to apple super should be called at end of method
|
||
super.updateConstraints()
|
||
}
|
||
```
|
||
|
||
### 3. snp_remakeConstraints
|
||
|
||
`snp_remakeConstraints` is similar to `snp_makeConstraints`, but will first remove all existing constraints installed by SnapKit.
|
||
|
||
```swift
|
||
func changeButtonPosition() {
|
||
self.button.snp_remakeConstraints { (make) -> Void in
|
||
make.size.equalTo(self.buttonSize)
|
||
|
||
if topLeft {
|
||
make.top.left.equalTo(10)
|
||
} else {
|
||
make.bottom.equalTo(self.view).offset(-10)
|
||
make.right.equalTo(self.view).offset(-10)
|
||
}
|
||
}
|
||
}
|
||
```
|
||
|
||
## Features
|
||
|
||
* Not limited to a subset of Auto Layout. Anything NSLayoutConstraint can do SnapKit can also do.
|
||
* Better debugging support to help find breaking constraints.
|
||
* No crazy operator overloads.
|
||
* Not string or dictionary based and you get the strictest compile time checks possible.
|
||
|
||
## TODO
|
||
|
||
* Example Projects
|
||
* Better Debugging Support
|