经过大量的反复试验,我放弃并提出问题.我见过很多人有类似的问题,但无法得到所有正确的答案.
我有一个UITableView
由自定义单元格组成的.单元格由5个文本字段组成,彼此相邻(有点像网格).
当我尝试滚动并编辑底部的单元格时UITableView
,我无法将单元格正确放置在键盘上方.
我已经看到很多关于改变视图大小的答案......但到目前为止它们都没有很好地工作.
任何人都可以用具体的代码示例澄清"正确"的方法吗?
如果您使用UITableViewController而不是UIViewController,它将自动执行此操作.
滚动的功能可以更简单:
- (void) textFieldDidBeginEditing:(UITextField *)textField { UITableViewCell *cell; if (floor(NSFoundationVersionNumber) <= NSFoundationVersionNumber_iOS_6_1) { // Load resources for iOS 6.1 or earlier cell = (UITableViewCell *) textField.superview.superview; } else { // Load resources for iOS 7 or later cell = (UITableViewCell *) textField.superview.superview.superview; // TextField -> UITableVieCellContentView -> (in iOS 7!)ScrollView -> Cell! } [tView scrollToRowAtIndexPath:[tView indexPathForCell:cell] atScrollPosition:UITableViewScrollPositionTop animated:YES]; }
而已.根本没有计算.
我正在做一些非常类似的通用,不需要为你的代码计算特定的东西.只需查看代码上的备注:
在MyUIViewController.h中
@interface MyUIViewController: UIViewController{ UITableView *myTableView; UITextField *actifText; } @property (nonatomic, retain) IBOutlet UITableView *myTableView; @property (nonatomic, retain) IBOutlet UITextField *actifText; - (IBAction)textFieldDidBeginEditing:(UITextField *)textField; - (IBAction)textFieldDidEndEditing:(UITextField *)textField; -(void) keyboardWillHide:(NSNotification *)note; -(void) keyboardWillShow:(NSNotification *)note; @end
在MyUIViewController.m中
@implementation MyUIViewController @synthesize myTableView; @synthesize actifText; - (void)viewDidLoad { // Register notification when the keyboard will be show [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillShow:) name:UIKeyboardWillShowNotification object:nil]; // Register notification when the keyboard will be hide [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillHide:) name:UIKeyboardWillHideNotification object:nil]; } // To be link with your TextField event "Editing Did Begin" // memoryze the current TextField - (IBAction)textFieldDidBeginEditing:(UITextField *)textField { self.actifText = textField; } // To be link with your TextField event "Editing Did End" // release current TextField - (IBAction)textFieldDidEndEditing:(UITextField *)textField { self.actifText = nil; } -(void) keyboardWillShow:(NSNotification *)note { // Get the keyboard size CGRect keyboardBounds; [[note.userInfo valueForKey:UIKeyboardFrameBeginUserInfoKey] getValue: &keyboardBounds]; // Detect orientation UIInterfaceOrientation orientation = [[UIApplication sharedApplication] statusBarOrientation]; CGRect frame = self.myTableView.frame; // Start animation [UIView beginAnimations:nil context:NULL]; [UIView setAnimationBeginsFromCurrentState:YES]; [UIView setAnimationDuration:0.3f]; // Reduce size of the Table view if (orientation == UIInterfaceOrientationPortrait || orientation == UIInterfaceOrientationPortraitUpsideDown) frame.size.height -= keyboardBounds.size.height; else frame.size.height -= keyboardBounds.size.width; // Apply new size of table view self.myTableView.frame = frame; // Scroll the table view to see the TextField just above the keyboard if (self.actifText) { CGRect textFieldRect = [self.myTableView convertRect:self.actifText.bounds fromView:self.actifText]; [self.myTableView scrollRectToVisible:textFieldRect animated:NO]; } [UIView commitAnimations]; } -(void) keyboardWillHide:(NSNotification *)note { // Get the keyboard size CGRect keyboardBounds; [[note.userInfo valueForKey:UIKeyboardFrameBeginUserInfoKey] getValue: &keyboardBounds]; // Detect orientation UIInterfaceOrientation orientation = [[UIApplication sharedApplication] statusBarOrientation]; CGRect frame = self.myTableView.frame; [UIView beginAnimations:nil context:NULL]; [UIView setAnimationBeginsFromCurrentState:YES]; [UIView setAnimationDuration:0.3f]; // Increase size of the Table view if (orientation == UIInterfaceOrientationPortrait || orientation == UIInterfaceOrientationPortraitUpsideDown) frame.size.height += keyboardBounds.size.height; else frame.size.height += keyboardBounds.size.width; // Apply new size of table view self.myTableView.frame = frame; [UIView commitAnimations]; } @end
class ViewController: UIViewController, UITextFieldDelegate { @IBOutlet weak var activeText: UITextField! @IBOutlet weak var tableView: UITableView! override func viewDidLoad() { NSNotificationCenter.defaultCenter().addObserver(self, selector: Selector("keyboardWillShow:"), name: UIKeyboardWillShowNotification, object: nil) NSNotificationCenter.defaultCenter().addObserver(self, selector: Selector("keyboardWillHide:"), name: UIKeyboardWillHideNotification, object: nil) } func textFieldDidBeginEditing(textField: UITextField) { activeText = textField } func textFieldDidEndEditing(textField: UITextField) { activeText = nil } func keyboardWillShow(note: NSNotification) { if let keyboardSize = (note.userInfo?[UIKeyboardFrameBeginUserInfoKey] as? NSValue)?.CGRectValue() { var frame = tableView.frame UIView.beginAnimations(nil, context: nil) UIView.setAnimationBeginsFromCurrentState(true) UIView.setAnimationDuration(0.3) frame.size.height -= keyboardSize.height tableView.frame = frame if activeText != nil { let rect = tableView.convertRect(activeText.bounds, fromView: activeText) tableView.scrollRectToVisible(rect, animated: false) } UIView.commitAnimations() } } func keyboardWillHide(note: NSNotification) { if let keyboardSize = (note.userInfo?[UIKeyboardFrameBeginUserInfoKey] as? NSValue)?.CGRectValue() { var frame = tableView.frame UIView.beginAnimations(nil, context: nil) UIView.setAnimationBeginsFromCurrentState(true) UIView.setAnimationDuration(0.3) frame.size.height += keyboardSize.height tableView.frame = frame UIView.commitAnimations() } } }
我有同样的问题,但注意到它只出现在一个视图中.所以我开始寻找控制器的差异.
我发现滚动行为是在- (void)viewWillAppear:(BOOL)animated
超级实例中设置的.
所以一定要这样实现:
- (void)viewWillAppear:(BOOL)animated { [super viewWillAppear:animated]; // your code }
如果你使用UIViewController
或者无关紧要UITableViewController
; 通过将a UITableView
作为self.view的子视图进行检查UIViewController
.这是相同的行为.如果呼叫[super viewWillAppear:animated];
丢失,视图不允许滚动.
基于BartłomiejSemańczyk解决方案的Swift 3最简单的解决方案:
override func viewDidLoad() { super.viewDidLoad() NotificationCenter.default.addObserver(self, selector: #selector(CreateEditRitualViewController.keyboardWillShow(notification:)), name: NSNotification.Name.UIKeyboardDidShow, object: nil) NotificationCenter.default.addObserver(self, selector: #selector(CreateEditRitualViewController.keyboardWillHide(notification:)), name: NSNotification.Name.UIKeyboardDidHide, object: nil) } deinit { NotificationCenter.default.removeObserver(self) } // MARK: Keyboard Notifications @objc func keyboardWillShow(notification: NSNotification) { if let keyboardHeight = (notification.userInfo?[UIKeyboardFrameEndUserInfoKey] as? NSValue)?.cgRectValue.height { tableView.contentInset = UIEdgeInsetsMake(0, 0, keyboardHeight, 0) } } @objc func keyboardWillHide(notification: NSNotification) { UIView.animate(withDuration: 0.2, animations: { // For some reason adding inset in keyboardWillShow is animated by itself but removing is not, that's why we have to use animateWithDuration here self.tableView.contentInset = UIEdgeInsetsMake(0, 0, 0, 0) }) }
我可能错过了这个,因为我没有在这里阅读整篇文章,但我想出的似乎看似简单.我没有通过绞拧器,在所有情况下测试,但它似乎应该工作得很好.
只需通过键盘的高度调整tableview的contentInset,然后将单元格滚动到底部:
- (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); self.myTableView.contentInset = contentInsets; self.myTableView.scrollIndicatorInsets = contentInsets; [self.myTableView scrollToRowAtIndexPath:self.currentField.indexPath atScrollPosition:UITableViewScrollPositionBottom animated:YES]; }
而且当然
- (void)keyboardWasHidden:(NSNotification *)aNotification { [UIView animateWithDuration:.3 animations:^(void) { self.myTableView.contentInset = UIEdgeInsetsZero; self.myTableView.scrollIndicatorInsets = UIEdgeInsetsZero; }]; }
这太简单了吗?我错过了什么吗?到目前为止它对我来说很好,但正如我所说,我还没有通过绞尽脑汁......
我想我已经提出了与Apple应用程序行为相匹配的解决方案.
首先,在你的viewWillAppear中:订阅键盘通知,这样你就知道键盘何时显示和隐藏,系统会告诉你键盘的大小,但不要忘记在你的viewWillDisappear中取消注册:.
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillShow:) name:UIKeyboardWillShowNotification object:nil]; [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillHide:) name:UIKeyboardWillHideNotification object:nil];
实现类似于下面的方法,以便在键盘显示后调整tableView的大小以匹配可见区域.这里我分别跟踪键盘的状态,因此我可以选择何时将tableView设置回自己的全高,因为您在每次更改字段时都会收到这些通知.不要忘记实现keyboardWillHide:并选择适合的地方来修复tableView大小.
-(void) keyboardWillShow:(NSNotification *)note { CGRect keyboardBounds; [[note.userInfo valueForKey:UIKeyboardBoundsUserInfoKey] getValue: &keyboardBounds]; keyboardHeight = keyboardBounds.size.height; if (keyboardIsShowing == NO) { keyboardIsShowing = YES; CGRect frame = self.view.frame; frame.size.height -= keyboardHeight; [UIView beginAnimations:nil context:NULL]; [UIView setAnimationBeginsFromCurrentState:YES]; [UIView setAnimationDuration:0.3f]; self.view.frame = frame; [UIView commitAnimations]; } }
现在,这里的滚动位,我们制定出了几个规模第一,然后我们看到我们在可见区域,并设置我们要滚动到RECT要高于或文本字段的基于偏下半视它在视图中的位置.在这种情况下,我们有UITextFields数组和跟踪他们的枚举,所以由行号的rowHeight乘以为我们提供了实际的这种外视图中的帧偏移.
- (void) textFieldDidBeginEditing:(UITextField *)textField { CGRect frame = textField.frame; CGFloat rowHeight = self.tableView.rowHeight; if (textField == textFields[CELL_FIELD_ONE]) { frame.origin.y += rowHeight * CELL_FIELD_ONE; } else if (textField == textFields[CELL_FIELD_TWO]) { frame.origin.y += rowHeight * CELL_FIELD_TWO; } else if (textField == textFields[CELL_FIELD_THREE]) { frame.origin.y += rowHeight * CELL_FIELD_THREE; } else if (textField == textFields[CELL_FIELD_FOUR]) { frame.origin.y += rowHeight * CELL_FIELD_FOUR; } CGFloat viewHeight = self.tableView.frame.size.height; CGFloat halfHeight = viewHeight / 2; CGFloat midpoint = frame.origin.y + (textField.frame.size.height / 2); if (midpoint < halfHeight) { frame.origin.y = 0; frame.size.height = midpoint; } else { frame.origin.y = midpoint; frame.size.height = midpoint; } [self.tableView scrollRectToVisible:frame animated:YES]; }
这看起来效果很好.
如果您可以使用UITableViewController
,您将免费获得该功能.但是,有时候这不是一个选项,特别是如果您需要多个视图而不仅仅是UITableView
.
这里提出的一些解决方案不适用于iOS≥4,有些不适用于iPad或横向模式,有些不适用于蓝牙键盘(我们不希望任何滚动),有些则不适用在多个文本字段之间切换时工作.因此,如果您选择任何解决方案,请务必测试这些情况.这是我们的解决方案使用 用于在InAppSettingsKit:
- (void)_keyboardWillShow:(NSNotification*)notification { if (self.navigationController.topViewController == self) { NSDictionary* userInfo = [notification userInfo]; // we don't use SDK constants here to be universally compatible with all SDKs ? 3.0 NSValue* keyboardFrameValue = [userInfo objectForKey:@"UIKeyboardBoundsUserInfoKey"]; if (!keyboardFrameValue) { keyboardFrameValue = [userInfo objectForKey:@"UIKeyboardFrameEndUserInfoKey"]; } // Reduce the tableView height by the part of the keyboard that actually covers the tableView CGRect windowRect = [[UIApplication sharedApplication] keyWindow].bounds; if (UIInterfaceOrientationLandscapeLeft == self.interfaceOrientation ||UIInterfaceOrientationLandscapeRight == self.interfaceOrientation ) { windowRect = IASKCGRectSwap(windowRect); } CGRect viewRectAbsolute = [_tableView convertRect:_tableView.bounds toView:[[UIApplication sharedApplication] keyWindow]]; if (UIInterfaceOrientationLandscapeLeft == self.interfaceOrientation ||UIInterfaceOrientationLandscapeRight == self.interfaceOrientation ) { viewRectAbsolute = IASKCGRectSwap(viewRectAbsolute); } CGRect frame = _tableView.frame; frame.size.height -= [keyboardFrameValue CGRectValue].size.height - CGRectGetMaxY(windowRect) + CGRectGetMaxY(viewRectAbsolute); [UIView beginAnimations:nil context:NULL]; [UIView setAnimationDuration:[[userInfo objectForKey:UIKeyboardAnimationDurationUserInfoKey] doubleValue]]; [UIView setAnimationCurve:[[userInfo objectForKey:UIKeyboardAnimationCurveUserInfoKey] intValue]]; _tableView.frame = frame; [UIView commitAnimations]; UITableViewCell *textFieldCell = (id)((UITextField *)self.currentFirstResponder).superview.superview; NSIndexPath *textFieldIndexPath = [_tableView indexPathForCell:textFieldCell]; // iOS 3 sends hide and show notifications right after each other // when switching between textFields, so cancel -scrollToOldPosition requests [NSObject cancelPreviousPerformRequestsWithTarget:self]; [_tableView scrollToRowAtIndexPath:textFieldIndexPath atScrollPosition:UITableViewScrollPositionMiddle animated:YES]; } } - (void) scrollToOldPosition { [_tableView scrollToRowAtIndexPath:_topmostRowBeforeKeyboardWasShown atScrollPosition:UITableViewScrollPositionTop animated:YES]; } - (void)_keyboardWillHide:(NSNotification*)notification { if (self.navigationController.topViewController == self) { NSDictionary* userInfo = [notification userInfo]; [UIView beginAnimations:nil context:NULL]; [UIView setAnimationDuration:[[userInfo objectForKey:UIKeyboardAnimationDurationUserInfoKey] doubleValue]]; [UIView setAnimationCurve:[[userInfo objectForKey:UIKeyboardAnimationCurveUserInfoKey] intValue]]; _tableView.frame = self.view.bounds; [UIView commitAnimations]; [self performSelector:@selector(scrollToOldPosition) withObject:nil afterDelay:0.1]; } }
这是InAppSettingsKit中该类的完整代码.要测试它,请使用"完整列表"子窗格,您可以在其中测试上述方案.
Swift最简单的解决方案:
override func viewDidLoad() { super.viewDidLoad() searchBar?.becomeFirstResponder() NSNotificationCenter.defaultCenter().addObserver(self, selector: #selector(MyViewController.keyboardWillShow(_:)), name: UIKeyboardDidShowNotification, object: nil) NSNotificationCenter.defaultCenter().addObserver(self, selector: #selector(MyViewController.keyboardWillHide(_:)), name: UIKeyboardDidHideNotification, object: nil) } deinit { NSNotificationCenter.defaultCenter().removeObserver(self) } func keyboardWillShow(notification: NSNotification) { if let userInfo = notification.userInfo { if let keyboardHeight = userInfo[UIKeyboardFrameEndUserInfoKey]?.CGRectValue.size.height { tableView.contentInset = UIEdgeInsetsMake(0, 0, keyboardHeight, 0) } } } func keyboardWillHide(notification: NSNotification) { UIView.animateWithDuration(0.2, animations: { self.table_create_issue.contentInset = UIEdgeInsetsMake(0, 0, 0, 0) }) // For some reason adding inset in keyboardWillShow is animated by itself but removing is not, that's why we have to use animateWithDuration here }
我希望你们已经有了解决所有这些问题的解决方案.但我发现我的解决方案如下.我期待你已经有了一个单元格UITextField
.所以在准备时只需将行索引保留在文本字段的标记中.
cell.textField.tag = IndexPath.row;
创建一个具有全局范围的activeTextField
实例,UITextField
如下所示:
@interface EditViewController (){ UITextField *activeTextField; }
所以,现在你只需复制粘贴我的代码.而且别忘了添加UITextFieldDelegate
#pragma mark - TextField Delegation - (BOOL)textFieldShouldBeginEditing:(UITextField *)textField{ activeTextField = textField; return YES; } - (void)textFieldDidEndEditing:(UITextField *)textField{ activeTextField = nil; }
注册键盘 notifications
#pragma mark - Keyboard Activity - (void)registerForKeyboardNotifications { [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWasShown:) name:UIKeyboardDidShowNotification object:nil]; [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillBeHidden:) name:UIKeyboardWillHideNotification object:nil]; }
处理键盘Notifications
:
UIKeyboardDidShowNotification
发送时调用.
- (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); [self.tableView setContentInset:contentInsets]; [self.tableView setScrollIndicatorInsets:contentInsets]; NSIndexPath *currentRowIndex = [NSIndexPath indexPathForRow:activeTextField.tag inSection:0]; [self.tableView scrollToRowAtIndexPath:currentRowIndex atScrollPosition:UITableViewScrollPositionTop animated:YES]; }
UIKeyboardWillHideNotification
发送时调用
- (void)keyboardWillBeHidden:(NSNotification*)aNotification { UIEdgeInsets contentInsets = UIEdgeInsetsZero; [self.tableView setContentInset:contentInsets]; [self.tableView setScrollIndicatorInsets:contentInsets]; }
现在剩下一件事,调用registerForKeyboardNotifications
方法in ViewDidLoad
方法如下:
- (void)viewDidLoad { [super viewDidLoad]; // Registering keyboard notification [self registerForKeyboardNotifications]; // Your codes here... }
你完成了,希望你的textFields
意志不再被键盘隐藏.
结合并填充几个答案的空白(特别是Ortwin Gentz,用户98013)和另一篇文章,这将在纵向或横向模式的iPad上开箱即用:
@implementation UIView (FindFirstResponder) - (UIResponder *)findFirstResponder { if (self.isFirstResponder) { return self; } for (UIView *subView in self.subviews) { UIResponder *firstResponder = [subView findFirstResponder]; if (firstResponder != nil) { return firstResponder; } } return nil; } @end @implementation MyViewController - (UIResponder *)currentFirstResponder { return [self.view findFirstResponder]; } - (IBAction)editingEnded:sender { [sender resignFirstResponder]; } - (BOOL)textFieldShouldReturn:(UITextField *)textField { [textField resignFirstResponder]; return NO; } - (void)textFieldDidBeginEditing:(UITextField *)textField { UITableViewCell *cell = (UITableViewCell*) [[textField superview] superview]; [_tableView scrollToRowAtIndexPath:[_tableView indexPathForCell:cell] atScrollPosition:UITableViewScrollPositionTop animated:YES]; } - (void)keyboardWillShow:(NSNotification*)notification { if ([self currentFirstResponder] != nil) { NSDictionary* userInfo = [notification userInfo]; // we don't use SDK constants here to be universally compatible with all SDKs ? 3.0 NSValue* keyboardFrameValue = [userInfo objectForKey:@"UIKeyboardBoundsUserInfoKey"]; if (!keyboardFrameValue) { keyboardFrameValue = [userInfo objectForKey:@"UIKeyboardFrameEndUserInfoKey"]; } // Reduce the tableView height by the part of the keyboard that actually covers the tableView CGRect windowRect = [[UIApplication sharedApplication] keyWindow].bounds; CGRect viewRectAbsolute = [_tableView convertRect:_tableView.bounds toView:[[UIApplication sharedApplication] keyWindow]]; CGRect frame = _tableView.frame; if (UIInterfaceOrientationLandscapeLeft == self.interfaceOrientation ||UIInterfaceOrientationLandscapeRight == self.interfaceOrientation ) { windowRect = CGRectMake(windowRect.origin.y, windowRect.origin.x, windowRect.size.height, windowRect.size.width); viewRectAbsolute = CGRectMake(viewRectAbsolute.origin.y, viewRectAbsolute.origin.x, viewRectAbsolute.size.height, viewRectAbsolute.size.width); } frame.size.height -= [keyboardFrameValue CGRectValue].size.height - CGRectGetMaxY(windowRect) + CGRectGetMaxY(viewRectAbsolute); [UIView beginAnimations:nil context:NULL]; [UIView setAnimationDuration:[[userInfo objectForKey:UIKeyboardAnimationDurationUserInfoKey] doubleValue]]; [UIView setAnimationCurve:[[userInfo objectForKey:UIKeyboardAnimationCurveUserInfoKey] intValue]]; _tableView.frame = frame; [UIView commitAnimations]; UITableViewCell *textFieldCell = (id)((UITextField *)self.currentFirstResponder).superview.superview; NSIndexPath *textFieldIndexPath = [_tableView indexPathForCell:textFieldCell]; // iOS 3 sends hide and show notifications right after each other // when switching between textFields, so cancel -scrollToOldPosition requests [NSObject cancelPreviousPerformRequestsWithTarget:self]; _topmostRowBeforeKeyboardWasShown = [[_tableView indexPathsForVisibleRows] objectAtIndex:0]; [_tableView scrollToRowAtIndexPath:textFieldIndexPath atScrollPosition:UITableViewScrollPositionMiddle animated:YES]; } } - (void) scrollToOldPosition { [_tableView scrollToRowAtIndexPath:_topmostRowBeforeKeyboardWasShown atScrollPosition:UITableViewScrollPositionTop animated:YES]; } - (void)keyboardWillHide:(NSNotification*)notification { if ([self currentFirstResponder] != nil) { NSDictionary* userInfo = [notification userInfo]; [UIView beginAnimations:nil context:NULL]; [UIView setAnimationDuration:[[userInfo objectForKey:UIKeyboardAnimationDurationUserInfoKey] doubleValue]]; [UIView setAnimationCurve:[[userInfo objectForKey:UIKeyboardAnimationCurveUserInfoKey] intValue]]; _tableView.frame = self.view.bounds; [UIView commitAnimations]; [self performSelector:@selector(scrollToOldPosition) withObject:nil afterDelay:0.1]; } } @end
如果你使用uitableview来放置文本字段(来自Jeff Lamarche),你可以使用委托方法滚动tableview,就像这样.
(注意:我的文本字段存储在一个数组中,其索引与tableview中的行相同)
- (void) textFieldDidBeginEditing:(UITextField *)textField { int index; for(UITextField *aField in textFields){ if (textField == aField){ index = [textFields indexOfObject:aField]-1; } } if(index >= 0) [self.tableView scrollToRowAtIndexPath:[NSIndexPath indexPathForRow:index inSection:0] atScrollPosition:UITableViewScrollPositionTop animated:YES]; [super textFieldDidBeginEditing:textField]; }
键盘通知有效,但Apple的示例代码假定滚动视图是窗口的根视图.通常情况并非如此.您必须补偿标签栏等,以获得正确的偏移量.
它听起来比听起来容易.这是我在UITableViewController中使用的代码.它有两个实例变量,hiddenRect和keyboardShown.
// Called when the UIKeyboardDidShowNotification is sent. - (void)keyboardWasShown:(NSNotification*)aNotification { if (keyboardShown) return; NSDictionary* info = [aNotification userInfo]; // Get the frame of the keyboard. NSValue *centerValue = [info objectForKey:UIKeyboardCenterEndUserInfoKey]; NSValue *boundsValue = [info objectForKey:UIKeyboardBoundsUserInfoKey]; CGPoint keyboardCenter = [centerValue CGPointValue]; CGRect keyboardBounds = [boundsValue CGRectValue]; CGPoint keyboardOrigin = CGPointMake(keyboardCenter.x - keyboardBounds.size.width / 2.0, keyboardCenter.y - keyboardBounds.size.height / 2.0); CGRect keyboardScreenFrame = { keyboardOrigin, keyboardBounds.size }; // Resize the scroll view. UIScrollView *scrollView = (UIScrollView *) self.tableView; CGRect viewFrame = scrollView.frame; CGRect keyboardFrame = [scrollView.superview convertRect:keyboardScreenFrame fromView:nil]; hiddenRect = CGRectIntersection(viewFrame, keyboardFrame); CGRect remainder, slice; CGRectDivide(viewFrame, &slice, &remainder, CGRectGetHeight(hiddenRect), CGRectMaxYEdge); scrollView.frame = remainder; // Scroll the active text field into view. CGRect textFieldRect = [/* selected cell */ frame]; [scrollView scrollRectToVisible:textFieldRect animated:YES]; keyboardShown = YES; } // Called when the UIKeyboardDidHideNotification is sent - (void)keyboardWasHidden:(NSNotification*)aNotification { // Reset the height of the scroll view to its original value UIScrollView *scrollView = (UIScrollView *) self.tableView; CGRect viewFrame = [scrollView frame]; scrollView.frame = CGRectUnion(viewFrame, hiddenRect); keyboardShown = NO; }
如果您使用Three20
,则使用该autoresizesForKeyboard
属性.只需在视图控制器的-initWithNibName:bundle
方法中设置即可
self.autoresizesForKeyboard = YES
这需要注意:
收听键盘通知并调整表格视图的框架
滚动到第一个响应者
做完了.
我的方法:
我首先将UITextField子类化并添加一个indexPath属性.在cellFor ...方法中,我移交了indexPath属性.
然后我添加以下代码:
UITableViewCell *cell = [self.tableView cellForRowAtIndexPath:textField.indexPath]; CGPoint cellPoint = [cell convertPoint:textField.center toView:self.tableView]; [UIView animateWithDuration:0.3 animations:^(void){self.tableView.contentOffset = CGPointMake(0, cellPoint.y-50);}];
到textFieldShould/WillBegin ...等.
当键盘消失时,您必须将其反转:
[UIView animateWithDuration:0.3 animations:^(void){self.tableView.contentOffset = CGPointMake(0, 0);}];