I am creating a UISegmentedControl replacement so that it works with your own custom images. Because the separators need different colors on both sides I decided to give the middle item the two borders.
Now to display the UISegmentedControl replacement, I calculate the available width for one item (frame.size.width / numberOfItems). Then I create a UIButton with a custom background image (the stretchable middle segment image). The next thing is to position everything. Because the 1px separators need to be visible when you select an item, I give every item a 1px larger frame than it actually should have. So the next item overlaps 1px to the left.
segmentRect = CGRectMake(indexOfObject * (self.frame.size.width / numberOfSegments), 0, (self.frame.size.width / numberOfSegments) + 1, self.frame.size.height);
Using this result I get a nearly perfect custom UISegmentedControl (retina): 
Now things look pretty ok, but it all changes when adding more/less segments. This was a 300px wide control by the way, so each segment gets 25px of space. If I change that number to let’s say 13, this shows up: 
Notice the slightly different border between the ‘3’ and ‘4’. (Easier to spot on non-retina actually because of pixel doubling) I think this is caused by the not so nice amount of space each segment gets. (300 / 13 =
23,0769) One should think that the stretchable image would accommodate for this, no? The separators are exactly 1px in width and I change the frame by 1px, so the two separators should be placed exactly on top of each other, which is definitely not the case here.
Does anyone have an explanation why this happens and more important a way to fix this?
All coordinates are floats (CGFloat’s, actually) by default, so if you’re handing the system non-integer coordinates it will try its best to draw between pixels, using anti-aliasing. The weird 3/4 border is probably due to this.
One solution is to give all your segments integer-sized widths. This may sound a bit nasty, since they might not all be the same width in order to fill up the space (i.e. if the overall width is not divisible by the number of segments), but code like the following shows how this can be done without too much trouble:
I personally like this technique because it automatically evenly distributes the widths that are slightly larger than the others (all the widths will be within 1 pixel of each other).
This code is not including your 1-pixel overlaps, but that is easy to add.
Another benefit is that if your UILabel’s or UIImageView’s also have integer coordinates (in the coordinate system of the entire screen), they tend to look more crisp.