实例化 ViewController 的按钮在隐藏后不起作用
Button to instanciate ViewController is not working after hiding it
我刚发现这个非常奇怪的问题...
我有这个 button
触发了这个 function
:
@objc func vergessenTapped() {
let forgotPasswordVC = self.storyboard?.instantiateViewController(withIdentifier: "ForgotPasswordVC") as! ForgotPasswordVC
forgotPasswordVC.email = self.emailTextField.text!
self.present(forgotPasswordVC, animated: true, completion: nil)
}
我还有hide
/show
上面button
的这些功能:
// delegate Methode für eye-Button
func textFieldShouldBeginEditing(_ textField: UITextField) -> Bool {
switch textField {
case passwordTextField:
if passwordTextField.text != "" {
eyeButton.isHidden = false
vergessenButton.isHidden = true
} else {
eyeButton.isHidden = true
}
break
default:
break
}
return true
}
// delegate Methode für eye-Button
func textFieldShouldEndEditing(_ textField: UITextField) -> Bool {
if textField == passwordTextField {
self.eyeButton.isHidden = true
self.vergessenButton.isHidden = false
}
return true
}
@objc func textFieldDidChange(_ textField: UITextField) {
if textField.text == "" {
self.eyeButton.isHidden = true
self.vergessenButton.isHidden = false
}else {
self.vergessenButton.isHidden = true
self.eyeButton.isHidden = false
}
}
现在问题:
当我在上面的任何 delegate-function
隐藏它之前第一次按 button
时,ViewController
它 presents
工作得很好。
但是:一旦按钮第一次被隐藏,并且用户在它再次可见后单击它,forgotpasswordViewController
的行为真的很奇怪,例如:
1. 调用 self.dismiss
时,`ViewController 实际上并没有被关闭,而是弹出下面的 它。
@objc func backButtonTapped(){
self.dismiss(animated: true, completion: nil)
}
2. forgotpasswordViewController
中的 button
(只有一个按钮)没有任何作用。
这里有一个Screenvideo可以更好的理解。进入视频 22 秒后,我开始打字(不知何故在屏幕视频上不可见,但您可以看到“vergessen”但消失并再次出现。再次出现后,我单击它,如您所见,backButton
和confirmButton
像以前一样工作...
这是某种错误吗???我无法解释..所以如果有人帮助我,我将不胜感激!
演示项目:
与Vergessen按钮的显示和隐藏无关。问题是你的 ForgotPassword 视图控制器(实际上也是你的其他视图控制器)中的这类事情:
let backButton: UIButton = {
let v = UIButton()
v.translatesAutoresizingMaskIntoConstraints = false
v.setImage(UIImage(named:"down"), for: .normal)
v.addTarget(self, action: #selector(backButtonTapped), for: .touchUpInside)
return v
}()
这有点不对劲。你看到它是什么了吗?当然不是,因为这是所有 iOS 编程中最讨厌的小陷阱之一。您不能在实例 属性 的初始化程序中说 v.addTarget(self...
。为什么?因为实例 self
(此处为视图控制器)是我们正在初始化的对象。所以 self
在这里没有任何意义。好吧,有时它有意义,有时却没有;真正的陷阱是代码 ever 有效。那真的误导你了。 (你也被代码编译的事实误导了。在我看来,它不应该。我有一个filed a bug,如果它有任何安慰的话。)
好吧,所以我可以想到很多解决方案,但传统上我们在这里做的是用 lazy var
替换 let
。我想我在你的代码中看到了六个地方你需要这样做。
lazy var backButton: UIButton = { // ... and so on
当你这样做时,一切都会开始正常工作。
解决此问题的原因是 lazy
推迟了该代码的 运行 直到 在 视图控制器本身已初始化之后。那么 self
就是它应该表达的意思。
(很抱歉没有lazy let
,但我对此无能为力。你只需要说lazy var
然后就这样吧。)
我还要补充一点,iOS 14 中的新功能,您可以(如果愿意)停止调用 addTarget(_:action:for:)
,这样您就不会再掉入这个陷阱。但是,向按钮添加 UIAction 的修复仅适用于 iOS 14 及更高版本。
我刚发现这个非常奇怪的问题...
我有这个 button
触发了这个 function
:
@objc func vergessenTapped() {
let forgotPasswordVC = self.storyboard?.instantiateViewController(withIdentifier: "ForgotPasswordVC") as! ForgotPasswordVC
forgotPasswordVC.email = self.emailTextField.text!
self.present(forgotPasswordVC, animated: true, completion: nil)
}
我还有hide
/show
上面button
的这些功能:
// delegate Methode für eye-Button
func textFieldShouldBeginEditing(_ textField: UITextField) -> Bool {
switch textField {
case passwordTextField:
if passwordTextField.text != "" {
eyeButton.isHidden = false
vergessenButton.isHidden = true
} else {
eyeButton.isHidden = true
}
break
default:
break
}
return true
}
// delegate Methode für eye-Button
func textFieldShouldEndEditing(_ textField: UITextField) -> Bool {
if textField == passwordTextField {
self.eyeButton.isHidden = true
self.vergessenButton.isHidden = false
}
return true
}
@objc func textFieldDidChange(_ textField: UITextField) {
if textField.text == "" {
self.eyeButton.isHidden = true
self.vergessenButton.isHidden = false
}else {
self.vergessenButton.isHidden = true
self.eyeButton.isHidden = false
}
}
现在问题:
当我在上面的任何 delegate-function
隐藏它之前第一次按 button
时,ViewController
它 presents
工作得很好。
但是:一旦按钮第一次被隐藏,并且用户在它再次可见后单击它,forgotpasswordViewController
的行为真的很奇怪,例如:
1. 调用 self.dismiss
时,`ViewController 实际上并没有被关闭,而是弹出下面的 它。
@objc func backButtonTapped(){
self.dismiss(animated: true, completion: nil)
}
2. forgotpasswordViewController
中的 button
(只有一个按钮)没有任何作用。
这里有一个Screenvideo可以更好的理解。进入视频 22 秒后,我开始打字(不知何故在屏幕视频上不可见,但您可以看到“vergessen”但消失并再次出现。再次出现后,我单击它,如您所见,backButton
和confirmButton
像以前一样工作...
这是某种错误吗???我无法解释..所以如果有人帮助我,我将不胜感激!
演示项目:
与Vergessen按钮的显示和隐藏无关。问题是你的 ForgotPassword 视图控制器(实际上也是你的其他视图控制器)中的这类事情:
let backButton: UIButton = {
let v = UIButton()
v.translatesAutoresizingMaskIntoConstraints = false
v.setImage(UIImage(named:"down"), for: .normal)
v.addTarget(self, action: #selector(backButtonTapped), for: .touchUpInside)
return v
}()
这有点不对劲。你看到它是什么了吗?当然不是,因为这是所有 iOS 编程中最讨厌的小陷阱之一。您不能在实例 属性 的初始化程序中说 v.addTarget(self...
。为什么?因为实例 self
(此处为视图控制器)是我们正在初始化的对象。所以 self
在这里没有任何意义。好吧,有时它有意义,有时却没有;真正的陷阱是代码 ever 有效。那真的误导你了。 (你也被代码编译的事实误导了。在我看来,它不应该。我有一个filed a bug,如果它有任何安慰的话。)
好吧,所以我可以想到很多解决方案,但传统上我们在这里做的是用 lazy var
替换 let
。我想我在你的代码中看到了六个地方你需要这样做。
lazy var backButton: UIButton = { // ... and so on
当你这样做时,一切都会开始正常工作。
解决此问题的原因是 lazy
推迟了该代码的 运行 直到 在 视图控制器本身已初始化之后。那么 self
就是它应该表达的意思。
(很抱歉没有lazy let
,但我对此无能为力。你只需要说lazy var
然后就这样吧。)
我还要补充一点,iOS 14 中的新功能,您可以(如果愿意)停止调用 addTarget(_:action:for:)
,这样您就不会再掉入这个陷阱。但是,向按钮添加 UIAction 的修复仅适用于 iOS 14 及更高版本。