how to add UILabel over slider thumb with step slider?
Asked Answered
U

3

6

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)
Urbanity answered 20/5, 2018 at 9:15 Comment(0)
P
12

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)
}
Phlogistic answered 20/5, 2018 at 10:51 Comment(7)
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! can you help me fix it?!Urbanity
Are you using Auto Layout?Phlogistic
no! I put my label fixed with my own constraints! I tried to add my label programmatically, and the jump issue solved, but my label is not showing until I touch thumb and move it! :(Urbanity
Please show me how you are adding the label programmaticallyPhlogistic
I've added what Ive done to my code! thank you very much for your time and help!Urbanity
And this doesn't work? Are you changing the text of the label according to the slider value?Phlogistic
Are you setting the text of the label in ViewDidLoad?Phlogistic
S
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() 
}
Sussex answered 24/6, 2021 at 12:22 Comment(0)
H
1

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
    } 
}
Haemophilia answered 29/9, 2022 at 10:19 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.