通过触摸UITableView背景关闭键盘


105

我有一个UITableViewUITextFields作为单元格。我想在UITableView触摸的背景时关闭键盘。我正在尝试通过创建UIButton的大小UITableView并将其放在的后面来实现此目的UITableView。唯一的问题是,UIButton即使触摸在UITableView上,也要捕获所有触摸。我究竟做错了什么?

谢谢!


相关的问题和答案:Q1Q2Q3
谢艳涛

Answers:


203

可以通过创建UITapGestureRecognizer对象(默认情况下单击一次即可检测到“手势”,因此不需要进一步的自定义)轻松地完成此操作,并指定触发手势时的目标/动作,然后附加手势识别器对象到您的表格视图。

例如,也许在您的viewDidLoad方法中:

UITapGestureRecognizer *gestureRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(hideKeyboard)];
[self.tableView addGestureRecognizer:gestureRecognizer];

hideKeyboard方法可能如下所示:

- (void) hideKeyboard {
    [textField1 resignFirstResponder];
    [textField2 resignFirstResponder];
    ...
    ...
}

请注意,触摸UITextField对象内部时不会触发手势。但是会在UITableView背景,页脚视图,页眉视图和UILabels内部单元格等上触发它。


4
当我尝试此操作时,我发现它阻止了表选择单元格:(。否则,这是很棒的解决方案
布莱恩

109
根据下面的解决方案,您可以通过设置以下gestureRecognizer.cancelsTouchesInView = NO;
各项

3
并且,一旦将其附着到tableView上,别忘了释放它。
保罗·林奇

39
对于该hideKeyboard方法,您可以执行,而不是直接与文本字段进行通信[self.view endEditing:NO];。从Apple文档中:“ 该方法查看当前视图和它的子视图层次结构中当前是第一响应者的文本字段。如果找到该文本字段,则要求该文本字段辞去第一响应者的角色。如果force参数设置为是的,从未询问过该文本字段;它被迫辞职。
Gobot 2012年

1
使用这种方式,不会调用我的“ didSelectRowAtIndexPath”方法。任何解决方案?
uniruddh

127

如果您进行以下设置,则UITapGestureRecognizer解决方案可用于表格单元格选择:

gestureRecognizer.cancelsTouchesInView = NO;

1
这允许触摸单元格,但手势也可以识别,也许我们应该实现此委托方法shouldReceiveTouch
onmyway133 '16

61

这是执行此操作的最佳方法。做这个

[self.view endEditing:YES];

要么

[[self.tableView superView] endEditing:YES];

我应该在哪里放置此代码?对不起,我是初学者。并请提供快速代码。
约翰

54

您也可以从情节提要中执行此操作: 在此处输入图片说明


1
无论选择什么:在拖动时关闭,以交互方式关闭,当我触摸表格单元格时,它被选中。我正在使用Xcode 8,Swift3。请帮忙
John

22

作为UITableView的子类UIScrollView,实现下面的一个委托方法提供了一种极其简单,快速的解决方案。resignFirstResponder由于视图层次结构会进行自省并找到当前响应者,并要求其退出响应者状态,因此甚至无需参与。

- (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView
{
    [self.view endEditing:YES];
}

并记住要添加UIScrollViewDelegate到头文件。


2
如果您的目标是iOS7及更高版本,则可以通过@Joe Masilotti指出的这一衬套来完成: self.tableView.keyboardDismissMode = UIScrollViewKeyboardDismissModeOnDrag;
atulkhatri 2015年

如果您点击屏幕底部的一个文本字段(该文本字段应向上滚动以显示键盘),会发生什么情况?-您的键盘将被隐藏。
Islam Q.

迅捷 self.tableView.keyboardDismissMode = UIScrollViewKeyboardDismissMode.onDrag
4-– RobLabs

13

首先,通过添加来收听scrollViewWillBeginDraggingUIViewController的声音UIScrollViewDelegate

在.h文件中:

@interface MyViewController : UIViewController <UIScrollViewDelegate> 

在.m文件中:

- (void)scrollViewWillBeginDragging:(UIScrollView *)activeScrollView {

    [self dismissKeyboard];

}

然后听其他交互:

- (void)setupKeyboardDismissTaps {

    UISwipeGestureRecognizer *swipeUpGestureRecognizer = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(dismissKeyboard)];
    swipeUpGestureRecognizer.cancelsTouchesInView = NO;
    swipeUpGestureRecognizer.direction = UISwipeGestureRecognizerDirectionUp;
    [self.tableView addGestureRecognizer:swipeUpGestureRecognizer];

    UISwipeGestureRecognizer *swipeDownGestureRecognizer = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(dismissKeyboard)];
    swipeDownGestureRecognizer.cancelsTouchesInView = NO;
    swipeDownGestureRecognizer.direction = UISwipeGestureRecognizerDirectionDown;
    [self.tableView addGestureRecognizer:swipeDownGestureRecognizer];

    UISwipeGestureRecognizer *swipeLeftGestureRecognizer = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(dismissKeyboard)];
    swipeLeftGestureRecognizer.cancelsTouchesInView = NO;
    swipeLeftGestureRecognizer.direction = UISwipeGestureRecognizerDirectionLeft;
    [self.tableView addGestureRecognizer:swipeLeftGestureRecognizer];

    UISwipeGestureRecognizer *swipeRightGestureRecognizer = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(dismissKeyboard)];
    swipeRightGestureRecognizer.cancelsTouchesInView = NO;
    swipeRightGestureRecognizer.direction = UISwipeGestureRecognizerDirectionRight;
    [self.tableView addGestureRecognizer:swipeRightGestureRecognizer];


    UITapGestureRecognizer *tapGestureRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(dismissKeyboard)];
    tapGestureRecognizer.cancelsTouchesInView = NO;
    [self.tableView addGestureRecognizer:tapGestureRecognizer];

}

