最終確認日

SnapKitをはがす

OKAIMOで使っていたSnapKit を剥がす。SnapKit自体で何か問題が起きているわけではないが、依存ライブラリを減らしたい。

このプロジェクトではUIKitからわざわざSwiftUIに移行する必要はないかなと考えているので、そのままUIKitのままにする。

環境

せっかくなのでAIを使ってみる

Xcode 26.3だしねってことで。

Migrate SnapKit to native NSLayoutConstraint. を実行してみる。めちゃめちゃ誤字しちゃって Migrate SnapKit and native NSConstraintLayout. で実行しちゃったけど理解してもらえた。

Remove SnapKit and rewrite constraints using NSLayoutConstraint とかの方がいいかもしれない。

SnapKitを剥がす-1770887202119

差分

-import SnapKit

-        contentView.snp.makeConstraints {
-            $0.edges.equalToSuperview()
+        contentView.translatesAutoresizingMaskIntoConstraints = false
+        if let superview = self.superview {
+            NSLayoutConstraint.activate([
+                contentView.topAnchor.constraint(equalTo: superview.topAnchor),
+                contentView.bottomAnchor.constraint(equalTo: superview.bottomAnchor),
+                contentView.leadingAnchor.constraint(equalTo: superview.leadingAnchor),
+                contentView.trailingAnchor.constraint(equalTo: superview.trailingAnchor)
+            ])
         }
// SnapKit での書き方
contentView.snp.makeConstraints {
    $0.edges.equalToSuperview()
}

// SnapKit 剥がし
contentView.translatesAutoresizingMaskIntoConstraints = false
if let superview = self.superview {
	NSLayoutConstraint.activate([
		contentView.topAnchor.constraint(equalTo: superview.topAnchor),
		contentView.bottomAnchor.constraint(equalTo: superview.bottomAnchor),
		contentView.leadingAnchor.constraint(equalTo: superview.leadingAnchor),
		contentView.trailingAnchor.constraint(equalTo: superview.trailingAnchor)
	])
}

少し漏れがあったので、再度 Remove SnapKit and rewrite constraints using NSLayoutConstraint で実行。

うむ。崩れております。手動で直す。

1箇所だけ手動で直してあとは大丈夫そう。

Extension などに置き換えるか

悩ましいが、このプロジェクトではコードからAuto Layoutを使っている箇所が少ないからまぁいいかという気もする。

SnapKitを使っているアプリは、自分のアプリではOKAIMOが最初で最後であり、他のUIKitを使ったプロジェクトでは次のようなextensionを用いている。

出自は自分が最初ではなかったはずなので、一部のみ紹介。自分でも改良はしている。

import UIKit

extension UIView {

    @discardableResult
    func alignLeft(anchor: NSLayoutAnchor<NSLayoutXAxisAnchor>,
                   constant: CGFloat = 0,
                   priority: UILayoutPriority = .required) -> NSLayoutConstraint {
        translatesAutoresizingMaskIntoConstraints = false
        let constraint = leftAnchor.constraint(equalTo: anchor, constant: constant)
        constraint.isActive = true
        constraint.priority = priority
        return constraint
    }
}

使う時は以下の感じで指定する。

bannerView.alignLeft(anchor: view.leftAnchor)
bannerView.alignRight(anchor: view.rightAnchor)
bannerView.alignHeight(constant: 50, priority: .defaultHigh)
bannerView.alignBottom(anchor: toolbar.topAnchor)

また、Superviewに対するAuto LayoutAppleで紹介されていた次のextensionをよく使っている。

Using content views — App Dev Tutorials | Apple Developer Documentation

UIView+PinnedSubview.swift
import UIKit

extension UIView {
    func addPinnedSubview(
        _ subview: UIView, height: CGFloat? = nil,
        insets: UIEdgeInsets = UIEdgeInsets(top: 0, left: 8, bottom: 0, right: 8)
    ) {
        addSubview(subview)
        subview.translatesAutoresizingMaskIntoConstraints = false
        subview.topAnchor.constraint(equalTo: topAnchor, constant: insets.top).isActive = true
        subview.leadingAnchor.constraint(equalTo: leadingAnchor, constant: insets.left).isActive = true
        subview.trailingAnchor.constraint(equalTo: trailingAnchor, constant: -1.0 * insets.right)
            .isActive = true
        subview.bottomAnchor.constraint(equalTo: bottomAnchor, constant: -1.0 * insets.bottom)
            .isActive = true
        if let height {
            subview.heightAnchor.constraint(equalToConstant: height).isActive = true
        }
    }
}

これを使うと view.addSubview(hogeView) をする時に同時にConstraintの設定をすることができる。

おわりに

そもそもUIKitの出番はもう少ないと思うが、それ故に依存ライブラリもあまり更新されてなくなっていくと思うので、一応メモしておいた。

サイトアイコン
公開日
更新日