官方网址:http://snapkit.io/
Github: https://github.com/SnapKit/SnapKit
While SnapKit supports iOS 7.0 and OS X 10.9 these are considered legacy platforms, so you must manually integrate the source files directly. Please see the Legacy Platforms page for more information and steps.
The first thing you’ll need to do with SnapKit is get it installed into your project. We support three different integrations:
CocoaPods 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:
$ gem install cocoapods
To integrate SnapKit into your Xcode project using CocoaPods, specify it in your Podfile
:
source 'https://github.com/CocoaPods/Specs.git' platform :ios, '8.0' use_frameworks! pod 'SnapKit', '~> 0.15.0'
Then, run the following command:
$ pod install
Carthage is a decentralized dependency manager that automates the process of adding frameworks to your Cocoa application.
You can install Carthage with Homebrew using the following command:
$ brew update $ brew install carthage
To integrate SnapKit into your Xcode project using Carthage, specify it in your Cartfile
:
github "SnapKit/SnapKit" >= 0.15.0
cd
-ing into your top-level project directory, and entering the following command:$ git submodule add https://github.com/SnapKit/SnapKit.git
SnapKit
folder, and drag SnapKit.xcodeproj
into the file navigator of your app project.SnapKit.framework
matches that of the application target.SnapKit.framework
.+
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 addSnapKit.framework
.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.
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:
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:
setTranslatesAutoresizingMaskIntoConstraints(false)
is called on all appropriate views.
.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:
make.centerX.lessThanOrEqualTo(view2.snp_left)
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 |
// these two constraints are exactly the same make.left.greaterThanOrEqualTo(label) make.left.greaterThanOrEqualTo(label.snp_left)
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:
// 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:
// 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:
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))
.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:
make.left.greaterThanOrEqualTo(label.snp_left).priorityLow() make.top.equalTo(label.snp_top).priority(600)
SnapKit also gives you a few convenience methods to create multiple constraints at the same time.
// 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).inset(UIEdgeInsetsMake(5, 10, 15, 20))
// 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))
// 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:
// All edges but the top should equal those of the superview make.left.right.bottom.equalTo(superview) make.top.equalTo(otherView)
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.
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.
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)
Alternative if you are only updating the constant value of the constraint you can use the methodsnp_updateConstraints
instead of snp_makeConstraints
// 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.
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) } } }