How to change the colors of a segment in a UISegmentedControl in iOS 13?

IosUikitUisegmentedcontrolIos13

Ios Problem Overview


A UISegmentedControl has a new appearance in iOS 13 and existing code to alter the colors of the segmented control no longer work as they did.

Prior to iOS 13 you could set the tintColor and that would be used for the border around the segmented control, the lines between the segments, and the background color of the selected segment. Then you could change the color of the titles of each segment using the foreground color attribute with titleTextAttributes.

Under iOS 13, the tintColor does nothing. You can set the segmented control's backgroundColor to change the overall color of the segmented control. But I can't find any way to alter the color used as the background of the selected segment. Setting the text attributes still works. I even tried setting the background color of the title but that only affects the background of the title, not the rest of the selected segment's background color.

In short, how do you modify the background color of the currently selected segment of a UISegmentedControl in iOS 13? Is there a proper solution, using public APIs, that doesn't require digging into the private subview structure?

There are no new properties in iOS 13 for UISegmentedControl or UIControl and none of the changes in UIView are relevant.

Ios Solutions


Solution 1 - Ios

As of iOS 13b3, there is now a selectedSegmentTintColor on UISegmentedControl.

To change the overall color of the segmented control use its backgroundColor.

To change the color of the selected segment use selectedSegmentTintColor.

To change the color/font of the unselected segment titles, use setTitleTextAttributes with a state of .normal/UIControlStateNormal.

To change the color/font of the selected segment titles, use setTitleTextAttributes with a state of .selected/UIControlStateSelected.

If you create a segmented control with images, if the images are created as template images, then the segmented control's tintColor will be used to color the images. But this has a problem. If you set the tintColor to the same color as selectedSegmentTintColor then the image won't be visible in the selected segment. If you set the tintColor to the same color as backgroundColor, then the images on the unselected segments won't be visible. This means your segmented control with images must use 3 different colors for everything to be visible. Or you can use non-template images and not set the tintColor.

Under iOS 12 or earlier, simply set the segmented control's tintColor or rely on the app's overall tint color.

Solution 2 - Ios

As of Xcode 11 beta 3

>There is now the selectedSegmentTintColor property on UISegmentedControl.

See rmaddy's answer


To get back iOS 12 appearance

I wasn't able to tint the color of the selected segment, hopefully it will be fixed in an upcoming beta.

Setting the background image of the selected state doesn't work without setting the background image of the normal state (which removes all the iOS 13 styling)

But I was able to get it back to the iOS 12 appearance (or near enough, I wasn't able to return the corner radius to its smaller size).

It's not ideal, but a bright white segmented control looks a bit out of place in our app.

(Didn't realise UIImage(color:) was an extension method in our codebase. But the code to implement it is around the web)

extension UISegmentedControl {
	/// Tint color doesn't have any effect on iOS 13.
	func ensureiOS12Style() {
		if #available(iOS 13, *) {
			let tintColorImage = UIImage(color: tintColor)
			// Must set the background image for normal to something (even clear) else the rest won't work
			setBackgroundImage(UIImage(color: backgroundColor ?? .clear), for: .normal, barMetrics: .default)
			setBackgroundImage(tintColorImage, for: .selected, barMetrics: .default)
			setBackgroundImage(UIImage(color: tintColor.withAlphaComponent(0.2)), for: .highlighted, barMetrics: .default)
			setBackgroundImage(tintColorImage, for: [.highlighted, .selected], barMetrics: .default)
			setTitleTextAttributes([.foregroundColor: tintColor, NSAttributedString.Key.font: UIFont.systemFont(ofSize: 13, weight: .regular)], for: .normal)
			setDividerImage(tintColorImage, forLeftSegmentState: .normal, rightSegmentState: .normal, barMetrics: .default)
			layer.borderWidth = 1
			layer.borderColor = tintColor.cgColor
		}
	}
}

Image showing the effect of the above code

Solution 3 - Ios

IOS 13 and Swift 5.0 (Xcode 11.0)Segment Control 100% Working

enter image description here

enter image description here

 if #available(iOS 13.0, *) {
      yoursegmentedControl.backgroundColor = UIColor.black
      yoursegmentedControl.layer.borderColor = UIColor.white.cgColor
      yoursegmentedControl.selectedSegmentTintColor = UIColor.white
      yoursegmentedControl.layer.borderWidth = 1
      
      let titleTextAttributes = [NSAttributedString.Key.foregroundColor: UIColor.white]    
      yoursegmentedControl.setTitleTextAttributes(titleTextAttributes, for:.normal)
              
      let titleTextAttributes1 = [NSAttributedString.Key.foregroundColor: UIColor.black]
      yoursegmentedControl.setTitleTextAttributes(titleTextAttributes1, for:.selected)
  } else {
              // Fallback on earlier versions
}

