UISegmentedControl maintain aspect ratio on image
Asked Answered
L

4

7

I'm having a hard time making images on a UISegmentedControl keep their aspect ratio and not scale to all sides. Here's what it looks like: UiSegmentedControl maintain aspect ratio

The images are 100X100(except nr 6 gonna replace soon) and I want them to maintain the aspect ratio.

I have tried:

self.segment.contentMode = .ScaleAspectFit
//and:
self.segment.contentMode = UIViewContentMode.Center

Are there a way I can target the UIImageView in the segment..that way I can set the contentMode..right? Or is there another approach?

Thanks

Lapboard answered 13/8, 2016 at 20:19 Comment(0)
B
8
segmentedControl.subviews.flatMap{$0.subviews}.forEach { subview in
    if let imageView = subview as? UIImageView, let image = imageView.image, image.size.width > 5 {
        // The imageView which isn't separator
        imageView.contentMode = .scaleAspectFit
    }
}
Beelzebub answered 5/5, 2018 at 17:27 Comment(3)
Please add an explanation.Santasantacruz
This is the only solution of found that actually works reliably. However, I'm having a hard time figuring out when (i.e., where in code) to execute it. I have a UISegmentedControl subclass, and tried putting it in awakeFromNib, but it didn't work. I also have a target action on .valueChanged, and when I handle it there it works. So there's something about the order of (re)drawing that clearly makes a difference. In my case, it's in a table view cell, so perhaps a layoutSubviews is running?Vaules
We decided to simply use a stack view with buttonsPalladio
V
2

Actually, there's a great, general purpose solution for this:

UIImageView.appearance(whenContainedInInstancesOf: [UISegmentedControl.self]).contentMode = .scaleAspectFit

This uses the approach described here: UIImageView.appearance is overriding UISegmentedControl.appearance

In my case, I constrained it to a subclass of UISegmentedControl (in case I want the default aspectFill for other situations).

Vaules answered 1/7, 2018 at 17:43 Comment(0)
G
0

I didn't find how to set the contentMode to ScaleAspectFit but you can use the following code to set a margin around your image when you are setting the image :

yourSegmentedControl.setImage(yourImage.resizableImage(withCapInsets: .init(top: 0, left: 10, bottom: 0, right: 10), resizingMode: .stretch), forSegmentAt: 0)

You can change the values of "top", "left", "bottom" and "right" as you want. This worked for me, I hope it will help!

Grossularite answered 20/12, 2016 at 21:2 Comment(0)
R
0

It is probably late for this, but Im sure it will help someone.

My Problem #1: Images in the segmented control are distorted in ratio.

My Problem #2: You can't even change the colour of the image. It remains black. Even if you use .alwaysTemplate and imageview tint colour. It wont budge.

Solution: Forget trying to hack the SDK, or achieving the goal through unofficial means. Apple can easily change the SegmentedControl and all your work becomes redundant. Use this instead: BetterSegmentedControl. Happy coding.

It is highly customisable and easy to use, plus it supports images.

Ramie answered 13/2, 2020 at 22:45 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.