【问题标题】:Custom Clear Button自定义清除按钮
【发布时间】:2015-02-06 07:43:39
【问题描述】:

我想在 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? 或任何解决方法的想法?

【问题讨论】:

    标签: ios swift uitextfield


    【解决方案1】:

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

    【讨论】:

    • 使用另一种自定义方法来清除它...,很简单,为什么我无法弄清楚,谢谢@rakeshbs
    • 以防万一这发生在任何人身上。不要将方法设为私有,因为它是从其他地方调用的。我调试了几分钟,直到我意识到这一点。 :)
    【解决方案2】:

    按照其他答案中的建议实施自定义文本字段不是一个好主意。如果可能,您应该尝试使用扩展而不是继承,因为通过继承,您更有可能需要对代码库进行重大更改以响应更改,而使用扩展则可以更灵活地进行更改。

    我强烈建议不要实现自定义文本字段,而是像这样扩展 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()
    

    【讨论】:

      【解决方案3】:

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

      【讨论】:

        【解决方案4】:

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

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

        【讨论】:

          【解决方案5】:

          更新到 Swift 5,基于 @marmoy answer

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

          【讨论】:

            猜你喜欢
            • 2018-09-17
            • 1970-01-01
            • 1970-01-01
            • 2010-12-03
            • 2014-02-06
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多