Solution 4 - Ios

Swift version of @Ilahi Charfeddine answer:

if #available(iOS 13.0, *) {
   segmentedControl.setTitleTextAttributes([.foregroundColor: UIColor.white], for: .selected)
   segmentedControl.selectedSegmentTintColor = UIColor.blue
} else {
   segmentedControl.tintColor = UIColor.blue
}

Solution 5 - Ios

I've tried the workaround and it works great for me. Here's the Objective-C version:

@interface UISegmentedControl (Common)
- (void)ensureiOS12Style;
@end
@implementation UISegmentedControl (Common)
- (void)ensureiOS12Style {
    // UISegmentedControl has changed in iOS 13 and setting the tint
    // color now has no effect.
    if (@available(iOS 13, *)) {
        UIColor *tintColor = [self tintColor];
        UIImage *tintColorImage = [self imageWithColor:tintColor];
        // Must set the background image for normal to something (even clear) else the rest won't work
        [self setBackgroundImage:[self imageWithColor:self.backgroundColor ? self.backgroundColor : [UIColor clearColor]] forState:UIControlStateNormal barMetrics:UIBarMetricsDefault];
        [self setBackgroundImage:tintColorImage forState:UIControlStateSelected barMetrics:UIBarMetricsDefault];
        [self setBackgroundImage:[self imageWithColor:[tintColor colorWithAlphaComponent:0.2]] forState:UIControlStateHighlighted barMetrics:UIBarMetricsDefault];
        [self setBackgroundImage:tintColorImage forState:UIControlStateSelected|UIControlStateSelected barMetrics:UIBarMetricsDefault];
        [self setTitleTextAttributes:@{NSForegroundColorAttributeName: tintColor, NSFontAttributeName: [UIFont systemFontOfSize:13]} forState:UIControlStateNormal];
        [self setDividerImage:tintColorImage forLeftSegmentState:UIControlStateNormal rightSegmentState:UIControlStateNormal barMetrics:UIBarMetricsDefault];
        self.layer.borderWidth = 1;
        self.layer.borderColor = [tintColor CGColor];
    }
}

- (UIImage *)imageWithColor: (UIColor *)color {
    CGRect rect = CGRectMake(0.0f, 0.0f, 1.0f, 1.0f);
    UIGraphicsBeginImageContext(rect.size);
    CGContextRef context = UIGraphicsGetCurrentContext();
    CGContextSetFillColorWithColor(context, [color CGColor]);
    CGContextFillRect(context, rect);
    UIImage *theImage = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();
    return theImage;
}
@end

Solution 6 - Ios

As of Xcode 11 beta 3

>There is now the selectedSegmentTintColor property on UISegmentedControl.

Thank you @rmaddy!


Original answer, for Xcode 11 beta and beta 2

>Is there a proper solution, using public APIs, that doesn't require digging into the private subview structure?

With Xcode 11.0 beta, it seems to be a challenge to do it by-the-rules, because it basically requires to redraw all the background images for every states by yourself, with round corners, transparency and resizableImage(withCapInsets:). For instance, you would need to generate a colored image similar to:
enter image description here

So for now, the let's-dig-into-the-subviews way seems much easier:

class TintedSegmentedControl: UISegmentedControl {

    override func layoutSubviews() {
        super.layoutSubviews()
        
        if #available(iOS 13.0, *) {
            for subview in subviews {
                if let selectedImageView = subview.subviews.last(where: { $0 is UIImageView }) as? UIImageView,
                    let image = selectedImageView.image {
                    selectedImageView.image = image.withRenderingMode(.alwaysTemplate)
                    break
                }
            }
        }
    }
}

This solution will correctly apply the tint color to the selection, as in: enter image description here

Solution 7 - Ios

iOS13 UISegmentController

how to use:

segment.setOldLayout(tintColor: .green)

