问题描述
我刚刚发现了一个非常奇怪的问题......
I have this very weird problem that I just found out...
我有这个 button
触发这个 function
:
I have this button
which is triggering this 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
的功能:
I also have these function which hide
/show
the button
above:
// 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
它 礼物
工作得很好.
When I press the button
the first time before any of the delegate-function
above are hiding it, the ViewController
it presents
works just fine.
但是:一旦按钮第一次被隐藏,并且用户在它再次可见后单击它,forgotpasswordViewController
的行为真的很奇怪,例如:
However: As soon as the button is hidden for the first time, and the user clicks it after it is visible again the forgotpasswordViewController
behaves really really weird, e.g:
1. 在调用 self.dismiss
时,`ViewController 实际上并没有被关闭,而是弹出 下面的一个.p>
1. when calling self.dismiss
, the `ViewController is actually not dismissed, but is popping the one below it.
@objc func backButtonTapped(){
self.dismiss(animated: true, completion: nil)
}
2. forgotpasswordViewController
中的 button
(只有一个按钮)没有做任何事情.
2. The button
in the forgotpasswordViewController
(only one button there) is not doing anything.
这里有一个屏幕视频,以便更好地理解.我开始输入视频 22 秒后(在屏幕视频上不知何故不可见,但您可以看到vergessen"但消失并再次出现.再次出现后,我单击它,如您所见,backButton
也不是 confirmButton
像以前那样工作......
Here is a Screenvideo for a better understanding. 22 seconds into the video I start typing (somehow not visible on the screenvideo but you can see that the "vergessen" but disappears and appears again. After appearing again I click it and as you can see, neither the backButton
nor the confirmButton
work like they did before...
这是某种错误吗???我无法解释......所以如果有人在这里帮助我,我将不胜感激!
Is this some kind of bug??? I can't explain it .. so if anyone helps me out here I would really appreciated!
演示项目:
推荐答案
它与显示和隐藏 Vergessen 按钮无关.问题是您的 ForgotPassword 视图控制器(实际上也是您的其他视图控制器)中的这种事情:
It has nothing to do with showing and hiding the Vergessen button. The problem is this sort of thing in your ForgotPassword view controller (and your other view controller too, actually):
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 工作.这真的误导了你.(你也被代码编译的事实误导了.在我看来,它不应该.我有一个 提交了一个错误,如果有任何安慰的话.)
There is something very wrong with that. Do you see what it is? Of course not, because this is one of the nastiest little traps in all of iOS programming. You cannot say v.addTarget(self...
in the initializer of an instance property. Why? Because the instance self
(here, the view controller) is what we are in the middle of initializing. So self
has no meaning here. Well, sometimes it has a meaning and sometimes it doesn't; the real trap for you is that the code ever worked. That really misled you. (Also you were misled by the fact that the code compiled. In my opinion, it should not. I have a filed a bug, if it's any comfort.)
好的,所以我可以想到很多解决方案,但传统上我们在这里所做的是将 let
替换为 lazy var
.我想我在你的代码中有六个地方需要这样做.
Okay, so I can think of a lot of solutions, but traditionally what we do here is replace let
with lazy var
. I think I see six places in your code where you need to do that.
lazy var backButton: UIButton = { // ... and so on
当你这样做时,一切都会开始正常工作.
And when you do, everything will start working just fine.
解决问题的原因是 lazy
推迟了该代码的运行,直到 视图控制器本身已初始化.那么 self
的意思就是它应该的意思.
The reason this fixes the problem is that lazy
postpones the running of that code until after the view controller itself has been initialized. So then self
means what it is supposed to mean.
(很抱歉没有 lazy let
,但我对此无能为力.你只需要说 lazy var
就可以了.)
(I'm sorry there is no lazy let
, but there's nothing I can do about that. You just have to say lazy var
and let it go at that.)
我还应该补充一点,iOS 14 中的新功能,您可以(如果您愿意)停止调用 addTarget(_:action:for:)
,这样您就不会陷入这种情况再次陷入陷阱.但修复,即向按钮添加 UIAction,仅适用于 iOS 14 及更高版本.
I should also add that, new in iOS 14, you can (if you wish) stop calling addTarget(_:action:for:)
, and that way you won't fall into this trap ever again. But the fix, which is to add a UIAction to the button, is only on iOS 14 and later.
这篇关于用于实例化 ViewController 的按钮在隐藏后不起作用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!