Skip to content

Instantly share code, notes, and snippets.

@Tulakshana
Last active October 9, 2024 07:20
Show Gist options
  • Save Tulakshana/0b903747c20e04a14160882ce51230e3 to your computer and use it in GitHub Desktop.
Save Tulakshana/0b903747c20e04a14160882ce51230e3 to your computer and use it in GitHub Desktop.
A subclass of UISlider which has a tool tip indicating the current value of the slider.
import UIKit
class CustomSlider: UISlider {
private var toolTip: ToolTipPopupView?
override func awakeFromNib() {
super.awakeFromNib()
self.initToolTip()
}
private func initToolTip() {
toolTip = ToolTipPopupView.init(frame: CGRect.zero)
toolTip?.backgroundColor = UIColor.clear
toolTip?.draw(CGRect.zero)
self.addSubview(toolTip!)
}
override func thumbRect(forBounds bounds: CGRect, trackRect rect: CGRect, value: Float) -> CGRect {
let knobRect = super.thumbRect(forBounds: bounds, trackRect: rect, value: value)
let popupRect = knobRect.offsetBy(dx: 0, dy: -(knobRect.size.height))
toolTip?.frame = popupRect.offsetBy(dx: 0, dy: 0)
toolTip?.setValue(value: self.value)
return knobRect
}
}
class ToolTipPopupView: UIView {
private var toolTipValue: NSString?
override func draw(_ rect: CGRect) {
if toolTipValue != nil {
let paraStyle = NSMutableParagraphStyle.init()
paraStyle.lineBreakMode = .byWordWrapping
paraStyle.alignment = .center
let textAttributes = [NSAttributedStringKey.font: UIFont.textFont(), NSAttributedStringKey.paragraphStyle: paraStyle, NSAttributedStringKey.foregroundColor: UIColor.white]
if let s: CGSize = toolTipValue?.size(withAttributes: textAttributes) {
let yOffset = s.height
let textRect = CGRect.init(x: self.bounds.origin.x, y: yOffset, width: self.bounds.size.width, height: s.height)
toolTipValue?.draw(in: textRect, withAttributes: textAttributes)
}
}
}
func setValue(value: Float) {
toolTipValue = NSString.init(format: "%d", Int(value))
self.setNeedsDisplay()
}
}
@shalinipk
Copy link

Thank you. This helped me immensely

@Tulakshana
Copy link
Author

You are welcome. I’m glad it did.

@NickCorel
Copy link

NickCorel commented Feb 1, 2022

I had to change the code to this for it to work. Maybe I have a newer version of swift... although I am coding my first app so idk.

import UIKit

class CustomSlider: UISlider {

    private var tool_tip: ToolTipPopupView?
    
    override func awakeFromNib() {
        super.awakeFromNib()
        
        self.initToolTip()
    }
    
    private func initToolTip() {
        tool_tip = ToolTipPopupView.init(frame: CGRect.zero)
        tool_tip?.backgroundColor = UIColor.clear
        tool_tip?.draw(CGRect.zero)
        self.addSubview(tool_tip!)
    }
    
    override func thumbRect(forBounds bounds: CGRect, trackRect rect: CGRect, value: Float) -> CGRect {
        
        let knobRect = super.thumbRect(forBounds: bounds, trackRect: rect, value: value)
        
        let popupRect = knobRect.offsetBy(dx: 0, dy: -(knobRect.size.height))
        tool_tip?.frame = popupRect.offsetBy(dx: 0, dy: 0)
        tool_tip?.setValue(value: self.value)
        
        return knobRect
    }
}

class ToolTipPopupView: UIView {
    
    private var toolTipValue: NSString?
    
    override func draw(_ rect: CGRect) {
        
        if toolTipValue != nil {
            
            let paraStyle = NSMutableParagraphStyle.init()
            paraStyle.lineBreakMode = .byWordWrapping
            paraStyle.alignment = .center
            
            let textAttributes = [NSAttributedString.Key.font: UIFont(name: "Helvetica", size: 10), NSAttributedString.Key.paragraphStyle: paraStyle, NSAttributedString.Key.foregroundColor: UIColor.white]
            
            if let s: CGSize = toolTipValue?.size(withAttributes: textAttributes as [NSAttributedString.Key : Any]) {
                let yOffset = s.height
                let textRect = CGRect.init(x: self.bounds.origin.x, y: yOffset, width: self.bounds.size.width, height: s.height)
                

                toolTipValue?.draw(in: textRect, withAttributes: textAttributes as [NSAttributedString.Key : Any])
            }
        }
    }
    
    func setValue(value: Float) {
        toolTipValue = NSString.init(format: "%d", Int(value))
        self.setNeedsDisplay()
    }
}

Also what I did not know that you had to:

  1. Go to identity inspector while having the slider selected on Main
  2. The field with the label class, you need to enter "CustomSlider" (the name of the swift file and class)
  3. Tick inherent module from target

Hope this helped any newbies like me. Take what I have done with a grain of salt as I am a newbie.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment