如何更改UITextField上清除按钮的色调颜色

时间:2015-01-14 14:03:30

标签: ios objective-c swift uibutton uitextfield

我的UITextfield上有一个自动生成的清除按钮,默认为蓝色色调。我无法将色调颜色更改为白色。我尝试修改故事板和代码但没有成功,我不想使用自定义图像。

如何在不使用自定义图像的情况下更改默认的清除按钮色调?

clicked

24 个答案:

答案 0 :(得分:69)

你走了!

TintTextField。

不使用自定义图像或添加按钮等。

enter image description here

class TintTextField: UITextField {

  var tintedClearImage: UIImage?

  required init(coder aDecoder: NSCoder) {
    super.init(coder: aDecoder)
    setupTintColor()
  }

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

  func setupTintColor() {
    clearButtonMode = UITextFieldViewMode.WhileEditing
    borderStyle = UITextBorderStyle.RoundedRect
    layer.cornerRadius = 8.0
    layer.masksToBounds = true
    layer.borderColor = tintColor.CGColor
    layer.borderWidth = 1.5
    backgroundColor = UIColor.clearColor()
    textColor = tintColor
  }

  override func layoutSubviews() {
    super.layoutSubviews()
    tintClearImage()
  }

  private func tintClearImage() {
    for view in subviews as! [UIView] {
      if view is UIButton {
        let button = view as! UIButton
        if let uiImage = button.imageForState(.Highlighted) {
          if tintedClearImage == nil {
            tintedClearImage = tintImage(uiImage, tintColor)
          }
          button.setImage(tintedClearImage, forState: .Normal)
          button.setImage(tintedClearImage, forState: .Highlighted)
        }
      }
    }
  }
}


func tintImage(image: UIImage, color: UIColor) -> UIImage {
  let size = image.size

  UIGraphicsBeginImageContextWithOptions(size, false, image.scale)
  let context = UIGraphicsGetCurrentContext()
  image.drawAtPoint(CGPointZero, blendMode: CGBlendMode.Normal, alpha: 1.0)

  CGContextSetFillColorWithColor(context, color.CGColor)
  CGContextSetBlendMode(context, CGBlendMode.SourceIn)
  CGContextSetAlpha(context, 1.0)

  let rect = CGRectMake(
    CGPointZero.x,
    CGPointZero.y,
    image.size.width,
    image.size.height)
  CGContextFillRect(UIGraphicsGetCurrentContext(), rect)
  let tintedImage = UIGraphicsGetImageFromCurrentImageContext()
  UIGraphicsEndImageContext()

  return tintedImage
}

答案 1 :(得分:22)

您在执行此操作时遇到问题的原因是清晰的按钮图像没有着色。它们只是普通的图像。

清除按钮是UITextField内部的按钮。像任何按钮一样,它可以有一个图像,它可以。特别是,它有两个图像:一个用于Normal状态,一个用于Highlighted状态。 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的双分辨率tiff图像,在这里它是:

enter image description here

理论上,您可以将图像更改为其他颜色,并可以将其指定为文本视图的清除按钮的图像以显示突出显示的状态。但实际上这并不容易,因为按钮并不总是存在;当它不存在时你不能引用它(它不仅是不可见的;它实际上根本不是视图层次结构的一部分,因此无法访问它)。

此外,没有UITextField API来自定义清除按钮。

因此,最简单的解决方案是建议here:创建一个包含自定义正常和突出显示图像的按钮,并将其作为UITextField的rightView提供。然后,您将clearButtonMode设置为从不(因为您正在使用正确的视图),将rightViewMode设置为您喜欢的任何内容。

enter image description here

当然,您必须检测到点击此按钮并通过清除文本字段的文本进行响应;但这很容易做到,并留给读者练习。

答案 2 :(得分:15)

基于@Mikael Hellman的回应我已经为Objective-C准备了类似的UITextField子类实现。唯一的区别是我允许为正常和突出状态分别使用颜色。

.h文件

#import <UIKit/UIKit.h>


@interface TextFieldTint : UITextField

-(void) setColorButtonClearHighlighted:(UIColor *)colorButtonClearHighlighted;
-(void) setColorButtonClearNormal:(UIColor *)colorButtonClearNormal;

@end

.m文件

#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

答案 3 :(得分:11)

在Swift中,您可以编写扩展名并在项目的任何文本字段中使用。

extension UITextField {
    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
    }

    func clear(_ sender : AnyObject) {
        self.text = ""
        sendActions(for: .editingChanged)
    }
}

答案 4 :(得分:10)

对于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
            }
        }
    }
}

答案 5 :(得分:5)

您可以使用KVO访问清除按钮并进行更新:

RewriteEngine On

RewriteCond %{HTTP_USER_AGENT} (facebookexternalhit/[0-9]|Twitterbot|Pinterest|Google.*snippet)
RewriteCond %{QUERY_STRING} ^courseID=([^&]+)
RewriteRule ^reviews/view-course$ /social_scrape2/static-page [P]

#angular html5
RewriteCond %{REQUEST_FILENAME} -s [OR]
RewriteCond %{REQUEST_FILENAME} -l [OR]
RewriteCond %{REQUEST_FILENAME} -d
RewriteRule ^.*$ - [NC,L]

RewriteRule ^(.*) /reviews/index.html [NC,L]

注意:此解决方案不是未来证明 - 如果Apple更改了清除按钮的实现,这将优雅地停止工作。

答案 6 :(得分:3)

