5

I have a slider with 5 part, which I wanted to step over for these part! and I did this :

@IBAction func changeCostSlider(_ sender: UISlider) {
    sender.value = roundf(costSlider.value)
}

I also want to add a label over the thumb of my slider, I tried to add this code to the code above :

let trackRect: CGRect  = costSlider.trackRect(forBounds: costSlider.bounds)
    let thumbRect: CGRect  = costSlider.thumbRect(forBounds: costSlider.bounds , trackRect: trackRect, value: costSlider.value)
    let x = thumbRect.origin.x + costSlider.frame.origin.x
    let y = costSlider.frame.origin.y - 20
    sliderLabel.center = CGPoint(x: x, y: y)

but when I move my slider, my label jumps from where I put the label in storyboard, and it has some lags! anybody have any suggestion on how to add this label to my step slider and works correctly?!

I think my problem is that I put my UILable fixed in storyborad, and when I move thumb in slider, for a mili second, it goes back to the fixed place! how can I solve it?!

I've tried to add my UILabel programmatically and it's not working until I touch the thumb! and there is how it's done:

var sliderLableP = UILabel()
@IBAction func changeCostSlider(_ sender: UISlider) {
    sender.value = roundf(costSlider.value)
    print(costSlider.value)
    let trackRect: CGRect  = costSlider.trackRect(forBounds: costSlider.bounds)
    let thumbRect: CGRect  = costSlider.thumbRect(forBounds: costSlider.bounds , trackRect: trackRect, value: costSlider.value)
    let x = thumbRect.origin.x + costSlider.frame.origin.x
    let y = costSlider.frame.origin.y - 20
    sliderLableP.center = CGPoint(x: x, y: y)
}

and in my viewDidLoad I've added this:

sliderLableP = UILabel(frame: CGRect(x: 0, y: 0, width: 100, height: 20))
    let trackRect: CGRect  = costSlider.trackRect(forBounds: costSlider.bounds)
    let thumbRect: CGRect  = costSlider.thumbRect(forBounds: costSlider.bounds , trackRect: trackRect, value: costSlider.value)
    let x = thumbRect.origin.x + costSlider.frame.origin.x
    let y = costSlider.frame.origin.y - 20
    sliderLableP.center = CGPoint(x: x, y: y)
    sliderLableP.textAlignment = NSTextAlignment.center
    sliderLableP.textColor = UIColor.blue
    self.containerView.addSubview(sliderLableP)
    containerView.bringSubview(toFront: sliderLableP)
Azin Nilchi
  • 849
  • 1
  • 10
  • 24

3 Answers3

13

This solution works for me:

@IBAction func changeCostSlider(_ sender: UISlider) {
    sender.value = roundf(sender.value)

    let trackRect = sender.trackRect(forBounds: sender.frame)
    let thumbRect = sender.thumbRect(forBounds: sender.bounds, trackRect: trackRect, value: sender.value)
    self.sliderLabel.center = CGPoint(x: thumbRect.midX, y: self.sliderLabel.center.y)
}
Josef Zoller
  • 921
  • 2
  • 8
  • 24
1

I have created an extension of UISlider.

extension UISlider {

    func setThumbValueWithLabel() -> CGPoint {
    
        let slidertTrack : CGRect = self.trackRect(forBounds: self.bounds)
        let sliderFrm : CGRect = self.thumbRect(forBounds: self.bounds, trackRect: slidertTrack, value: self.value)
        return CGPoint(x: sliderFrm.origin.x + self.frame.origin.x + 8, y: self.frame.origin.y - 20)
    }
}

This is how you can use this:-

step1:- add an target action on .valueChanged property of UISlider.

self.slider.addTarget(self, action: #selector(sliderValueChanged),for: .valueChanged)
    

step2:- on sliderValueChanged() method, use the extension method.

@objc private func sliderValueChanged(_ sender: UISlider) {
    
    self.yourLabel.text = Int(sender.value).description
    self.yourLabel.center = sender.setThumbValueWithLabel() 
}
Vipul Kumar
  • 893
  • 9
  • 19
0

assign CustomSlider class to UISlider

class CustomSlider: UISlider { 
    private var thumbTextLabel = UILabel()

    private var thumbFrame: CGRect {
        thumbRect(forBounds: bounds, trackRect: trackRect(forBounds: bounds), value: value)
    }

    override func layoutSubviews() {
        super.layoutSubviews()
        thumbTextLabel.text = "\(Int(value))" // change text as per required
        thumbTextLabel.frame = CGRect(x: thumbFrame.origin.x, y: thumbFrame.maxY - 5, width: 100, height: 30) // change width as per length of your text
        thumbTextLabel.center = CGPoint(x: thumbFrame.midX, y: thumbTextLabel.center.y)
    }

    override func awakeFromNib() {
        super.awakeFromNib()
        addSubview(thumbTextLabel)
        // MARK: formate your label
        thumbTextLabel.font = UIFont(name: "popins-Regular", size: size) ?? UIFont.systemFont(ofSize: size, weight: .medium)
        thumbTextLabel.textAlignment = .center
        thumbTextLabel.textColor = .white
        thumbTextLabel.layer.zPosition = layer.zPosition + 1
    } 
}
Deep Gandhi
  • 157
  • 1
  • 4
  • 13