iOS
Swift

ボタンのタップ領域を拡張する

はじめに

Try Swift2018の「関心の分離と単純化のためのSwiftコードの最適化」のセッションの中で紹介されていた内容を共有します。

例えば、デザイナーさんからHIGを無視した小さなボタンのデザインが来たが、デザインを変えずに、ボタンのタップ領域のみ拡張する例です。

例1

個別にタップ領域を拡張する。

button.frame = CGRect(origin: .zero, size: CGSize(width: 44, height: 44))

例2

hitTestメソッドをオーバーライドしてタップ領域を拡張する。
使い方をUIButtonをMinimunHitAreaButtonに変更する。

import UIKit

final class MinimunHitAreaButton: UIButton {

    let mimimumHitAreaWidth = 44
    let mimimumHItAreaHeight = 44

    override func hitTest(_ point: CGPoint, with event: UIEvent?) -> UIView? {
        guard !isHidden && isEnabled && isUserInteractionEnabled && alpha >= 0.01 else {
            return nil
        }

        let lengthOfTappableAreaOutside: CGFloat = 10.0
        let mimimumHitAreaSize = CGSize(width: mimimumHitAreaWidth, height: mimimumHItAreaHeight)

        // hitFrameをmimimumHitAreaSizeに変更する
        let buttonSize = bounds.size
        let widthToAdd = max(mimimumHitAreaSize.width - buttonSize.width, lengthOfTappableAreaOutside * 2)
        let heightToAdd = max(mimimumHitAreaSize.height - buttonSize.height, lengthOfTappableAreaOutside * 2)
        let largerFrame = bounds.insetBy(dx: -widthToAdd / 2, dy: -heightToAdd / 2)

        // 大きいフレームでhitTestを実行する
        let hit = largerFrame.contains(point)
        return hit ? self :nil
    }
}

まとめ

やり方は、他にも色々ありますが、今回紹介された方法をご紹介しました。
参考になればと思います。