Как изменить цвет оттенка кнопки очистки на UITextField
У меня есть автогенерированная кнопка очистки на моем UITextfield, с цветом синего оттенка по умолчанию. Я не могу изменить цвет оттенков на белый. Я пробовал модифицировать раскадровку и код без успеха, и я не хочу использовать пользовательский образ.
Как изменить цвет оттенка кнопки по умолчанию, не используя пользовательский образ?
![clicked]()
Ответы
Ответ 1
Ну вот!
TintTextField.
Не использовать пользовательское изображение или добавленные кнопки и т.д.
![Image of UITextField with white tint color for cancel button]()
class TintTextField: UITextField {
var tintedClearImage: UIImage?
required init(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
self.setupTintColor()
}
override init(frame: CGRect) {
super.init(frame: frame)
self.setupTintColor()
}
func setupTintColor() {
self.borderStyle = UITextField.BorderStyle.roundedRect
self.layer.cornerRadius = 8.0
self.layer.masksToBounds = true
self.layer.borderColor = self.tintColor.cgColor
self.layer.borderWidth = 1.5
self.backgroundColor = .clear
self.textColor = self.tintColor
}
override func layoutSubviews() {
super.layoutSubviews()
self.tintClearImage()
}
private func tintClearImage() {
for view in subviews {
if view is UIButton {
let button = view as! UIButton
if let image = button.image(for: .highlighted) {
if self.tintedClearImage == nil {
tintedClearImage = self.tintImage(image: image, color: self.tintColor)
}
button.setImage(self.tintedClearImage, for: .normal)
button.setImage(self.tintedClearImage, for: .highlighted)
}
}
}
}
private func tintImage(image: UIImage, color: UIColor) -> UIImage {
let size = image.size
UIGraphicsBeginImageContextWithOptions(size, false, image.scale)
let context = UIGraphicsGetCurrentContext()
image.draw(at: .zero, blendMode: CGBlendMode.normal, alpha: 1.0)
context?.setFillColor(color.cgColor)
context?.setBlendMode(CGBlendMode.sourceIn)
context?.setAlpha(1.0)
let rect = CGRect(x: CGPoint.zero.x, y: CGPoint.zero.y, width: image.size.width, height: image.size.height)
UIGraphicsGetCurrentContext()?.fill(rect)
let tintedImage = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
return tintedImage ?? UIImage()
}
}
Ответ 2
Причина, по которой у вас возникли проблемы с этим, заключается в том, что четкие изображения кнопок не тонированы. Это обычные изображения.
Кнопка очистки - это кнопка, внутренняя для UITextField. Как и любая кнопка, у нее может быть изображение, и это так. В частности, он имеет два изображения: одно для нормального состояния и одно для состояния выделенного. Синим цветом, на который указывает объект OP, является выделенное изображение, и его можно захватить, запустив этот код в то время, когда имеется кнопка очистки:
let tf = self.tf // the text view
for sv in tf.subviews as! [UIView] {
if sv is UIButton {
let b = sv as! UIButton
if let im = b.imageForState(.Highlighted) {
// im is the blue x
}
}
}
Как только вы его захватите, вы обнаружите, что это изображение с четырьмя разрешениями с разрешением 14x14, и вот оно:
![enter image description here]()
В теории вы можете изменить изображение на другой цвет, и вы можете назначить его как изображение с четким отображением текста для выделенного состояния. Но на практике это совсем нелегко сделать, потому что кнопка не всегда присутствует; вы не можете ссылаться на него, когда он отсутствует (он не просто невидим, он вообще не является частью иерархии представлений, поэтому нет доступа к нему).
Кроме того, для настройки кнопки очистки нет UITextField API.
Таким образом, самым простым решением является здесь: создайте кнопку с пользовательскими изображениями Normal и Highlighted и поставьте ее как UITextField rightView
. Затем вы установите для параметра clearButtonMode
значение "Никогда" (поскольку вместо этого вы используете правильное представление) и rightViewMode
в любое удобное для вас время.
![enter image description here]()
Вы, конечно же, должны будете обнаружить нажатие этой кнопки и ответить, очистив текст текстового поля; но это легко сделать и остается для упражнения читателем.
Ответ 3
Основываясь на ответе @Mikael Hellman, я подготовил аналогичную реализацию подкласса UITextField для Objective-C. Единственное различие заключается в том, что я разрешаю иметь отдельные цвета для состояний Normal и Highlighted.
.h файл
#import <UIKit/UIKit.h>
@interface TextFieldTint : UITextField
-(void) setColorButtonClearHighlighted:(UIColor *)colorButtonClearHighlighted;
-(void) setColorButtonClearNormal:(UIColor *)colorButtonClearNormal;
@end
.m file
#import "TextFieldTint.h"
@interface TextFieldTint()
@property (nonatomic,strong) UIColor *colorButtonClearHighlighted;
@property (nonatomic,strong) UIColor *colorButtonClearNormal;
@property (nonatomic,strong) UIImage *imageButtonClearHighlighted;
@property (nonatomic,strong) UIImage *imageButtonClearNormal;
@end
@implementation TextFieldTint
-(void) layoutSubviews
{
[super layoutSubviews];
[self tintButtonClear];
}
-(void) setColorButtonClearHighlighted:(UIColor *)colorButtonClearHighlighted
{
_colorButtonClearHighlighted = colorButtonClearHighlighted;
}
-(void) setColorButtonClearNormal:(UIColor *)colorButtonClearNormal
{
_colorButtonClearNormal = colorButtonClearNormal;
}
-(UIButton *) buttonClear
{
for(UIView *v in self.subviews)
{
if([v isKindOfClass:[UIButton class]])
{
UIButton *buttonClear = (UIButton *) v;
return buttonClear;
}
}
return nil;
}
-(void) tintButtonClear
{
UIButton *buttonClear = [self buttonClear];
if(self.colorButtonClearNormal && self.colorButtonClearHighlighted && buttonClear)
{
if(!self.imageButtonClearHighlighted)
{
UIImage *imageHighlighted = [buttonClear imageForState:UIControlStateHighlighted];
self.imageButtonClearHighlighted = [[self class] imageWithImage:imageHighlighted
tintColor:self.colorButtonClearHighlighted];
}
if(!self.imageButtonClearNormal)
{
UIImage *imageNormal = [buttonClear imageForState:UIControlStateNormal];
self.imageButtonClearNormal = [[self class] imageWithImage:imageNormal
tintColor:self.colorButtonClearNormal];
}
if(self.imageButtonClearHighlighted && self.imageButtonClearNormal)
{
[buttonClear setImage:self.imageButtonClearHighlighted forState:UIControlStateHighlighted];
[buttonClear setImage:self.imageButtonClearNormal forState:UIControlStateNormal];
}
}
}
+ (UIImage *) imageWithImage:(UIImage *)image tintColor:(UIColor *)tintColor
{
UIGraphicsBeginImageContextWithOptions(image.size, NO, 0.0);
CGContextRef context = UIGraphicsGetCurrentContext();
CGRect rect = (CGRect){ CGPointZero, image.size };
CGContextSetBlendMode(context, kCGBlendModeNormal);
[image drawInRect:rect];
CGContextSetBlendMode(context, kCGBlendModeSourceIn);
[tintColor setFill];
CGContextFillRect(context, rect);
UIImage *imageTinted = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return imageTinted;
}
@end
Ответ 4
В Swift вы можете написать расширение и использовать его в любом текстовом поле вашего проекта.
extension UITextField {
@objc func modifyClearButton(with image : UIImage) {
let clearButton = UIButton(type: .custom)
clearButton.setImage(image, for: .normal)
clearButton.frame = CGRect(x: 0, y: 0, width: 15, height: 15)
clearButton.contentMode = .scaleAspectFit
clearButton.addTarget(self, action: #selector(UITextField.clear(_:)), for: .touchUpInside)
rightView = clearButton
rightViewMode = .whileEditing
}
@objc func clear(_ sender : AnyObject) {
if delegate?.textFieldShouldClear?(self) == true {
self.text = ""
sendActions(for: .editingChanged)
}
}
}
Ответ 5
Для Swift 4 добавьте это в подкласс UITextField:
import UIKit
class CustomTextField: UITextField {
override func layoutSubviews() {
super.layoutSubviews()
for view in subviews {
if let button = view as? UIButton {
button.setImage(button.image(for: .normal)?.withRenderingMode(.alwaysTemplate), for: .normal)
button.tintColor = .white
}
}
}
}
Ответ 6
Вы можете использовать KVO для доступа к кнопке очистки и обновления:
UIButton *clearButton = [myTextField valueForKey:@"_clearButton"]
if([clearButton respondsToSelector:@selector(setImage:forState:)]){
//ensure that the app won't crash in the future if _clearButton reference changes to a different class instance
[clearButton setImage:[UIImage imageNamed:@"MyImage.png"] forState:UIControlStateNormal];
}
Примечание. Это решение не является будущим доказательством - если Apple изменит реализацию кнопки очистки, это будет изящно прекратить работу.
Ответ 7
Если вы используете UIAppearance в вашем приложении, вы можете установить tintColor для кнопки очистки во время выполнения.
let textField = UITextField.appearance()
textField.tintColor = .green
При запуске мы вызываем функцию класса в нашем AppDelegate, в которой есть ряд других элементов управления, для которых .appearance()
их .appearance()
.
Предположим, что ваш класс для настройки внешнего вида в вашем приложении называется Beautyify
вы бы создали что-то вроде этого:
@objc class Beautify: NSObject {
class func applyAppearance() {
let tableViewAppearance = UITableView.appearance()
tableViewAppearance.tintColor = .blue
let textField = UITextField.appearance()
textField.tintColor = .green
}
}
Тогда внутри AppDelegate didFinishLaunchingWithOptions
просто вызовите его.
Beautify.applyAppearance()
Это отличный способ настроить внешний вид вещей в вашем приложении одновременно.
Ответ 8
Это может быть даже проще, чем самый высокий рейтинг, доступный для iOS 7 и более поздних версий.
@interface MyTextField
@end
@implementation MyTextField
- (void)layoutSubviews {
[super layoutSubviews];
for (UIView *subView in self.subviews) {
if ([subView isKindOfClass:[UIButton class]]) {
UIButton *button = (UIButton *)subView;
[button setImage:[[button imageForState:UIControlStateNormal] imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate]
forState:UIControlStateNormal];
button.tintColor = self.tintColor;
}
}
}
@end
Ответ 9
Вот обновленное решение Swift 3:
extension UITextField {
func modifyClearButtonWithImage(image : UIImage) {
let clearButton = UIButton(type: .custom)
clearButton.setImage(image, for: .normal)
clearButton.frame = CGRect(x: 0, y: 0, width: 15, height: 15)
clearButton.contentMode = .scaleAspectFit
clearButton.addTarget(self, action: #selector(self.clear(sender:)), for: .touchUpInside)
self.rightView = clearButton
self.rightViewMode = .whileEditing
}
func clear(sender : AnyObject) {
self.text = ""
}
}
Наслаждайтесь;)
Ответ 10
Это работало для меня с помощью objective-C. Я потянул куски из других потоков на эту тему и придумал это решение:
UIButton *btnClear = [self.textFieldUserID valueForKey:@"clearButton"];
[btnClear setImage:[UIImage imageNamed:@"facebookLoginButton"] forState:UIControlStateNormal];
Ответ 11
Вы можете использовать свой пользовательский значок, и он работает в iOS 11,
searchBar.setImage(UIImage(named: "ic_clear"), for: .clear, state: .normal)
Ответ 12
Прекрасно работает в iOS8
searchBar.setImage(UIImage(named: "iconSearchBarClear"), forSearchBarIcon: .Clear, state: .Normal)
searchBar.setImage(UIImage(named: "iconSearchBarClear"), forSearchBarIcon: .Clear, state: .Highlighted)
Ответ 13
Пройдя все ответы и возможности, я нашел это простое и прямое решение.
-(void)updateClearButtonColor:(UIColor *)color ofTextField:(UITextField *)textField {
UIButton *btnClear = [textField valueForKey:@"_clearButton"];
UIImage * img = [btnClear imageForState:UIControlStateNormal];
if (img) {
UIImage * renderingModeImage = [img imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate];
[btnClear setImage:renderingModeImage forState:UIControlStateNormal];
//-- Add states you want to update
[btnClear setImage:renderingModeImage forState:UIControlStateSelected];
}
[btnClear setTintColor:color];
}
[self updateClearButtonColor:[UIColor whiteColor] ofTextField:self.textField];
Ответ 14
В SWIFT 3: это работает для меня
if let clearButton = self.textField.value(forKey: "_clearButton") as? UIButton {
// Create a template copy of the original button image
let templateImage = clearButton.imageView?.image?.withRenderingMode(.alwaysTemplate)
// Set the template image copy as the button image
clearButton.setImage(templateImage, for: .normal)
clearButton.setImage(templateImage, for: .highlighted)
// Finally, set the image color
clearButton.tintColor = .white
}
Ответ 15
Отправленный матом выше правильный. Кнопка очистки внутри UITextField
не существует, если не показана. Можно попытаться получить к нему доступ сразу после того, как UITextField
выполнит его layoutSubviews и проверит наличие кнопки.
Самый простой подход заключается в подклассе a UITextField
, переопределении layoutSubviews, и если кнопка отображается в первый раз, сохраните исходные изображения для последующего использования, а затем во время любых последующих всплывающих окон примените оттенок.
Ниже я покажу вам, как это сделать с помощью расширения, так как вы можете применить свой собственный оттенок к любому UITextField, включая те, которые вложены в готовые классы, такие как UISearchBar.
Веселитесь и дайте большие пальцы, если вам это нравится:)
Swift 3.2
Вот основное расширение:
import UIKit
extension UITextField {
private struct UITextField_AssociatedKeys {
static var clearButtonTint = "uitextfield_clearButtonTint"
static var originalImage = "uitextfield_originalImage"
}
private var originalImage: UIImage? {
get {
if let cl = objc_getAssociatedObject(self, &UITextField_AssociatedKeys.originalImage) as? Wrapper<UIImage> {
return cl.underlying
}
return nil
}
set {
objc_setAssociatedObject(self, &UITextField_AssociatedKeys.originalImage, Wrapper<UIImage>(newValue), .OBJC_ASSOCIATION_RETAIN)
}
}
var clearButtonTint: UIColor? {
get {
if let cl = objc_getAssociatedObject(self, &UITextField_AssociatedKeys.clearButtonTint) as? Wrapper<UIColor> {
return cl.underlying
}
return nil
}
set {
UITextField.runOnce
objc_setAssociatedObject(self, &UITextField_AssociatedKeys.clearButtonTint, Wrapper<UIColor>(newValue), .OBJC_ASSOCIATION_RETAIN)
applyClearButtonTint()
}
}
private static let runOnce: Void = {
Swizzle.for(UITextField.self, selector: #selector(UITextField.layoutSubviews), with: #selector(UITextField.uitextfield_layoutSubviews))
}()
private func applyClearButtonTint() {
if let button = UIView.find(of: UIButton.self, in: self), let color = clearButtonTint {
if originalImage == nil {
originalImage = button.image(for: .normal)
}
button.setImage(originalImage?.tinted(with: color), for: .normal)
}
}
func uitextfield_layoutSubviews() {
uitextfield_layoutSubviews()
applyClearButtonTint()
}
}
Вот дополнительные фрагменты, используемые в приведенном выше коде:
Хорошая обертка для любых материалов, к которым вы хотели бы получить доступ к объектам:
class Wrapper<T> {
var underlying: T?
init(_ underlying: T?) {
self.underlying = underlying
}
}
Небольшое расширение для поиска вложенных подзонов любого типа:
extension UIView {
static func find<T>(of type: T.Type, in view: UIView, includeSubviews: Bool = true) -> T? where T: UIView {
if view.isKind(of: T.self) {
return view as? T
}
for subview in view.subviews {
if subview.isKind(of: T.self) {
return subview as? T
} else if includeSubviews, let control = find(of: type, in: subview) {
return control
}
}
return nil
}
}
Расширение для UIImage
для применения цвета оттенков
extension UIImage {
func tinted(with color: UIColor) -> UIImage? {
UIGraphicsBeginImageContextWithOptions(self.size, false, self.scale)
color.set()
self.withRenderingMode(.alwaysTemplate).draw(in: CGRect(origin: CGPoint(x: 0, y: 0), size: self.size))
let result = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
return result
}
}
... и, наконец, Swizzling:
class Swizzle {
class func `for`(_ className: AnyClass, selector originalSelector: Selector, with newSelector: Selector) {
let method: Method = class_getInstanceMethod(className, originalSelector)
let swizzledMethod: Method = class_getInstanceMethod(className, newSelector)
if (class_addMethod(className, originalSelector, method_getImplementation(swizzledMethod), method_getTypeEncoding(swizzledMethod))) {
class_replaceMethod(className, newSelector, method_getImplementation(method), method_getTypeEncoding(method))
} else {
method_exchangeImplementations(method, swizzledMethod)
}
}
}
Ответ 16
Swift 4, это работает для меня (измените tintColor
на собственный цвет):
var didSetupWhiteTintColorForClearTextFieldButton = false
private func setupTintColorForTextFieldClearButtonIfNeeded() {
// Do it once only
if didSetupWhiteTintColorForClearTextFieldButton { return }
guard let button = yourTextField.value(forKey: "_clearButton") as? UIButton else { return }
guard let icon = button.image(for: .normal)?.withRenderingMode(.alwaysTemplate) else { return }
button.setImage(icon, for: .normal)
button.tintColor = .white
didSetupWhiteTintColorForClearTextFieldButton = true
}
override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
setupTintColorForTextFieldClearButtonIfNeeded()
}
Необходимо вызвать его в viewDidLayoutSubviews()
чтобы убедиться, что он вызван в конечном итоге, потому что существуют разные ситуации clearButtonMode
(always
, whileEditing
и т.д.). Я считаю, что эти кнопки создаются лениво. Поэтому вызовите его в viewDidLoad()
основном, не работают.
Ответ 17
Swift 4, чистый и сжатый подкласс
import UIKit
class CustomTextField: UITextField {
override func layoutSubviews() {
super.layoutSubviews()
for view in subviews where view is UIButton {
(view as! UIButton).setImage(<MY_UIIMAGE>, for: .normal)
}
}
}
Ответ 18
Идея состоит в том, чтобы получить кнопку очистки клавишей clearButton
, а затем повторно визуализировать четкое изображение в режиме alwaysTemplate
.
[Swift 4.2] Только что сделал расширение для UITextField
здесь:
extension UITextField {
var clearButton: UIButton? {
return value(forKey: "clearButton") as? UIButton
}
var clearButtonTintColor: UIColor? {
get {
return clearButton?.tintColor
}
set {
let image = clearButton?.imageView?.image?.withRenderingMode(.alwaysTemplate)
clearButton?.setImage(image, for: .normal)
clearButton?.tintColor = newValue
}
}
}
Но проблема с этим решением заключается в том, что изображение кнопки очистки в тот момент, когда вы звоните, чтобы установить цвет оттенка, равно nil
.
Таким образом, для каждого используется RxSwift
чтобы наблюдать изображение в кнопку очистки.
import RxSwift
extension UITextField {
var clearButton: UIButton? {
return value(forKey: "clearButton") as? UIButton
}
var clearButtonTintColor: UIColor? {
get {
return clearButton?.tintColor
}
set {
_ = rx.observe(UIImage.self, "clearButton.imageView.image")
.takeUntil(rx.deallocating)
.subscribe(onNext: { [weak self] _ in
let image = self?.clearButton?.imageView?.image?.withRenderingMode(.alwaysTemplate)
self?.clearButton?.setImage(image, for: .normal)
})
clearButton?.tintColor = newValue
}
}
}
Ответ 19
Вы можете использовать мою библиотеку LSCategories, чтобы сделать это с помощью одной строки:
[textField lsSetClearButtonWithColor:[UIColor redColor] mode:UITextFieldViewModeAlways];
Он НЕ использует какой-либо private api, он НЕ ищет исходный UIButton в иерархии subviews UITextField, и он НЕ требует подкласса UITextField в качестве некоторых других ответов здесь. Вместо этого он использует свойство rightView для имитации кнопки очистки системы, поэтому вам не нужно беспокоиться о том, что она перестанет работать в будущем, если Apple что-то изменит. Он также работает в Swift.
Ответ 20
Создайте этот метод.
func configureClearButtonColor() {
guard let clearButton = textField.value(forKey: "_clearButton") as? UIButton else {
return
}
let templateImage = clearButton.imageView?.image?.withRenderingMode(.alwaysTemplate)
clearButton.setImage(templateImage, for: .normal)
clearButton.setImage(templateImage, for: .highlighted)
clearButton.tintColor = .white
}
И реализуйте свой UITextFieldDelegate при вызове метода textFieldDidEndEditing. Это изменить ваше изображение, прежде чем создавать текст.
func textFieldDidEndEditing(_ textField: UITextField) {
configureClearButtonColor()
}
Ответ 21
подробности
- Версия Xcode 10.1 (10B61)
- Swift 4.2
Решение
import UIKit
extension UISearchBar {
func getTextField() -> UITextField? { return value(forKey: "searchField") as? UITextField }
func setClearButton(color: UIColor) {
getTextField()?.setClearButton(color: color)
}
}
extension UITextField {
private class ClearButtonImage {
static private var _image: UIImage?
static private var semaphore = DispatchSemaphore(value: 1)
static func getImage(closure: @escaping (UIImage?)->()) {
DispatchQueue.global(qos: .userInteractive).async {
semaphore.wait()
DispatchQueue.main.async {
if let image = _image { closure(image); semaphore.signal(); return }
guard let window = UIApplication.shared.windows.first else { semaphore.signal(); return }
let searchBar = UISearchBar(frame: CGRect(x: 0, y: -200, width: UIScreen.main.bounds.width, height: 44))
window.rootViewController?.view.addSubview(searchBar)
searchBar.text = "txt"
searchBar.layoutIfNeeded()
_image = searchBar.getTextField()?.getClearButton()?.image(for: .normal)
closure(_image)
searchBar.removeFromSuperview()
semaphore.signal()
}
}
}
}
func setClearButton(color: UIColor) {
ClearButtonImage.getImage { [weak self] image in
guard let image = image,
let button = self?.getClearButton() else { return }
button.imageView?.tintColor = color
button.setImage(image.withRenderingMode(.alwaysTemplate), for: .normal)
}
}
func getClearButton() -> UIButton? { return value(forKey: "clearButton") as? UIButton }
}
Полный образец
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
let textField = UITextField(frame: CGRect(x: 20, y: 20, width: 200, height: 44))
view.addSubview(textField)
textField.backgroundColor = .lightGray
textField.clearButtonMode = .always
textField.setClearButton(color: .red)
let searchBar = UISearchBar(frame: CGRect(x: 20, y: 80, width: 200, height: 44))
view.addSubview(searchBar)
searchBar.backgroundColor = .lightGray
searchBar.setClearButton(color: .red)
}
}
Результат
![enter image description here]()
Ответ 22
Я пробовал много ответов, пока не нашел это решение, основанное на решении @Mikael Hellman. Это решение использует Swift 4.2.
Идея та же:
Не использовать пользовательское изображение или добавленные кнопки и т.д.
И используя пользовательский класс, который расширяет UITextField
.
class TintClearTextField: UITextField {
private var updatedClearImage = false
override func layoutSubviews() {
super.layoutSubviews()
tintClearImage()
}
private func tintClearImage() {
if updatedClearImage { return }
if let button = self.value(forKey: "clearButton") as? UIButton,
let image = button.image(for: .highlighted)?.withRenderingMode(.alwaysTemplate) {
button.setImage(image, for: .normal)
button.setImage(image, for: .highlighted)
button.tintColor = .white
updatedClearImage = true
}
}
}
Вам не нужен updatedClearImage
, но имейте в виду, что вы будете выполнять всю логику в каждом добавлении персонажа.
Мне даже не нужно устанавливать tintColor
чтобы получить результат, который я искал. Попробуйте прокомментировать эту строку, прежде чем установить свой цвет.
Если он не выглядит так, как вы хотите, измените .white
цвет на нужный вам, и все.
PS: у меня есть поле, которое уже заполнено на моем начальном экране, и для этого только одно изменение цвета с помощью tintColor
происходит за миллисекунды после отображения цвета элемента по умолчанию, например, "сбой". Я не мог сделать это лучше, но так как я не использую tintColor
, это нормально для меня.
Надеюсь, поможет :)