Отключить клавиатуру, прикоснувшись к фону UITableView - PullRequest
100 голосов
/ 23 февраля 2010

У меня есть UITableView с UITextField с в качестве ячеек. Я хотел бы отклонить клавиатуру при прикосновении к фону UITableView. Я пытаюсь сделать это, создав UIButton размер UITableView и поместив его позади UITableView. Единственная проблема заключается в том, что UIButton ловит все касания, даже когда касание находится на UITableView. Что я делаю не так?

Спасибо!

Ответы [ 27 ]

0 голосов
/ 12 мая 2010

Если вы хотите создать подкласс (тьфу!) Представления таблицы, что-то вроде этого может работать:

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {

   BOOL backgroundTouched = YES;

   for (UITouch *touch in touches) {
      CGPoint location = [touch locationInView:self];
      for (UITableViewCell *cell in self.visibleCells) {
         if (CGRectContainsPoint(cell.frame, location)) {
            backgroundTouched = NO;
            break;
         }
      }
   }

   if (backgroundTouched) {
      for (UITableViewCell *cell in self.visibleCells) {
         // This presumes the first subview is the text field you want to resign.
         [[cell.contentView.subviews objectAtIndex:0] resignFirstResponder];
      }
   }

   [super touchesBegan:touches withEvent:event];
}
0 голосов
/ 28 сентября 2017

UITableView имеет удобное свойство backgroundView, с помощью которого я добился такого поведения, не вмешиваясь в выделение ячеек, как показано ниже в Swift:

let tableBackTapRecognizer = UITapGestureRecognizer(target: self, action: #selector(hideKeyboard))
tableView.backgroundView = UIView()
tableView.backgroundView?.addGestureRecognizer(tableBackTapRecognizer)
0 голосов
/ 18 февраля 2012

Если вы хотите закрыть клавиатуру при нажатой клавише возврата, вы можете просто добавить следующий код в textField, который должен возвращать метод, т. Е.

- (BOOL)textFieldShouldReturn:(UITextField *)atextField
{
   [textField resignFirstresponder];
}

Некоторые текстовые поля могут иметь представление выбора или другое в качестве подпредставления, поэтому в этом случае вышеуказанный метод не работает, поэтому в этом случае нам нужно использовать класс UITapGestureRecognizer, т.е. добавить следующий фрагмент кода в метод viewDidLoad, т.е. :

UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self
                                                                          action:@selector(dismissKeyboard)];

    [self.view addGestureRecognizer:tap];

Теперь просто добавьте респондент в отставку к методу селектора, т.е.

-(void)dismissKeyboard 
{
    [textField resignFirstResponder];
}

Надеюсь, это поможет, спасибо:)

0 голосов
/ 24 сентября 2014

@ mixca ответ очень полезен, но что, если у меня есть что-то отличное от UITextField. Я думаю, что лучший способ справиться с этим путем поиска всех подпредставлений основного вида с помощью рекурсивной функции, посмотрите пример ниже

- (BOOL)findAndResignFirstResponder {
if (self.isFirstResponder) {
    [self resignFirstResponder];
    return YES;
}

    for (UIView *subView in self.subviews) {
        if ([subView findAndResignFirstResponder]) {
            return YES;
        }
    }
    return NO;
}

, а также вы можете поместить этот метод в свой служебный класс и использовать его с помощью жеста, как ответ @ mixca.

0 голосов
/ 06 августа 2014

Вот как я наконец заработал. Я объединил предложения и коды из разных ответов. Особенности: отклонение клавиатуры, перемещение текстовых полей над клавиатурой при редактировании и установка типа возврата «Далее» и «Готово» для клавиатуры. ЗАМЕНА «...» с дополнительными полями

static const CGFloat ANIMATION_DURATION = 0.4;
static const CGFloat LITTLE_SPACE = 5;
CGFloat animatedDistance;
CGSize keyboardSize;

@interface ViewController () <UITextFieldDelegate>
 @property (weak, nonatomic) IBOutlet UITextField *firstNameTXT;
  .....// some other text fields
 @property (weak, nonatomic) IBOutlet UITextField *emailTXT;
@end

@implementation ViewController
- (void)viewDidLoad{
.....
// add tap gesture to help in dismissing keyboard
UITapGestureRecognizer * tapGesture = [[UITapGestureRecognizer alloc]
                                       initWithTarget:self
                                       action:@selector(tapScreen:)];// outside textfields

[self.view addGestureRecognizer:tapGesture];

// set text fields return key type to Next, last text field to Done
[self.firstNameTXT setReturnKeyType:UIReturnKeyNext];
.....
[self.emailTXT setReturnKeyType:UIReturnKeyDone];

// set text fields tags
[self.firstNameTXT setTag:0];
....// more text fields
[self.emailTXT setTag:5];

// add keyboard notification
[[NSNotificationCenter defaultCenter] addObserver:self     selector:@selector(keyboardDidShow:) name:UIKeyboardDidShowNotification object:nil];
}
[[NSNotificationCenter defaultCenter] addObserver:self      selector:@selector(keyboardDidHide:) name:UIKeyboardDidHideNotification object:nil];
}

// dismiss keyboard when tap outside text fields
- (IBAction)tapScreen:(UITapGestureRecognizer *)sender {
  if([self.firstNameTXT isFirstResponder])[self.firstNameTXT resignFirstResponder];
  ...
  if([self.emailTXT isFirstResponder])[self.emailTXT  resignFirstResponder];

  }
