Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

UISegmentedControl iOS 13 clear color

On iOS 12, to get a UISegmentedControl with clear border, clear divider line, everything clear was easy. All I did was this:

  settingControl.tintColor = .clear

   let font = myFont
   let boldfont = myBoldFont

  settingControl.setTitleTextAttributes([NSAttributedString.Key.foregroundColor : UIColor.white, NSAttributedString.Key.font:font], for: .normal)
  settingControl.setTitleTextAttributes([NSAttributedString.Key.foregroundColor : UIColor.red, NSAttributedString.Key.font:boldfont], for: .selected)

And then UISegmentedControl was full clear color (divider line, background, border)

But in iOS 13, I can not get it fully clear. I can set

settingControl.selectedSegmentTintColor = UIColor.clear

But it still does not clear the backgroundColor and divider line.

I tried setting backgroundColor to clear, but no effect.

 settingControl.backgroundColor = UIColor.clear

I also tried setting a clear image but still nothing:

 public extension UIImage {

  /**
   Returns image with size 1x1px of certain color.
   */
 class func imageWithColor(color : UIColor) -> UIImage? {
    let rect = CGRect(x: 0, y: 0, width: 1, height: 1)
    UIGraphicsBeginImageContext(rect.size)
    let context = UIGraphicsGetCurrentContext()

    context?.setFillColor(color.cgColor)

    context?.fill(rect)

    let image = UIGraphicsGetImageFromCurrentImageContext()
    UIGraphicsEndImageContext()

    return image
}

 }

And then this:

  let clearImage = UIImage.imageWithColor(color: UIColor.clear)
    settingControl.setDividerImage(clearImage, forLeftSegmentState: .normal, rightSegmentState: .normal, barMetrics: .default)


   settingControl.setBackgroundImage(clearImage, for: .normal, barMetrics: .default)
   settingControl.setBackgroundImage(clearImage, for: .selected, barMetrics: .default)

This is how it looks like on iOS 12. On iOS 13, this seems impossible.

This is how it looks like on iOS 12. On iOS 13, this seems impossible.

like image 202
Deepak Sharma Avatar asked Aug 11 '19 14:08

Deepak Sharma


People also ask

How do I change the background color in 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 .

How do I change the Uiimage color in Objective C?

setBlendMode(. multiply) ctx. draw(image. cgImage!, in: imageRect) let newImage = UIGraphicsGetImageFromCurrentImageContext() UIGraphicsEndImageContext() return newImage! } }

When would you use segmented control?

A segmented control is a linear set of segments, each of which functions as a button that can display a different view. Use a segmented control to offer choices that are closely related but mutually exclusive. A tab bar gives people the ability to switch between different subtasks, views, or modes in an app.


1 Answers

Here's a way to replicate that plain segmented control in iOS 13:

import UIKit
import PlaygroundSupport

class PlainSegmentedControl: UISegmentedControl {
    override init(items: [Any]?) {
        super.init(items: items)

        setup()
    }

    override init(frame: CGRect) {
        super.init(frame: frame)
    }

    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }

    // Used for the unselected labels
    override var tintColor: UIColor! {
        didSet {
            setTitleTextAttributes([.foregroundColor: tintColor!, NSAttributedString.Key.font: UIFont.systemFont(ofSize: 13, weight: .regular)], for: .normal)
        }
    }

    // Used for the selected label
    override var selectedSegmentTintColor: UIColor? {
        didSet {
            setTitleTextAttributes([.foregroundColor: selectedSegmentTintColor ?? tintColor!, NSAttributedString.Key.font: UIFont.systemFont(ofSize: 13, weight: .regular)], for: .selected)
        }
    }

    private func setup() {
        backgroundColor = .clear

        // Use a clear image for the background and the dividers
        let tintColorImage = UIImage(color: .clear, size: CGSize(width: 1, height: 32))
        setBackgroundImage(tintColorImage, for: .normal, barMetrics: .default)
        setDividerImage(tintColorImage, forLeftSegmentState: .normal, rightSegmentState: .normal, barMetrics: .default)

        // Set some default label colors
        setTitleTextAttributes([.foregroundColor: UIColor.black, NSAttributedString.Key.font: UIFont.systemFont(ofSize: 13, weight: .regular)], for: .normal)
        setTitleTextAttributes([.foregroundColor: tintColor!, NSAttributedString.Key.font: UIFont.systemFont(ofSize: 13, weight: .regular)], for: .selected)
    }
}

Here's some test code to put in a playground:

// Create a dark green view as a test background
let bg = UIView(frame: CGRect(x: 0, y: 0, width: 400, height: 100))
bg.backgroundColor = UIColor(red: 0.224, green: 0.408, blue: 0.467, alpha: 1)

// The plain segmented control
let seg = PlainSegmentedControl(items: ["Number One", "Number Two", "Number Three"])
seg.tintColor = .white
seg.selectedSegmentTintColor = .green
seg.selectedSegmentIndex = 0
bg.addSubview(seg)
PlaygroundPage.current.liveView = bg

Here's the UIImage extension to create a sized image from a color:

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()!)!
    }
}
like image 173
rmaddy Avatar answered Sep 23 '22 02:09

rmaddy