然后执行dismissKeyboard

- (void)dismissKeyboard {

    NSLog(@"dismissKeyboard");

    [yourTextFieldPointer resignFirstResponder];

}

并且,如果像我一样,您想要关闭自定义表格单元格内的UITextField的键盘,请执行以下操作:

- (void)dismissKeyboard {

    NSLog(@"dismissKeyboard");

    CustomCellClass *customCell = [tableView cellForRowAtIndexPath:[NSIndexPath indexPathForRow:0 inSection:0]];
    [customCell.textFieldInCell resignFirstResponder]; 

}

希望对任何人有帮助!!



8

这是您的编码乐趣的快速版本:

它添加了轻击手势识别器,然后关闭了键盘。TextField不需要插座!

override func viewDidLoad() {
    super.viewDidLoad()
    view.addGestureRecognizer(UITapGestureRecognizer(target: self, action: "handleTap:"))
}

func handleTap(sender: UITapGestureRecognizer) {
    if sender.state == .Ended {
        view.endEditing(true)
    }
    sender.cancelsTouchesInView = false
}

1
即使使用自定义tableViewCell,它也可以工作!我花了很多时间试图解决这个问题。非常感谢!你是我的英雄。youtu.be/EqWRaAF6_WY
和平型2015年

8

有Swift 3版本,没有阻止单元格上的点击。

viewDidLoad()方法中:

let dismissKeyboardGesture = UITapGestureRecognizer(target: self, action: #selector(hideKeyboard))
dismissKeyboardGesture.cancelsTouchesInView = false
tableView.addGestureRecognizer(dismissKeyboardGesture)

而且hideKeyboard是这样的:

func hideKeyboard() {
    view.endEditing(true)
}

7

我这样做是这样的:

在TableViewController中创建一个方法以停用第一个响应者(此时将是您的TextBox)

- (BOOL)findAndResignFirstResonder:(UIView *)stView {
    if (stView.isFirstResponder) {
        [stView resignFirstResponder];
        return YES;     
    }

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

tableView:didSelectRowAtIndexPath:调用上一个方法时:

- (void)tableView:(UITableView *)tableView
                             didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
    ...
    [self findAndResignFirstResonder: self.view];
    ...
}

您按要求的方式做错了。您没有在视图上放置按钮,而是告诉视图删除键盘,如答案所示

2
如果您在表格视图单元格内(以及该表格视图单元格内的任何UITextField之外)点击,则可以很好地工作。但是,如果我点击表格视图的背景(通常更容易达到目标-菲茨定律!),那么运气就不好了。的确,这是预期的,因为我们正在tableView:didSelectRowAtIndexPath:中执行此操作。如果可以通过某种方式将其调整为可以在表格视图中的其他任何位置轻按(否则就不需要键盘焦点),那么我认为我们已经赢了!
Joe D'Andrea

我和jdandrea有同样的问题。这didSelectRowAtIndexPath不,如果你挖掘的TableView本身火灾。
zekel 2010年

如果didSelectRowAtIndexPath还不够,在touchesBegan中也做同样的事情!
Amogh Talpallikar

5

我有一个UITableViewController,实施touchesBegan:withEvent:对我没有用。

这是起作用的:

迅速:

override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
    view.endEditing(true)
}

目标C:

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
    [self.view endEditing:YES];
}

好主意,我喜欢。
HotFudgeSunday

4
@interface DismissableUITableView : UITableView {
}
@end

@implementation DismissableUITableView