- (BOOL)textFieldShouldReturn:(UITextField *)textField{
   if(textField.returnKeyType==UIReturnKeyNext) {
     // find the text field with next tag
     UIView *next = [[textField superview] viewWithTag:textField.tag+1];
     [next becomeFirstResponder];
   } else if (textField.returnKeyType==UIReturnKeyDone || textField.returnKeyType==UIReturnKeyDefault) {
    [textField resignFirstResponder];
 }
return YES;
}

// Moving current text field above keyboard
-(BOOL) textFieldShouldBeginEditing:(UITextField*)textField{
   CGRect viewFrame = self.view.frame;
   CGRect textFieldRect = [self.view.window convertRect:textField.bounds fromView:textField];
   CGRect viewRect = [self.view.window convertRect:self.view.bounds fromView:self.view];
   CGFloat textFieldBottomLine = textFieldRect.origin.y + textFieldRect.size.height + LITTLE_SPACE;//

   CGFloat keyboardHeight = keyboardSize.height;

   BOOL isTextFieldHidden = textFieldBottomLine > (viewRect.size.height - keyboardHeight)? TRUE :FALSE;
  if (isTextFieldHidden) {
    animatedDistance = textFieldBottomLine - (viewRect.size.height - keyboardHeight) ;
    viewFrame.origin.y -= animatedDistance;
    [UIView beginAnimations:nil context:NULL];
    [UIView setAnimationBeginsFromCurrentState:YES];
    [UIView setAnimationDuration:ANIMATION_DURATION];
    [self.view setFrame:viewFrame];
    [UIView commitAnimations];
  }
  return YES;
}

-(void) restoreViewFrameOrigionYToZero{
  CGRect viewFrame = self.view.frame;
  if (viewFrame.origin.y != 0) {
    viewFrame.origin.y = 0;
    [UIView beginAnimations:nil context:NULL];
    [UIView setAnimationBeginsFromCurrentState:YES];
    [UIView setAnimationDuration:ANIMATION_DURATION];
    [self.view setFrame:viewFrame];
    [UIView commitAnimations];
  }
}

-(void)keyboardDidShow:(NSNotification*)aNotification{
   NSDictionary* info = [aNotification userInfo];
   keyboardSize = [[info objectForKey:UIKeyboardFrameBeginUserInfoKey] CGRectValue].size;
 }

-(void)keyboardDidHide:(NSNotification*)aNotification{
   [self restoreViewFrameOrigionYToZero];// keyboard is dismissed, restore frame view to its  zero origin
}
@end
0 голосов
/ 23 мая 2014

Много интересных ответов. Я хотел бы объединить различные подходы в решение, которое, по моему мнению, лучше всего подходит для сценария UITableView (это тот, который я обычно использую): Обычно мы хотим скрыть клавиатуру в двух сценариях: при нажатии вне элементов текстового интерфейса пользователя или при прокрутке UITableView вверх / вниз. Первый сценарий мы можем легко добавить с помощью TapGestureRecognizer, а второй - с помощью UIScrollViewDelegate scrollViewWillBeginDragging: метод. Первый порядок бизнеса, способ скрыть клавиатуру:

   /**
     *  Shortcut for resigning all responders and pull-back the keyboard
     */
    -(void)hideKeyboard
    {
        //this convenience method on UITableView sends a nested message to all subviews, and they resign responders if they have hold of the keyboard
        [self.tableView endEditing:YES];

    }

Этот метод отказывается от любого пользовательского интерфейса textField для подпредставлений в иерархии представлений UITableView, поэтому он более практичен, чем самостоятельная отставка каждого отдельного элемента.

Далее мы позаботимся об увольнении с помощью внешнего касания с помощью:

- (void)viewDidLoad
{
    [super viewDidLoad];
    // Do any additional setup after loading the view.
    [self setupKeyboardDismissGestures];

}

- (void)setupKeyboardDismissGestures
{

//    Example for a swipe gesture recognizer. it was not set-up since we use scrollViewDelegate for dissmin-on-swiping, but it could be useful to keep in mind for views that do not inherit from UIScrollView
//    UISwipeGestureRecognizer *swipeUpGestureRecognizer = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(hideKeyboard)];
//    swipeUpGestureRecognizer.cancelsTouchesInView = NO;
//    swipeUpGestureRecognizer.direction = UISwipeGestureRecognizerDirectionUp;
//    [self.tableView addGestureRecognizer:swipeUpGestureRecognizer];

    UITapGestureRecognizer *tapGestureRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(hideKeyboard)];
    //this prevents the gestureRecognizer to override other Taps, such as Cell Selection
    tapGestureRecognizer.cancelsTouchesInView = NO;
    [self.tableView addGestureRecognizer:tapGestureRecognizer];

}

Установка для tapGestureRecognizer.cancelsTouchesInView значения NO означает, что не позволяет gestRecognizer переопределять обычные внутренние операции UITableView (например, чтобы не мешать выбору ячейки).

Наконец, чтобы справиться с сокрытием клавиатуры при прокрутке вверх / вниз UITableView, мы должны реализовать протокол scrollViewWillBeginDragging: метод UIScrollViewDelegate, как:

.h файл

@interface MyViewController : UIViewController <UIScrollViewDelegate>

.m файл

#pragma mark - UIScrollViewDelegate

-(void)scrollViewWillBeginDragging:(UIScrollView *)scrollView
{
    [self hideKeyboard];
}

Надеюсь, это поможет! =)

0 голосов
/ 25 февраля 2010

Почему вы хотите создать таблицу, полную текстовых полей? Вы должны использовать подробное представление для каждой строки, которая содержит текстовые поля. Когда вы нажимаете подробное представление, убедитесь, что вы вызываете «[myTextField intoFirstResponder]», чтобы пользователь мог начать редактирование одним щелчком мыши из списка таблиц.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...