【Swift】UIViewを切り抜く方法

2022.10.25

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

UIViewを切り抜く方法を調べてみました。

環境

  • Xcode 14

UIViewを切り抜く方法

まず、UIViewを切り抜く際に使用するUIView+Extensionを作成しました。

UIView+ClipMask

import UIKit

extension UIView {

    func clipMask(withRect rect: CGRect, isReversed: Bool = false) {
        let maskLayer = CAShapeLayer()
        let path = CGMutablePath()

        if isReversed {
            // 切り抜きを反転させる場合は、自身のboundsをpathに追加する
            path.addRect(bounds)

            // 塗りつぶしルールの指定
            // 反転させる場合は、パスが重なっていない箇所を領域外と判定して残す
            maskLayer.fillRule = .evenOdd
        }

        path.addRect(rect)
        maskLayer.path = path

        // 作成したMask用のレイヤーをセットする
        layer.mask = maskLayer
    }
}

第一引数のrectでマスクをかける範囲をCGRectで指定してあげて、isReversedのフラグで通常のマスクかリバースマスクを切り替えることが出来ます。

CAShapeLayer.fillRuleはデフォルトでは、.nonZeroですが、リバースマスクの場合は領域内を残すような表現をしたい為、.evenOddに指定しています。

CAShapeLayer.fillRuleについては下記の記事がとても参考になりました。

使用例

Storyboard

Viewに切り抜きしたいcoveringViewとその前面に切り抜き範囲対象のViewclippingViewを配置しています。また切り抜きする処理を実行するボタンを下部に配置しました。

ViewController

import UIKit

class ViewController: UIViewController {

    @IBOutlet private weak var coveringView: UIView!
    @IBOutlet private weak var clippingView: UIView!

    override func viewDidLoad() {
        super.viewDidLoad()
    }

    @IBAction private func clipView() {
        coveringView.clipMask(withRect: clippingView.frame, isReversed: true)
    }
}

デモ

このような感じで切り抜きが出来ました。

demo-clip-mask

おわりに

UIViewを切り抜くことが出来ました。今回はUIViewでの切り抜き方法でしたが、SwiftUIでのViewの切り抜き方法について今度調べてみたいと思いました。

この記事が誰かの救いになれば嬉しいです。

参考