它可能比最高等级的答案更容易,适用于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

答案 7 :(得分:3)

这是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 = ""
    }
}

享受;)

答案 8 :(得分:2)

这对我使用Objective-C起作用。我从这个主题的其他主题中删除了部分并提出了这个解决方案:

if(!family[i].equals(perTst)
        && !perTst.equals(couples.get(family[i]))
        && !family[i].equals(couples.get(perTst))) {
    //...
}

答案 9 :(得分:2)

您可以使用自定义图标,它可以在iOS 11中使用,

searchBar.setImage(UIImage(named: "ic_clear"), for: .clear, state: .normal)

答案 10 :(得分:2)

如果您在应用程序中使用UIAppearance,则可以在运行时为清除按钮设置tintColor。

.appearance()

在启动时,我们在AppDelegate中调用一个类函数,该函数有许多其他控件,其中配置了Beautyify

假设您在应用中设置外观的类称为@objc class Beautify: NSObject { class func applyAppearance() { let tableViewAppearance = UITableView.appearance() tableViewAppearance.tintColor = .blueColor() let textField = UITextField.appearance() textField.tintColor = .greenColor() } } ,您可以创建如下内容:

didFinishLaunchingWithOptions

然后在AppDelegate Beautify.applyAppearance()内部调用它。

{{1}}

这是在应用程序中同时配置事物外观的好方法。

答案 11 :(得分:1)

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情况(alwayswhileEditing等。) 。我相信这些按钮是懒洋洋地创建的。所以在viewDidLoad()中调用它几乎不起作用。

答案 12 :(得分:1)

快速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)
        }
    }
}

答案 13 :(得分:1)

上面的matt发布的答案是正确的。如果没有显示,UITextField内的清除按钮不存在。可以在UITextField执行其layoutSubviews并检查按钮是否存在后立即尝试访问它。 最简单的方法是子类化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)
        }
    }

}

答案 14 :(得分:1)

在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 :(得分:1)

在完成所有答案和可能性之后,我找到了这个简单而直接的解决方案。

-(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];

答案 16 :(得分:0)

您可以使用我的库LSCategories通过一行执行此操作:

[textField lsSetClearButtonWithColor:[UIColor redColor] mode:UITextFieldViewModeAlways];

它不使用任何私有api,它不会在UITextField子视图层次结构中搜索原始UIButton,并且它不需要将UITextField子类化为其他答案。相反,它使用rightView属性来模仿系统清除按钮,因此您不必担心如果Apple更改某些内容它将来会停止工作。它也适用于Swift。

答案 17 :(得分:0)

创建此方法。

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
}

并在 textFieldDidEndEditing 的方法中实现您的 UITextFieldDelegate 。这样可以在创建一些文本之前更改图像。

func textFieldDidEndEditing(_ textField: UITextField) {
    configureClearButtonColor()
}

答案 18 :(得分:0)

详细信息

  • Xcode版本10.1(10B61)
  • 迅速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

答案 19 :(得分:0)

我尝试了很多答案,直到找到基于@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,所以对我来说还可以。

希望它会有所帮助:)

答案 20 :(得分:0)

想法是通过按键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
        }
    }
}

答案 21 :(得分:0)

修改@ 3vangelos解决方案,绕过此for循环

for view in subviews where view is UIButton {
        (view as! UIButton).setImage(<MY_UIIMAGE>, for: .normal)
    }

我的修改:-

class CustomTextField:UITextField { 
override func layoutSubviews()
    {super.layoutSubviews()
    let clearButton = self.value(forKey: "clearButton") as? UIButton
    clearButton?.setImage(#imageLiteral(resourceName: "icons8-cancel.pdf"), for: .normal)
    clearButton?.tintColor = UIColor(<YOUR_COLOR>)
}

可以在UISearchBar中使用相同的解决方案,并添加一些代码:-

 override func viewWillAppear(_ animated: Bool)
{
    super.viewWillAppear(animated)
if let textField = agentsSearchBar.value(forKey: "searchField") as? UITextField
    {
let clearButton = textField.value(forKey: "clearButton") as? UIButton
clearButton?.setImage(#imageLiteral(resourceName: "icons8-cancel.pdf"), for: .normal)
clearButton?.tintColor = UIColor(<YOUR_COLOR>)
} }

图像(icons8-cancel.pdf)可以在以下位置下载 https://icons8.com/icon/set/clear-button/ios7#并使用以下属性enter image description here

添加到您的图像资产中

答案 22 :(得分:0)

就像@Brody Robertson的答案一样,这是 Swift 5 版本,它对我有用:

let textField = UITextField()
if let button = textField.value(forKey: "clearButton") as? UIButton {
  button.tintColor = .white
  button.setImage(UIImage(named: "yourImage")?.withRenderingMode(.alwaysTemplate), for: .normal)
}

注意:您需要使用图标替换yourImage,或者如果目标是iOS 13.0或更高版本,则可以将方法UIImage(named:)替换为{{1} }。 Apple在iOS 13.0或更高版本中已为您准备好此清除图标。我希望这个能帮上忙!祝你好运!

答案 23 :(得分:-1)

Swift 5 解决方案:

   if let clearButton = yourTextField.value(forKey: "_clearButton") as? UIButton {
       let templateImage = clearButton.imageView?.image?.withRenderingMode(.alwaysTemplate)
       clearButton.setImage(templateImage, for: .normal)
       clearButton.tintColor = .darkGray
   }