Ios 在常规UIViewController上的UITableViewCell中,滚动键盘上方的UITextField
我已经在StackOverflow上尝试了这里的大多数示例。我也用了苹果的。我似乎有一个问题,他们没有考虑UITableView中的UITextField。我已经做过很多次了,但不是这样。我有一个自定义的UITableViewCell,其中有一个UITextField 在我的UITableView(不是UITableViewController)上,我需要能够避免将UITextField隐藏在UITableView下 到目前为止,我有:Ios 在常规UIViewController上的UITableViewCell中,滚动键盘上方的UITextField,ios,ios4,Ios,Ios4,我已经在StackOverflow上尝试了这里的大多数示例。我也用了苹果的。我似乎有一个问题,他们没有考虑UITableView中的UITextField。我已经做过很多次了,但不是这样。我有一个自定义的UITableViewCell,其中有一个UITextField 在我的UITableView(不是UITableViewController)上,我需要能够避免将UITextField隐藏在UITableView下 到目前为止,我有: -(void)viewDidLoad { ....
-(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;
}
我花了一整天的时间想弄明白这一点。我把它贴在这里,然后找到了一个博客链接和一个非常简单的解决方案。看起来是这样的:
-(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;
}
我尝试了@inturbidus为iOS8发布的链接,但不幸的是,它对我不起作用。经过一番挖掘,苹果的网站上确实有一些示例代码,可以像在UITableViewController中一样自然地工作。这是Objective-C版本的苹果链接,我还在这里添加了swift版本 苹果的Objective-C链接(滚动至清单5-1):
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
}
快速适应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
}
我尝试了@inturbidus为iOS8发布的链接,但不幸的是,它对我不起作用。经过一番挖掘,苹果的网站上确实有一些示例代码,可以像在UITableViewController中一样自然地工作。这是Objective-C版本的苹果链接,我还在这里添加了swift版本 苹果的Objective-C链接(滚动至清单5-1):
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
}
快速适应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的链接。
请注意,Apple示例用于普通视图中的scrollview。
在表格视图中,您必须将activeField的Point和Rect转换为表格的坐标,因此我更改了函数键盘中的一些行,如图所示:
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下):
感谢@Salman的链接。
请注意,Apple示例用于普通视图中的scrollview。
在表格视图中,您必须将activeField的Point和Rect转换为表格的坐标,因此我更改了函数键盘中的一些行,如图所示:
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下):
在常规UIViewController swift 3和Xcode 8.1上的UITableViewCell中,滚动键盘上方的UITextField 1) set 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
}
在常规UIViewController swift 3和Xcode 8.1上的UITableViewCell中,滚动键盘上方的UITextField 1) set 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
}
我混合了马特和萨尔曼的答案。 这适用于tableView中的许多文本字段Swift 3 基本上是触摸文本输入的底部Y点。一旦有了它,我会检查键盘是否覆盖了文本输入,如果覆盖了,我会更改tableView的contentOffset 首先注册到通知。在init if是UIView或viewDidLoad if是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
}
func键盘将显示(通知:NSNotification){
var userInfo=notification.userInfo!
如果让keyboardFrame=(userInfo[UIKeyboardFrameEndUserInfoKey]作为?NSValue)?.cgRectValue{
//了解我的身高尺寸
设myheight=tableView.frame.height
//获取键盘在视图中结束的Y点
让keyboardEndPoint=myheight-keyboardFrame.height
//获取textInput的底部Y点并将其转换为currentView坐标。
如果let pointInTable=inputActive.superview?.convert(inputActive.frame.origin,to:tableView){
设textfieldbotompoint=pointInTable.y+inputActive.frame.size.height+20
//最后检查键盘是否覆盖文本输入
如果键盘端点我将马特和萨尔曼的答案混合在一起。
这适用于表视图中的许多文本字段。Swift 3
基本上是触摸文本输入的底部Y点。一旦触摸到,我会检查键盘是否覆盖文本输入,如果覆盖,我会更改tableView的contentOffset
首先注册到通知。如果是UIView,则在init中,如果是UIViewController,则在viewDidLoad中:
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
}
func键盘将显示(通知:NSNotification){
var userInfo=notification.userInfo!
如果让keyboardFrame=(userInfo[UIKeyboardFrameEndUserInfoKey]作为?NSValue)?.cgRectValue{
//了解我的身高尺寸
设myheight=tableView.frame.height
//获取键盘在视图中结束的Y点
让keyboardEndPoint=myheight-keyboardFrame.height
//获取textInput的底部Y点并将其转换为currentView坐标。
如果let pointInTable=inputActive.superview?.convert(inputActive.frame.origin,to:tableView
func cell(_ cell: UITableViewCell, willStartEditing view: UIView) {
if let inputAccessoryViewHeight = view.inputAccessoryView?.frame.size.height {
var contentOffset = self.tableView.contentOffset
let pointInTable = view.convert(view.frame.origin, to: self.tableView)
contentOffset.y = pointInTable.y - inputAccessoryViewHeight
self.tableView.setContentOffset(contentOffset, animated: true)
}
}
func cell(_ cell: UITableViewCell, willEndEditing view: UIView) {
view.resignFirstResponder()
if let position = self.tableView.indexPath(for: cell) {
self.tableView.scrollToRow(at: position, at: .middle, animated: true)
}
}
func textFieldShouldBeginEditing(_ textField: UITextField) -> Bool {
delegate?.cell(self, willStartEditing: textField)
return true
}
func textFieldShouldEndEditing(_ textField: UITextField) -> Bool {
delegate?.cell(self, willEndEditing: textField)
return true
}