Nie*_*ben 50 objective-c uibutton uitextfield ios swift
我的UITextfield上有一个自动生成的清除按钮,默认为蓝色色调.我无法将色调颜色更改为白色.我试过修改故事板和代码没有成功,我不想使用自定义图像.
如何在不使用自定义图像的情况下更改默认的清除按钮色调?
Mik*_*man 73
干得好!
一个TintTextField.
不使用自定义图像或添加按钮等.
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()
}
}
Run Code Online (Sandbox Code Playgroud)
mat*_*att 23
您无法做到这一点的原因是清晰的按钮图像没有着色.它们只是普通的图像.
清除按钮是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
}
}
}
Run Code Online (Sandbox Code Playgroud)
一旦你捕获它,你会发现它是一个14x14的双分辨率tiff图像,这里是:
理论上,您可以将图像更改为其他颜色,并可以将其指定为文本视图的清除按钮的图像以显示突出显示的状态.但实际上这并不容易,因为按钮并不总是存在; 当它不存在时你不能引用它(它不仅是不可见的;它实际上根本不是视图层次结构的一部分,因此无法访问它).
此外,没有UITextField API来自定义清除按钮.
因此,最简单的解决办法是什么,建议在这里:创建一个按钮,自定义标准,并强调图像,并提供其作为的UITextField的rightView
.然后,您将设置clearButtonMode
为从不(因为您正在使用正确的视图)和rightViewMode
任何您喜欢的.
当然,您必须检测到点击此按钮并通过清除文本字段的文本进行响应; 但这很容易做到,并留给读者练习.
MP2*_*P23 15
基于@Mikael Hellman的响应,我为Objective-C准备了类似的UITextField子类实现.唯一的区别是我允许为正常状态和突出显示状态分别使用颜色.
.h文件
#import <UIKit/UIKit.h>
@interface TextFieldTint : UITextField
-(void) setColorButtonClearHighlighted:(UIColor *)colorButtonClearHighlighted;
-(void) setColorButtonClearNormal:(UIColor *)colorButtonClearNormal;
@end
Run Code Online (Sandbox Code Playgroud)
.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
Run Code Online (Sandbox Code Playgroud)
Moh*_*diq 14
在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)
}
}
}
Run Code Online (Sandbox Code Playgroud)
小智 13
斯威夫特 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
}
Run Code Online (Sandbox Code Playgroud)
CW0*_*007 11
对于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
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
这个想法是通过 key 获取清晰的按钮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
}
}
}
Run Code Online (Sandbox Code Playgroud)
但此解决方案的问题是清除按钮的图像是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
}
}
}
Run Code Online (Sandbox Code Playgroud)
您可以使用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];
}
Run Code Online (Sandbox Code Playgroud)
注意:此解决方案不是未来证明 - 如果Apple更改了清除按钮的实现,这将优雅地停止工作.
您可以使用自定义图标,它适用于 iOS 11,
searchBar.setImage(UIImage(named: "ic_clear"), for: .clear, state: .normal)
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
33487 次 |
最近记录: |