7

Is there a way to transform the content of a specific segment contained in segmented control? (I have to rotate it by 180deg)

Not the image contained in it, because in my case there isn't one (I have used FontAwesome)

Demonstration:

from: original to: rotated

Dorad
  • 3,413
  • 2
  • 44
  • 71

2 Answers2

4

Yes there is!

Consider that we have a segmented control contains 3 segments:

enter image description here

Actually, it is a view which contains 3 subviews, typed as UISegment. If we try to print this segmented control subviews (Assuming that we connected it to the desired view controller as segmentedControl IBOutlet):

class ViewController: UIViewController {
    // MARK:- IBOutlets
    @IBOutlet weak var segmentedControl: UISegmentedControl!

    override func viewDidLoad() {
        super.viewDidLoad()

        for view in segmentedControl.subviews {
            print(view)
        }
    }
}

The log should display something similar to:

UISegment: 0x7febebc06980; frame = (229 0; 114 29); layer = CALayer: 0x60000002edc0 UISegment: 0x7febebe140c0; frame = (114 0; 114 29); layer = CALayer: 0x618000231800 UISegment: 0x7febebe14d30; frame = (0 0; 113 29); layer = CALayer: 0x6180002319c0

So, you can access the segments in the segmented control as a UISegment, thus apply needed edit to it as a UIView. For instance, if you want to rotate the second segment, you could implement:

override func viewDidLoad() {
    super.viewDidLoad()

    for view in segmentedControl.subviews[1].subviews {
        print(view)
        view.transform = CGAffineTransform(scaleX: -1, y: 1)
    }
}

As you can see, the segment also has subviews:

UISegmentLabel: 0x7f8b51701770; frame = (0 0; 64 22.5); text = 'Second'; opaque = NO; userInteractionEnabled = NO; layer = _UILabelLayer: 0x610000091530

UIImageView: 0x7f8b51701470; frame = (114 0; 1 1); alpha = 0; opaque = NO; autoresize = LM; userInteractionEnabled = NO; tag = -1030; layer = CALayer: 0x610000031480

So, you should rotate all of these subviews, as implemented in above the code snippet.

The output would be:

enter image description here


The same approach should be applicable with segmented controls that have images instead of titles:

Before rotating:

enter image description here

After rotating:

enter image description here

Ahmad F
  • 30,560
  • 17
  • 97
  • 143
  • Could you mention what is the problem? have you tried to print the subviews of a segmented control as mentioned in the answer? I think that you might miss something... – Ahmad F Jul 19 '17 at 14:26
  • it's printing pretty the same, but the view isn't changing. – Dorad Jul 19 '17 at 14:30
  • If it prints the same (it contains subviews of UISegment), then it should works fine... If you think that there is a specific part of the mentioned code is not working, please tell me about it. I might create a repo and share it... – Ahmad F Jul 19 '17 at 14:48
  • In iOS 13, I am experiencing a bug that causes subviews to return 3 instances of UISegment, as well as 3 instances of UIImageView. So there are 6 subviews in total. It's making it difficult to access the UISegments as UISegment is private. – swiftyboi Oct 25 '19 at 17:19
1

A segment is a small UIView, you can just apply a transformation to it.

Refer to this question about getting the subview:

UISegmentedControl selected segment color

And refer to this other one to "rotate" the content.

How to rotate UIView using transform

Then again, i'd just be easier to make an image out of it and use that instead.

Pochi
  • 13,391
  • 3
  • 64
  • 104
  • Thanks @Pochi. However when the whole UIView is being mirrored, some other properties are flipped too, like those rounded borders. I have edit the question now - asking for flipping UIView's content and not the UIView itself. P.S.: UIView doesn't contain a UILabel. It contains a thing called UISegmentLabel. – Dorad Jul 13 '17 at 12:49