Edited at

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

More than 1 year has 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)
}
}



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

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