添加到文本字段的 Swift Gesture 识别器在成为第一响应者后无法操作?

Posted

技术标签:

【中文标题】添加到文本字段的 Swift Gesture 识别器在成为第一响应者后无法操作?【英文标题】:Swift Gesture recognizers added to textfield inoperable after becomes first responder? 【发布时间】:2015-06-19 11:59:19 【问题描述】:

我在 swift 中向文本字段添加了点击和双击手势识别器,以便单击执行功能,但双击实际上使文本字段成为第一响应者。尽管在文本字段第一次成为第一响应者后它停止工作。也就是说,文本字段通过单击而不是双击成为第一响应者来正常运行。关于如何让我的手势识别器正常工作的任何想法?

【问题讨论】:

这种逻辑对我来说毫无意义。你为什么要这样做? 文本字段显示倒数计时器值。单击启动或暂停计时器。双击编辑计时器值。随意提出一个更好的方法来实现这一点。 参见 Tushar 的回答。问题是编辑值?我会使用类似于苹果实现的方法。 【参考方案1】:

另一种方法:

只需在文本字段顶部创建一个“不可见”视图并将手势识别器添加到其中

    import UIKit

    class ViewController: UIViewController, UITextFieldDelegate 

        @IBOutlet weak var textField: UITextField!

        override func viewDidLoad() 
            super.viewDidLoad()
            textField.delegate = self;
        

        override func viewDidAppear(animated: Bool) 
            let tap1 = UITapGestureRecognizer(target: self, action: "onSingleTap")
            let tap2 = UITapGestureRecognizer(target: self, action: "onDoubleTap")
            tap2.numberOfTapsRequired = 2

            // create a view and put it on top of the textfield
            // here created at viewDidAppear for example but you can do it better

            var dummieView = UIView(frame: self.textField.frame)
            dummieView.backgroundColor = UIColor(red: 1.0, green: 0.0, blue: 0.0, alpha: 0.25)
            self.view.addSubview(dummieView)
            dummieView.addGestureRecognizer(tap1)
            dummieView.addGestureRecognizer(tap2)
        

        func onSingleTap()
            println("custom single tap")
            if self.textField.isFirstResponder() 
                self.textField.resignFirstResponder()
            
        

        func onDoubleTap()
            println("double tap")
            self.textField.becomeFirstResponder()
        

        func textFieldShouldReturn(textField: UITextField) -> Bool 
            if self.textField.isFirstResponder() 
                self.textField.resignFirstResponder()
            
            return true
        


    

【讨论】:

效果很好。谢谢!尽管那个看不见的视图并不是完全看不见的。不过很容易修复。再次感谢。【参考方案2】:

从逻辑上讲,如果您按照以下步骤操作会更容易:

    将“可编辑”设置为 false 到 texField 在 doubleTap 操作实现上使文本字段可编辑为 true 并调用 becomeFirstResponder 以便用户可以输入。 实现文本字段委托方法 -textFieldDidEndEditing 并通过将“可编辑”属性设置为 false 再次使该文本字段不可编辑。

【讨论】:

恐怕这行不通。虽然 uitextview 有一个“可编辑”字段,但 uitextfield 没有。并且使用看似“启用”的字段会禁用所有触摸,因此也不起作用。【参考方案3】:

我有一个类似的问题,想要在显示和隐藏 UIPicker 之间切换。

问题在于 UITextField 添加了自己的手势识别器。因此,继承 UITextField 并添加您自己的,但不允许添加默认手势识别器。

class MyTextField: UITextField

    fileprivate var tap1Gesture: UITapGestureRecognizer?
    fileprivate var tap2Gesture: UITapGestureRecognizer?

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

        gestureRecognizers = nil
        tap1Gesture = UITapGestureRecognizer( target: self, action: #selector( tapped1( _: ) ) )
        addGestureRecognizer( tap1Gesture! )
        tap2Gesture = UITapGestureRecognizer( target: self, action: #selector( tapped2( _: ) ) )
        tap2Gesture.numberOfTapsRequired = 2
        addGestureRecognizer( tap2Gesture! )
    

    override func addGestureRecognizer(_ gestureRecognizer: UIGestureRecognizer)
    
        if gestureRecognizer == tap1Gesture || gestureRecognizer == tap2Gesture
        
            super.addGestureRecognizer( gestureRecognizer )
        
    

    internal func tapped1( _ sender: UITapGestureRecognizer )
    
        // Do your "performs a function"
    

    internal func tapped2( _ sender: UITapGestureRecognizer )
    
        if self.isFirstResponder
        
            _ = self.resignFirstResponder()
        
        else
        
            self.becomeFirstResponder()
        
    

如果你想隐藏选择的文本,你也可以在你的派生类中添加以下内容(帮助http://www.b2cloud.com.au/tutorial/disabling-the-caret-and-text-entry-in-uitextfields/):

extension MyTextField

    override var selectedTextRange: UITextRange?
    
        get  return nil 
        set  return 
    

    override func canPerformAction( _ action: Selector, withSender sender: Any? ) -> Bool
    
        return false
    

    override func caretRect( for position: UITextPosition ) -> CGRect
    
        return .zero
    

【讨论】:

以上是关于添加到文本字段的 Swift Gesture 识别器在成为第一响应者后无法操作?的主要内容,如果未能解决你的问题,请参考以下文章

在 Swift 中将文本字段添加到 UILocalNotification

使用 swift 将多个文本字段添加到 firebase

swift 中手势的使用

Swift 3 - 带有 Tap Gesture 的图像视图

Swift 多文本字段参数

如何在swift ui watch os中的同一屏幕中添加键盘和文本字段[关闭]