ios - 用于实例化 ViewController 的按钮在隐藏后不起作用
问题描述
我有一个非常奇怪的问题,我刚刚发现......
我有这个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
}
}
现在的问题:
当我在上述任何内容隐藏它button
之前第一次按下时,它工作得很好。delegate-function
ViewController
presents
但是:一旦按钮第一次被隐藏,并且用户在它再次可见后单击它,forgotpasswordViewController
行为真的很奇怪,例如:
1.调用时self.dismiss
,`ViewController 实际上并没有被关闭,而是弹出它下面的 那个。
@objc func backButtonTapped(){
self.dismiss(animated: true, completion: nil)
}
2.button
中的(forgotpasswordViewController
只有一个按钮)没有做任何事情。
这是一个屏幕视频,以便更好地理解。进入视频 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
这里没有任何意义。嗯,有时它有意义,有时没有;对你来说真正的陷阱是代码曾经工作过。这真的误导了你。(你也被代码编译的事实误导了。在我看来,它不应该。我已经提交了一个错误,如果它有任何安慰的话。)
好的,所以我可以想到很多解决方案,但传统上我们在这里所做的是替换let
为lazy var
. 我想我在你的代码中有六个地方需要这样做。
lazy var backButton: UIButton = { // ... and so on
当你这样做时,一切都会开始正常工作。
解决问题的原因是lazy
推迟了代码的运行,直到视图控制器本身被初始化之后。所以 thenself
意味着它应该是什么意思。
(很抱歉,没有lazy let
,但我对此无能为力。你只需要说lazy var
出来就可以了。)
我还应该补充一点,iOS 14 中的新功能,您可以(如果您愿意) stop call addTarget(_:action:for:)
,这样您就不会再掉入这个陷阱了。但修复,即向按钮添加 UIAction,仅适用于 iOS 14 及更高版本。
推荐阅读
- c - 在 Eclipse 中使用终端作为调试控制台
- angularjs - 无法读取 AngularJS 拦截器中的响应数据和标头
- java - 如何从 json 文件中设置发布请求有效负载再保证
- oracle - oracle表单12c中的Json_table函数
- javascript - 如何将谷歌表格数据转换为json
- php - 如何使当前用户成为帖子作者?
- android - 仅在 EditText 中隐藏数字以获取 pin 码 (Android)
- python - Python - 具有多个条件的过滤函数
- laravel - Livewire 内部组件中的属性不会刷新
- xaml - 如何在框架内使用网格分隔条目和图像?