调用resignFirstResponder在覆盖firstResponder中不起作用

idr*_*mer 2 uitextfield uiresponder ios swift

如何使用UIResponder关注激活的UITextField?

代码如下:

//  customTextField.swift
import UIKit
class customTextField: UITextField {

override func becomeFirstResponder() -> Bool {
    if self.tag == 1 {
        self.borderStyle = .Line
        self.superview?.viewWithTag(2)?.resignFirstResponder()
        self.superview?.viewWithTag(3)?.resignFirstResponder()
    } else if self.tag == 2 {
        self.borderStyle = .Line
        self.superview?.viewWithTag(1)?.resignFirstResponder()
        self.superview?.viewWithTag(3)?.resignFirstResponder()            
    } else {
        self.borderStyle = .Line
        self.superview?.viewWithTag(1)?.resignFirstResponder()
        self.superview?.viewWithTag(2)?.resignFirstResponder()
    }
    return true
}
override func resignFirstResponder() -> Bool {
    print("This is called")
    self.borderStyle = .None
    super.resignFirstResponder()
    return true
}}
Run Code Online (Sandbox Code Playgroud)

我想通过View的标签检查哪个textfield是firstResponder.然后,如果其他TextField应该由resignFirstResponder未聚焦.

但是,resignFirstResponder当我在视图中触摸textField时,甚至没有调用becomefirstResponder的代码块.

Swi*_*ect 7

不要破坏超类:传递消息

在覆盖系统消息的过程中becomeFirstResponder,您可能会无意中禁用父类.最安全的,没有操作的becomeFirstResponder是:

override func becomeFirstResponder() -> Bool {
    return super.becomeFirstResponder()
}
Run Code Online (Sandbox Code Playgroud)

省略super.becomeFirstResponder()会妥协UITextField.

同样让原始逻辑(何时成为或不成为响应者)采取其路线.始终响应truefalse更改父类的行为,这可能会产生不必要的和不幸的副作用.

    override func becomeFirstResponder() -> Bool {
        let becomeFirstResponder = super.becomeFirstResponder()
        // Do stuff
        return becomeFirstResponder
    }
Run Code Online (Sandbox Code Playgroud)

不要复制操作系统

无需跟踪当前的响应者.
让你的操作系统消息是响应者:尝试进行跟踪,否则当屏幕键盘被解除而没有点击新字段时,实际上可能无法工作,并且必然会中断.相反,以resignFirstResponder同样的方式倾听:

override func resignFirstResponder() -> Bool {
    return super.resignFirstResponder()
}
Run Code Online (Sandbox Code Playgroud)

代码更少,灵活性更高

将两个规则放在一起,并使用.RoundedRect&.Line进行显式重绘(.None没有效果),整个CustomTextField看起来像这样:

class CustomTextField: UITextField {

    override func becomeFirstResponder() -> Bool {
        let becomeFirstResponder = super.becomeFirstResponder()
        if becomeFirstResponder {
            self.borderStyle = .line
        }
        return becomeFirstResponder
    }

    override func resignFirstResponder() -> Bool {
        let resignFirstResponder = super.resignFirstResponder()
        if resignFirstResponder {
            self.borderStyle = .roundedRect
        }
        return resignFirstResponder
    }
}
Run Code Online (Sandbox Code Playgroud)

请注意,如果成功或未成功,则不采取任何措施.super.becomeFirstResponder()super.resignFirstResponder()


演示

动画


►在GitHub上找到此解决方案以及有关Swift Recipes的其他详细信息.