ios 自定义清除按钮

kkih6yb8  于 2022-11-26  发布在  iOS
关注(0)|答案(6)|浏览(188)

我想在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?2或者有什么解决办法吗?

avwztpqn

avwztpqn1#

您可以添加自定义按钮作为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)
    }
}
jfewjypa

jfewjypa2#

按照其他答案中的建议实现一个自定义文本字段不是一个好主意。如果可能的话,您应该尝试使用扩展而不是继承,因为使用继承,您更有可能需要对代码库进行重大更改以响应更改,而使用扩展,更改起来要灵活得多。
我强烈建议您不要实现自定义文本字段,而是像下面这样扩展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()
uqdfh47h

uqdfh47h3#

这是我在Swift 3中的解决方案。除了已经存在的答案之外,我还通过覆盖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 = ""
    }
}
3vpjnl9f

3vpjnl9f4#

在iOS 14中,没有一个解决方案对我有效。清除按钮对于不同的设备大小得到了错误的偏移。我有图像。如果你没有,你可以从SF Symbols下载。名称是xmark.circle.fill最后,我用了这个

let customClearButton = UIButton.appearance(whenContainedInInstancesOf: [UITextField.self])
        customClearButton.setImage(UIImage(named: "icon-x"), for: .normal)
cld4siwp

cld4siwp5#

已更新至Swift 5,基于@marmoy答案:

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

sgtfey8w6#

对于右填充&侦听文本字段的clear委托

class SearchBoxTextField: UITextField {

override open func awakeFromNib() {
    super.awakeFromNib()
    self.initialize()
}

override init(frame: CGRect) {
    super.init(frame: frame)
    self.initialize()
}

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

func initialize() {
    let clearButton = UIButton(frame: CGRect(x: 0, y: 0, width: 12, height: 12))
    clearButton.setImage(UIImage(named: "removeIcon")!, for: .normal)
    let clearView = UIView(frame: CGRect(x: 0, y: 0, width: 22, height: 12))
    clearView.addSubview(clearButton)
    
    self.rightView = clearView
    clearButton.addTarget(self, action: #selector(clearClicked), for: .touchUpInside)
    
    self.clearButtonMode = .never
    self.rightViewMode = .whileEditing
}

@objc func clearClicked(sender:UIButton) {
    self.text = ""
    _ = self.delegate?.textFieldShouldClear?(self)
}

}

相关问题