LoginSignup
22
14

More than 5 years have passed since last update.

IB上で範囲の確認ができるUIButtonのタップエリアを拡大する実装

Last updated at Posted at 2017-05-11

はじめに

こんにちは:leaves:
少し前にボタンの大きさやデザインを変えずにタップ領域だけを広くする事について悩んだ際に【iOS】UIButtonのタップ領域だけを拡大するという素晴らしい記事を拝見し、実装することができたので共有してみたいと思います。今回はIB上での拡大した領域の確認値の設定が出来るようにしてみました。

screen.png

ソースコード

クラス名や関数名など、ご自由に変更してください

TapAreaExpandButton.swift
import UIKit

@IBDesignable class TapAreaExpandButton: UIButton {

    @IBInspectable var dotLineColor: UIColor = .black

    @IBInspectable var top: CGFloat {
        get { return expandEdgeInsets.top }
        set { expandEdgeInsets.top = newValue }
    }
    @IBInspectable var left: CGFloat {
        get { return expandEdgeInsets.left }
        set { expandEdgeInsets.left = newValue }
    }
    @IBInspectable var bottom: CGFloat {
        get { return expandEdgeInsets.bottom }
        set { expandEdgeInsets.bottom = newValue }
    }
    @IBInspectable var right: CGFloat {
        get { return expandEdgeInsets.right }
        set { expandEdgeInsets.right = newValue }
    }

    var expandEdgeInsets = UIEdgeInsets.zero

    var expandedBounds: CGRect {
        return CGRect(x: bounds.origin.x - expandEdgeInsets.left,
                      y: bounds.origin.y - expandEdgeInsets.top,
                      width: bounds.size.width + expandEdgeInsets.left + expandEdgeInsets.right,
                      height: bounds.size.height + expandEdgeInsets.top + expandEdgeInsets.bottom)
    }

    override init(frame: CGRect) {
        super.init(frame: frame)
    }

    required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
    }

    override func point(inside point: CGPoint, with event: UIEvent?) -> Bool {
        return expandedBounds.contains(point)
    }

    //IB上でのみ実行される処理
    override func prepareForInterfaceBuilder() {
        if expandEdgeInsets == UIEdgeInsets.zero { return }
        let tapGuideView = UIView(frame: expandedBounds)
        let lineLayer = CAShapeLayer()
        lineLayer.frame = tapGuideView.bounds
        lineLayer.strokeColor = dotLineColor.cgColor
        lineLayer.lineWidth = 1
        lineLayer.lineDashPattern = [2, 2]
        lineLayer.fillColor = nil
        lineLayer.path = UIBezierPath(rect: lineLayer.frame).cgPath
        tapGuideView.isUserInteractionEnabled = false
        tapGuideView.backgroundColor = UIColor.clear
        tapGuideView.isHidden = false
        tapGuideView.layer.addSublayer(lineLayer)
        addSubview(tapGuideView)
    }
}

実装について

  • UIButtonに対して点線を入れても表示するサイズが足りないため、 Interface Builder上で実行されるprepareForInterfaceBuilder()で表示用のUIViewを作成しています。

IB.pngRun.png

  • @IBInspectableUIEdgeInsetsに対応されていないため、CGFloatを用いて間接的に値を設定しています

value.png

参考にさせていただいた記事

見て頂いてありがとうございます。

22
14
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
22
14