カテゴリー
iOS Swift

Custom Slider Barを作ってみた

Github Repo

UIViewのoverride func touchesMoved() のtouchesは色々な情報を含んでいますが、その中のtouches: Set<UITouch>を利用しています。

ポイントとしては。。。

scaleBar.layer.anchorPointのイニシャル値はセンター(0.5, 0.5)ですが、(0.5, 1)とすることでshapeの底辺中央をanchorPointに設定できます。

iOSではy値はその自身の左上コーナーを基点とするので、自身のheightからy値を引いたものをyValueとし、scaleBy(x: 1, yValue)でy方向にのみscaleさせています。

0 <= yValue <= height としたいため、max(min(height, touch.location(in: self).y), 0) としています。

RxSwiftのBehaviorRelayを使って、スライダーの値が変化する度にUIなどを変更出来るようにしています。

lazy var scaleBar: UIView = {
    let scaleBar = UIView()
    scaleBar.translatesAutoresizingMaskIntoConstraints = false
    scaleBar.backgroundColor = .blue
    // initial anchorPoint is (0.5, 0.5) and the shape stretches from the center
    scaleBar.layer.anchorPoint = CGPoint(x: 0.5, y: 1)
    return scaleBar
}()

override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?) {
    guard let touch = touches.first else { return }
    let yValue = height - max(min(height, touch.location(in: self).y), 0)
    yValueRelay.accept(yValue)
    scaleBar.transform = startTransform?.scaledBy(x: 1, y: yValue) ?? CGAffineTransform.identity
}