ios - when - uitableview keyboard contentinset
Выполнение прокрутки UITableView при выборе текстового поля (20)
Если вы используете UITableViewController вместо UIViewController, он автоматически сделает это.
После долгих проб и ошибок я сдаюсь и задаю вопрос. Я видел много людей с подобными проблемами, но не могу получить ответы на все правильно.
У меня есть UITableView
который состоит из пользовательских ячеек. Ячейки состоят из 5 текстовых полей рядом друг с другом (вроде сетки).
Когда я пытаюсь прокручивать и редактировать ячейки в нижней части UITableView
, я не могу правильно расположить ячейки над клавиатурой.
Я видел много ответов, рассказывающих об изменении размеров и т. Д. ... но ни один из них не работал до сих пор.
Может ли кто-нибудь прояснить «правильный» способ сделать это с помощью конкретного примера кода?
Если вы можете использовать UITableViewController
, вы получаете бесплатную функциональность. Иногда, однако, это не вариант, особенно если вам нужно несколько просмотров, а не только UITableView
.
Некоторые из представленных здесь решений не работают на iOS ≥4, некоторые не работают на iPad или в ландшафтном режиме, некоторые не работают для клавиатур Bluetooth (там, где мы не хотим прокрутки), некоторые не работают работа при переключении между несколькими текстовыми полями. Поэтому, если вы выберете какое-либо решение, обязательно проверьте эти случаи. Это решение, которое мы используем в 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. Чтобы протестировать его, используйте дочернюю панель «Полный список», где вы можете протестировать описанные выше сценарии.
Мой подход:
Я первый подкласс 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);}];
к текстуFieldShould / WillBegin ... и т. д.
Когда Клавиатура исчезает, вы должны отменить ее:
[UIView animateWithDuration:0.3 animations:^(void){self.tableView.contentOffset = CGPointMake(0, 0);}];
Надеюсь, вы, ребята, уже получили решение, читая все это. Но я нашел решение следующим образом. Я ожидаю, что у вас уже есть ячейка с UITextField
. Поэтому при подготовке просто держите индекс строки в теге текстового поля.
cell.textField.tag = IndexPath.row;
Создайте activeTextField
, экземпляр UITextField
с глобальной областью, как 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];
}
Теперь осталось одно: ViewDidLoad
метод registerForKeyboardNotifications
метод ViewDidLoad
следующим образом:
- (void)viewDidLoad {
[super viewDidLoad];
// Registering keyboard notification
[self registerForKeyboardNotifications];
// Your codes here...
}
Вы закончили, надеюсь, что ваши textFields
больше не будут скрыты клавиатурой.
Простейшее решение для 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
}
У меня была такая же проблема, но я заметил, что она появляется только в одном представлении. Поэтому я начал искать различия в контроллерах.
Я узнал, что поведение прокрутки задано в - (void)viewWillAppear:(BOOL)animated
из супер-экземпляра.
Поэтому обязательно выполните следующие действия:
- (void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
// your code
}
И не имеет значения, используете ли вы UIViewController
или UITableViewController
; проверил его, поставив UITableView
в качестве подзаголовка self.view в UIViewController
. Это было одно и то же поведение. В представлении не разрешалось прокручивать, если вызов [super viewWillAppear:animated];
скучал.
Я делаю что-то очень похожее, это родовое, не нужно вычислять что-то конкретное для вашего кода. Просто проверьте замечания по коду:
В 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
В 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
Версия 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()
}
}
}
Я думаю, что я придумал решение, чтобы соответствовать поведению приложений Apple.
Во-первых, в вашем представленииWillAppear: подписаться на уведомления о клавиатуре, так что вы знаете, когда клавиатура покажет и скроется, и система сообщит вам размер клавиатуры, но не забывайте отменить регистрацию в своем представленииWillDisappear :.
[[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];
}
}
Теперь вот бит прокрутки, сначала мы разрабатываем несколько размеров, затем видим, где мы находимся в видимой области, и устанавливаем прямоугольник, который мы хотим прокрутить, чтобы быть либо полуразложением выше или ниже середины текстового поля где он находится в поле зрения. В этом случае у нас есть массив 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];
}
Кажется, это работает очень хорошо.
Другой простой метод (работает только с одним разделом)
//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];
Если ваш UITableView управляется подклассом UITableViewController, а не UITableView, а делегатом текстового поля является UITableViewController, он должен автоматически управлять всей прокруткой - все эти другие комментарии очень сложно реализовать на практике.
Для хорошего примера см. Проект кода примера apple: TaggedLocations.
Вы можете видеть, что он прокручивается автоматически, но, похоже, не существует кода, который делает это. В этом проекте также есть пользовательские таблицы представления таблиц, поэтому, если вы создаете приложение с ним в качестве руководства, вы должны получить желаемый результат.
ПРАВЫЙ ОТВЕТ - ответ Сэма Хо:
«Если вы используете UITableViewController вместо UIViewController, он автоматически сделает это».
Просто убедитесь, что вы подключили свой UITableView к свойству TableView UITableViewController (поэтому, например, не добавляйте его в качестве подзадачи свойства View для UITableViewController).
Также не забудьте установить свойство AutoresizingMask вашего UITableView в FlexibleHeight
Поскольку у вас есть текстовые поля в таблице, лучшим способом является изменение размера таблицы - вам нужно установить, что tableView.frame будет меньше по высоте на размер клавиатуры (я думаю, около 165 пикселей), а затем развернуть его снова, когда клавиатура отклоняется.
В то же время вы также можете отключить взаимодействие с пользователем для tableView, если вы не хотите прокручивать пользователя.
Этот солетон работает для меня, ПОЖАЛУЙСТА, обратите внимание на линию
[tableView setContentOffset:CGPointMake(0.0, activeField.frame.origin.y-kbSize.height+160) animated:YES];
Вы можете изменить значение 160, чтобы оно соответствовало вам.
- (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];
}
Я столкнулся с чем-то вроде вашей проблемы (мне нужен экран, похожий на настройки iPhone iPhone .app с кучей редактируемых ячеек, уложенных поверх другого) и обнаружил, что этот подход хорошо работает:
UITextField's
delegate
Метод использования :
стриж
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
}
Objective-C
- (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;
}
Более поточное решение. Он вписывается в методы делегата UITextField, поэтому он не требует беспорядочного ввода сообщений w / UIKeyboard.
Замечания по внедрению:
kSettingsRowHeight - высота UITableViewCell.
offsetTarget и offsetThreshold передаются с помощью kSettingsRowHeight. Если вы используете другую высоту строки, установите эти значения в свойство y точки. [alt: рассчитать смещение строки другим способом.]
- (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;
}
Если вы используете Three20
, используйте autoresizesForKeyboard
свойство. Просто установите в свой -initWithNibName:bundle
метод контроллера вида
self.autoresizesForKeyboard = YES
Это позаботится:
- Прослушивание уведомлений клавиатуры и настройка рамы в виде таблицы
- Прокрутка до первого ответчика
Сделано и сделано.
Если вы используете uitableview для размещения текстовых полей ( от Jeff Lamarche ), вы можете просто прокрутить табличное представление, используя метод делегата.
(Примечание: мои текстовые поля хранятся в массиве с тем же индексом, что и строка в представлении таблицы)
- (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];
}
Пример в Swift, используя точную точку текстового поля из Get indexPath UITextField в UITableViewCell со 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)
}
Сообщения о клавиатуре работают, но пример кода 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;
}