在常规UIViewController上的UITableViewCell中的上方滚动UITextField
我已经尝试了大部分*上的示例。我也用苹果的。我似乎对他们的问题是,他们没有考虑UITextField在UITableView中。我已经做了很多次,但没有这样做。我有一个自定义的UITableViewCell和UITextField。在常规UIViewController上的UITableViewCell中的上方滚动UITextField
在我的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,但我不能使用任何第三方。
我花了整整一天的时间来解决这个问题。我在这里发布了它,然后找到了一个博客链接和一个非常简单的解决方案。它看起来像这样:
-(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;
}
我得到它的工作,但我不得不删除IfEndEditing的If语句。另外,如果你需要像我一样有多个文本框,你还必须实现textFieldDidBeginEditing和textFieldDidEndEditing。只需复制并粘贴与ShouldBegin和ShouldEnd相同的代码即可。这将允许用户从textField跳转到textField,同时保持相同的功能。 如果你正在努力W/NSIndexPath,这里是一个方式,就是任意iOS版本不兼容:http://*.com/questions/9577392/uitextfield-subview-of-uitableviewcell-get-indexpath-of-cell/ 9577406#9577406 – user1107173 2013-07-09 22:53:50
不要使用superviews链。这不是可靠的设计。使用indexPaths和textField views标签的字典来查找哪个文本字段是下一个响应者,并使其成为firstResponder。 – 2015-07-15 13:00:25
如果您在文本字段调用'becomeFirstResponder'而不是点击它,则这不起作用。 – Babiker 2015-11-05 06:34:48
我试过@inturbidus张贴iOS8上的链接,但遗憾的是它并没有为我工作。经过一番挖掘之后,事实证明,苹果公司在他们的网站上确实有示例代码,以便像在UITableViewController中那样自然地工作。这是Objective-C版本的Apple链接,我也在这里添加了快速版本。从苹果
Objective-C的链接(滚动到列表5-1):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
}
我没有添加链接,@Hector做到了。 – 2015-08-09 14:43:11
我知道这是一个旧的答案,但我想补充任何遇到此问题的人:我的tableview没有覆盖整个视图到底部,我不得不稍微纠正kbSize.height,因为只有部分UITableView由键盘覆盖。如果我使用这个解决方案,这个行滚动出UITableView并且不可见。所以这行'contentInsets = UIEdgeInsets(顶部:0,左:0,下:kbSize.height,右:0)'在'keyboardWasShow'变为'UIEdgeInsets(顶部:0,左:0,下:kbSize.height -margin,right:0)'。 – 2017-05-09 19:40:35
斯威夫特适应。
只需注意Apple视图在正常视图中用于滚动视图。
在表中查看你必须点和activeField的矩形转换为表的坐标,所以我改变功能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高度contentInsets代替UIEdgeInsetsZero (如果没有,你最后的底部行可能的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
}
}
滚动的UITextField键盘上方的一个UITableViewCell定期迅速的UIViewController 3和Xcode的8.1
1)设置代表= 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
}
我制成的混合物与马特的答案,并也塞勒曼。 这适用于tableView中的许多文本字段。Swift 3
基本上是得到了BOTTOM 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)
然后设置文本字段触摸作为电流输入
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中工作
希望这有助于!
我认为这将是有益的给你解释得在你的代码是如何工作的一点点,它正在做什么是不需要改变keyboardWillBeHidden。 – GrumpyCrouton 2017-06-09 17:40:48
@GrumpyCrouton感谢您的建议。我在代码上添加了一些评论,并对我的工作做了一些解释。 =] – Victor 2017-06-09 18:20:16
非常感谢!你赢了upvote :) – GrumpyCrouton 2017-06-09 18:21:52
这个答案是Xamarin iOS用户,但有人可以很容易地修改它,使其与雨燕或目的C.
的解决方案是非常简单的,并已在我的情况,我需要一个细胞的工作完美工作出现在屏幕的上半部分,以便单元格的文本字段位于键盘上方。因此,我所做的是以下几点:
我实现textField.ShouldBeginEditing方式如下:
myTextField.ShouldBeginEditing = textField =>
{
myTableView.ScrollToRow(indexPath, UITableViewScrollPosition.Top, true);
return true;
};
其中:
myTextField将是小区的文本字段,
myTableView是表格视图,
indexPath是表格视图内单元的索引路径。
正如我前面提到的,这个解决方案在我的情况下是完美的,所以我想我可以与你们分享它,以防它对你有用。快乐编码:)
didnt工作,文本框仍然键盘 – kemdo 2017-11-10 08:41:30
我的解决方案(上的Xcode 8.3.3,斯威夫特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
}
}
隐藏我想你想UIKeyboardFrameEndUserInfoKey在DidShow。开始是动画开始处的框架 – Aneel 2017-11-27 14:30:04
当你叫'[自scrollToRectOfTextField]'? – 2013-02-23 03:00:54
此外,如果您为tableview的底部边缘设置动画而不是尝试更改框架,您将获得更平滑的动画。 – 2013-02-23 03:01:35
这是一个很好的问题。它并没有被用在我从中拉出来的例子中。 – 2013-02-23 03:08:30