extension UISegmentedControl
{
    func setOldLayout(tintColor: UIColor)
    {
        if #available(iOS 13, *)
        {
            let bg = UIImage(color: .clear, size: CGSize(width: 1, height: 32))
             let devider = UIImage(color: tintColor, size: CGSize(width: 1, height: 32))
            
             //set background images
             self.setBackgroundImage(bg, for: .normal, barMetrics: .default)
             self.setBackgroundImage(devider, for: .selected, barMetrics: .default)
             
             //set divider color
             self.setDividerImage(devider, forLeftSegmentState: .normal, rightSegmentState: .normal, barMetrics: .default)
             
             //set border
             self.layer.borderWidth = 1
             self.layer.borderColor = tintColor.cgColor
             
             //set label color
             self.setTitleTextAttributes([.foregroundColor: tintColor], for: .normal)
             self.setTitleTextAttributes([.foregroundColor: UIColor.white], for: .selected)
        }
        else
        {
            self.tintColor = tintColor
        }
    }
}
extension UIImage {
    convenience init(color: UIColor, size: CGSize) {
        UIGraphicsBeginImageContextWithOptions(size, false, 1)
        color.set()
        let ctx = UIGraphicsGetCurrentContext()!
        ctx.fill(CGRect(origin: .zero, size: size))
        let image = UIGraphicsGetImageFromCurrentImageContext()!
        UIGraphicsEndImageContext()

        self.init(data: image.pngData()!)!
    }
}

Solution 8 - Ios

if (@available(iOS 13.0, *)) {

    [self.segmentedControl setTitleTextAttributes:@{NSForegroundColorAttributeName: [UIColor whiteColor], NSFontAttributeName: [UIFont systemFontOfSize:13]} forState:UIControlStateSelected];
    [self.segmentedControl setSelectedSegmentTintColor:[UIColor blueColor]];

} else {

[self.segmentedControl setTintColor:[UIColor blueColor]];}

Solution 9 - Ios

XCODE 11.1 & iOS 13

Based on @Jigar Darji 's answer but a safer implementation.

We first create a failable convenience initialiser:

extension UIImage {

convenience init?(color: UIColor, size: CGSize) {
    UIGraphicsBeginImageContextWithOptions(size, false, 1)
    color.set()
    guard let ctx = UIGraphicsGetCurrentContext() else { return nil }
    ctx.fill(CGRect(origin: .zero, size: size))
    guard
        let image = UIGraphicsGetImageFromCurrentImageContext(),
        let imagePNGData = image.pngData()
        else { return nil }
    UIGraphicsEndImageContext()

    self.init(data: imagePNGData)
   }
}

Then we extend UISegmentedControl:

extension UISegmentedControl {

func fallBackToPreIOS13Layout(using tintColor: UIColor) {
    if #available(iOS 13, *) {
        let backGroundImage = UIImage(color: .clear, size: CGSize(width: 1, height: 32))
        let dividerImage = UIImage(color: tintColor, size: CGSize(width: 1, height: 32))

        setBackgroundImage(backGroundImage, for: .normal, barMetrics: .default)
        setBackgroundImage(dividerImage, for: .selected, barMetrics: .default)

        setDividerImage(dividerImage,
                        forLeftSegmentState: .normal,
                        rightSegmentState: .normal, barMetrics: .default)

        layer.borderWidth = 1
        layer.borderColor = tintColor.cgColor

        setTitleTextAttributes([.foregroundColor: tintColor], for: .normal)
        setTitleTextAttributes([.foregroundColor: UIColor.white], for: .selected)
    } else {
        self.tintColor = tintColor
    }
  }
}

Solution 10 - Ios

Here is my take on Jonathan.'s answer for Xamarin.iOS (C#), but with fixes for image sizing. As with Cœur's comment on Colin Blake's answer, I made all images except the divider the size of the segmented control. The divider is 1xheight of the segment.

public static UIImage ImageWithColor(UIColor color, CGSize size)
{
    var rect = new CGRect(0, 0, size.Width, size.Height);
    UIGraphics.BeginImageContext(rect.Size);
    var context = UIGraphics.GetCurrentContext();
    context.SetFillColor(color.CGColor);
    context.FillRect(rect);
    var image = UIGraphics.GetImageFromCurrentImageContext();
    UIGraphics.EndImageContext();
    return image;
}

