问题
I have this very weird problem that I just found out...
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)
}
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
}
}
Now the Problem:
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.
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. 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. The button
in the forgotpasswordViewController
(only one button there) is not doing anything.
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!
Demo-Project:
Demo-Project
回答1:
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
}()
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.)
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.
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.
(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.)
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.
来源:https://stackoverflow.com/questions/63892806/button-to-instanciate-viewcontroller-is-not-working-after-hiding-it