在常规UIViewController上的UITableViewCell中的上方键盘上滚动UITextField

我已经尝试了StackOverflow上的大部分示例。 我也用苹果的。 我似乎与他们的问题是,他们不占UITextField在UITableView。 我已经做了很多次了,但没有这样做。 我有一个UITextField在它自定义的UITableViewCell。

在我的UITableView(这不是一个UITableViewController),我需要能够避免隐藏在UITableView下的UITextField。

我现在有这个:

-(void)viewDidLoad { .... [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillShow:) name:UIKeyboardWillShowNotification object:nil]; [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillHide:) name:UIKeyboardWillHideNotification object:nil]; .... } - (void)scrollToRectOfTextField { UITableViewCell *cell = (UITableViewCell*)[self.activeTextField superview]; CGRect r = CGRectMake(self.activeTextField.frame.origin.x, cell.frame.origin.y+self.activeTextField.frame.origin.y, self.activeTextField.frame.size.width, self.activeTextField.frame.size.height); [self.tableView scrollRectToVisible:r animated:YES]; } - (void)keyboardDidShow:(NSNotification *)notification { if (UI_USER_INTERFACE_IDIOM()== UIUserInterfaceIdiomPhone) { NSDictionary *userInfo = [notification userInfo]; CGSize size = [[userInfo objectForKey:UIKeyboardFrameEndUserInfoKey] CGRectValue].size; NSLog(@"TableView: %@", NSStringFromCGRect(self.tableView.frame)); CGRect newTableViewFrame = CGRectMake(self.tableView.frame.origin.x, self.tableView.frame.origin.y, self.tableView.frame.size.width, self.tableView.frame.size.height - size.height); self.tableView.frame = newTableViewFrame; NSLog(@"New TableView: %@", NSStringFromCGRect(self.tableView.frame)); self.tableView.contentSize = CGSizeMake(self.tableView.contentSize.width, self.tableView.contentSize.height-size.height); } } - (void)keyboardWillHide:(NSNotification *)notification { NSDictionary *userInfo = [notification userInfo]; CGSize size = [[userInfo objectForKey: UIKeyboardFrameEndUserInfoKey] CGRectValue].size; self.tableView.frame = CGRectMake(self.tableView.frame.origin.x, self.tableView.frame.origin.y, self.tableView.frame.size.width, self.tableView.frame.size.height + size.height); NSLog(@"%@", NSStringFromCGRect(self.tableView.frame)); } -(void)textFieldDidBeginEditing { [self scrollToRectOfTextField]; } 

这似乎推动了一堆白色空间通过我的键盘。 还请注意,我也在我的UITextField上有一个inputAccessoryView。

哦,我不能使用任何第三方类。 我爱TPKeyboardAvoidingScrollView,但我不能使用任何第三方。

我花了整整一天的时间来解决这个问题。 我把它发布在这里,然后find一个博客链接和一个非常简单的解决scheme。 它看起来像这样:

 -(BOOL)textFieldShouldBeginEditing:(UITextField *)textField { CGPoint pointInTable = [textField.superview convertPoint:textField.frame.origin toView:self.tableView]; CGPoint contentOffset = self.tableView.contentOffset; contentOffset.y = (pointInTable.y - textField.inputAccessoryView.frame.size.height); NSLog(@"contentOffset is: %@", NSStringFromCGPoint(contentOffset)); [self.tableView setContentOffset:contentOffset animated:YES]; return YES; } -(BOOL)textFieldShouldEndEditing:(UITextField *)textField { [textField resignFirstResponder]; if ([textField.superview.superview isKindOfClass:[UITableViewCell class]]) { UITableViewCell *cell = (UITableViewCell*)textField.superview.superview; NSIndexPath *indexPath = [self.tableView indexPathForCell:cell]; [self.tableView scrollToRowAtIndexPath:indexPath atScrollPosition:UITableViewScrollPositionMiddle animated:TRUE]; } return YES; } 

检查这个iOS 8

我尝试了@inturbidus针对iOS8发布的链接,但不幸的是,它并没有为我工作。 经过一番挖掘,事实certificate,苹果确实有自己的网站上的示例代码,使其工作自然就像他们在UITableViewController。 这里是Objective-C版本的Apple链接,我也在这里添加swift版本。

从Apple的Objective-C链接(滚动到列表5-1): https //developer.apple.com/library/ios/documentation/StringsTextFonts/Conceptual/TextAndWebiPhoneOS/KeyboardManagement/KeyboardManagement.html