- (void) touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
 [self.superview endEditing:YES];
 [super touchesBegan:touches withEvent:event];
}

@end

然后确保在您的Nib文件中将UITableView的类型设置为DismissableUITableView .....也许我可以想到此类的更好名称,但是您明白了。


4

如果您的目标是iOS7,则可以使用以下之一:

tableView.keyboardDismissMode = UIScrollViewKeyboardDismissModeOnDrag;

tableView.keyboardDismissMode = UIScrollViewKeyboardDismissModeInteractive;

滚动表视图时,前者将在屏幕外为键盘动画,而后者将像股票Messages应用一样隐藏键盘。

请注意,这些都是UIScrollView,这UITableView从继承。


很好 我设法通过从屏幕上方向上滑动向下滑动直到键盘开始向下移动,然后向后滑动向上滑动直到键盘向上移动一点,然后松开来解决它。滚动视图不会弹出应有的顶部。
山姆

3

试试这个:

viewDidLoad(){

    let tap: UITapGestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(dismissKeyboard))

    tableView.addGestureRecognizer(tap)

}
//Calls this function when the tap is recognized.
@objc func dismissKeyboard() {

    //Causes the view (or one of its embedded text fields) to resign the first responder status.
    view.endEditing(true)

}

2

UITableView是UIScrollView的子类。

我这样做的方法是侦听用户的滚动事件,然后重新签名resignFirstResponder。这是在代码中实现的UIScrollViewDelegate方法;

- (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView

解决这类问题时,我发现最好的方法是研究每个对象和父类的委托协议(在这种情况下,UITableViewDelegate,UIScrollViewDelegate。NS对象触发的事件数量非常大而且很全面。还可以轻松实现协议,然后再将其子类化。


2

我遇到了同样的问题,这是我的解决方案,它对我来说非常有效:

在您实现的视图或视图控制器中 <UITextFieldDelegate>

(以我为例, UITableViewCell名为TextFieldCell),

声明UITapGestureRecognizer为属性:

@interface TextFieldCell : UITableViewCell <UITextFieldDelegate>
{
    UITextField *theTextField;
    UITapGestureRecognizer *gestureRecognizer;
}
@property (nonatomic,retain) UITextField *theTextField;
@property (nonatomic,retain) UITapGestureRecognizer *gestureRecognizer; 

并在您的视图/控制器中对其进行初始化:

self.gestureRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(closeKeyboard:)];

- (void)textFieldDidBeginEditing:(UITextField *)textField方法中,使用superView上移到tableView并调用addGestureRecognizer

[self.superview.superview addGestureRecognizer:gestureRecognizer];

而在 - (void)textFieldDidEndEditing:(UITextField *)textField,只需删除手势识别器即可:

[self.superview.superview removeGestureRecognizer:gestureRecognizer];

希望能帮助到你。


这为我做到了。谢谢hac.jack
gilsaints88

2

我希望我的单元格在选择单元格的任何部分时都可以打开键盘,并在单击该单元格的任何位置时将其关闭。要打开键盘:

- (void)setSelected:(BOOL)selected animated:(BOOL)animated
{
    [super setSelected:selected animated:animated];
    if (selected)
    {
        [self.textField becomeFirstResponder];
    }
}

(注:我子类细胞,但你可以很容易地在实现这一目标tableView:didSelectRowAtIndexPath:的委托方法UITableView

这样做意味着在最佳解决方案中,如果您两次单击该单元格,键盘都会摇晃,首先是手势识别器尝试关闭键盘,然后重新选择该单元格并尝试打开键盘。

解决方案是检查单击是否发生在当前选定的单元格内:

- (void)viewDidLoad
{
    [super viewDidLoad];
    //gesture recognizer to close the keyboard when user taps away
    UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self
                                                                          action:@selector(dismissKeyboard:)];
    tap.cancelsTouchesInView = NO;
    [self.tableView addGestureRecognizer:tap];
}

-(void)dismissKeyboard:(UIGestureRecognizer*)tapGestureRecognizer
{
    if (!CGRectContainsPoint([self.tableView cellForRowAtIndexPath:[self.tableView indexPathForSelectedRow]].frame, [tapGestureRecognizer locationInView:self.tableView]))
    {
        [self.view endEditing:YES];
    }
}

2

我找到了一个很好的解决方案。

需要使用UIGestureRecognizerDelegate和方法- gestureRecognizer:shouldReceiveTouch:

将手势识别器添加到TableView中,如下所示:

UITapGestureRecognizer *tapGestureRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(hideKeyboard)];
tapGestureRecognizer.cancelsTouchesInView = NO;
tapGestureRecognizer.delegate = self;
[self.suggestedTableView addGestureRecognizer:tapGestureRecognizer];
[tapGestureRecognizer release];

