はじめに
swiftでsliderを使用するとなると、UISliderが一般的ですよね。
ただ、つまみを2つにしたい(範囲を選択したいなど)場合はUISliderでは難しいのが現実だと思います。
そこでRangeUISliderというライブラリを使い、実現できたので記載していきます。
ライブラリ
podでインポートします。
pod 'RangeUISlider', '~> 3.0'
※SwiftPackageManagerでも入れることができます
イメージ

今回は時間間隔を取得するケースです。
左のつまみ調整で開始時間、右のつまみ調整で終了時間がLabelに反映されます。
ソースコード
import UIKit
import RangeUISlider
final class RangeUISliderViewController: UIViewController {
@IBOutlet weak var startTimeLabel: UILabel!
@IBOutlet weak var endTimeLabel: UILabel!
@IBOutlet weak var rangeUISlider: RangeUISlider! {
didSet {
rangeUISlider.delegate = self
}
}
override func viewDidLoad() {
setUpView()
}
}
// MARK: - SetUpRangeUISlider
extension RangeUISliderViewController: RangeUISliderDelegate {
func rangeIsChanging(minValueSelected: CGFloat, maxValueSelected: CGFloat, slider: RangeUISlider) {
startTimeLabel.text = SliderCalculation.transformTimeString(value: minValueSelected)
endTimeLabel.text = SliderCalculation.transformTimeString(value: maxValueSelected)
}
func setUpView() {
rangeUISlider.leftKnobColor = .blue
rangeUISlider.rightKnobColor = .blue
rangeUISlider.rangeSelectedColor = .blue
rangeUISlider.rangeNotSelectedColor = UIColor.gray
rangeUISlider.leftKnobWidth = 20
rangeUISlider.leftKnobHeight = 20
rangeUISlider.leftKnobCorners = 10
rangeUISlider.rightKnobWidth = 20
rangeUISlider.rightKnobHeight = 20
rangeUISlider.rightKnobCorners = 10
rangeUISlider.barHeight = 5
rangeUISlider.scaleMinValue = 0
rangeUISlider.scaleMaxValue = 100
rangeUISlider.defaultValueLeftKnob = 0
rangeUISlider.defaultValueRightKnob = 100
rangeUISlider.scaleMinValue = 0
rangeUISlider.scaleMaxValue = 96
rangeUISlider.stepIncrement = 1
}
}
まずはViewを配置して、@IBOutletで繋ぎます。
その際、TypeをUIViewではなくRangeUISliderにするのが肝です。
あとは開始時間と終了時間のLabelを追加します。
値はどうやって受けとっているかというと・・
func rangeIsChanging(minValueSelected: CGFloat, maxValueSelected: CGFloat, slider: RangeUISlider) {
startTimeLabel.text = SliderCalculation.transformTimeString(value: minValueSelected)
endTimeLabel.text = SliderCalculation.transformTimeString(value: maxValueSelected)
}
上記メソッドで、minValueSelectedが最小の値、maxValueSelectedで最大の値をCGFloatで受け取れます。
そして、計算用クラスのメソッドでStringに変換しています。
import UIKit
final class SliderCalculation {
// CGFloatで渡ってきた値を時間に変換して返す
static func transformTimeString(value: CGFloat) -> String {
let hour = floor(value / 4)
let minute = value.truncatingRemainder(dividingBy: 4) * 15
// 0埋めする
var formatHour = String(format: "%02.0f", hour)
var formatMinute = String(format: "%02.0f", minute)
return "\(formatHour):\(formatMinute)"
}
}
全体の範囲が24時間で、15分刻みの値を取得する計算です。
セットアップ時にデフォルトの最小・最大値を決定しています。
rangeUISlider.scaleMaxValue = 96
rangeUISlider.stepIncrement = 1
時間取得の場合は単純に4で割り、分取得の場合は4で割った余りに15をかけています。
その後に0埋めして、Stringとして返せば終わり。
let hour = floor(value / 4)
let minute = value.truncatingRemainder(dividingBy: 4) * 15
//valueが50の場合・・・
//12:30となる
おわりに
ソースコードはGitHubにのせていますので、サクッと挙動確認したい場合はそちらから↓
計算の箇所はもっとスッキリとした書き方がありそうなので、分かる方はご教授願います・・!