Help us understand the problem. What is going on with this article?

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

More than 3 years have passed since last update.

はじめに

こんにちは:leaves:
UISliderThumbにオリジナルの画像を設定してカスタマイズした際などに、
タップ領域について気になったので、投稿してみたいと思います。
至らぬ点など多々あると思いますが、コメントなど頂けたら幸いです。

snap.png

実装について

※ このような画像をThumbに設定して、画像自体が細くてタッチエリアが不安でも、領域を調節することができます。

ThumbImg = Rectangle.png

※ タップ領域を拡大する方法として、画像に透明色を塗り、画像自体を大きくする方法もあるみたいです。
https://stackoverflow.com/questions/13196263/custom-uislider-increase-hot-spot-size

ソースコード

※ この記事のUISliderのThumbの表示領域(SizeやFrame)を計算するExtensionを利用しています。

TapAreaExpandSlider.swift
import UIKit

@IBDesignable class TapAreaExpandSlider: UISlider {

    @IBInspectable var thumbImage: UIImage? {
        didSet {
            setThumbImage(thumbImage, for: .normal)
        }
    }

    @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 expandedThumbBounds: CGRect {
        return CGRect(x: thumbBounds.origin.x - expandEdgeInsets.left,
                      y: thumbBounds.origin.y - expandEdgeInsets.top,
                      width: thumbBounds.size.width + expandEdgeInsets.left + expandEdgeInsets.right,
                      height: thumbBounds.size.height + expandEdgeInsets.top + expandEdgeInsets.bottom)
    }

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

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

    override func beginTracking(_ touch: UITouch, with event: UIEvent?) -> Bool {
        let location = touch.location(in: self)
        return expandedThumbBounds.contains(location)
    }

    //IB上でのみ実行される処理
    override func prepareForInterfaceBuilder() {
        setThumbImage(thumbImage, for: .normal)
        if expandEdgeInsets == UIEdgeInsets.zero { return }
        let tapGuideView = UIView(frame: expandedThumbBounds)
        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)
    }
}

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

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

KikurageChan
見て頂いてありがとうございます。
https://kikuragechan.com
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away