自定义清除按钮
Custom Clear Button
我想在 UITextField 上创建自定义清除按钮,即使用 rightView 并将图像放在那里,问题是将原始清除按钮事件附加到该自定义 rightView。
在Objective-C中我可以这样做:
SEL clearButtonSelector = NSSelectorFromString(@"clearButton");
// Reference clearButton getter
IMP clearButtonImplementation = [self methodForSelector:clearButtonSelector];
// Create function pointer that returns UIButton from implementation of method that contains clearButtonSelector
UIButton * (* clearButtonFunctionPointer)(id, SEL) = (void *)clearButtonImplementation;
// Set clearTextFieldButton reference to “clearButton” from clearButtonSelector
UIButton *_clearTextFieldButton = clearButtonFunctionPointer(self, clearButtonSelector);
[_clearTextFieldButton setImage:[UIImage imageNamed:@"icon_remove"] forState:UIControlStateNormal];
self.hasClearButtonAsRightView = YES;
现在如何将其转换为 Swift?
或任何解决方法?
您可以像这样添加一个自定义按钮作为 UITextField
的右视图
class CustomTextField : UITextField
{
override init(frame: CGRect) {
super.init(frame: frame)
let clearButton = UIButton(frame: CGRect(origin: .zero, size: CGSize(width: 15, height: 15))
clearButton.setImage(UIImage(named: "clear.png")!, forState: UIControlState.Normal)
self.rightView = clearButton
clearButton.addTarget(self, action: "clearClicked:", forControlEvents: .touchUpInside)
self.clearButtonMode = .never
self.rightViewMode = .always
}
func clearClicked(sender: UIButton)
{
self.text = ""
}
required init(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
}
}
这是我在 Swift 3 中的解决方案。除了已经存在的答案外,我还确保文本字段的左右视图(即搜索放大镜图像视图和自定义清除按钮) ) 通过覆盖 leftViewRect()
和 rightViewRect()
对其 left/right 进行填充。否则,它们会粘在文本框的边缘。
class CustomTextField: UITextField
{
fileprivate let searchImageLength: CGFloat = 22
fileprivate let cancelButtonLength: CGFloat = 15
fileprivate let padding: CGFloat = 8
override init( frame: CGRect )
{
super.init( frame: frame )
self.customLayout()
}
required init?( coder aDecoder: NSCoder )
{
super.init( coder: aDecoder )
self.customLayout()
}
override func leftViewRect( forBounds bounds: CGRect ) -> CGRect
{
let x = self.padding
let y = ( bounds.size.height - self.searchImageLength ) / 2
let rightBounds = CGRect( x: x, y: y, width: self.searchImageLength, height: self.searchImageLength )
return rightBounds
}
override func rightViewRect( forBounds bounds: CGRect ) -> CGRect
{
let x = bounds.size.width - self.cancelButtonLength - self.padding
let y = ( bounds.size.height - self.cancelButtonLength ) / 2
let rightBounds = CGRect( x: x, y: y, width: self.cancelButtonLength, height: self.cancelButtonLength )
return rightBounds
}
fileprivate func customLayout()
{
// Add search icon on left side
let searchImageView = UIImageView()
searchImageView.contentMode = .scaleAspectFit
let searchIcon = UIImage( named: "search_magnifier" )
searchImageView.image = searchIcon
self.leftView = searchImageView
self.leftViewMode = .always
// Set custom clear button on right side
let clearButton = UIButton()
clearButton.setImage( UIImage( named: "search_cancel" ), for: .normal )
clearButton.contentMode = .scaleAspectFit
clearButton.addTarget( self, action: #selector( self.clearClicked ), for: .touchUpInside )
self.rightView = clearButton
self.clearButtonMode = .never
self.rightViewMode = .whileEditing
}
@objc fileprivate func clearClicked( sender: UIButton )
{
self.text = ""
}
}
按照其他答案中的建议实施自定义文本字段不是一个好主意。如果可能的话,您应该尝试使用扩展而不是继承,因为有了继承,您更有可能需要对代码库进行重大更改以响应更改,而使用扩展则可以更灵活地进行更改。
我强烈建议您不要实现自定义文本字段,而是像这样扩展 UITextField class:
extension UITextField {
func applyCustomClearButton() {
clearButtonMode = .Never
rightViewMode = .WhileEditing
let clearButton = UIButton(frame: CGRectMake(0, 0, 16, 16))
clearButton.setImage(UIImage(name: "iCFieldClear")!, forState: .Normal)
clearButton.addTarget(self, action: "clearClicked:", forControlEvents: .TouchUpInside)
rightView = clearButton
}
func clearClicked(sender:UIButton) {
text = ""
}
}
然后要使用它,您只需这样做:
yourTextField.applyCustomClearButton()
与 iOS 14,none 的解决方案对我有用。对于不同的设备尺寸,清除按钮的偏移量是错误的。
我有图像。如果没有,可以从 SF Symbols 下载。名字是 xmark.circle.fill
最后我用了这个
let customClearButton = UIButton.appearance(whenContainedInInstancesOf: [UITextField.self])
customClearButton.setImage(UIImage(named: "icon-x"), for: .normal)
已更新为 Swift 5,基于 :
public func addClearAllCustomButton() {
clearButtonMode = .never
rightViewMode = .whileEditing
let clearButton = UIButton(frame: rightViewRect(forBounds: bounds))
clearButton.setImage(UIImage(named: "clearAll"), for: .normal)
clearButton.addTarget(self, action: #selector(didTouchClearAllButton(sender:)), for: .touchUpInside)
rightView = clearButton
}
public func removeClearAllButton() {
rightViewMode = .never
}
@objc func didTouchClearAllButton(sender: UIButton) {
text = ""
}
我想在 UITextField 上创建自定义清除按钮,即使用 rightView 并将图像放在那里,问题是将原始清除按钮事件附加到该自定义 rightView。
在Objective-C中我可以这样做:
SEL clearButtonSelector = NSSelectorFromString(@"clearButton");
// Reference clearButton getter
IMP clearButtonImplementation = [self methodForSelector:clearButtonSelector];
// Create function pointer that returns UIButton from implementation of method that contains clearButtonSelector
UIButton * (* clearButtonFunctionPointer)(id, SEL) = (void *)clearButtonImplementation;
// Set clearTextFieldButton reference to “clearButton” from clearButtonSelector
UIButton *_clearTextFieldButton = clearButtonFunctionPointer(self, clearButtonSelector);
[_clearTextFieldButton setImage:[UIImage imageNamed:@"icon_remove"] forState:UIControlStateNormal];
self.hasClearButtonAsRightView = YES;
现在如何将其转换为 Swift? 或任何解决方法?
您可以像这样添加一个自定义按钮作为 UITextField
的右视图
class CustomTextField : UITextField
{
override init(frame: CGRect) {
super.init(frame: frame)
let clearButton = UIButton(frame: CGRect(origin: .zero, size: CGSize(width: 15, height: 15))
clearButton.setImage(UIImage(named: "clear.png")!, forState: UIControlState.Normal)
self.rightView = clearButton
clearButton.addTarget(self, action: "clearClicked:", forControlEvents: .touchUpInside)
self.clearButtonMode = .never
self.rightViewMode = .always
}
func clearClicked(sender: UIButton)
{
self.text = ""
}
required init(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
}
}
这是我在 Swift 3 中的解决方案。除了已经存在的答案外,我还确保文本字段的左右视图(即搜索放大镜图像视图和自定义清除按钮) ) 通过覆盖 leftViewRect()
和 rightViewRect()
对其 left/right 进行填充。否则,它们会粘在文本框的边缘。
class CustomTextField: UITextField
{
fileprivate let searchImageLength: CGFloat = 22
fileprivate let cancelButtonLength: CGFloat = 15
fileprivate let padding: CGFloat = 8
override init( frame: CGRect )
{
super.init( frame: frame )
self.customLayout()
}
required init?( coder aDecoder: NSCoder )
{
super.init( coder: aDecoder )
self.customLayout()
}
override func leftViewRect( forBounds bounds: CGRect ) -> CGRect
{
let x = self.padding
let y = ( bounds.size.height - self.searchImageLength ) / 2
let rightBounds = CGRect( x: x, y: y, width: self.searchImageLength, height: self.searchImageLength )
return rightBounds
}
override func rightViewRect( forBounds bounds: CGRect ) -> CGRect
{
let x = bounds.size.width - self.cancelButtonLength - self.padding
let y = ( bounds.size.height - self.cancelButtonLength ) / 2
let rightBounds = CGRect( x: x, y: y, width: self.cancelButtonLength, height: self.cancelButtonLength )
return rightBounds
}
fileprivate func customLayout()
{
// Add search icon on left side
let searchImageView = UIImageView()
searchImageView.contentMode = .scaleAspectFit
let searchIcon = UIImage( named: "search_magnifier" )
searchImageView.image = searchIcon
self.leftView = searchImageView
self.leftViewMode = .always
// Set custom clear button on right side
let clearButton = UIButton()
clearButton.setImage( UIImage( named: "search_cancel" ), for: .normal )
clearButton.contentMode = .scaleAspectFit
clearButton.addTarget( self, action: #selector( self.clearClicked ), for: .touchUpInside )
self.rightView = clearButton
self.clearButtonMode = .never
self.rightViewMode = .whileEditing
}
@objc fileprivate func clearClicked( sender: UIButton )
{
self.text = ""
}
}
按照其他答案中的建议实施自定义文本字段不是一个好主意。如果可能的话,您应该尝试使用扩展而不是继承,因为有了继承,您更有可能需要对代码库进行重大更改以响应更改,而使用扩展则可以更灵活地进行更改。
我强烈建议您不要实现自定义文本字段,而是像这样扩展 UITextField class:
extension UITextField {
func applyCustomClearButton() {
clearButtonMode = .Never
rightViewMode = .WhileEditing
let clearButton = UIButton(frame: CGRectMake(0, 0, 16, 16))
clearButton.setImage(UIImage(name: "iCFieldClear")!, forState: .Normal)
clearButton.addTarget(self, action: "clearClicked:", forControlEvents: .TouchUpInside)
rightView = clearButton
}
func clearClicked(sender:UIButton) {
text = ""
}
}
然后要使用它,您只需这样做:
yourTextField.applyCustomClearButton()
与 iOS 14,none 的解决方案对我有用。对于不同的设备尺寸,清除按钮的偏移量是错误的。 我有图像。如果没有,可以从 SF Symbols 下载。名字是 xmark.circle.fill 最后我用了这个
let customClearButton = UIButton.appearance(whenContainedInInstancesOf: [UITextField.self])
customClearButton.setImage(UIImage(named: "icon-x"), for: .normal)
已更新为 Swift 5,基于
public func addClearAllCustomButton() {
clearButtonMode = .never
rightViewMode = .whileEditing
let clearButton = UIButton(frame: rightViewRect(forBounds: bounds))
clearButton.setImage(UIImage(named: "clearAll"), for: .normal)
clearButton.addTarget(self, action: #selector(didTouchClearAllButton(sender:)), for: .touchUpInside)
rightView = clearButton
}
public func removeClearAllButton() {
rightViewMode = .never
}
@objc func didTouchClearAllButton(sender: UIButton) {
text = ""
}