iOS13 上的 UIControlSegment 背景颜色不再透明
UIControlSegment background color is not transparent anymore on iOS13
我有一个 UISegmentedControl。
它在 iOS13 之前工作正常(我将 backgroundColor 和 tintColor 都设置为清除)。
但是现在,我没有得到相同的结果。
我的 SegmentedControl 有一个浅灰色层。
我做了一些研究,但没有任何效果。
(我遇到了同样的问题:https://forums.developer.apple.com/thread/123955)
之前的状态:
当前状态 - iOS13:
为了满足设计要求,我也遇到了这个问题。在我的例子中,SegmentedControl 背景颜色应该是白色或透明颜色,因为视图的背景颜色也是白色。
所以我只是在 SegmentControl 背景中添加了一个白色的 UImage,这个技巧对我有用。
if (@available(iOS 13.0, *)) {
[segmentController setBackgroundImage:[UIImage imageNamed:@"someWhiteImage"] forState:UIControlStateNormal barMetrics:UIBarMetricsDefault];
}
虽然这不是一个完美的解决方案,但使用这个技巧可以满足我的要求。您现在也可以在背景中添加纯色背景图像。希望有人告诉我们正确的处理方式。
需要设计及之前 iOS 13
iOS13
之后
所以添加白色背景图片对我有用
.selectedSegmentTintColor
定义所选按钮的颜色和 .layer.backgroundColor
整个 UISegmentedControl 背景的颜色。
事实证明,这不适用于背景清晰或白色,因为在 iOS 13 中,在分段控件的背景和分隔符上添加了一种背景图像。
解决方法是使用 UIGraphicsGetImageFromCurrentImageContext
从颜色创建图像。试试这个:
class ViewController: UIViewController {
@IBOutlet weak var segmentedControl: UISegmentedControl!
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
segmentedControl.setiOS12Layout(tintColor: .red)
}
}
extension UISegmentedControl {
func setiOS12Layout(tintColor: UIColor) {
if #available(iOS 13, *) {
let background = UIImage(color: .clear, size: CGSize(width: 1, height: 32))
let divider = UIImage(color: tintColor, size: CGSize(width: 1, height: 32))
self.setBackgroundImage(background, for: .normal, barMetrics: .default)
self.setBackgroundImage(divider, for: .selected, barMetrics: .default)
self.setDividerImage(divider, forLeftSegmentState: .normal, rightSegmentState: .normal, barMetrics: .default)
self.layer.borderWidth = 1
self.layer.borderColor = tintColor.cgColor
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 context = UIGraphicsGetCurrentContext()!
context.fill(CGRect(origin: .zero, size: size))
let image = UIGraphicsGetImageFromCurrentImageContext()!
UIGraphicsEndImageContext()
self.init(data: image.pngData()!)!
}
}
结果:
您可以创建一个扩展来使您的段控制清晰
segmentControl.clearBG()
这是扩展
extension UISegmentedControl {
func clearBG() {
setBackgroundImage(imageWithColor(color: UIColor.white), for: .normal, barMetrics: .default)
setBackgroundImage(imageWithColor(color: UIColor.white), for: .normal, barMetrics: .default)
setDividerImage(imageWithColor(color: .white), forLeftSegmentState: .normal, rightSegmentState: .normal, barMetrics: .default)
}
// create a 1x1 image with this color
private func imageWithColor(color: UIColor) -> UIImage {
let rect = CGRect(x: 0.0, y: 0.0, width: 1.0, height: 1.0)
UIGraphicsBeginImageContext(rect.size)
let context = UIGraphicsGetCurrentContext()
context!.setFillColor(color.cgColor);
context!.fill(rect);
let image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return image!
}
}
感谢@Maulik Pandya 的回答,
我已经稍微改进了你的答案。
extension UISegmentedControl {
func clearBG() {
let clearImage = UIImage().imageWithColor(color: .clear)
setBackgroundImage(clearImage, for: .normal, barMetrics: .default)
setBackgroundImage(clearImage, for: .selected, barMetrics: .default)
setDividerImage(clearImage, forLeftSegmentState: .normal, rightSegmentState: .normal, barMetrics: .default)
}
}
public extension UIImage {
public func imageWithColor(color: UIColor) -> UIImage {
let rect = CGRect(x: 0.0, y: 0.0, width: 1.0, height: 1.0)
UIGraphicsBeginImageContext(rect.size)
guard let context = UIGraphicsGetCurrentContext() else { return UIImage()}
context.setFillColor(color.cgColor)
context.fill(rect)
let image = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
return image!
}
}
我有一个 UISegmentedControl。 它在 iOS13 之前工作正常(我将 backgroundColor 和 tintColor 都设置为清除)。 但是现在,我没有得到相同的结果。 我的 SegmentedControl 有一个浅灰色层。 我做了一些研究,但没有任何效果。 (我遇到了同样的问题:https://forums.developer.apple.com/thread/123955)
之前的状态:
当前状态 - iOS13:
为了满足设计要求,我也遇到了这个问题。在我的例子中,SegmentedControl 背景颜色应该是白色或透明颜色,因为视图的背景颜色也是白色。
所以我只是在 SegmentControl 背景中添加了一个白色的 UImage,这个技巧对我有用。
if (@available(iOS 13.0, *)) {
[segmentController setBackgroundImage:[UIImage imageNamed:@"someWhiteImage"] forState:UIControlStateNormal barMetrics:UIBarMetricsDefault];
}
虽然这不是一个完美的解决方案,但使用这个技巧可以满足我的要求。您现在也可以在背景中添加纯色背景图像。希望有人告诉我们正确的处理方式。
需要设计及之前 iOS 13
iOS13
之后所以添加白色背景图片对我有用
.selectedSegmentTintColor
定义所选按钮的颜色和 .layer.backgroundColor
整个 UISegmentedControl 背景的颜色。
事实证明,这不适用于背景清晰或白色,因为在 iOS 13 中,在分段控件的背景和分隔符上添加了一种背景图像。
解决方法是使用 UIGraphicsGetImageFromCurrentImageContext
从颜色创建图像。试试这个:
class ViewController: UIViewController {
@IBOutlet weak var segmentedControl: UISegmentedControl!
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
segmentedControl.setiOS12Layout(tintColor: .red)
}
}
extension UISegmentedControl {
func setiOS12Layout(tintColor: UIColor) {
if #available(iOS 13, *) {
let background = UIImage(color: .clear, size: CGSize(width: 1, height: 32))
let divider = UIImage(color: tintColor, size: CGSize(width: 1, height: 32))
self.setBackgroundImage(background, for: .normal, barMetrics: .default)
self.setBackgroundImage(divider, for: .selected, barMetrics: .default)
self.setDividerImage(divider, forLeftSegmentState: .normal, rightSegmentState: .normal, barMetrics: .default)
self.layer.borderWidth = 1
self.layer.borderColor = tintColor.cgColor
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 context = UIGraphicsGetCurrentContext()!
context.fill(CGRect(origin: .zero, size: size))
let image = UIGraphicsGetImageFromCurrentImageContext()!
UIGraphicsEndImageContext()
self.init(data: image.pngData()!)!
}
}
结果:
您可以创建一个扩展来使您的段控制清晰
segmentControl.clearBG()
这是扩展
extension UISegmentedControl {
func clearBG() {
setBackgroundImage(imageWithColor(color: UIColor.white), for: .normal, barMetrics: .default)
setBackgroundImage(imageWithColor(color: UIColor.white), for: .normal, barMetrics: .default)
setDividerImage(imageWithColor(color: .white), forLeftSegmentState: .normal, rightSegmentState: .normal, barMetrics: .default)
}
// create a 1x1 image with this color
private func imageWithColor(color: UIColor) -> UIImage {
let rect = CGRect(x: 0.0, y: 0.0, width: 1.0, height: 1.0)
UIGraphicsBeginImageContext(rect.size)
let context = UIGraphicsGetCurrentContext()
context!.setFillColor(color.cgColor);
context!.fill(rect);
let image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return image!
}
}
感谢@Maulik Pandya 的回答, 我已经稍微改进了你的答案。
extension UISegmentedControl {
func clearBG() {
let clearImage = UIImage().imageWithColor(color: .clear)
setBackgroundImage(clearImage, for: .normal, barMetrics: .default)
setBackgroundImage(clearImage, for: .selected, barMetrics: .default)
setDividerImage(clearImage, forLeftSegmentState: .normal, rightSegmentState: .normal, barMetrics: .default)
}
}
public extension UIImage {
public func imageWithColor(color: UIColor) -> UIImage {
let rect = CGRect(x: 0.0, y: 0.0, width: 1.0, height: 1.0)
UIGraphicsBeginImageContext(rect.size)
guard let context = UIGraphicsGetCurrentContext() else { return UIImage()}
context.setFillColor(color.cgColor)
context.fill(rect)
let image = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
return image!
}
}