Цвет фона UIControlSegment больше не прозрачен на iOS13
У меня есть UISegmentedControl. он работал нормально до iOS13 (я установил как backgroundColor, так и tintColor, чтобы очистить). Но сейчас я не получаю того же результата. My SegmentedControl имеет светло-серый слой. Я провел небольшое исследование, но ничего не помогло. (У меня такая же проблема: https://forums.developer.apple.com/thread/123955)
Предыдущее состояние:
текущее состояние - iOS13:
4 ответа
Спасибо @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!
}
}
Вы можете создать расширение, чтобы ваш сегментный контроль был понятен
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!
}
}
Я также столкнулся с этой проблемой, чтобы соответствовать требованиям дизайна. В моем случае цвет фона SegmentedControl должен быть белым или прозрачным, потому что цвет фона представления также был белым.
Поэтому я просто добавляю белый UImage в фон SegmentControl, и этот трюк у меня сработал.
if (@available(iOS 13.0, *)) {
[segmentController setBackgroundImage:[UIImage imageNamed:@"someWhiteImage"] forState:UIControlStateNormal barMetrics:UIBarMetricsDefault];
}
Хотя это не идеальное решение, но мои требования удовлетворяются с помощью этого трюка. Вы также можете добавить одноцветное фоновое изображение в качестве фона. Надеюсь, кто-нибудь покажет нам правильный способ обращения.
Требуемый дизайн и до iOS 13
После iOS 13
Так что добавление белого фонового изображения сработало для меня
.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()!)!
}
}
Результат: