Синтаксический сахар для верстки с использованием подходов Auto Layout
Carthage is a decentralized dependency manager that builds your dependencies and provides you with binary frameworks. To integrate this framework into your Xcode project using Carthage, specify it in your Cartfile
:
github "Heads-and-Hands/auto-layout-sugar-ios"
- Select File > Swift Packages > Add Package Dependency. Enter
https://github.com/Heads-and-Hands/auto-layout-sugar-ios
in the "Choose Package Repository" dialog. - In the next page, specify the version resolving rule as "Up to Next Major" with "1.0.6" as its earliest version.
- After Xcode checking out the source and resolving the version, you can choose the "AutoLayoutSugar" library and add it to your app target.
All we know, that auto layout engine switches on only if we'll set view's translatesAutoresizingMaskIntoConstraints property to false. Without autoLayoutSugar we write:
view.translatesAutoresizingMaskIntoConstraints = false
after:
view.prepareForAutoLayout()
Also, prepareForAutoLayout
method returns view
- we can chain something if needed after this method calling.
before:
let viewBottomConstraint = view.bottomAnchor.constraint(equalTo: superview.bottomAnchor)
let viewTopConstraint = view.topAnchor.constraint(equalTo: superview.topAnchor, constant: 10)
after:
let viewBottomConstraint = view.bottomAnchor ~= superview.bottomAnchor
let viewTopConstraint = view.topAnchor ~= superView.topAnchor + 10
before:
NSLayoutConstraint.activate([
view.topAnchor.constraint(equalTo: superview.topAnchor, constant: 10),
view.leftAnchor.constraint(equalTo: superview.leftAnchor, constant: 10),
view.rightAnchor.constraint(equalTo: superview.rightAnchor, constant: -10),
view.bottomAnchor.constraint(equalTo: superview.bottomAnchor, constant: -10)
])
after:
let viewInsets = UIEdgeInsets(top: 10, left: 10, bottom: 10, right: 10)
view.pinToSuperview(with: viewInsets)
pinToSuperview method overloaded by AutoLayoutSugar with default insets equals .zero., and we can use this feature like that: before:
NSLayoutConstraint.activate([
view1.topAnchor.constraint(equalTo: superview.topAnchor),
view1.leftAnchor.constraint(equalTo: superview.leftAnchor),
view1.rightAnchor.constraint(equalTo: superview.rightAnchor),
view1.bottomAnchor.constraint(equalTo: superview.bottomAnchor)
])
after:
view1.pinToSuperview()
AutoLayoutSugar provides pinning all sides excluded one with/without insets: before:
NSLayoutConstraint.activate([
view1.topAnchor.constraint(equalTo: superview.topAnchor),
view1.leftAnchor.constraint(equalTo: superview.leftAnchor),
view1.rightAnchor.constraint(equalTo: superview.rightAnchor)
])
after:
view1.pin(excluding .bottom)
AutoLayoutSugar provides pinning certain sides: before:
NSLayoutConstraint.activate([
view1.topAnchor.constraint(equalTo: superview.topAnchor),
view1.leftAnchor.constraint(equalTo: superview.leftAnchor)
])
after:
view1.pin([.top, .left])
All pinning methods has relatedView argument, nil
by default and equals to superview. But if needed, we can set related view like this:
view1.pin([.top, .left], to: view2)
Remember: Related view should has one parent superview with current operated view.
If we have any reasons to use safe areas in our layout logic, AutoLayoutSugar provides closure-based API:
collectionView.left().right().safeArea { $0.top().bottom(10) }
Remember: Use only AutoLayoutSugar chained methods in this closure, because third-party methods calling in this place has no layout effect.
before:
let superView = UIView()
let leftView = UIView()
let rightView = UIView(
let bottomView = UIView()
[leftView, rightView, bottomView].forEach {
$0.translatesAutoresizingMaskIntoConstraints = false
superView.addSubview($0)
}
superView.translatesAutoresizingMaskIntoConstraints = false
NSLayoutConstraint.activate([
leftView.topAnchor.constraint(equalTo: superView.topAnchor, constant: 10),
leftView.leftAnchor.constraint(equalTo: superView.leftAnchor, constant: 10),
leftView.rightAnchor.constraint(equalTo: rightView.leftAnchor, constant: -20),
leftView.heightAnchor.constraint(equalToConstant: 25),
leftView.bottomAnchor.constraint(equalTo: bottomView.topAnchor, constant: -15),
rightView.widthAnchor.constraint(equalTo: leftView.widthAnchor),
rightView.topAnchor.constraint(equalTo: superView.topAnchor, constant: 10),
rightView.rightAnchor.constraint(equalTo: superView.rightAnchor, constant: -10),
rightView.bottomAnchor.constraint(equalTo: bottomView.topAnchor, constant: -15),
bottomView.leftAnchor.constraint(equalTo: superView.leftAnchor, constant: 10),
bottomView.rightAnchor.constraint(equalTo: superView.rightAnchor, constant: -10),
bottomView.bottomAnchor.constraint(equalTo: superView.bottomAnchor)
])
after:
let superView = UIView().prepareForAutoLayout()
let leftView = UIView().prepareForAutoLayout()
let rightView = UIView().prepareForAutoLayout()
let bottomView = UIView().prepareForAutoLayout()
[leftView, rightView, bottomView].forEach { superView.addSubview($0) }
leftView.width(as: rightView).height(25).top(10).left(10).right(to: .left(20), of: rightView).bottom(to: .top(15), of: bottomView)
rightView.top(10).right(10).bottom(to: .top(15), of: bottomView)
bottomView.left(10).right(10).bottom()
switcher.centerY().left(8)
label.centerY().centerX()
button
.left(to: .right(20), of: label)
.top(to: switcher)
.right(24)