Bharat Raichur
Bharat Raichur

Reputation: 435

Changing UISwitch width and height

I am trying to change the default height and width of a UISwitch element in iOS, but unsuccessfully.

Can you change the default height and width of a UISwitch element?
Should the element be created programmatically?

Upvotes: 39

Views: 50489

Answers (9)

markckim
markckim

Reputation: 499

Based on Ivan's solution that only takes in a desired height value in order to maintain aspect ratio and avoid "stretching".

extension UISwitch {
    func set(absoluteHeight: CGFloat) {
        let standardHeight = CGFloat(31)

        let heightRatio = absoluteHeight / standardHeight

        transform = CGAffineTransform(scaleX: heightRatio, y: heightRatio)
    }
}

Upvotes: 0

Simran Singh Sandhu
Simran Singh Sandhu

Reputation: 501

switchBtn.transform = CGAffineTransform(scaleX: 0.8, y: 0.8)

Upvotes: -1

Luda
Luda

Reputation: 7058

import UIKit

extension UISwitch {

    static let standardHeight: CGFloat = 31
    static let standardWidth: CGFloat = 51
    
    @IBInspectable var width: CGFloat {
        set {
            set(width: newValue, height: height)
        }
        get {
            frame.width
        }
    }
    
    @IBInspectable var height: CGFloat {
        set {
            set(width: width, height: newValue)
        }
        get {
            frame.height
        }
    }
    
    func set(width: CGFloat, height: CGFloat) {

        let heightRatio = height / UISwitch.standardHeight
        let widthRatio = width / UISwitch.standardWidth

        transform = CGAffineTransform(scaleX: widthRatio, y: heightRatio)
    }
}

Upvotes: 1

Aaron T
Aaron T

Reputation: 179

Even if it’s possible to make a UISwitch smaller, this would negatively effect the user experience. Apple's Human Interface Guidelines recommend a minimum size of 44 points for touch targets.

Provide ample touch targets for interactive elements. Try to maintain a minimum tappable area of 44pt x 44pt for all controls

By scaling this to smaller than the standard size, it will become more difficult for users to tap, and also introduce accessibility concerns. Please consider users with less than perfect vision or motor control before making UI elements small.

Finally, here’s an excerpt from a great article about touch target sizes illustrating what can happen when controls are too small.

Interviewer — “I noticed, you had some trouble submitting your email address on this screen, can you tell me how that felt?”

User — “Oh yeah, I’m not very good at technology.”

Interviewer — “What do you think was causing you to struggle at that point?”

User — “The buttons were hard to tap, and I just kept stuffing it up.”

Upvotes: 1

Ivan
Ivan

Reputation: 1434

Swift 5:

import UIKit

extension UISwitch {

    func set(width: CGFloat, height: CGFloat) {

        let standardHeight: CGFloat = 31
        let standardWidth: CGFloat = 51

        let heightRatio = height / standardHeight
        let widthRatio = width / standardWidth

        transform = CGAffineTransform(scaleX: widthRatio, y: heightRatio)
    }
}

Upvotes: 20

Barath
Barath

Reputation: 1754

Swift 4

@IBOutlet weak var switchDemo: UISwitch!

override func viewDidLoad() {
    super.viewDidLoad()
   switchDemo.transform = CGAffineTransform(scaleX: 0.75, y: 0.75)
}

Upvotes: 35

William George
William George

Reputation: 6785

I tested the theory and it appears that you can use a scale transform to increase the size of the UISwitch

UISwitch *aSwitch = [[UISwitch alloc] initWithFrame:CGRectMake(120, 120, 51, 31)];
aSwitch.transform = CGAffineTransformMakeScale(2.0, 2.0);
[self.view addSubview:aSwitch];

Upvotes: 49

Benny Davidovitz
Benny Davidovitz

Reputation: 1202

here is a nice UISwitch subclass that i wrote for this purpose, its also IBDesignable so you can control it from your Storyboard / xib

@IBDesignable class BigSwitch: UISwitch {

    @IBInspectable var scale : CGFloat = 1{
        didSet{
            setup()
        }
    }

    //from storyboard
    required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
        setup()
    }
    //from code
    override init(frame: CGRect) {
        super.init(frame: frame)
        setup()
    }

    private func setup(){
        self.transform = CGAffineTransform(scaleX: scale, y: scale)
    }

    override func prepareForInterfaceBuilder() {
        setup()
        super.prepareForInterfaceBuilder()
    }


}

Upvotes: 15

Warren Burton
Warren Burton

Reputation: 17372

Not possible. A UISwitch has a locked intrinsic height of 51 x 31 .

You can force constraints on the switch at design time in the xib...

enter image description here

but come runtime it will snap back to its intrinsic size.

You can supply another image via the .onImage / .offImage properties but again from the docs.

The size of this image must be less than or equal to 77 points wide and 27 points tall. If you specify larger images, the edges may be clipped.

You are going to have to bake your own custom one if you want another size.

Upvotes: 17

Related Questions