用户点击文本域外的其他区域时如何关闭键盘?

时间:2013-09-12 05:42:03

标签: ios objective-c

今天我尝试在我的iPod(iOS 6.1.3)上运行我的代码,我在这里找到了一些有趣的东西......

首先,当我点击文本字段时,键盘会显示,但当我点击文本字段外的其他位置时,它不会隐藏。

所以我决定使用谷歌搜索并找到了这个解决方案:

_fieldEmail.delegate = self;
_fieldEmail.returnKeyType = UIReturnKeyDone;

_fieldPassword.delegate = self;
_fieldPassword.returnKeyType = UIReturnKeyDone;

_fieldRegisterName.delegate = self;
_fieldRegisterName.returnKeyType = UIReturnKeyDone;

_fieldRegisterEmail.delegate = self;
_fieldRegisterEmail.returnKeyType = UIReturnKeyDone;

_fieldRegisterPassword.delegate = self;
_fieldRegisterPassword.returnKeyType = UIReturnKeyDone;

它有效...它给了一个“完成”'键盘底部的按钮,现在可以通过按键隐藏键盘。

但我在这里有两个问题:

  1. 键盘只有在“完成”时才会隐藏'按钮被点击。不要通过点击文本字段之外的其他区域。我不知道iOS世界是否正常,但通常我看到很多应用都不会这样做。
  2. 有没有办法循环这个过程,所以我没有手动添加该委托逐个我所拥有的文本字段?该怎么做?
  3. 我需要知道的全部

14 个答案:

答案 0 :(得分:82)

以下代码适用于UIView中所有UITextField

的所有组件
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
    for (UIView * txt in self.view.subviews){
        if ([txt isKindOfClass:[UITextField class]] && [txt isFirstResponder]) {
            [txt resignFirstResponder];
        }
    }
}

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

答案 1 :(得分:30)

  1. 只需在您的视图中添加UITapGestureRecogniser即可调用resignFirstResponder
  2. 在viewDidLoad中:

    UITapGestureRecognizer * tapGesture = [[UITapGestureRecognizer alloc] 
                                       initWithTarget:self
                                       action:@selector(hideKeyBoard)];
    
    [self.view addGestureRecognizer:tapGesture];
    

    然后:

    -(void)hideKeyBoard {
           [yourTextField resignFirstResponder];
    }
    

    2.你可以继承UITextField,但除非你有1000个textFields,否则你可以像现在这样做。

答案 2 :(得分:19)

这是针对Xcode 6.0.1的 Swift 编程

override func viewDidAppear(animated: Bool) {
    super.viewDidAppear(animated)

    let tapRecognizer = UITapGestureRecognizer(target: self, action: "handleSingleTap:")
    tapRecognizer.numberOfTapsRequired = 1
    self.view.addGestureRecognizer(tapRecognizer)
}

func handleSingleTap(recognizer: UITapGestureRecognizer) {
    self.view.endEditing(true)
}

答案 3 :(得分:7)

使用

UITapGestureRecognizer *singleTap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(handleSingleTap:)];
[self.view addGestureRecognizer:singleTap];

和方法代码

-(void)handleSingleTap:(UITapGestureRecognizer *)sender{
    [self.TextFiledName resignFirstResponder];

}

或_和最好的其他选项是

添加

  [self.view endEditing:YES];

当您从视图中点击任何位置时,键盘将隐藏:)

答案 4 :(得分:7)

关闭键盘

<plugin>
    <groupId>org.codehaus.mojo</groupId>
    <artifactId>aspectj-maven-plugin</artifactId>
    <artifactId>1.5</artifactId>
    <configuration>
          <Xlint>adviceDidNotMatch=error,noGuardForLazyTjp=ignore</Xlint>
    </configuration>
</plugin>

答案 5 :(得分:3)

我通常做的是致电

[field resignFirstResponder]; 
从视图上的隐形按钮