// https://stackoverflow.com/a/56465501/420175
public static void ColorSegmentiOS13(UISegmentedControl uis, UIColor tintColor, UIColor textSelectedColor, UIColor textDeselectedColor)
{
    if (!UIDevice.CurrentDevice.CheckSystemVersion(13, 0))
    {
        return;
    }

    UIImage image(UIColor color)
    {
        return ImageWithColor(color, uis.Frame.Size);
    }

    UIImage imageDivider(UIColor color)
    {
        return ImageWithColor(color, 1, uis.Frame.Height);
    }

    // Must set the background image for normal to something (even clear) else the rest won't work
    //setBackgroundImage(UIImage(color: backgroundColor ?? .clear), for: .normal, barMetrics: .default)
    uis.SetBackgroundImage(image(UIColor.Clear), UIControlState.Normal, UIBarMetrics.Default);

    // setBackgroundImage(tintColorImage, for: .selected, barMetrics: .default)
    uis.SetBackgroundImage(image(tintColor), UIControlState.Selected, UIBarMetrics.Default);

    // setBackgroundImage(UIImage(color: tintColor.withAlphaComponent(0.2)), for: .highlighted, barMetrics: .default)
    uis.SetBackgroundImage(image(tintColor.ColorWithAlpha(0.2f)), UIControlState.Highlighted, UIBarMetrics.Default);

    // setBackgroundImage(tintColorImage, for: [.highlighted, .selected], barMetrics: .default)
    uis.SetBackgroundImage(image(tintColor), UIControlState.Highlighted | UIControlState.Selected, UIBarMetrics.Default);

    // setTitleTextAttributes([.foregroundColor: tintColor, NSAttributedString.Key.font: UIFont.systemFont(ofSize: 13, weight: .regular)], for: .normal)
    // Change: support distinct color for selected/de-selected; keep original font
    uis.SetTitleTextAttributes(new UITextAttributes() { TextColor = textDeselectedColor }, UIControlState.Normal); //Font = UIFont.SystemFontOfSize(13, UIFontWeight.Regular)
    uis.SetTitleTextAttributes(new UITextAttributes() { TextColor = textSelectedColor, }, UIControlState.Selected); //Font = UIFont.SystemFontOfSize(13, UIFontWeight.Regular)

    // setDividerImage(tintColorImage, forLeftSegmentState: .normal, rightSegmentState: .normal, barMetrics: .default)
    uis.SetDividerImage(imageDivider(tintColor), UIControlState.Normal, UIControlState.Normal, UIBarMetrics.Default);

    //layer.borderWidth = 1
    uis.Layer.BorderWidth = 1;

    //layer.borderColor = tintColor.cgColor
    uis.Layer.BorderColor = tintColor.CGColor;
}

Solution 11 - Ios

You can implement following method

extension UISegmentedControl{
    func selectedSegmentTintColor(_ color: UIColor) {
        self.setTitleTextAttributes([.foregroundColor: color], for: .selected)
    }
    func unselectedSegmentTintColor(_ color: UIColor) {
        self.setTitleTextAttributes([.foregroundColor: color], for: .normal)
    }
}

Usage code

segmentControl.unselectedSegmentTintColor(.white)
segmentControl.selectedSegmentTintColor(.black)

Solution 12 - Ios

