ss1271's Site

风餐露宿,不可一日无码.

比較靠譜的解決iPhone中鍵盤遮蓋文本框的問題One Possible Solution of iPhone Keyboard Covers the TextField When Editing

| Comments

最近在學着編寫iPhone程序,遇到一個應該是所有iPhone開發者都曾遇到過的問題:iPhone鍵盤有時候會蓋住文本輸入框(UITextField)。這個小問題在以往我編寫Android程序的時候不曾遇到過,想必是Android本身已經是自動Handle這件事了?不過好在Apple官方文檔提供了解決方案,應該可以解決一些很初步的問題:你會發現屏幕會有滾動,但是滾動並不完美。StackOverflow上有人提出類似的問題,說他的屏幕滾動過頭。 我一開始做的時候,也遇到這個問題,而且很是頭痛,一來這是我第一個像樣的程序;二來對於iPhone編程確實不是很瞭解,總之參考了無數人的例子,結果從發現幾乎都不能用到可以滾動但是仍然遮蓋鍵盤,再到終於可以完美滾動但是不會遮蓋鍵盤。這中間雖然讓我很有解決難題的成就感和滿足感,但是也確實太浪費時間了。所以我記錄一下這個,希望大家可以少走彎路。 首先應該確保你的UIScrollView有過IBOutlet連接。然後你可以參考一下我上面提到的官網的Doc,看一看背景是否隨着鍵盤彈出而滾動,如果有滾動,但是不出所料的仍然遮蓋或者部分遮蓋Text Field,那麼請參考一下我下面的修改算法: 和Apple的不同之處在於第31行,我認爲Apple提供的滾動數值計算有重大缺陷,所以專門修改了一下。 圖解在這裏(點擊可查看大圖): Recently I’m learning iPhone programming and I encountered a problem that I bet every iOS programming beginner have met before: iPhone on screen keyboard will cover the text field. This little piece of cake is not even a question on Android, but hey, this is iOS, we should have different perspective, got it? Fortunately, Apple has already provided some documents about “Keyboard Management”, which will resolve the issue of scrolling the view when keyboard pops up. But wait, it is not perfect if you copy/paste the code from the webpage. Some one from Stack Overflow said that the code will result in “over scroll” on his project. I have met this kind of issue since I began my project and spent a hell of hours on this. I think this is because I am first to iOS and not very familiar with this “Advanced Platform”. In all, I viewed a mass of questions and how-tos as well as tutorials but none of these articles could lend me a hand. And eventually, I managed to get it worked by myself. It’s better to share my solution than just keep it. First, please ensure you have did an IBOutlet between your UIScrollView and your view, then you can take a close look at the Apple document I’ve mentioned above, see if you could let the textfield scroll when the keyboard pops. If you can, but the keyboard still covers or partially covers the textfield, time to refer to my “enhanced algorithm”: The difference between Apple Doc and mine is from Line 31, where I believe Apple Doc provides a defect method of scrolling. The mockup draft is here (Click to see the enlarged image): 代碼在這裏: [obj-c]// Call this method somewhere in the view controller setup code. - (void)registerForKeyboardNotifications { [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWasShown:) name:UIKeyboardDidShowNotification object:nil]; [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillBeHidden:) name:UIKeyboardWillHideNotification object:nil]; } // Call this to unregister the notifications - (void)unregisterForKeyboardNotifications { [[NSNotificationCenter defaultCenter] removeObserver:self]; } // Called when the UIKeyboardDidShowNotification is sent. - (void)keyboardWasShown:(NSNotification*)aNotification { NSDictionary* info = [aNotification userInfo]; CGSize kbSize = [[info objectForKey:UIKeyboardFrameBeginUserInfoKey] CGRectValue].size; UIEdgeInsets contentInsets = UIEdgeInsetsMake(0.0, 0.0, kbSize.height, 0.0); scrollView.contentInset = contentInsets; scrollView.scrollIndicatorInsets = contentInsets; // If active text field is hidden by keyboard, scroll it so it’s visible // Your application might not need or want this behavior. CGRect aRect = self.view.frame; aRect.size.height -= kbSize.height; if (aRect.size.height < activeField.frame.origin.y+activeField.frame.size.height) { CGPoint scrollPoint = CGPointMake(0.0, activeField.frame.origin.y+activeField.frame.size.height-aRect.size.height); [scrollView setContentOffset:scrollPoint animated:YES]; } } // Called when the UIKeyboardWillHideNotification is sent - (void)keyboardWillBeHidden:(NSNotification*)aNotification { UIEdgeInsets contentInsets = UIEdgeInsetsZero; scrollView.contentInset = contentInsets; scrollView.scrollIndicatorInsets = contentInsets; } [/obj-c] 希望對各位有幫助。 And this is the code: [obj-c]// Call this method somewhere in the view controller setup code. - (void)registerForKeyboardNotifications { [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWasShown:) name:UIKeyboardDidShowNotification object:nil]; [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillBeHidden:) name:UIKeyboardWillHideNotification object:nil]; } // Call this to unregister the notifications - (void)unregisterForKeyboardNotifications { [[NSNotificationCenter defaultCenter] removeObserver:self]; } // Called when the UIKeyboardDidShowNotification is sent. - (void)keyboardWasShown:(NSNotification*)aNotification { NSDictionary* info = [aNotification userInfo]; CGSize kbSize = [[info objectForKey:UIKeyboardFrameBeginUserInfoKey] CGRectValue].size; UIEdgeInsets contentInsets = UIEdgeInsetsMake(0.0, 0.0, kbSize.height, 0.0); scrollView.contentInset = contentInsets; scrollView.scrollIndicatorInsets = contentInsets; // If active text field is hidden by keyboard, scroll it so it’s visible // Your application might not need or want this behavior. CGRect aRect = self.view.frame; aRect.size.height -= kbSize.height; if (aRect.size.height < activeField.frame.origin.y+activeField.frame.size.height) { CGPoint scrollPoint = CGPointMake(0.0, activeField.frame.origin.y+activeField.frame.size.height-aRect.size.height); [scrollView setContentOffset:scrollPoint animated:YES]; } } // Called when the UIKeyboardWillHideNotification is sent - (void)keyboardWillBeHidden:(NSNotification*)aNotification { UIEdgeInsets contentInsets = UIEdgeInsetsZero; scrollView.contentInset = contentInsets; scrollView.scrollIndicatorInsets = contentInsets; } [/obj-c] Hopes it could do some help on your programming.

Comments