Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

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 the ones in the iOS control center.
Note that I want the same iOS thumb, not a custom thumb image. So far, I've tried thumbRect(forBounds...) but no luck.
Any suggestions?

like image 497
UI Scuti Avatar asked Feb 07 '17 14:02

UI Scuti


People also ask

What is UISlider?

A control for selecting a single value from a continuous range of values.


2 Answers

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.

enter image description here

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>
like image 82
Axel Guilmin Avatar answered Oct 08 '22 11:10

Axel Guilmin


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)         setThumbImage(thumb, for: .highlighted)     }          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:

enter image description here

like image 32
Adam Avatar answered Oct 08 '22 12:10

Adam