While answers above are great, most of them get the color of text inside selected segment wrong. I've created UISegmentedControl subclass which you can use on iOS 13 and pre-iOS 13 devices and use the tintColor property as you would on pre iOS 13 devices.

    class LegacySegmentedControl: UISegmentedControl {
        private func stylize() {
            if #available(iOS 13.0, *) {
                selectedSegmentTintColor = tintColor
                let tintColorImage = UIImage(color: tintColor)
                setBackgroundImage(UIImage(color: backgroundColor ?? .clear), for: .normal, barMetrics: .default)
                setBackgroundImage(tintColorImage, for: .selected, barMetrics: .default)
                setBackgroundImage(UIImage(color: tintColor.withAlphaComponent(0.2)), for: .highlighted, barMetrics: .default)
                setBackgroundImage(tintColorImage, for: [.highlighted, .selected], barMetrics: .default)
                setTitleTextAttributes([.foregroundColor: tintColor!, NSAttributedString.Key.font: UIFont.systemFont(ofSize: 13, weight: .regular)], for: .normal)
                
                setDividerImage(tintColorImage, forLeftSegmentState: .normal, rightSegmentState: .normal, barMetrics: .default)
                layer.borderWidth = 1
                layer.borderColor = tintColor.cgColor
                
// Detect underlying backgroundColor so the text color will be properly matched

                if let background = backgroundColor {
                    self.setTitleTextAttributes([.foregroundColor: background, NSAttributedString.Key.font: UIFont.systemFont(ofSize: 13, weight: .regular)], for: .selected)
                } else {
                    func detectBackgroundColor(of view: UIView?) -> UIColor? {
                        guard let view = view else {
                            return nil
                        }
                        if let color = view.backgroundColor, color != .clear {
                            return color
                        }
                        return detectBackgroundColor(of: view.superview)
                    }
                    let textColor = detectBackgroundColor(of: self) ?? .black
                    
                    self.setTitleTextAttributes([.foregroundColor: textColor, NSAttributedString.Key.font: UIFont.systemFont(ofSize: 13, weight: .regular)], for: .selected)
                }
            }
        }
        
        override func tintColorDidChange() {
            super.tintColorDidChange()
            stylize()
        }
    }
    
    fileprivate extension UIImage {
        public convenience init?(color: UIColor, size: CGSize = CGSize(width: 1, height: 1)) {
          let rect = CGRect(origin: .zero, size: size)
          UIGraphicsBeginImageContextWithOptions(rect.size, false, 0.0)
          color.setFill()
          UIRectFill(rect)
          let image = UIGraphicsGetImageFromCurrentImageContext()
          UIGraphicsEndImageContext()
    
          guard let cgImage = image?.cgImage else { return nil }
          self.init(cgImage: cgImage)
        }
    }

Using tintColorDidChange method we ensure that the stylize method will be called every time the tintColor property changes on the segment view, or any of the underlying views, which is preferred behaviour on iOS.

Result: enter image description here

Solution 13 - Ios

The SwiftUI Picker lacks some basic options. For people trying to customize a Picker with SegmentedPickerStyle() in SwiftUI in iOS 13 or 14, the simplest option is to use UISegmentedControl.appearance() to set the appearance globally. Here is an example function that could be called to set the appearance.

func setUISegmentControlAppearance() {
    UISegmentedControl.appearance().selectedSegmentTintColor = .white
    UISegmentedControl.appearance().backgroundColor = UIColor(red: 1.0, green: 1.0, blue: 1.0, alpha: 0.1)
    UISegmentedControl.appearance().setTitleTextAttributes([.foregroundColor: UIColor.black], for: .normal)
    UISegmentedControl.appearance().setTitleTextAttributes([.foregroundColor: UIColor.white], for: .selected)
}

However, globally setting appearance options with UISegmentedControl.appearance() is not great if you want multiple controls with different settings. Another option is to implement UIViewRepresentable for UISegmentedControl. Here is an example that sets the properties asked about in the the original question and sets .apportionsSegmentWidthsByContent = true as a bonus. Hopefully this will save you some time...

struct MyPicker: UIViewRepresentable {

    @Binding var selection: Int // The type of selection may vary depending on your use case
    var items: [Any]?

    class Coordinator: NSObject {
        let parent: MyPicker
        init(parent: MyPicker) {
            self.parent = parent
        }

        @objc func valueChanged(_ sender: UISegmentedControl) {
            self.parent.selection = Int(sender.selectedSegmentIndex)
        }
    }

    func makeCoordinator() -> MyPicker.Coordinator {
        Coordinator(parent: self)
    }

