简体   繁体   中英

Moving view when keyboard shows for secureTextEntry

I'm trying to move my self.view up, when the keyboard appears.

I used the normal:

NSNotificationCenter.defaultCenter().addObserver(self, selector: Selector("keyboardWillShow:"), name:UIKeyboardWillShowNotification, object: nil)
NSNotificationCenter.defaultCenter().addObserver(self, selector: Selector("keyboardWillHide:"), name:UIKeyboardWillHideNotification, object: nil)

in my viewDidLoad() , like I usually do. With these 2 functions.

func keyboardWillShow(sender: NSNotification) {
    self.view.frame.origin.y -= 160
}
func keyboardWillHide(sender: NSNotification) {
    self.view.frame.origin.y += 160
}

However this particular view. has different keyboard types for it's UITextFields .

Specifically, these textfields are:

firstName - normal keyboard
lastName - normal keyboard
email - email keyboard
password - secureTextEntry

My usual functions seems to work fine for all of them except the password. Unfortunately, when I click "next/return" on my email UITextField . It moves my view up another 160 points.

it obviously thinks I'm adding another keyboard, without removing one.

My first thought was to simply, change the value when that specific UITextField is called. But the view acts as it's supposed to when I just click the password UITextField .

It only messes up when I'm currently in one of the other views, then clicking next, or tapping the password UITextFIeld , so I can't just specify how much the view moves, in textFieldShouldReturn either.

How do I move the view up properly, taking the secureTextEntry problem into account?

As suggested by Joko Sarmiento I tried this as well:

var originalFrame: CGRect!

override func viewDidLoad() {
    originalFrame = self.view.frame
}

func textFieldShouldReturn(textField: UITextField) -> Bool {
    self.view.frame = originalFrame
    return false
}

I also added self.view.frame = originalFrame to my touchesBegan event, since as mentioned before, it's not only on return.

But the above attempt didn't work, here's a screenshot of the password field after having clicked next from the email field. And it stays that way after dismissing the textfield as well.

在此处输入图片说明

I also tried moving it up with self.view.frame = originalframe.origin.y+160 instead. But still causes a problem with the password field.

The reason it messes up is due to my errorView, which changes height. Making it so the originalFrame is now incorrect.

Any help would be greatly appreciated!

I experienced this a while back. It seems your keyboardWillHide: method isn't being called when the password field is made first responder.

You could reset your view's origin to its original value in textFieldShouldReturn: , not by adding 160px , but having an originalValue variable that you set in viewDidLoad .

You can do something like:

var originalFrame: CGRect!

override func viewDidLoad() {
    originalFrame = self.view.frame
}

func textFieldShouldReturn(textField: UITextField) -> Bool {
    self.view.frame = originalFrame

    return false
}

Edit 1:

I just noticed that the above code will only work if you tap the return button. You should reset the view's frame whenever a text field resigns the first responder.


Edit 2:

This problem should be easily solved if you used a UIScrollView in your content view. Embed your form elements in UIScrollView and whenever the app fires keyboardWillShow: or keyboardWillHide: , you adjust the contentInset property of the UIScrollView based on keyboard height (which you can get from the notification's userInfo ).

Anyway, since you solved the problem without having to use a UIScrollView , here's an explanation on why your approach didn't work and how you might have gotten it to work:

  1. First, You were trying to subtract/add a fixed height of 160px to the content view. You have to understand that the keyboard height differs on different devices. A good approach is to use the keyboard height that you get from NSNotification userInfo . This is easily retrieved via notification.userInfo in your keyboardWillShow: or keyboardWillHide: .

  2. You were not resetting self.view to its original frame. This can cause the frame's Y origin to be modified multiple times without being reset, causing the subtracted pixels to double, etc. Since you're using self.view.frame.origin.y -= 160 , if the UIKeyboardWillShowNotification notification didn't fire when you switch to your password field, the frame's origin will not reset, and subtract an additional 160px .

  3. UIKeyboardWillHideNotification may not have been firing all this time, whenever you switch your password text field. I still need to confirm this but it could be the reason why your keyboardWillHide: function isn't being called, thus subtracting an additional 160px instead of adding 160px then subtracting 160px .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM