How to make UISlider default thumb to be smaller like the ones in the iOS control center

后端 未结 5 541
孤独总比滥情好
孤独总比滥情好 2021-02-01 06:50

I\'m working on an app and I have a custom UISlider.
However, I\'m having some issues on how to make the default thumb to appear smaller like t

相关标签:
5条回答
  • 2021-02-01 07:38

    I created a UISlider subclass that allows to change the thumb size as well as track size, all without using images.

    import UIKit
    
    class CustomSlider: UISlider {
    
        @IBInspectable var trackHeight: CGFloat = 3
    
        @IBInspectable var thumbRadius: CGFloat = 20
    
        // Custom thumb view which will be converted to UIImage
        // and set as thumb. You can customize it's colors, border, etc.
        private lazy var thumbView: UIView = {
            let thumb = UIView()
            thumb.backgroundColor = .yellow//thumbTintColor
            thumb.layer.borderWidth = 0.4
            thumb.layer.borderColor = UIColor.darkGray.cgColor
            return thumb
        }()
    
        override func awakeFromNib() {
            super.awakeFromNib()
            let thumb = thumbImage(radius: thumbRadius)
            setThumbImage(thumb, for: .normal)
        }
    
        private func thumbImage(radius: CGFloat) -> UIImage {
            // Set proper frame
            // y: radius / 2 will correctly offset the thumb
    
            thumbView.frame = CGRect(x: 0, y: radius / 2, width: radius, height: radius)
            thumbView.layer.cornerRadius = radius / 2
    
            // Convert thumbView to UIImage
            // See this: https://stackoverflow.com/a/41288197/7235585
    
            let renderer = UIGraphicsImageRenderer(bounds: thumbView.bounds)
            return renderer.image { rendererContext in
                thumbView.layer.render(in: rendererContext.cgContext)
            }
        }
    
        override func trackRect(forBounds bounds: CGRect) -> CGRect {
            // Set custom track height
            // As seen here: https://stackoverflow.com/a/49428606/7235585
            var newRect = super.trackRect(forBounds: bounds)
            newRect.size.height = trackHeight
            return newRect
        }
    
    }
    

    Result:

    0 讨论(0)
  • 2021-02-01 07:40

    You can't change the size of the default thumb image, but UISlider has a method setThumbImage(_:for:) that will allow you to pass a similar, smaller image.

    In your view controller viewDidLoad :

    let image:UIImage? = // ...
    yourSlider.setThumbImage(image, for: .normal)
    yourSlider.setThumbImage(image, for: .highlighted) // Also change the image when dragging the slider
    

    See Customizing the Slider’s Appearance of the API Reference.


    On iOS10, the default thumb image appear to be no more than a bordered white circle with a thin shadow dropped under (if you don't set the thumbTintColor).

    I use this snippet to generate a similar image that can be scaled down ;)

    var canvas = document.getElementById("canvas");
    var ctx = canvas.getContext("2d");
    var data = " \
    <svg xmlns='http://www.w3.org/2000/svg' width='86' height='86'> \
    <foreignObject width='100%' height='100%'> \
    	<div xmlns='http://www.w3.org/1999/xhtml'> \
    		<style> \
    		#ios-uislider-thumb { \
    		  -webkit-box-sizing: content-box; \
    		  -moz-box-sizing: content-box; \
    		  box-sizing: content-box; \
    		  width: 66px; \
    		  height: 66px; \
    		  overflow: hidden; \
    		  border: 1px solid #CCC; \
    		  -webkit-border-radius: 33px; \
    		  border-radius: 33px; \
    		  background: #FFFFFF; \
    		  -webkit-box-shadow: 0 6px 6px 0 rgba(0,0,0,0.2); \
    		  box-shadow: 0 6px 6px 0 rgba(0,0,0,0.2); \
    		  margin : 5px 10px 15px 10px; \
    		} \
    		</style> \
    		<div id='ios-uislider-thumb'></div> \
    	</div> \
    </foreignObject> \
    </svg> \
    ";
    var DOMURL = self.URL || self.webkitURL || self;
    var img = new Image();
    var svg = new Blob([data], {
      type: "image/svg+xml;charset=utf-8"
    });
    var url = DOMURL.createObjectURL(svg);
    img.onload = function() {
      ctx.drawImage(img, 0, 0);
      DOMURL.revokeObjectURL(url);
    };
    img.src = url;
    <canvas id="canvas" style="border:2px dotted black;" width="86" height="86"></canvas>

    0 讨论(0)
  • 2021-02-01 07:41

    If you want to change Thumb Image as well as Tint Color then both can't be possible; There is one workaround of this issue. Create circular image programmatically and change the color of the image and assign that image to slider thumb; In this way, you can also resize the image as well as color.

    Here is the fully working sample code:

    fileprivate func makeCircleWith(size: CGSize, backgroundColor: UIColor) -> UIImage? {
        UIGraphicsBeginImageContextWithOptions(size, false, 0.0)
        let context = UIGraphicsGetCurrentContext()
        context?.setFillColor(backgroundColor.cgColor)
        context?.setStrokeColor(UIColor.clear.cgColor)
        let bounds = CGRect(origin: .zero, size: size)
        context?.addEllipse(in: bounds)
        context?.drawPath(using: .fill)
        let image = UIGraphicsGetImageFromCurrentImageContext()
        UIGraphicsEndImageContext()
        return image
    }
    

    You can call this function like this:

        func setSliderThumbTintColor(_ color: UIColor) {
        let circleImage = makeCircleWith(size: CGSize(width: 20, height: 20),
                       backgroundColor: color)
        slider.setThumbImage(circleImage, for: .normal)
        slider.setThumbImage(circleImage, for: .highlighted)
    }
    

    This method setSliderThumbTintColor will be called on valueChanged event of UISlider.

    0 讨论(0)
  • 2021-02-01 07:53

    Here's an option for you, use a CGAffineTransform.

    Swift 4

    mySlider.transform = CGAffineTransform(scaleX: 0.85, y: 0.85)
    

    This will change the width and height of the slider, so you may need to realign it with your interface.

    0 讨论(0)
  • 2021-02-01 07:55
    1. Download an image similar to the one you have in the iOS control centre.

    2. Scale it to the size you want (20x20 or even smaller) and save it in your assets.

    3. Paste the following code in viewDidLoad:

      self.yourSlider.setThumbImage(UIImage(named: "SliderName")!, for: .normal)
      
    0 讨论(0)
提交回复
热议问题