    func makeUIView(context: Context) -> UISegmentedControl {
        let picker = UISegmentedControl(items: self.items)

        // Any number of other UISegmentedControl settings can go here
        picker.selectedSegmentTintColor = .white
        picker.backgroundColor = UIColor(red: 1.0, green: 1.0, blue: 1.0, alpha: 0.1)
        picker.setTitleTextAttributes([.foregroundColor: UIColor.black], for: .normal)
        picker.setTitleTextAttributes([.foregroundColor: UIColor.white], for: .selected)
        picker.apportionsSegmentWidthsByContent = true

        // Make sure the coordinator updates the picker when the value changes
        picker.addTarget(context.coordinator, action: #selector(Coordinator.valueChanged(_:)), for: .valueChanged)

        return picker
    }

    func updateUIView(_ uiView: UISegmentedControl, context: Context) {
        uiView.selectedSegmentIndex = self.selection
    }
 }

Solution 14 - Ios

In iOS 13 and above, when I accessed the segmented control's subviews in viewDidLoad, it has 1 UIImageView. Once I inserted more segments, it increases respectively, so 3 segments means 3 UIImageView as the segmented control's subviews.

Interestingly, by the time it reaches viewDidAppear, the segmented control's subviews became 3 UISegment (each contained a UISegmentLabel as its subview; this is your text) and 4 UIImageView as shown below:

viewDidAppear

Those 3 UIImageView in viewDidLoad somehow become UISegment, and we don't want to touch them (but you can try to set their image or isHidden just to see how it affects the UI). Let's ignore these private classes.

Those 4 UIImageView are actually 3 "normal" UIImageView (together with 1 UIImageView subview as the vertical separator) and 1 "selected" UIImageView (i.e. this is actually your selectedSegmentTintColor image, notice in the screenshot above there are no subviews under it).

In my case, I needed a white background, so I had to hide the greyish background images (see: https://medium.com/flawless-app-stories/ios-13-uisegmentedcontrol-3-important-changes-d3a94fdd6763). I also wanted to remove/hide the vertical separators between the segments.

Hence the simple solution in viewDidAppear, without needed to set divider image or background image (in my case), is to simply hide those first 3 UIImageView:

// This method might be a bit 'risky' since we are not guaranteed of the internal sequence ordering, but so far it seems ok.
if #available(iOS 13.0, *) {
    for i in 0...(segmentedControl.numberOfSegments - 1) {
        segmentedControl.subviews[i].isHidden = true
    }
}

or

// This does not depend on the ordering sequence like the above, but this is also risky in the sense that if the UISegment becomes UIImageView one day, this will break.
if #available(iOS 13.0, *) {
    for subview in segmentedControl.subviews {
        if String(describing: subview).contains("UIImageView"),
           subview.subviews.count > 0 {
               subview.isHidden = true
        }
    }
}

Pick your poison...

Solution 15 - Ios

If you want to set the background to clear you have to do this:

if #available(iOS 13.0, *) {
  let image = UIImage()
  let size = CGSize(width: 1, height: segmentedControl.intrinsicContentSize.height)
  UIGraphicsBeginImageContextWithOptions(size, false, 0.0)
  image.draw(in: CGRect(origin: .zero, size: size))
  let scaledImage = UIGraphicsGetImageFromCurrentImageContext()
  UIGraphicsEndImageContext()
  segmentedControl.setBackgroundImage(scaledImage, for: .normal, barMetrics: .default)
  segmentedControl.setDividerImage(scaledImage, forLeftSegmentState: .normal, rightSegmentState: .normal, barMetrics: .default)
}

Result looks like: enter image description here

Solution 16 - Ios

iOS 12+

I struggled a lot for background color. Setting .clear color as background color always added default grey color. Here is how i fixed

self.yourSegmentControl.backgroundColor = .clear //Any Color of your choice

self.yourSegmentControl.setBackgroundImage(UIImage(), for: .normal, barMetrics: .default) //This does the magic

Additionally for Divider Color

self.yourSegmentControl.setDividerImage(UIImage(), forLeftSegmentState: .normal, rightSegmentState: .normal, barMetrics: .default) // This will remove the divider image.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionrmaddyView Question on Stackoverflow
Solution 1 - IosrmaddyView Answer on Stackoverflow
Solution 2 - IosJonathan.View Answer on Stackoverflow
Solution 3 - IosMaulik PatelView Answer on Stackoverflow
Solution 4 - IosVignan SankatiView Answer on Stackoverflow
Solution 5 - IosColin BlakeView Answer on Stackoverflow
Solution 6 - IosCœurView Answer on Stackoverflow
Solution 7 - IosJigarView Answer on Stackoverflow
Solution 8 - IosIlahi CharfeddineView Answer on Stackoverflow
Solution 9 - IosFredFlinstoneView Answer on Stackoverflow
Solution 10 - Iost9mikeView Answer on Stackoverflow
Solution 11 - IosZain AnjumView Answer on Stackoverflow
Solution 12 - IosAdamView Answer on Stackoverflow
Solution 13 - Iosuser1248465View Answer on Stackoverflow
Solution 14 - IosCyberMewView Answer on Stackoverflow
Solution 15 - IosCameron PorterView Answer on Stackoverflow
Solution 16 - IosKedar SukerkarView Answer on Stackoverflow