迅速适应Objective-C版本

 var activeField: UITextField? func textFieldDidBeginEditing(textField: UITextField) { self.activeField = textField } func textFieldDidEndEditing(textField: UITextField) { self.activeField = nil } func registerForKeyboardNotifications() { NSNotificationCenter.defaultCenter().addObserver(self, selector: "keyboardWasShown:", name: UIKeyboardDidShowNotification, object: nil) NSNotificationCenter.defaultCenter().addObserver(self, selector: "keyboardWillBeHidden:", name: UIKeyboardWillHideNotification, object: nil) } func keyboardWasShown(aNotification: NSNotification) { let info = aNotification.userInfo as! [String: AnyObject], kbSize = (info[UIKeyboardFrameBeginUserInfoKey] as! NSValue).CGRectValue().size, contentInsets = UIEdgeInsets(top: 0, left: 0, bottom: kbSize.height, right: 0) self.tableView.contentInset = contentInsets self.tableView.scrollIndicatorInsets = contentInsets // If active text field is hidden by keyboard, scroll it so it's visible // Your app might not need or want this behavior. var aRect = self.view.frame aRect.size.height -= kbSize.height if !CGRectContainsPoint(aRect, activeField!.frame.origin) { self.tableView.scrollRectToVisible(activeField!.frame, animated: true) } } func keyboardWillBeHidden(aNotification: NSNotification) { let contentInsets = UIEdgeInsetsZero self.tableView.contentInset = contentInsets self.tableView.scrollIndicatorInsets = contentInsets } 

感谢@Salman的链接。
只要注意,苹果的例子是正常的看法用于滚动视图。
在表格视图中,你必须将activeField的Point和Rect转换为表的坐标,所以我改变了函数keyboardWasShown中的一些行:

 func keyboardWasShown(aNotification: NSNotification) { let info = aNotification.userInfo as! [String: AnyObject], kbSize = (info[UIKeyboardFrameBeginUserInfoKey] as! NSValue).CGRectValue().size, contentInsets = UIEdgeInsets(top: 0, left: 0, bottom: kbSize.height, right: 0) self.tableBasket.contentInset = contentInsets self.tableBasket.scrollIndicatorInsets = contentInsets var aRect = self.view.frame aRect.size.height -= kbSize.height let pointInTable = activeField!.superview!.convertPoint(activeField!.frame.origin, toView: tableView) let rectInTable = activeField!.superview!.convertRect(activeField!.frame, toView: tableView) if !CGRectContainsPoint(aRect, pointInTable) { self.tableView.scrollRectToVisible(rectInTable, animated: true) } } 

如果你的视图有tabBarController,记得用tabBar高度而不是UIEdgeInsetsZero重置contentInsets(如果不是,你最后的最后一行可能是隐藏在tabBar下):

 func keyboardWillBeHidden(aNotification: NSNotification) { //UIEdgeInsetsZero is used in view without tabBar //let contentInsets = UIEdgeInsetsZero let tabBarHeight = self.tabBarController!.tabBar.frame.height let contentInsets = UIEdgeInsets(top: 0, left: 0, bottom: tabBarHeight, right: 0) self.tableView.contentInset = contentInsets self.tableView.scrollIndicatorInsets = contentInsets } } 

我与马特萨尔曼的答案混合在一起。 这适用于tableView中的许多文本字段。 Swift 3

基本上是得到文字Input的底部Y点触摸。 一旦我们有,我检查如果键盘覆盖textInput,如果这样做,我会改变tableView的contentOffset

首先注册通知。 在init中,如果是UIView,或者在viewDidLoad中,如果是UIViewController:

  NotificationCenter.default.addObserver(self, selector: #selector(keyboardWillShow), name: NSNotification.Name.UIKeyboardWillShow, object: nil) NotificationCenter.default.addObserver(self, selector: #selector(keyboardWillHide), name: NSNotification.Name.UIKeyboardWillHide, object: nil) 

然后将触摸的文本框设置为当前input

 var inputActive: UITextField! func textViewShouldBeginEditing(_ textView: UITextView) -> Bool { inputActive = textInput return true } 

最后实现通知方法:

 func keyboardWillShow(notification: NSNotification) { var userInfo = notification.userInfo! if let keyboardFrame = (userInfo[UIKeyboardFrameEndUserInfoKey] as? NSValue)?.cgRectValue { // Get my height size let myheight = tableView.frame.height // Get the top Y point where the keyboard will finish on the view let keyboardEndPoint = myheight - keyboardFrame.height // Get the the bottom Y point of the textInput and transform it to the currentView coordinates. if let pointInTable = inputActive.superview?.convert(inputActive.frame.origin, to: tableView) { let textFieldBottomPoint = pointInTable.y + inputActive.frame.size.height + 20 // Finally check if the keyboard will cover the textInput if keyboardEndPoint <= textFieldBottomPoint { tableView.contentOffset.y = textFieldBottomPoint - keyboardEndPoint } else { tableView.contentOffset.y = 0 } } } } func keyboardWillHide(notification: NSNotification) { tableView.contentOffset.y = 0 } 

几件事要补充。 填充是一些额外的距离,我在我的情况下添加了20分。 另外在我的情况下,UITableView被添加到UIViewController,但是这也应该在UITableViewController

希望这可以帮助!

在普通的UIViewController上的UITableViewCell上滚动上面的UITextField swift 3和Xcode 8.1

1)设置Delegate = UITextFieldDelegate

  override func viewWillAppear(_ animated: Bool) { NotificationCenter.default.addObserver(self, selector: #selector(DayViewController.keyboardWillShow), name:NSNotification.Name.UIKeyboardWillShow, object: nil); NotificationCenter.default.addObserver(self, selector: #selector(DayViewController.keyboardWillHide), name:NSNotification.Name.UIKeyboardWillHide, object: nil); } func textFieldDidBeginEditing(_ textField: UITextField) { self.activeField = textField } func textFieldDidEndEditing(_ textField: UITextField) { self.activeField = nil } //MARK: - Keyboard Show and Hide Methods func keyboardWillShow(notification: NSNotification) { let info = notification.userInfo! as! [String: AnyObject], kbSize = (info[UIKeyboardFrameBeginUserInfoKey] as! NSValue).cgRectValue.size, contentInsets = UIEdgeInsets(top: 0, left: 0, bottom: kbSize.height, right: 0) self.FourthTblMainTableView.contentInset = contentInsets self.FourthTblMainTableView.scrollIndicatorInsets = contentInsets var aRect = self.FourthTblMainTableView.frame aRect.size.height -= kbSize.height } func keyboardWillHide(notification: NSNotification) { let contentInsets = UIEdgeInsets.zero self.FourthTblMainTableView.contentInset = contentInsets self.FourthTblMainTableView.scrollIndicatorInsets = contentInsets } 

这个答案适用于Xamarin的iOS用户,但是有人可以很容易地修改它,使其与Swift或Objective C一起工作。

这个解决scheme非常简单,并且在我需要单元格出现在屏幕的上半部分以使单元格的文本字段位于键盘上方的情况下完美工作。 所以我做了以下几点:

我实现了textField.ShouldBegin,编辑方式如下:

 myTextField.ShouldBeginEditing = textField => { myTableView.ScrollToRow(indexPath, UITableViewScrollPosition.Top, true); return true; }; 

哪里:

myTextField是单元格的文本字段,

myTableView是表视图,

indexPath是表格视图内单元格的索引path。

正如我前面提到的,这个解决scheme在我的情况下完美的工作,所以我想我可以与你们分享,以防万一它适合你。 快乐编码:)

我的解决scheme(工作在Xcode 8.3.3,Swift 3,iOS 10.3.1):

 class MyTableViewController: UITableViewController { override func viewWillAppear(_ animated: Bool) { NotificationCenter.default.addObserver(self, selector: #selector(actionKeyboardDidShow(with:)), name: .UIKeyboardDidShow, object: nil) NotificationCenter.default.addObserver(self, selector: #selector(actionKeyboardWillHide(with:)), name: .UIKeyboardWillHide, object: nil) } override func viewDidDisappear(_ animated: Bool) { NotificationCenter.default.removeObserver(self, name: .UIKeyboardDidShow, object: nil) NotificationCenter.default.removeObserver(self, name: .UIKeyboardWillHide, object: nil) } @objc private func actionKeyboardDidShow(with notification: Notification) { guard let userInfo = notification.userInfo as? [String: AnyObject], let keyboardFrame = (userInfo[UIKeyboardFrameBeginUserInfoKey] as? NSValue)?.cgRectValue else { return } var contentInset = self.tableView.contentInset contentInset.bottom += keyboardFrame.height self.tableView.contentInset = contentInset self.tableView.scrollIndicatorInsets = contentInset } @objc private func actionKeyboardWillHide(with notification: Notification) { guard let userInfo = notification.userInfo as? [String: AnyObject], let keyboardFrame = (userInfo[UIKeyboardFrameBeginUserInfoKey] as? NSValue)?.cgRectValue else { return } var contentInset = self.tableView.contentInset contentInset.bottom -= keyboardFrame.height self.tableView.contentInset = contentInset self.tableView.scrollIndicatorInsets = contentInset } }