然后,实现shouldReceiveTouch委托方法以拒绝在UITableViewCell类中执行的触摸。该hideKeyboard方法只有当触摸已经UITableViewCell类,外执行将被调用。

- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch {
    if([touch.view isKindOfClass:[UITableViewCell class]]) {
        return NO;
    }
    // UITableViewCellContentView => UITableViewCell
    if([touch.view.superview isKindOfClass:[UITableViewCell class]]) {
        return NO;
    }
    // UITableViewCellContentView => UITableViewCellScrollView => UITableViewCell
    if([touch.view.superview.superview isKindOfClass:[UITableViewCell class]]) {
        return NO;
    }
    return YES; // handle the touch
}

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

2

UITableView具有一个方便的backgroundView属性,通过它我可以实现此行为而不会影响单元格选择,如以下Swift中所示:

let tableBackTapRecognizer = UITapGestureRecognizer(target: self, action: #selector(hideKeyboard))
tableView.backgroundView = UIView()
tableView.backgroundView?.addGestureRecognizer(tableBackTapRecognizer)


1

只需使用UITapGestureRecognizer并cancelsTouchesInView = NO意味着点击单元格和UITextViews也会触发隐藏。如果您有多个UITextView,然后单击下一个,则这很不好。键盘将开始隐藏,然后下一个textView成为firstResponder,并且键盘将再次变为可见。为避免这种情况,请检查轻敲位置,仅在轻敲不在单元格上时才隐藏键盘:

// init
UITapGestureRecognizer *tapRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(didTapTableView:)];
tapRecognizer.cancelsTouchesInView = NO;
[self.tableView addGestureRecognizer:tapRecognizer];


// Hide on tap
- (void)didTapTableView:(UITapGestureRecognizer *)tap
{
    CGPoint point = [tap locationInView:tap.view];
    [self.view endEditing:!CGRectContainsPoint([self.tableView rectForRowAtIndexPath:[self.tableView indexPathForRowAtPoint:point]], point)];
}

为了scrollViewWillBeginDragging:被触发,tableView的scrollEnabled属性必须是YES

// Hide on scroll
- (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView
{
    [self.view endEditing:YES];
}

适合我。在表视图单元格中添加了一个texbox;如果我在键盘外触摸则解雇
Nicola

0

为什么要创建一个充满文本字段的表?您应该为包含文本字段的每一行使用详细视图。按下详细视图时,请确保调用“ [myTextField成为FirstResponder]”,以便用户只需单击表列表即可一开始进行编辑。


苹果的通讯录应用程序正是这样做的。我不会说它本身充满了文本字段,但是它确实使用了它们,效果很好。
乔·安德里亚

2
在表格视图中内联编辑文本比为用户要编辑的每个文本字段推送详细信息视图更快,更直观……只问您最近的HTML表单,iPhone首选项窗格或“联系人”应用程序中的文本字段,或者等等等等……真让人感到遗憾的是,Apple并未将其设置为标准单元类型,但是网络上有很多有关实现此目标的信息。
glenc 2010年

0

如果你愿意的子类(啊!)你的表视图,这样的事情可能工作:

- (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

如果要在按下返回键的同时关闭键盘,则只需在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

许多有趣的答案。我想在我认为最适合UITableView方案的解决方案中使用不同的方法(这是我通常使用的方案):通常,我们通常希望在两种情况下隐藏键盘:在Text UI元素外部点击,或向下/向上滚动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];

    }

此方法可对UITableView视图层次结构内的子视图的任何textField UI进行辞职,因此比独立地对每个元素进行辞职更实用。

接下来,我们将通过外部的Tap手势来消除,具体如下:

- (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是为了避免gestureRecognizer覆盖UITableView的正常内部工作(例如,不干扰单元格选择)。

最后,要在向上/向下滚动UITableView时隐藏键盘,我们必须实现UIScrollViewDelegate协议scrollViewWillBeginDragging:方法,如下所示:

.h文件

@interface MyViewController : UIViewController <UIScrollViewDelegate>

.m文件

#pragma mark - UIScrollViewDelegate

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

希望对您有所帮助!=)


0

这就是我最终制作作品的方式。我结合了来自不同答案的建议和代码。功能:消除键盘,在编辑和设置“下一步”和“完成”键盘返回类型时移动键盘上方的文本字段。替换带有更多字段的“ ...”

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

@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

斯威夫特4 / 4.2 / 5

您也可以在轻按单元格时关闭键盘-在执行其他操作之前。

    override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
    view.endEditing(true)
    // Do something here
    }

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.