How To Custom UISegmentControl
Version: Swift 5, iOS 13.0, Xcode 13.0
In this article, we will learn about how to custom UISegmentControl, such as corner radius, selected imageView color.
Demo :
Have you ever written following code of Figure 0.1 to modify corner radius, and UISegmentedControl not thing changed at all…
If you have the problem same as me, let’s begin following tutorial !
Standard
Step 1.0
Create a subclass of UISegmentedControl :
Create a subclass of UISegmentedControl , named “CustomizableSegmentControl” and configure the first item status was selected.
We will change it’s corner radius and color in this class.
Step 1.1
Analyze UISegmentControl’s view hierarchy :
We have to know UISegmentControl’s view hierarchy, before we want to change it’s radius and color.
We have to know how many subviews on UISegmentedControl and which subviews these are we want to modify corner radius and color, let’s watch Figure 1.1.1.
In Figure 1.1.1, we can see the bottom view is the orange view and it’s the UISegmentedControl background view, if we want to modify corner radius , we have to find it’s subviews and modify corner radius and color.
Step 1.2
Modify corner radius :
Now, let’s define a property to store radius in CustomizableSegmentControl.swift, like Figure 1.2.1.
Every UI element from loading memoery to render on screen, it go through many life cycle, when the UI will render on to screen , it will excuted func layoutSubviews(), so we can override this life cycle and modify corner radius to what we want.
If you instaniate CustomizableSegmentControl and add it to view that you want to show, you will see Figure 1.2.3 , it’s great! But, the Figure 1.2.3 have some different with fighre 1.2.4 that we want, let’s keep refining it !
Step 1.3
Modify Selected Segment Apperance :
Let’s see what are the differences between Figure 1.2.3 and Figure 1.2.4
- Different selected segment color.
- Different edge inset.
- Different selected segment corner radius.
First, let’s handle the first point ,modify the selected color. Go back to Figure 1.1.1, we can the green view is a UIImageView, and it is representing selected segment, we call it “selected imageView”. So, we just need to modify the selected imageView background color to green, well… sounds simply, but, how did we find the selected ImageView ?
Let’s looking carefully at the view hierarchy of Fighure 1.1.1, we can find selected imageView from subviews of CustomizableSegmentControl’s backgroundView.
So we can write following code of Figure 1.3.1 to find selectedImageView , and change the color:
Why we can find selected imageView by the code of Figure 1.3.1 ?
Let’s see Figure 1.1.1, we can find the selected imageView at the position of subviews[2], if we have three items in UISegmentedControl, the selected imageView position of subview will atsubviews[3].
According to this logicso, we using nuberOfSegments property to representing selected imageView index of subviews, and get the selected imageView of subviews, then we modify it’s background color and set the image to nil.
Well! Looks great!! The selected imageView not only color cnaged but also snap to edge, but…we will find the selected imageView center color changed and corner radius changed when we click or swip, just like Figure 1.3.2.
Let fix it!!
Step 1.4
Configure selected imageView edge inset :
We can find , if we set selected imageView color not yet, selected imageView have some inset of edge, however when we set the color , the selected imageView will snap to edge. and the selected imageView appear inset of edge when we click or swip.
To fix it, we have to define a property to store edge inset, let’s named it “segmentInset” and this peoperty can’t be 0, or the bug can’t be fix.
Then, we add a linke of code to layoutSubviews(), like Figure 1.4.2.
Life cycle layoutSubviews() looks like Figure 1.4.3 :
Now, screen looks like Figure 1.4.4 :
Step 1.5
Configure selected imageView corner radius :
Now, looks great !! All of click and swip animation are very smooth, but we also still missing some round corners of selected imageView, let’s keep refining this effect.
In layoutSubviews(), add some code of selected imageView layer , like Figure 1.5.1:
Great !! We almost complete all function , but I find there is a bug with segmentInset, if segmentInset is slightly larger , we will see a weird effect, just like Figure 1.5.2 :
To fix this werid effect bug, we need to add a code of line in layoutSubview(), just like Figure 1.5.3
Now, life cycle layoutSubviews() should look like Figure 1.5.4:
Step 2.0
How to use :
When we complete create this subclass, just add it to which view we want to show custom UISegmentedControl, just like Figure 2.0.1.
Phew… we’re finally done this custom sub class of UISegmentedControl !!
Here is the complete code :
If my article save you some time, please give me some claps or any advice, I will very thank you.