ios - uitextfield鍵盤擋住 - swift隱藏鍵盤




iOS-在觸摸UITextField外部時關閉鍵盤 (20)

我想知道如何在用戶觸摸到UITextField之外時使鍵盤消失。


這工作

在這個例子中,aTextField是唯一的UITextField ....如果有其他人或UITextViews,還有很多事情要做。

// YourViewController.h
// ...
@interface YourViewController : UIViewController /* some subclass of UIViewController */ <UITextFieldDelegate> // <-- add this protocol
// ...
@end

// YourViewController.m

@interface YourViewController ()
@property (nonatomic, strong, readonly) UITapGestureRecognizer *singleTapRecognizer;
@end
// ...

@implementation
@synthesize singleTapRecognizer = _singleTapRecognizer;
// ...

- (void)viewDidLoad
{
    [super viewDidLoad];
    // your other init code here
    [self.view addGestureRecognizer:self.singleTapRecognizer];

{

- (UITapGestureRecognizer *)singleTapRecognizer
{
    if (nil == _singleTapRecognizer) {
        _singleTapRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(singleTapToDismissKeyboard:)];
        _singleTapRecognizer.cancelsTouchesInView = NO; // absolutely required, otherwise "tap" eats events.
    }
    return _singleTapRecognizer;
}

// Something inside this VC's view was tapped (except the navbar/toolbar)
- (void)singleTapToDismissKeyboard:(UITapGestureRecognizer *)sender
{
    NSLog(@"singleTap");
    [self hideKeyboard:sender];
}

// When the "Return" key is pressed on the on-screen keyboard, hide the keyboard.
// for protocol UITextFieldDelegate
- (BOOL)textFieldShouldReturn:(UITextField*)textField
{
    NSLog(@"Return pressed");
    [self hideKeyboard:textField];
    return YES;
}

- (IBAction)hideKeyboard:(id)sender
{
    // Just call resignFirstResponder on all UITextFields and UITextViews in this VC
    // Why? Because it works and checking which one was last active gets messy.
    [aTextField resignFirstResponder];
    NSLog(@"keyboard hidden");
}

@ Jensen2k的答案的快速版本:

let gestureRecognizer : UITapGestureRecognizer = UITapGestureRecognizer.init(target: self, action: "dismissKeyboard")
self.view.addGestureRecognizer(gestureRecognizer)

func dismissKeyboard() {
    aTextField.resignFirstResponder()
}

一個班輪

self.view.addTapGesture(UITapGestureRecognizer.init(target: self, action: "endEditing:"))

斯威夫特4

例如在viewDidLoad使用這個擴展方法設置你的UIViewController

override func viewDidLoad() {
    super.viewDidLoad()
    self.setupHideKeyboardOnTap()
}

即使點擊NavigationBar ,鍵盤也將被解除。

import UIKit
extension UIViewController {
    /// Call this once to dismiss open keyboards by tapping anywhere in the view controller
    func setupHideKeyboardOnTap() {
        self.view.addGestureRecognizer(self.endEditingRecognizer())
        self.navigationController?.navigationBar.addGestureRecognizer(self.endEditingRecognizer())
    }

    /// Dismisses the keyboard from self.view
    private func endEditingRecognizer() -> UIGestureRecognizer {
        let tap = UITapGestureRecognizer(target: self.view, action: #selector(self.view.endEditing(_:)))
        tap.cancelsTouchesInView = false
        return tap
    }
}

只是在這裡添加我的版本,如何在外部觸摸上解除鍵盤。

viewDidLoad中:

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

任何地方:

-(void)handleSingleTap:(UITapGestureRecognizer *)sender{
    [textFieldName resignFirstResponder];
    puts("Dismissed the keyboard");
}

如果我有你的權利,你想要辭職鍵盤wile輕拍在textfield正面,但你沒有參考你的textfield框。

嘗試這個;

  • 以全局textField為例,我們稱它為reftextField
  • 現在在textFieldDidBeginEditing設置引用文本字段為

    - (void) textFieldDidBeginEditing:(UITextField *)textField{
        reftextField = textField;
    }
    
  • 現在你可以愉快地使用任何按鈕時鐘,(在開始編輯推薦時增加一個透明按鈕)

    - (void)dismissKeyboard {
          [reftextField resignFirstResponder];
    }
    
  • 或者為了完成按鈕嘗試這個。

    //for resigning on done button    
    - (BOOL) textFieldShouldReturn:(UITextField *)textField{
        [textField resignFirstResponder];
        return YES;
    }
    

如果視圖完全嵌入到UIScrollView那麼您可以使用以下方法:

tableView.keyboardDismissMode = UIScrollViewKeyboardDismissModeOnDrag;
tableView.keyboardDismissMode = UIScrollViewKeyboardDismissModeInteractive;

當桌面視圖滾動時,前者將使鍵盤脫離屏幕動畫,而後者將像股票消息應用程序一樣隱藏鍵盤。

請注意,這些都可在iOS 7.0或更高版本上使用。


將消息resignFirstResponder發送到放置在那裡的文本文件。 請參閱此帖以獲取更多信息。


對於那些在Swift中掙扎的人。 這是Jensen2k接受的答案,但在Swift中。

Swift 2.3

    override func viewDidLoad() {
        //.....

        let viewTapGestureRec = UITapGestureRecognizer(target: self, action: #selector(handleViewTap(_:)))
        //this line is important
        viewTapGestureRec.cancelsTouchesInView = false
        self.view.addGestureRecognizer(viewTapGestureRec)

         //.....
    }

    func handleViewTap(recognizer: UIGestureRecognizer) {
        myTextField.resignFirstResponder()
    }

您可以使用XCode 6及更高版本中的Storyboard進行此操作:


創建隱藏鍵盤的操作

將此添加到您的ViewController使用的類的頭文件中:

@interface TimeDelayViewController : UIViewController <UITextFieldDelegate>

- (IBAction)dissmissKeyboardOnTap:(id)sender;

@end

然後將其添加到相同ViewController的實現文件中:

- (IBAction)dissmissKeyboardOnTap:(id)sender{
    [[self view]endEditing:YES];
}

這將成為您的故事板場景(即ViewController)的“已收到操作”之一:


將操作連接到用戶事件

現在您需要將此操作連接到觸摸鍵盤的用戶手勢。

重要 - 您需要將故事板中包含的'UIView'轉換為UIControl ,以便它可以接收事件。 從View Controller Scene層次結構中選擇視圖:

...並改變它的類:

現在從您的場景的“接收動作”旁邊的小圓圈拖動到場景的“空白”部分(實際上是將'接收的動作'拖動到UIControl中)。 您將看到一系列活動,您可以將活動與以下內容聯繫起來:

選擇'修改裡面'選項。 您現在已將您創建的IBAction掛接到觸摸鍵盤的用戶操作。 當用戶點擊鍵盤時,它現在將被隱藏。

(注意:要將操作掛鉤到事件,您還可以將接收到的操作直接拖到View Controller層次結構中的UIControl中,它在層次結構中顯示為“Control”。)


您可以創建UiView的類別並覆蓋touchesBegan meathod,如下所示。

它對我來說工作得很好,而且它正在集中解決這個問題。

#import "UIView+Keyboard.h"
@implementation UIView(Keyboard)

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
    [self.window endEditing:true];
    [super touchesBegan:touches withEvent:event];
}
@end

我使用巴里的例子來進行我的新開發。 它效果很好! 但是我不得不稍微改變一下,只有在編輯的文本字段時才需要關閉鍵盤。

所以,我給巴里添加了以下例子:

- (void) textFieldDidBeginEditing:(UITextField *)textField
{
    _textBeingEdited = textField;
}
-(void) textFieldDidEndEditing:(UITextField *)textField
{
    _textBeingEdited = nil;
}

另外,我更改hideKeyboard方法如下:

- (IBAction)hideKeyboard:(id)sender
{
    // Just call resignFirstResponder on all UITextFields and UITextViews in this VC
    // Why? Because it works and checking which one was last active gets messy.
    //UITextField * tf = (UITextField *) sender;
    [_textBeingEdited resignFirstResponder];
}

我在這裡嘗試了很多回應,沒有運氣。 點擊時,我的輕擊手勢識別器總是導致我的UIButtons不響應,即使我將手勢識別器的cancelsTouchesInView屬性設置為NO。

這是最終解決問題的方法:

有一個伊娃:

UITapGestureRecognizer *_keyboardDismissGestureRecognizer;

當文本字段開始編輯時,設置手勢識別器:

- (void) textFieldDidBeginEditing:(UITextField *)textField
{
    if(_keyboardDismissGestureRecognizer == nil)
    {
        _keyboardDismissGestureRecognizer = [[[UITapGestureRecognizer alloc]
                                       initWithTarget:self
                                       action:@selector(dismissKeyboard)] autorelease];
        _keyboardDismissGestureRecognizer.cancelsTouchesInView = NO;

        [self.view addGestureRecognizer:_keyboardDismissGestureRecognizer];
    }
}

然後訣竅在於如何設置dismissKeyboard方法:

- (void) dismissKeyboard
{
    [self performSelector:@selector(dismissKeyboardSelector) withObject:nil afterDelay:0.01];
}

- (void) dismissKeyboardSelector
{
    [self.view endEditing:YES];

    [self.view removeGestureRecognizer:_keyboardDismissGestureRecognizer];
    _keyboardDismissGestureRecognizer = nil;
}

我想只有一些關於讓dismissKeyboardSelector執行脫離觸摸處理執行堆棧的事情......


我發現有些人在使用UITapGestureRecognizer方法時遇到了問題。 在完成此功能的同時,仍保留現有按鈕的抽頭行為的最簡單方法是在@ Jensen2k的答案中只添加一行:

[tap setCancelsTouchesInView:NO];

這讓我現有的按鈕仍然可以使用@Dmitry Sitnikov的方法。

在這裡閱讀有關該property (搜索CancelsTouchesInView ): UIGestureRecognizer類參考

我不確定它是如何與滾動條一起工作的,因為我看到一些問題,但希望其他人可能遇到同樣的情況。


我認為做到這一點最簡單(也是最好)的方法是對全局視圖進行子類化,並使用hitTest:withEvent方法來偵聽任何觸摸。 在鍵盤上觸摸沒有註冊,所以hitTest:withEvent只有當你觸摸/滾動/刷卡/捏...在其他地方,然後調用[self endEditing:YES]調用。

這比使用touchesBegan更好touchesBegan因為如果點擊視圖頂部的按鈕, touchesBegan不會被調用。 例如,它比UITapGestureRecognizer更好,它無法識別滾動手勢。 它比使用昏暗的屏幕更好,因為在復雜和動態的用戶界面中,無法將黯淡的屏幕放在任何地方。 此外,它不會阻止其他操作,您不需要點擊兩次以選擇外部按鈕(例如在UIPopover的情況下)。

另外,它比調用[textField resignFirstResponder] ,因為屏幕上可能有很多文本字段,所以這對所有的字符都適用。


最簡單和最短的方法之一是將此代碼添加到您的viewDidLoad

[self.view addGestureRecognizer:[[UITapGestureRecognizer alloc]
                                     initWithTarget:self.view
                                     action:@selector(endEditing:)]];

檢查一下,這將是最簡單的方法,

-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event{
      [self.view endEditing:YES];// this will do the trick
}

要么

這個庫將處理包括滾動條自動滾動,點擊空間來隱藏鍵盤等...

https://github.com/michaeltyson/TPKeyboardAvoiding



這是一個很好的通用解決方案:

Objective-C的:

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

迅速:

override func touchesBegan(touches: NSSet, withEvent event: UIEvent) {
    self.view.endEditing(true)
}

基於@icodebuster解決方案: https://.com/a/18756253/417652 ://.com/a/18756253/417652


- (void)viewDidLoad
{
    [super viewDidLoad]; 

UITapGestureRecognizer *singleTapGestureRecognizer = [[UITapGestureRecognizer alloc]
                                                          initWithTarget:self
                                                          action:@selector(handleSingleTap:)];
    [singleTapGestureRecognizer setNumberOfTapsRequired:1];
    [singleTapGestureRecognizer requireGestureRecognizerToFail:singleTapGestureRecognizer];

    [self.view addGestureRecognizer:singleTapGestureRecognizer];
}

- (void)handleSingleTap:(UITapGestureRecognizer *)recognizer
{
    [self.view endEditing:YES];
    [textField resignFirstResponder];
    [scrollView setContentOffset:CGPointMake(0, -40) animated:YES];

}

override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {

    if let touch = touches.first{
     view.endEditing(true)

     }
}






uikit