。我确信这是一个更好的方法。自从我在应用程序中完成此操作已经有一段时间了。

答案 6 :(得分:2)

简单,

使用IQKeyboardManager并将此行代码放在AppDelegate.m

[[IQKeyboardManager sharedManager] setShouldResignOnTouchOutside:YES];

答案 7 :(得分:1)

我是这样做的:

在myView的.h文件中:

@property (strong) UITextField * savedTextField;

在myView的.m文件中:

@implementation myView

@synthesize savedTextField;

在myView的init例程中:

[self setSavedTextField: nil];

在myView的textField委托区域中,我保存了当前正在激活的textField的id:

- (BOOL) textFieldShouldBeginEditing: (UITextField *) textField
   {
   [self setSavedTextField: textField];
   .
   .
   .
   return( YES );
   }

在myView的例程中,当访问其他控件时路由所有流量时,我有代码查看textField是否处于活动状态,如果是,则调用它来重新签名其FirstResponder状态和然后将一个nil放入savedTextField属性:

- (void) handleCtrlEvents: (UIControl *) aCtrl
  {
  if ( [self savedTextField] != nil )
     {
     [[self savedTextField] resignFirstResponder];
     [self setSavedTextField: nil];
     }
  .
  .
  .
  }

这对我来说很干净。

答案 8 :(得分:1)

我遇到了完全相同的问题。通常你想要的是,无论你在你的应用程序中点击什么(显示在你的主/当前UIView中),而不是在键盘上关闭它。在网上搜索智能解决方案并测试几个之后,我认为最好扩展/子类化/实现UIGestureRecognizerDelegate

由于许多控件(如UITableView等)都可以响应手势(选择,滚动等),如果您只是将UITapGestureRecognizer添加到整个(主 - )ViewController的视图来关闭键盘,那么用户体验并不是最好的因为如果用户不打算关闭键盘,例如,用户需要点击两次从App的当前“主”视图中的UITableView中选择一行。

由于我对整个iOS都很陌生,并且 swift code 示例很少见,所以这是我的全键盘控制剪切:

class ViewController: UIViewController, UIGestureRecognizerDelegate {

override func viewDidLoad(){
     self.initializeCloseKeyboardTap()
}

func initializeCloseKeyboardTap() {

    NSNotificationCenter.defaultCenter().addObserver(self, selector: "onKeyboardOpen:", name: UIKeyboardDidShowNotification, object: nil)

    NSNotificationCenter.defaultCenter().addObserver(self, selector: "onKeyboardClose:", name: UIKeyboardDidHideNotification, object: nil)
    let tapRecognizer = UITapGestureRecognizer(target: self, action: "handleOnTapAnywhereButKeyboard:")
    tapRecognizer.delegate = self //delegate event notifications to this class
    self.view.addGestureRecognizer(tapRecognizer)

}


func onKeyboardClose(notification: NSNotification) {
    println("keyboardClosed")
}

func onKeyboardOpen(notification: NSNotification) {
    println("keyboardOpen")
}

func gestureRecognizer(gestureRecognizer: UIGestureRecognizer, shouldReceiveTouch touch: UITouch) -> Bool {
    self.view.endEditing(true)
    return false
}

您可以将它嵌套在ViewController中并在viewDidLoad实现中调用initiallizeCloseKeyboardTa()...它还实现了一个规范观察器,以便在通过NSNotificationCenter UIKeyboardDidShowNotification和UIKeyboardDidHideNotification打开或关闭键盘(完成)时接收事件

希望拯救其他人一段时间: - )

答案 9 :(得分:1)

| * |解雇UITextField的键盘:覆盖方法touchesBegan:withEvent:for ViewController

override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?)
{
    view.endEditing(true)
    super.touchesBegan(touches, withEvent: event)
}

|或|

override func viewDidLoad()
{
    super.viewDidLoad()
// For tapping outside text box
    self.view.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(DismisKeyPadFnc)))
}

// For tapping outside text box
func DismisKeyPadFnc()
{
    view.endEditing(true)
}

