自定义清除button

我想在UITextField上创build自定义清除button,即使用rightView并将图像放在那里,问题是将原始清除button事件附加到该自定义的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? 或任何想法来解决它?

你可以添加一个自定义button作为像这样的UITextField右视图

 class CustomTextField : UITextField { override init(frame: CGRect) { super.init(frame: frame) let clearButton = UIButton(frame: CGRectMake(0, 0, 15, 15)) clearButton.setImage(UIImage(named: "clear.png")!, forState: UIControlState.Normal) self.rightView = clearButton clearButton.addTarget(self, action: "clearClicked:", forControlEvents: UIControlEvents.TouchUpInside) self.clearButtonMode = UITextFieldViewMode.Never self.rightViewMode = UITextFieldViewMode.Always } func clearClicked(sender:UIButton) { self.text = "" } required init(coder aDecoder: NSCoder) { super.init(coder: aDecoder) } } 

这里是我在Swift 3中的解决scheme。除了已经存在的答案之外,我还确保文本字段的左侧和右侧视图(即search放大镜图像视图和自定义清除button)具有填充到其左/右通过重写leftViewRect()rightViewRect() 。 否则,他们将坚持正确的文本框的边缘。

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

按照其他答案中的build议实现自定义文本字段不是一个好主意 。 如果可能的话,你应该总是尽量使用扩展而不是inheritance,因为inheritance你更有可能需要对你的代码库作出响应变化的重大改变,而使用扩展你可以更灵活地改变。

我强烈build议您不要实现自定义文本字段,而是像下面这样扩展UITextField类:

 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()