在撰寫 iOS 畫面時,AutoLayout 是一個很常見的手法,雖然我們可以使用 storyboard 或是 xib 來拉畫面,但有時畫面只是一個小小的畫面而已,太多的檔案反而會減少編繹的速度。而使用原生的 constraints 來做 AutoLayout 又很麻煩,所以我們可以利用 Snapkit 這個工具來做 AutoLayout。
首先,我們先引入這個,並在 UIView 中加入個 extension,接下來的程式碼會用到。
extension UIView {
var constraints: some Constrainable {
ConstraintHelper(view: self)
}
}
接下來,在新增這個 protocol
protocol Constrainable {
// MARK: - 基本對齊方法
func alignLeading(to view: UIView, padding: CGFloat)
func alignTop(to view: UIView, padding: CGFloat)
func alignTrailing(to view: UIView, padding: CGFloat)
func alignBottom(to view: UIView, padding: CGFloat)
// MARK: - 與父視圖對齊的方法
func alignLeadingToSuperview(padding: CGFloat)
func alignTopToSuperview(padding: CGFloat)
func alignTrailingToSuperview(padding: CGFloat)
func alignBottomToSuperview(padding: CGFloat)
func alignEdgesToSuperview(padding: CGFloat)
// MARK: - 尺寸調整方法
func setSize(width: CGFloat, height: CGFloat)
func setWidth(_ width: CGFloat)
func setHeight(_ height: CGFloat)
// MARK: - 置中方法
func centerInSuperview()
func centerVerticallyToSuperview()
func centerHorizontallyToSuperview()
}
在來新增一個 ConstraintHelper 的類別,這麼做的目的,是為了將來如果我們不用 Snapkit 這個套件,我們就可以快速抽換成別的套件。
import Foundation
import SnapKit
final class ConstraintHelper: Constrainable {
private weak var view: UIView?
init(view: UIView) {
self.view = view
}
func alignLeading(to view: UIView, padding: CGFloat) {
self.view?.snp.makeConstraints { make in
make.leading.equalTo(view).offset(padding)
}
}
func alignTop(to view: UIView, padding: CGFloat) {
self.view?.snp.makeConstraints { make in
make.top.equalTo(view).offset(padding)
}
}
func alignTrailing(to view: UIView, padding: CGFloat) {
self.view?.snp.makeConstraints { make in
make.trailing.equalTo(view).offset(padding)
}
}
func alignBottom(to view: UIView, padding: CGFloat) {
self.view?.snp.makeConstraints { make in
make.bottom.equalTo(view).offset(padding)
}
}
func alignLeadingToSuperview(padding: CGFloat) {
guard let superview = view?.superview else { return }
view?.snp.makeConstraints { make in
make.leading.equalTo(superview).offset(padding)
}
}
func alignTopToSuperview(padding: CGFloat) {
guard let superview = view?.superview else { return }
view?.snp.makeConstraints { make in
make.top.equalTo(superview).offset(padding)
}
}
func alignTrailingToSuperview(padding: CGFloat) {
guard let superview = view?.superview else { return }
view?.snp.makeConstraints { make in
make.trailing.equalTo(superview).offset(padding)
}
}
func alignBottomToSuperview(padding: CGFloat) {
guard let superview = view?.superview else { return }
view?.snp.makeConstraints { make in
make.bottom.equalTo(superview).offset(padding)
}
}
func alignEdgesToSuperview(padding: CGFloat) {
guard let superview = view?.superview else { return }
view?.snp.makeConstraints { make in
make.edges.equalTo(superview).inset(padding)
}
}
// MARK: - 尺寸調整方法
func setSize(width: CGFloat, height: CGFloat) {
view?.snp.makeConstraints { make in
make.width.equalTo(width)
make.height.equalTo(height)
}
}
func setWidth(_ width: CGFloat) {
view?.snp.makeConstraints { make in
make.width.equalTo(width)
}
}
func setHeight(_ height: CGFloat) {
view?.snp.makeConstraints { make in
make.height.equalTo(height)
}
}
// MARK: - 置中方法
func centerInSuperview() {
guard let superview = view?.superview else { return }
view?.snp.makeConstraints { make in
make.center.equalTo(superview)
}
}
func centerVerticallyToSuperview() {
guard let superview = view?.superview else { return }
view?.snp.makeConstraints { make in
make.centerY.equalTo(superview)
}
}
func centerHorizontallyToSuperview() {
guard let superview = view?.superview else { return }
view?.snp.makeConstraints { make in
make.centerX.equalTo(superview)
}
}
}
以設置 View 的寬度來說,要使用的話,只要這樣用就好了。
let view = UIView()
view.constraints.setWidth(100)
是不是相當容易呢?