| * |在induvidual文本框中关闭UITextField的键盘:

class NamVcc: UIViewController, UITextFieldDelegate
{
    @IBOutlet var NamTxtBoxVid: UITextField!

    override func viewDidLoad()
    {
        super.viewDidLoad()

    // For hitting return key
        NamTxtBoxVid.delegate = self

    // For tapping outside text box
        self.view.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(DismisKeyPadFnc)))
    }

/* For hitting return key */
    func textFieldShouldReturn(NamTxtBoxPsgVid: UITextField) -> Bool
    {
        NamTxtBoxPsgVid.resignFirstResponder()
        return true
    }

/* For tapping outside text box */
    func DismisKeyPadFnc()
    {
        view.endEditing(true)
    }
}


| * |实现下一步按钮单击:
1)您需要在xib / Storyboard或代码中的文本字段的增量序列中设置标记。
2)为每个文本字段设置代理 3)然后将以下代码粘贴到视图控制器中以获得所需的效果:

func textFieldShouldReturn(TxtBoxPsgVar: UITextField) -> Bool
{
    let NxtTxtBoxTagVal : Int = TxtBoxPsgVar.tag + 1

    let NxtTxtBoxVal: UIResponder? = TxtBoxPsgVar.superview?.superview?.viewWithTag(NxtTxtBoxTagVal)

    if let TxtBoxVal = NxtTxtBoxVal
    {
        // Found next responder, so set it.
        TxtBoxVal.becomeFirstResponder()
    }
    else
    {
        // Not found, so remove keyboard.
        TxtBoxPsgVar.resignFirstResponder()
    }
    return true
}

答案 10 :(得分:0)

我认为

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

方便但不是最好的解决方案。 而TapGestureRecongnizer更好但难以使用,您必须设置委托并添加和删除Recongnizer。 所以我写了一个简单的子类,可以很容易地使用:

class TapHideTextField: UITextField {
override func awakeFromNib() {
    super.awakeFromNib()
    tapGr = UITapGestureRecognizer(target: self, action:"tap")
    NSNotificationCenter.defaultCenter().addObserver(self, selector: "didBeginEditing", name:UITextFieldTextDidBeginEditingNotification, object: nil)
    NSNotificationCenter.defaultCenter().addObserver(self, selector: "didEndEditing", name:UITextFieldTextDidEndEditingNotification, object: nil)

}

deinit{
    NSNotificationCenter.defaultCenter().removeObserver(self)
}

var tapGr:UITapGestureRecognizer!
func tap(){
    self.endEditing(true)
}

func didBeginEditing(){
    self.superview!.addGestureRecognizer(tapGr)
}


func didEndEditing(){
    self.superview!.removeGestureRecognizer(tapGr)
}

}

你应该关注superview和cancelTouchesInView属性。

或在GitHub中:https://github.com/lilidan/TapHideText/blob/master/TapHideTextField.swift

答案 11 :(得分:0)

如果您使用的是滚动视图(或表视图)控制器,请在此处添加以下行:

    override func scrollViewWillBeginDragging(_ scrollView: UIScrollView) {
        view.endEditing(true)
    }

答案 12 :(得分:0)

我更喜欢IQKeyboardManager。您可以在任何状态下简单地处理键盘。要激活IQKeyboard,只需在AppDelegate中添加一行,然后在外部触摸屏上关闭键盘,如下所示,添加代码

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {

  IQKeyboardManager.shared.enable = true
  IQKeyboardManager.shared.shouldResignOnTouchOutside = true

  return true
}

答案 13 :(得分:-1)

-(void) textFieldDidBeginEditing: (UITextField *) textField{
     [self.view addGestureRecognizer:[[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(DismissKeyboard:)]];
}

-(void) DismissKeyboard:(UITapGestureRecognizer *) sender{
    [self.view endEditing:YES];
    [self.view removeGestureRecognizer:sender];
}