ios - appears - Realización de un desplazamiento de UITableView cuando se selecciona el campo de texto
keyboard hide textfield ios swift (30)
Combinando y completando los espacios en blanco de varias respuestas (en particular, Ortwin Gentz, usuario 98013) y otra publicación, esto funcionará de manera inmediata para SDK 4.3 en un iPad en modo Vertical u Horizontal:
@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
Después de muchas pruebas y errores, me rindo y hago la pregunta. He visto a muchas personas con problemas similares, pero no puedo lograr que todas las respuestas funcionen correctamente.
Tengo un UITableView
que se compone de celdas personalizadas. Las celdas están formadas por 5 campos de texto uno al lado del otro (algo así como una cuadrícula).
Cuando intento desplazar y editar las celdas en la parte inferior de la UITableView
, no puedo lograr que mis celdas se UITableView
correctamente sobre el teclado.
He visto muchas respuestas que hablan sobre cómo cambiar el tamaño de las vistas, etc ... pero ninguna de ellas ha funcionado bien hasta ahora.
¿Alguien podría aclarar la forma "correcta" de hacer esto con un ejemplo de código concreto?
Creo que he encontrado una solución que coincida con el comportamiento de las aplicaciones de Apple.
Primero, en su vista, WillAppear: suscríbase a las notificaciones del teclado, para saber cuándo se mostrará y ocultará el teclado, y el sistema le indicará el tamaño del teclado, pero no olvide volver a registrarse en su vista.
[[NSNotificationCenter defaultCenter]
addObserver:self
selector:@selector(keyboardWillShow:)
name:UIKeyboardWillShowNotification
object:nil];
[[NSNotificationCenter defaultCenter]
addObserver:self
selector:@selector(keyboardWillHide:)
name:UIKeyboardWillHideNotification
object:nil];
Implemente los métodos similares a los de abajo para que ajuste el tamaño de su tableView para que coincida con el área visible una vez que se muestra el teclado. Aquí estoy rastreando el estado del teclado por separado para que pueda elegir cuándo volver a configurar el tableView de nuevo a la altura máxima, ya que recibe estas notificaciones en cada cambio de campo. No se olvide de implementar el teclado que se ocultará: y elija un lugar apropiado para corregir el tamaño de su 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];
}
}
Ahora aquí está el bit de desplazamiento, primero elaboramos algunos tamaños, luego vemos dónde estamos en el área visible y configuramos el rectángulo al que queremos desplazarnos para que sea la mitad de la vista por encima o por debajo de la mitad del campo de texto. en donde está en la vista. En este caso, tenemos una matriz de UITextFields y una enumeración que los rastrea, por lo que multiplicar el rowHeight por el número de fila nos da el desplazamiento real del marco dentro de esta vista exterior.
- (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];
}
Esto parece funcionar bastante bien.
Espero que ya tengan una solución leyendo todos esos. Pero encontré mi solución de la siguiente manera. Estoy esperando que ya tengas un celular con UITextField
. Así que en la preparación, simplemente mantenga el índice de fila en la etiqueta del campo de texto.
cell.textField.tag = IndexPath.row;
Cree un activeTextField
, instancia de UITextField
con alcance global como se muestra a continuación:
@interface EditViewController (){
UITextField *activeTextField;
}
Entonces, ahora solo tienes que copiar y pegar mi código al final. Y también no te olvides de añadir UITextFieldDelegate
#pragma mark - TextField Delegation
- (BOOL)textFieldShouldBeginEditing:(UITextField *)textField{
activeTextField = textField;
return YES;
}
- (void)textFieldDidEndEditing:(UITextField *)textField{
activeTextField = nil;
}
Registra las notifications
teclado.
#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];
}
Maneja las Notifications
teclado:
Se llama cuando se envía la 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];
}
Se llama cuando se envía la UIKeyboardWillHideNotification
- (void)keyboardWillBeHidden:(NSNotification*)aNotification
{
UIEdgeInsets contentInsets = UIEdgeInsetsZero;
[self.tableView setContentInset:contentInsets];
[self.tableView setScrollIndicatorInsets:contentInsets];
}
Ahora queda una cosa: llamar al método registerForKeyboardNotifications
método ViewDidLoad
siguiente manera:
- (void)viewDidLoad {
[super viewDidLoad];
// Registering keyboard notification
[self registerForKeyboardNotifications];
// Your codes here...
}
Ya ha terminado, espero que sus textFields
ya no textFields
ocultos por el teclado.
Estoy haciendo algo muy similar, es genérico, sin necesidad de calcular algo específico para su código. Solo revisa los comentarios en el código:
En MyUIViewController.h
@interface MyUIViewController: UIViewController <UITableViewDelegate, UITableViewDataSource>
{
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
En 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
Versión Swift 1.2+:
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()
}
}
}
La función que hace el desplazamiento podría ser mucho más simple:
- (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];
}
Eso es. No hay cálculos en absoluto.
La solución más simple para Swift 3 , basada en la solución Bartłomiej Semańczyk :
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)
})
}
La solución más simple para 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
}
Mi acercamiento:
Primero subclase UITextField y agrego una propiedad indexPath. En el método cellFor ..., entrego la propiedad indexPath.
Luego agrego el siguiente código:
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);}];
para el textoCampoDeShould / WillBegin ... etc.
Cuando el teclado desaparece tienes que revertirlo con:
[UIView animateWithDuration:0.3 animations:^(void){self.tableView.contentOffset = CGPointMake(0, 0);}];
Puede que me haya perdido esto, ya que no leí la publicación completa aquí, pero lo que se me ocurrió parece ser aparentemente simple. No he puesto esto a través del escurridor, probando en todas las situaciones, pero parece que debería funcionar bien.
simplemente ajuste el ContentInset de la vista de tabla por la altura del teclado, y luego desplace la celda hacia abajo:
- (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];
}
y por supuesto
- (void)keyboardWasHidden:(NSNotification *)aNotification
{
[UIView animateWithDuration:.3 animations:^(void)
{
self.myTableView.contentInset = UIEdgeInsetsZero;
self.myTableView.scrollIndicatorInsets = UIEdgeInsetsZero;
}];
}
¿Esto es demasiado simple? ¿Me estoy perdiendo de algo? hasta ahora está funcionando bien para mí, pero como dije, no lo he puesto en el escurridor ...
Si puede utilizar UITableViewController
, obtiene la funcionalidad de forma gratuita. Sin embargo, a veces, esto no es una opción, específicamente si necesita varias vistas, no solo la UITableView
.
Algunas de las soluciones presentadas aquí no funcionan en iOS ≥4, otras no funcionan en iPad o en modo horizontal, otras no funcionan para teclados Bluetooth (donde no queremos ningún desplazamiento), otras no trabajar al cambiar entre varios campos de texto. Entonces, si elige alguna solución, asegúrese de probar estos casos. Esta es la solución que usamos en 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];
}
}
Aquí está el código completo de la clase en InAppSettingsKit. Para probarlo, use el panel secundario "Lista completa" donde puede probar los escenarios mencionados anteriormente.
Si usa UITableViewController en lugar de UIViewController, automáticamente lo hará.
Tuve el mismo problema pero noté que aparece solo en una vista. Así que empecé a buscar las diferencias en los controladores.
Descubrí que el comportamiento de desplazamiento se establece en - (void)viewWillAppear:(BOOL)animated
de la súper instancia.
Así que asegúrese de implementar así:
- (void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
// your code
}
Y no importa si usa UIViewController
o UITableViewController
; lo comprobó colocando un UITableView
como una subvista de self.view en UIViewController
. Era el mismo comportamiento. La vista no permitía desplazarse si la llamada [super viewWillAppear:animated];
Estaba faltando.
Acabo de resolver un problema de este tipo después de haber remitido una gran cantidad de soluciones encontradas a través de Google y .
En primer lugar, asegúrese de haber configurado un IBOutlet de su UIScrollView y, a continuación, observe detenidamente http://developer.apple.com/library/ios/#documentation/StringsTextFonts/Conceptual/TextAndWebiPhoneOS/KeyboardManagement/KeyboardManagement.html . Finalmente, si puede desplazarse por el fondo, pero el teclado aún cubre los campos de texto, por favor, eche un vistazo a este fragmento de código:
// If active text field is hidden by keyboard, scroll it so it''s visible
// Your application might not need or want this behavior.
CGRect aRect = self.view.frame;
aRect.size.height -= kbSize.height;
if (aRect.size.height < activeField.frame.origin.y+activeField.frame.size.height) {
CGPoint scrollPoint = CGPointMake(0.0, activeField.frame.origin.y+activeField.frame.size.height-aRect.size.height);
[scrollView setContentOffset:scrollPoint animated:YES];
La principal diferencia entre esta pieza y la de Apple radica en la condición if. Creo que el cálculo de Apple de la distancia de desplazamiento y la condición de si el campo de texto cubierto por el teclado no es exacto, así que hice la modificación como se indica arriba.
Déjame saber si funciona
Esta solución funciona para mí, tenga en cuenta la línea
[tableView setContentOffset:CGPointMake(0.0, activeField.frame.origin.y-kbSize.height+160) animated:YES];
Puede cambiar el valor de 160 para que coincida con su trabajo
- (void)keyboardWasShown:(NSNotification*)aNotification
{
NSDictionary* info = [aNotification userInfo];
CGSize kbSize = [[info objectForKey:UIKeyboardFrameBeginUserInfoKey] CGRectValue].size;
CGRect bkgndRect = activeField.superview.frame;
bkgndRect.size.height += kbSize.height;
[activeField.superview setFrame:bkgndRect];
[tableView setContentOffset:CGPointMake(0.0, activeField.frame.origin.y-kbSize.height+160) animated:YES];
}
- (void)textFieldDidBeginEditing:(UITextField *)textField
{
activeField = textField;
}
-(void)textFieldDidEndEditing:(UITextField *)textField
{
activeField = nil;
}
// Called when the UIKeyboardWillHideNotification is sent
- (void)keyboardWillBeHidden:(NSNotification*)aNotification
{
UIEdgeInsets contentInsets = UIEdgeInsetsZero;
tableView.contentInset = contentInsets;
tableView.scrollIndicatorInsets = contentInsets;
NSDictionary* info = [aNotification userInfo];
CGSize kbSize = [[info objectForKey:UIKeyboardFrameBeginUserInfoKey] CGRectValue].size;
CGRect bkgndRect = activeField.superview.frame;
//bkgndRect.size.height += kbSize.height;
[activeField.superview setFrame:bkgndRect];
[tableView setContentOffset:CGPointMake(0.0, activeField.frame.origin.y-kbSize.height) animated:YES];
}
Esto funciona perfectamente, y también en iPad.
- (BOOL)textFieldShouldReturn:(UITextField *)textField
{
if(textField == textfield1){
[accountName1TextField becomeFirstResponder];
}else if(textField == textfield2){
[self.tableView scrollToRowAtIndexPath:[NSIndexPath indexPathForRow:0 inSection:1] atScrollPosition:UITableViewScrollPositionTop animated:YES];
[textfield3 becomeFirstResponder];
}else if(textField == textfield3){
[self.tableView scrollToRowAtIndexPath:[NSIndexPath indexPathForRow:1 inSection:1] atScrollPosition:UITableViewScrollPositionTop animated:YES];
[textfield4 becomeFirstResponder];
}else if(textField == textfield4){
[self.tableView scrollToRowAtIndexPath:[NSIndexPath indexPathForRow:2 inSection:1] atScrollPosition:UITableViewScrollPositionTop animated:YES];
[textfield5 becomeFirstResponder];
}else if(textField == textfield5){
[self.tableView scrollToRowAtIndexPath:[NSIndexPath indexPathForRow:3 inSection:1] atScrollPosition:UITableViewScrollPositionTop animated:YES];
[textfield6 becomeFirstResponder];
}else if(textField == textfield6){
[self.tableView scrollToRowAtIndexPath:[NSIndexPath indexPathForRow:4 inSection:1] atScrollPosition:UITableViewScrollPositionTop animated:YES];
[textfield7 becomeFirstResponder];
}else if(textField == textfield7){
[self.tableView scrollToRowAtIndexPath:[NSIndexPath indexPathForRow:5 inSection:1] atScrollPosition:UITableViewScrollPositionTop animated:YES];
[textfield8 becomeFirstResponder];
}else if(textField == textfield8){
[self.tableView scrollToRowAtIndexPath:[NSIndexPath indexPathForRow:6 inSection:1] atScrollPosition:UITableViewScrollPositionTop animated:YES];
[textfield9 becomeFirstResponder];
}else if(textField == textfield9){
[self.tableView scrollToRowAtIndexPath:[NSIndexPath indexPathForRow:7 inSection:1] atScrollPosition:UITableViewScrollPositionTop animated:YES];
[textField resignFirstResponder];
}
Hilo de discusión muy interesante, también me enfrenté al mismo problema que puede ser peor porque
- Estaba usando una celda personalizada y el campo de texto estaba dentro de eso.
- Tuve que usar UIViewController para cumplir con mis requisitos, por lo que no puedo aprovechar UITableViewController.
- Tenía criterios de filtro / clasificación en la celda de mi tabla, es decir, sus celdas siguen cambiando y siguiendo la ruta del índice, y todo eso no ayudará.
Así que lea los hilos aquí e implementé mi versión, que me ayudó a subir mis contenidos en iPad en modo horizontal . Aquí está el código (esto no es infalible y todo, pero solucionó mi problema) Primero, debe tener un delegado en su clase de celda personalizada, que, al comenzar la edición, envía el campo de texto a su controlador de vista y establece el campo activo = el Campo de texto allí.
// IMPLEMENTADO PARA MANEJAR EL MODO DE PAISAJE SOLAMENTE
- (void)keyboardWasShown:(NSNotification*)aNotification
{
NSDictionary* info = [aNotification userInfo];
CGSize kbValue = [[info objectForKey:UIKeyboardFrameBeginUserInfoKey] CGRectValue].size;
CGRect aRect = myTable.frame;
CGSize kbSize = CGSizeMake(kbValue.height, kbValue.width);
aRect.size.height -= kbSize.height+50;
// This will the exact rect in which your textfield is present
CGRect rect = [myTable convertRect:activeField.bounds fromView:activeField];
// Scroll up only if required
if (!CGRectContainsPoint(aRect, rect.origin) ) {
[myTable setContentOffset:CGPointMake(0.0, rect.origin.y) animated:YES];
}
}
// Llamado cuando se envía la UIKeyboardWillHideNotification
- (void)keyboardWillHide:(NSNotification*)aNotification
{
UIEdgeInsets contentInsets = UIEdgeInsetsZero;
myTable.contentInset = contentInsets;
myTable.scrollIndicatorInsets = contentInsets;
NSDictionary* info = [aNotification userInfo];
CGSize kbValue = [[info objectForKey:UIKeyboardFrameBeginUserInfoKey] CGRectValue].size;
CGSize kbSize = CGSizeMake(kbValue.height, kbValue.width);
CGRect bkgndRect = activeField.superview.frame;
bkgndRect.size.height += kbSize.height;
[activeField.superview setFrame:bkgndRect];
[myTable setContentOffset:CGPointMake(0.0, 10.0) animated:YES];
}
-anoop4real
La respuesta correcta es la respuesta de Sam Ho:
"Si usa UITableViewController en lugar de UIViewController, automáticamente lo hará".
Solo asegúrese de conectar su UITableView a la propiedad TableView del UITableViewController (así que, por ejemplo, no lo agregue como una subvista de la propiedad View del UITableViewController).
Asegúrese también de establecer la propiedad AutoresizingMask de su UITableView en FlexibleHeight
Me encontré con algo como tu problema (quería una pantalla similar a la configuración del iPhone.app con un montón de celdas editables apiladas encima de otra) y descubrí que este enfoque funcionaba bien:
Otro método fácil (solo funciona con una sección)
//cellForRowAtIndexPath
UItextField *tf;
[cell addSubview:tf];
tf.tag = indexPath.row;
tf.delegate = self;
//textFieldDidBeginEditing:(UITextField *)text
[[self.tableView scrollToRowsAtIndexPath:[NSIndexPath indexPathForRow:text.tag in section:SECTIONINTEGER] animated:YES];
Si su UITableView está gestionado por una subclase de UITableViewController y no por UITableView, y el delegado del campo de texto es el UITableViewController, debería gestionar todo el desplazamiento de forma automática; todos estos otros comentarios son muy difíciles de implementar en la práctica.
Para un buen ejemplo, vea el proyecto de código de ejemplo de Apple: TaggedLocations.
Puedes ver que se desplaza automáticamente, pero no parece haber ningún código que haga esto. Este proyecto también tiene celdas de vista de tabla personalizadas, por lo que si crea una aplicación con ella como guía, debe obtener el resultado deseado.
Ya que tiene campos de texto en una tabla, la mejor manera es cambiar el tamaño de la tabla; debe configurar el tableView.frame para que sea más pequeño en altura por el tamaño del teclado (creo que alrededor de 165 píxeles) y luego vuelva a expandirlo cuando Se despide el teclado.
Si lo desea, también puede deshabilitar la interacción del usuario para el tableView en ese momento, si no desea que el usuario se desplace.
UITextField''s
delegate
Método de uso :
Rápido
func textFieldShouldBeginEditing(textField: UITextField) -> bool {
let txtFieldPosition = textField.convertPoint(textField.bounds.origin, toView: yourTableViewHere)
let indexPath = yourTablViewHere.indexPathForRowAtPoint(txtFieldPosition)
if indexPath != nil {
yourTablViewHere.scrollToRowAtIndexPath(indexPath!, atScrollPosition: .Top, animated: true)
}
return true
}
C objetivo
- (BOOL)textFieldShouldBeginEditing:(UITextField *)textField
{
CGPoint txtFieldPosition = [textField convertPoint:CGPointZero toView: yourTablViewHere];
NSLog(@"Begin txtFieldPosition : %@",NSStringFromCGPoint(txtFieldPosition));
NSIndexPath *indexPath = [yourTablViewHere indexPathForRowAtPoint:txtFieldPosition];
if (indexPath != nil) {
[yourTablViewHere scrollToRowAtIndexPath:indexPath atScrollPosition:UITableViewScrollPositionMiddle animated:YES];
}
return YES;
}
Aquí es cómo hice este trabajo, que es una mezcla de las respuestas de Sam Ho y Marcel W, y algunas de mis propias correcciones de errores hechas a mi código de mierda. Estaba usando un UITableViewController. La tabla ahora cambia de tamaño correctamente cuando se muestra el teclado.
1) En viewDidLoad
agregué:
self.tableView.autoresizingMask = UIViewAutoresizingFlexibleHeight;
2) Había olvidado llamar a los super
equivalentes en viewWillAppear
y awakeFromNib
. He añadido estos de nuevo en.
Así que después de horas de trabajo agotador tratando de usar estas soluciones actuales (y fallando por completo) finalmente conseguí que las cosas funcionaran bien y las actualicé para usar los nuevos bloques de animación. Mi respuesta se basa totalmente en la respuesta de Ortwin anterior .
Entonces, por alguna razón, el código de arriba simplemente no estaba funcionando para mí. Mi configuración parecía bastante similar a la de otros, pero tal vez porque estaba en un iPad o 4.3 ... ni idea. Estaba haciendo algunas matemáticas locas y disparando mi vista de tabla desde la pantalla.
Ver el resultado final de mi solución: http://screencast.com/t/hjBCuRrPC (ignore la foto. :-P)
Así que fui con la esencia de lo que estaba haciendo Ortwin, pero cambié la forma en que estaba haciendo algunos cálculos matemáticos para sumar el origen y tamaño y la altura de mi vista de tabla con la altura del teclado. Cuando resto la altura de la ventana de ese resultado, me dice cuánta intersección tengo. Si es mayor que 0 (también conocido como superposición), realizo la animación de la altura del cuadro.
Además, hubo algunos problemas de redibujado que se resolvieron mediante 1) Esperando para desplazarse a la celda hasta que se realizó la animación y 2) utilizando la opción UIViewAnimationOptionBeginFromCurrentState al ocultar el teclado.
Un par de cosas a tener en cuenta.
- _topmostRowBeforeKeyboardWasShown & _originalFrame son variables de instancia declaradas en el encabezado.
- self.guestEntryTableView es mi tableView (estoy en un archivo externo)
- IASKCGRectSwap es el método de Ortwin para cambiar las coordenadas de un marco
- Solo actualizo la altura de la tableView si se mostrarán al menos 50px.
- Ya que no estoy en un UIViewController no tengo autoevaluación, así que simplemente devuelvo el tableView a su marco original
Una vez más, no me hubiera acercado a esta respuesta si Ortwin no hubiera proporcionado el punto crucial. Aquí está el código:
- (IBAction)textFieldDidBeginEditing:(UITextField *)textField
{
self.activeTextField = textField;
if ([self.guestEntryTableView indexPathsForVisibleRows].count) {
_topmostRowBeforeKeyboardWasShown = (NSIndexPath*)[[self.guestEntryTableView indexPathsForVisibleRows] objectAtIndex:0];
} else {
// this should never happen
_topmostRowBeforeKeyboardWasShown = [NSIndexPath indexPathForRow:0 inSection:0];
[textField resignFirstResponder];
}
}
- (IBAction)textFieldDidEndEditing:(UITextField *)textField
{
self.activeTextField = nil;
}
- (void)keyboardWillShow:(NSNotification*)notification {
NSDictionary* userInfo = [notification userInfo];
NSValue* keyboardFrameValue = [userInfo objectForKey:UIKeyboardFrameEndUserInfoKey];
// Reduce the tableView height by the part of the keyboard that actually covers the tableView
UIInterfaceOrientation orientation = [[UIApplication sharedApplication] statusBarOrientation];
CGRect windowRect = [[UIApplication sharedApplication] keyWindow].bounds;
CGRect viewRectAbsolute = [self.guestEntryTableView convertRect:self.guestEntryTableView.bounds toView:[[UIApplication sharedApplication] keyWindow]];
CGRect keyboardFrame = [keyboardFrameValue CGRectValue];
if (UIInterfaceOrientationLandscapeLeft == orientation ||UIInterfaceOrientationLandscapeRight == orientation ) {
windowRect = IASKCGRectSwap(windowRect);
viewRectAbsolute = IASKCGRectSwap(viewRectAbsolute);
keyboardFrame = IASKCGRectSwap(keyboardFrame);
}
// fix the coordinates of our rect to have a top left origin 0,0
viewRectAbsolute = FixOriginRotation(viewRectAbsolute, orientation, windowRect.size.width, windowRect.size.height);
CGRect frame = self.guestEntryTableView.frame;
_originalFrame = self.guestEntryTableView.frame;
int remainder = (viewRectAbsolute.origin.y + viewRectAbsolute.size.height + keyboardFrame.size.height) - windowRect.size.height;
if (remainder > 0 && !(remainder > frame.size.height + 50)) {
frame.size.height = frame.size.height - remainder;
float duration = [[userInfo objectForKey:UIKeyboardAnimationDurationUserInfoKey] doubleValue];
[UIView animateWithDuration: duration
animations:^{
self.guestEntryTableView.frame = frame;
}
completion:^(BOOL finished){
UITableViewCell *textFieldCell = (UITableViewCell*) [[self.activeTextField superview] superview];
NSIndexPath *textFieldIndexPath = [self.guestEntryTableView indexPathForCell:textFieldCell];
[self.guestEntryTableView scrollToRowAtIndexPath:textFieldIndexPath atScrollPosition:UITableViewScrollPositionMiddle animated:YES];
}];
}
}
- (void)keyboardWillHide:(NSNotification*)notification {
NSDictionary* userInfo = [notification userInfo];
float duration = [[userInfo objectForKey:UIKeyboardAnimationDurationUserInfoKey] doubleValue];
[UIView animateWithDuration: duration
delay: 0.0
options: (UIViewAnimationOptionBeginFromCurrentState)
animations:^{
self.guestEntryTableView.frame = _originalFrame;
}
completion:^(BOOL finished){
[self.guestEntryTableView scrollToRowAtIndexPath:_topmostRowBeforeKeyboardWasShown atScrollPosition:UITableViewScrollPositionTop animated:YES];
}];
}
#pragma mark CGRect Utility function
CGRect IASKCGRectSwap(CGRect rect) {
CGRect newRect;
newRect.origin.x = rect.origin.y;
newRect.origin.y = rect.origin.x;
newRect.size.width = rect.size.height;
newRect.size.height = rect.size.width;
return newRect;
}
CGRect FixOriginRotation(CGRect rect, UIInterfaceOrientation orientation, int parentWidth, int parentHeight) {
CGRect newRect;
switch(orientation)
{
case UIInterfaceOrientationLandscapeLeft:
newRect = CGRectMake(parentWidth - (rect.size.width + rect.origin.x), rect.origin.y, rect.size.width, rect.size.height);
break;
case UIInterfaceOrientationLandscapeRight:
newRect = CGRectMake(rect.origin.x, parentHeight - (rect.size.height + rect.origin.y), rect.size.width, rect.size.height);
break;
case UIInterfaceOrientationPortrait:
newRect = rect;
break;
case UIInterfaceOrientationPortraitUpsideDown:
newRect = CGRectMake(parentWidth - (rect.size.width + rect.origin.x), parentHeight - (rect.size.height + rect.origin.y), rect.size.width, rect.size.height);
break;
}
return newRect;
}
Intenté casi el mismo enfoque y se me ocurrió un código más simple y pequeño para el mismo. Creé un IBOutlet iTextView y lo asocié con el UITextView en el IB.
-(void)keyboardWillShow:(NSNotification *)notification
{
NSLog(@"Keyboard");
CGRect keyFrame = [[[notification userInfo]objectForKey:UIKeyboardFrameEndUserInfoKey]CGRectValue];
[UIView beginAnimations:@"resize view" context:nil];
[UIView setAnimationCurve:1];
[UIView setAnimationDuration:1.0];
CGRect frame = iTableView.frame;
frame.size.height = frame.size.height - keyFrame.size.height;
iTableView.frame = frame;
[iTableView scrollRectToVisible:frame animated:YES];
[UIView commitAnimations];
}
Las notificaciones de teclado funcionan, pero el código de muestra de Apple para eso asume que la vista de desplazamiento es la vista raíz de la ventana. Usualmente este no es el caso. Tienes que compensar las barras de pestañas, etc., para obtener el desplazamiento correcto.
Es más fácil de lo que parece. Aquí está el código que uso en un UITableViewController. Tiene dos variables de instancia, hiddenRect y 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;
}
Si usas Three20
, entonces usa la autoresizesForKeyboard
propiedad. Sólo establece en el -initWithNibName:bundle
método de su controlador de vista
self.autoresizesForKeyboard = YES
Esto se encarga de:
- Escuchar las notificaciones del teclado y ajustar el marco de la vista de tabla
- Desplazarse hasta el primer respondedor
Hecho y hecho.
Si utiliza una vista adecuada para colocar sus campos de texto ( de Jeff Lamarche ), puede desplazar la vista de tabla utilizando el método de delegado, de esta manera.
(Nota: mis campos de texto se almacenan en una matriz con el mismo índice que hay fila en la vista de tabla)
- (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];
}
Un ejemplo en Swift, usando el punto exacto del campo de texto de Obtener indexPath de UITextField en UITableViewCell con Swift :
func textFieldDidBeginEditing(textField: UITextField) {
let pointInTable = textField.convertPoint(textField.bounds.origin, toView: self.accountsTableView)
let textFieldIndexPath = self.accountsTableView.indexPathForRowAtPoint(pointInTable)
accountsTableView.scrollToRowAtIndexPath(textFieldIndexPath!, atScrollPosition: .Top, animated: true)
}
Una solución más forrada. Se desliza en los métodos de delegado de UITextField, por lo que no requiere que se mezclen las notificaciones con UIKeyboard
Notas de implementación:
kSettingsRowHeight: la altura de un UITableViewCell.
offsetTarget y offsetThreshold están desactivados en kSettingsRowHeight. Si usa una altura de fila diferente, establezca esos valores en la propiedad y del punto. [alt: calcula el desplazamiento de fila de una manera diferente.]
- (BOOL)textFieldShouldBeginEditing:(UITextField *)textField {
CGFloat offsetTarget = 113.0f; // 3rd row
CGFloat offsetThreshold = 248.0f; // 6th row (i.e. 2nd-to-last row)
CGPoint point = [self.tableView convertPoint:CGPointZero fromView:textField];
[UIView beginAnimations:nil context:nil];
[UIView setAnimationDuration:0.2];
[UIView setAnimationCurve:UIViewAnimationCurveEaseOut];
CGRect frame = self.tableView.frame;
if (point.y > offsetThreshold) {
self.tableView.frame = CGRectMake(0.0f,
offsetTarget - point.y + kSettingsRowHeight,
frame.size.width,
frame.size.height);
} else if (point.y > offsetTarget) {
self.tableView.frame = CGRectMake(0.0f,
offsetTarget - point.y,
frame.size.width,
frame.size.height);
} else {
self.tableView.frame = CGRectMake(0.0f,
0.0f,
frame.size.width,
frame.size.height);
}
[UIView commitAnimations];
return YES;
}
- (BOOL)textFieldShouldReturn:(UITextField *)textField {
[textField resignFirstResponder];
[UIView beginAnimations:nil context:nil];
[UIView setAnimationBeginsFromCurrentState:YES];
[UIView setAnimationDuration:0.2];
[UIView setAnimationCurve:UIViewAnimationCurveEaseOut];
CGRect frame = self.tableView.frame;
self.tableView.frame = CGRectMake(0.0f,
0.0f,
frame.size.width,
frame.size.height);
[UIView commitAnimations];
return YES;
}