在使用自定义单元格的UITableView内的UITextView中打开键盘时避免查看
我有一个UIViewController
包含一个UITableView
与自定义单元格,里面的单元格是UILabels
,一对不可编辑的UITextView
和一个可编辑的UITextView
。 现在,当我点击靠近桌子底部或底部的一个UITextView
, UITextView
被键盘覆盖。 我已经尝试http://cocoawithlove.com/2008/10/sliding-uitextfields-around-to-avoid.html这对textfield / textview非常好,但不能在自定义单元格的表上工作。 任何帮助或build议如何去做到这一点?
I fixed the issue. Please see my solution below: 1. First declare a global varibale called "activeFileld" @property(nonatomic,strong)id activeFiled; 2. Create a method called "registerForKeyboardNotifications" - (void)registerForKeyboardNotifications { [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillShow:) name:UIKeyboardWillShowNotification object:nil]; //Posted immediately prior to the display of the keyboard [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillHide:) name:UIKeyboardWillHideNotification object:nil]; //Posted immediately prior to the dismissal of the keyboard. } 3. Called the above method in viewWillAppear: -(void)viewWillAppear:(BOOL)animated{ [super viewWillAppear:animated]; //Register kryboard Notification [self registerForKeyboardNotifications]; } 4. Call the Delegate method for UitextFieldd Or UitextView - (void)textFieldDidBeginEditing:(UITextField *)sender { self.activeField = sender; } - (void)textFieldDidEndEditing:(UITextField *)sender{ self.activeField = nil; } - (void)textViewDidBeginEditing:(UITextView *)textView { // save the text view that is being edited _notes = textView.text; } - (void)textViewDidEndEditing:(UITextView *)textView { // release the selected text view as we don't need it anymore _activeField = nil; } 5. - (void)keyboardWillShow:(NSNotification *)notification { if([_activeField isKindOfClass:[UITextField class]]) { NSDictionary* info = [notification userInfo]; NSLog(@"Dictionary %@",info); CGRect kbRect = [[info objectForKey:UIKeyboardFrameBeginUserInfoKey] CGRectValue]; kbRect = [self.view convertRect:kbRect fromView:nil]; UIEdgeInsets contentInsets = UIEdgeInsetsMake(0.0, 0.0, kbRect.size.height, 0.0); self.tableView.contentInset = contentInsets; self.tableView.scrollIndicatorInsets = contentInsets; CGRect aRect = self.view.frame; aRect.size.height -= kbRect.size.height; UITextField *textField = (UITextField*)_activeField; if (!CGRectContainsPoint(aRect, textField.frame.origin) ) { [self.tableView scrollRectToVisible:textField.frame animated:YES]; } }else if([_activeField isKindOfClass:[UITextView class]]) { NSDictionary* info = [notification userInfo]; NSLog(@"Dictionary %@",info); CGRect kbRect = [[info objectForKey:UIKeyboardFrameBeginUserInfoKey] CGRectValue]; kbRect = [self.view convertRect:kbRect fromView:nil]; UIEdgeInsets contentInsets = UIEdgeInsetsMake(0.0, 0.0, kbRect.size.height, 0.0); self.tableView.contentInset = contentInsets; self.tableView.scrollIndicatorInsets = contentInsets; CGRect aRect = self.view.frame; aRect.size.height += kbRect.size.height; UITextView *activeTextView = (UITextView*)_activeField; if (!CGRectContainsPoint(aRect, textField.superview.superview.frame.origin) ) { [self.tableView scrollRectToVisible:activeTextView.superview.superview.frame animated:YES]; } } } // Called when the UIKeyboardWillHideNotification is received - (void)keyboardWillHide:(NSNotification *)aNotification { UIEdgeInsets contentInsets = UIEdgeInsetsZero; self.tableView.contentInset = contentInsets; self.tableView.scrollIndicatorInsets = contentInsets; }
两种解决scheme
首选 :使用UITableViewController而不是UIViewController,因为那样会自动确保您的键盘不会隐藏可编辑字段。
Hacky : 当键盘出现时,如何使UITextField向上移动?
简单的解决scheme。 实现heightForFooter
方法,并让它返回一个(比如说)100的值,当你在UITableView
select一个单元格时,它们只会向上滑动那个高度,而键盘将不会覆盖这个视图。
我一直使用这个两折的解决scheme。
- 调整表格的大小,使其适合较小的区域。
- 滚动到我们想要显示的单元格。 (我们需要为此重新调整表格大小,否则您仍然无法到达表格中最后一对单元格。)
要做到这一点,我注册键盘显示/隐藏事件,并在被调用时相应地采取行动。
- (void)keyboardWillShow:(NSNotification *)note { [self updateForKeyboardShowHide:note appearing:YES]; } - (void)keyboardWillHide:(NSNotification *)note { [self updateForKeyboardShowHide:note appearing:NO]; } - (void)updateForKeyboardShowHide:(NSNotification *)note appearing:(BOOL)isAppearing { // ignore notifications if our view isn't attached to the window if (self.view.window == nil) return; CGFloat directionalModifier = isAppearing?-1:1; CGRect keyboardBounds = [[note.userInfo valueForKey:UIKeyboardFrameBeginUserInfoKey] CGRectValue]; CGFloat animationDuration = [[note.userInfo valueForKey:UIKeyboardAnimationDurationUserInfoKey] floatValue]; // figure out table re-size based on keyboard CGFloat keyboardHeight; UIInterfaceOrientation orientation = [[UIApplication sharedApplication] statusBarOrientation]; if (UIInterfaceOrientationIsPortrait(orientation)) keyboardHeight = keyboardBounds.size.height; else keyboardHeight = keyboardBounds.size.width; [UIView animateWithDuration:animationDuration animations:^{ // resize table CGRect newFrame = table.frame; newFrame.size.height += [self calculateKeyboardOffsetWithHeight:keyboardHeight] * directionalModifier; table.frame = newFrame; } completion:^(BOOL finished){ // scroll to selected cell if (isAppearing) { NSIndexPath *indexPath = [NSIndexPath indexPathForRow:textFieldInEdit.tag inSection:0]; [table scrollToRowAtIndexPath:indexPath atScrollPosition:UITableViewScrollPositionBottom animated:YES]; } }]; } - (CGFloat)calulateKeyboardOffsetWithHeight:(CGFloat)keyboardHeight { // This depends on the size and position of your table. // If your table happen to go all the way to the bottom of // the screen, you'll needs to adjust it's size by the whole keyboard height. // You might as well ditch this method and inline the value. return keyboardHeight; // My table did not go to the bottom of the screen and the position was // change dynamically so and there was long boring calculation I needed to // do to figure out how much my table needed to shrink/grow. }
如果表视图包含像UITextField
或UITextView
这样的数据input字段,并且表视图足够长以覆盖屏幕,则在访问由键盘隐藏的数据input字段时会遇到问题。
为了克服这个问题,有两个解决scheme
-
最简单和推荐的方法是使用
UITableViewController
而不是UIViewController
,它自动确保键盘不会隐藏可编辑的字段( 如果可能的话,使用这种方法来避免UI调整的不便 ) -
如果您使用
UIViewController
和UITableView
作为其子视图。 您可以通过观察UIKeyboardWillShowNotification
和UIKeyboardWillHideNotification
来滚动UI框架- (void)registerForKeyboardNotifications { [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillShow:) name:UIKeyboardWillShowNotification object:nil]; //Posted immediately prior to the display of the keyboard [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillHide:) name:UIKeyboardWillHideNotification object:nil]; //Posted immediately prior to the dismissal of the keyboard. } - (void)keyboardWillShow:(NSNotification *)aNotification { CGRect keyboardBounds = [[[aNotification userInfo] objectForKey:UIKeyboardFrameBeginUserInfoKey] CGRectValue]; [UIView beginAnimations:nil context:nil]; [UIView setAnimationBeginsFromCurrentState:YES]; self.tableView.contentInset = UIEdgeInsetsMake(0, 0, keyboardBounds.size.height, 0); //when keyboard is up, that time just bring your text filed above the keyboard self.tableView.scrollIndicatorInsets = UIEdgeInsetsMake(0, 0, keyboardBounds.size.height, 0); [self.tableView scrollToRowAtIndexPath:[self findIndexPathToScroll] atScrollPosition:UITableViewScrollPositionTop animated:YES]; //findIndexPathToScroll implementation not shown [UIView commitAnimations]; } - (void)keyboardWillHide:(NSNotification *)aNotification { [UIView beginAnimations:nil context:nil]; [UIView setAnimationBeginsFromCurrentState:YES]; self.tableView.contentInset = UIEdgeInsetsZero; //Once keyboard is hidden then bring back your table into your original position. self.tableView.scrollIndicatorInsets = UIEdgeInsetsZero; [UIView commitAnimations]; }
-
registerForKeyboardNotifications
– 在加载UITableView时调用这个方法,例如:viewDidLoad -
findIndexPathToScroll
– (实现未显示)它是您的业务逻辑准备索引path应该滚动表视图 -
dealloc
和viewDidUnload
的removeObserver'UIKeyboardWillShowNotification'和'UIKeyboardWillHideNotification'
-