詳解UISlider(見た目をカスタマイズのいろは)
Sliderの色を変える

minimumTrackTintColorとmaximumTrackTintColorで左右の色を変更することができます
コード
slider.minimumTrackTintColor = .red
slider.maximumTrackTintColor = .green
両橋に画像を設定する

コード
slider.minimumValueImage = UIImage(named: "uni_cabbage")
slider.maximumValueImage = UIImage(named: "cooking_lemon")
背景を変更する
画像のサイズに関してはそのまま表示されてしまうので高さを自分で調節する必要があります。今回はデフォルトのUISliderの高さが30だったので画像の高さを30にして検証しています。
コード
let trackImg = UIImage(named: "bg_himawari_hatake_wide")!.resizableImage(withCapInsets: .zero, resizingMode: .tile)
slider.setMinimumTrackImage(trackImg, for: .normal)
slider.setMaximumTrackImage(trackImg, for: .normal)

つまみの画像を変更する
つまみに関しても背景画像と同じようにそのままのサイズでぶち込むとデカすぎるので高さを30に修正してから画像を入れています。
コード
slider.setThumbImage(UIImage(named: "sliderButton")!.resizableImage(withCapInsets: .zero, resizingMode: .tile), for: .normal)

タップ領域
UISliderのタップ領域に関しては高さの制約と画像を差し替えることで可能です。
Slider自体のScaleとかをいじれば標準のものでも実現できると思うのですがそちらは試していません。

UISliderの高さの制約を60にして画像の高さも60に合わせてみたときの挙動です。高さがわかりにくいのでUISliderに背景色を入れています。
タップで移動

コード
override func viewDidLoad() {
super.viewDidLoad()
let tapGestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(sliderTapped(gestureRecognizer:)))
self.slider.addGestureRecognizer(tapGestureRecognizer)
}
@objc func sliderTapped(gestureRecognizer: UIGestureRecognizer) {
let pointTapped: CGPoint = gestureRecognizer.location(in: self.view)
let positionOfSlider: CGPoint = slider.frame.origin
let widthOfSlider: CGFloat = slider.frame.size.width
let newValue = ((pointTapped.x - positionOfSlider.x) * CGFloat(slider.maximumValue) / widthOfSlider)
slider.setValue(Float(newValue), animated: true)
}