[Swift] 如何使用 Snapkit 來做 auotolayout?

在撰寫 iOS 畫面時,AutoLayout 是一個很常見的手法,雖然我們可以使用 storyboard 或是 xib 來拉畫面,但有時畫面只是一個小小的畫面而已,太多的檔案反而會減少編繹的速度。而使用原生的 constraints 來做 AutoLayout 又很麻煩,所以我們可以利用 Snapkit 這個工具來做 AutoLayout。

swift 1

首先,我們先引入這個,並在 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)

是不是相當容易呢?

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *