ios आईओएस-UITextField के बाहर छूते समय कीबोर्ड को खारिज करें




cocoa-touch uikit (24)

@ जेन्सेन 2 के उत्तर का स्विफ्ट संस्करण:

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:"))

मैं सोच रहा हूं कि जब उपयोगकर्ता UITextField बाहर छूता है तो कुंजीपटल गायब हो जाता है।


इसके बारे में: मुझे पता है कि यह एक पुरानी पोस्ट है। यह किसी की मदद कर सकता है :)

- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {  
    NSArray *subviews = [self.view subviews];
    for (id objects in subviews) {
        if ([objects isKindOfClass:[UITextField class]]) {
            UITextField *theTextField = objects;
            if ([objects isFirstResponder]) {
                [theTextField resignFirstResponder];
            }
        } 
    }
}

आप XCode 6 और ऊपर के स्टोरीबोर्ड का उपयोग करके ऐसा कर सकते हैं:


कीबोर्ड छुपाने के लिए कार्रवाई बनाएँ

इसे अपने ViewController द्वारा उपयोग की जाने वाली कक्षा की शीर्षलेख फ़ाइल में जोड़ें:

@interface TimeDelayViewController : UIViewController <UITextFieldDelegate>

- (IBAction)dissmissKeyboardOnTap:(id)sender;

@end

फिर इसे उसी व्यू कंट्रोलर की कार्यान्वयन फ़ाइल में जोड़ें:

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

यह अब आपके स्टोरीबोर्ड दृश्य (यानी व्यू कंट्रोलर) के लिए 'प्राप्त क्रियाएं' में से एक होगा:


उपयोगकर्ता घटना के लिए कार्रवाई को हुक अप करें

अब आपको कीबोर्ड को छूने के उपयोगकर्ता इशारे पर इस क्रिया को हुक करने की आवश्यकता है।

महत्वपूर्ण - आपको 'UIView' को परिवर्तित करना होगा जो आपके स्टोरीबोर्ड में यूआईसींट्रोल में निहित है , इसलिए यह ईवेंट प्राप्त कर सकता है। अपने व्यू कंट्रोलर सीन पदानुक्रम से दृश्य का चयन करें:

... और अपनी कक्षा बदलो:

अब अपने दृश्य के 'खाली' भाग पर, अपने दृश्य के 'प्राप्त कार्रवाई' के बगल में छोटे सर्कल से खींचें (वास्तव में आप 'प्राप्त कार्रवाई' को यूआईसींट्रोल में खींच रहे हैं)। आपको उन कार्यक्रमों का चयन दिखाया जाएगा जिन्हें आप अपनी क्रिया को जोड़ सकते हैं:

'अंदर स्पर्श करें' विकल्प का चयन करें। अब आपने कीबोर्ड को छूने के उपयोगकर्ता क्रिया में बनाए गए IBAction को झुका दिया है। जब उपयोगकर्ता कुंजीपटल को बंद कर देता है, तो अब यह छिपा होगा।

(नोट: ईवेंट में कार्रवाई को हुक करने के लिए, आप प्राप्त दृश्य से सीधे अपने व्यू कंट्रोलर पदानुक्रम में यूआईसींट्रोल पर भी खींच सकते हैं। इसे पदानुक्रम में 'नियंत्रण' के रूप में प्रदर्शित किया जाता है।)


संदेश resignFirstResponder भेजें resignFirstResponder पर जो इसे वहां रखता है। अधिक जानकारी के लिए कृपया इस पोस्ट को देखें।


  • दृश्य फ़ील्ड प्रतिनिधि को दृश्य में सेट करें लोड किया गया था:

    override func viewDidLoad() 
    {
      super.viewDidLoad()
      self.userText.delegate = self
    }
    
  • यह फ़ंक्शन जोड़ें:

    func textFieldShouldReturn(userText: UITextField!) -> Bool 
    {
     userText.resignFirstResponder()
     return true;
    }
    

यह काम

इस उदाहरण में, 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");
}

इस मामले में, स्क्रॉलव्यू का उपयोग किया जा सकता है और TextField में TextField में जोड़ा जा सकता है और मैं ScrollView टैप करना चाहता हूं और फिर कीबोर्ड को ScrollView करना चाहता हूं। मैंने बस मामले में नमूना कोड बनाने की कोशिश की। इस कदर,

import UIKit

class ViewController: UIViewController {

    @IBOutlet weak var scrollView: UIScrollView!
    @IBOutlet weak var textField: UITextField!

    override func viewDidLoad() {
        super.viewDidLoad()

        let tapGesture = UITapGestureRecognizer(target: self, action: #selector(ViewController.tap(_:)))
        view.addGestureRecognizer(tapGesture)
        // Do any additional setup after loading the view, typically from a nib.
    }
    func tap(gesture: UITapGestureRecognizer) {
        textField.resignFirstResponder()
    }
    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }
}

आपकी स्टोरीबोर्ड उस जस्ट लाइक को देखो।


UITapGestureRecognizer का उपयोग करने के बारे में बहुत सारे महान उत्तर - जिनमें से UITextField के स्पष्ट (एक्स) बटन को तोड़ता है। समाधान अपने प्रतिनिधि के माध्यम से इशारा पहचानकर्ता को दबाने के लिए है:

- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch {
    BOOL touchViewIsButton = [touch.view isKindOfClass:[UIButton class]];
    BOOL touchSuperviewIsTextField = [[touch.view superview] isKindOfClass:[UITextField class]];
    return !(touchViewIsButton && touchSuperviewIsTextField);
}

यह सबसे मजबूत समाधान नहीं है लेकिन यह मेरे लिए काम करता है।


मैंने यहां कई प्रतिक्रियाओं की कोशिश की और कोई भाग्य नहीं था। मेरा टैप इशारा पहचानकर्ता हमेशा मेरे UIButtons को टैप किए जाने पर प्रतिक्रिया देने का कारण नहीं बना रहा था, भले ही मैंने इशारा पहचानकर्ता की संख्या को रद्द कर दिया हो।

आखिरकार इस मुद्दे को हल किया गया:

एक ivar है:

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];
    }
}

फिर यह चाल है कि आपने कैसे खारिज की स्थापना की हैबोर्ड विधि:

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

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

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

मुझे लगता है कि टच हैंडलिंग निष्पादन स्टैक से बाहर निकलने के लिए बसबोर्डबोर्ड चयनकर्ता निष्पादन प्राप्त करने के बारे में कुछ है ...


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

}

मैं देखता हूं कि कुछ लोगों को UITapGestureRecognizer विधि का उपयोग कर समस्याएं आ रही हैं। मेरे मौजूदा बटन के टैप व्यवहार को बरकरार रखते हुए मैंने इस कार्यक्षमता को पूरा करने का सबसे आसान तरीका @ जेन्सेन 2 के उत्तर में केवल एक पंक्ति जोड़ रहा है:

[tap setCancelsTouchesInView:NO];

इसने मेरे मौजूदा बटन को अभी भी @Dmitry Sitnikov की विधि के बिना काम करने की अनुमति दी है।

उस property बारे में यहां पढ़ें ( CancelsTouchesInView लिए CancelsTouchesInView ): UIGestureRecognizer क्लास संदर्भ

मुझे यकीन नहीं है कि यह स्क्रॉलबार के साथ कैसे काम करेगा, क्योंकि मुझे लगता है कि कुछ के साथ समस्याएं थीं, लेकिन उम्मीद है कि कोई और मेरे पास उसी परिदृश्य में भाग सकता है।


आप UiView के लिए श्रेणी बना सकते हैं और निम्नानुसार बेगन मेथोड को छू सकते हैं।

यह मेरे लिए ठीक काम कर रहा है। और यह इस समस्या के लिए केंद्रीकृत समाधान है।

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

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

इस कोड को अपनी ViewController.m फ़ाइल में जोड़ें:

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

इसे जांचें, ऐसा करने का यह सबसे आसान तरीका होगा,

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

या

यह लाइब्रेरी स्क्रॉलबार ऑटो स्क्रॉलिंग, कीबोर्ड को छुपाने के लिए स्पेस इत्यादि सहित संभाल लेगी ...

https://github.com/michaeltyson/TPKeyboardAvoiding


अपने UIView को UIControl (इंटरफ़ेस बिल्डर में) का एक उदाहरण बनाना बेहतर है और फिर अपने TouchUpInside ईवेंट dismissKeyboard विधि को dismissKeyboard करने के लिए कनेक्ट करें। यह IBAction विधि इस तरह IBAction :

- (IBAction)dismissKeyboard:(id)sender {
    [aTextBox resignFirstResponder];
}

स्विफ्ट में इसके साथ संघर्ष करने वालों के लिए। यह जेन्सेन 2k लेकिन स्विफ्ट में स्वीकार्य उत्तर है।

स्विफ्ट 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()
    }

आप UITextField के बाहर क्लिक करके कीबोर्ड को खारिज करने के लिए UITapGestureRecongnizer विधि का उपयोग कर सकते हैं। इस विधि का उपयोग करके जब भी उपयोगकर्ता UITextField के बाहर क्लिक करेगा तो कीबोर्ड खारिज हो जाएगा। इसका उपयोग करने के लिए नीचे कोड स्निपेट है।

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

    [self.view addGestureRecognizer:tap];


//Method
- (void) dismissk
{
    [abctextfield resignFirstResponder];
    [deftextfield resignFirstResponder];

}

मैंने अपने नए विकास के लिए बैरी उदाहरण का इस्तेमाल किया। यह बहुत अच्छा काम किया! लेकिन मुझे थोड़ा बदलाव करना पड़ा, केवल टेक्स्टफील्ड को संपादित करने के लिए कीबोर्ड को खारिज करने की आवश्यकता थी।

तो, मैंने बैरी उदाहरण को निम्नलिखित में जोड़ा:

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

इसके अलावा, मैंने छुपायाबोर्ड विधि को निम्नानुसार बदल दिया:

- (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];
}

अगर मैं आपको सही समझता हूं तो आप टेक्स्टफील्ड के बाहर कीबोर्ड वाइल टैपिंग को इस्तीफा देना चाहते हैं लेकिन आपके पास अपने टेक्स्टफील्ड का संदर्भ नहीं है।

इसे इस्तेमाल करे;

  • वैश्विक reftextField लें, इसे reftextField कॉल करने 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;
    }
    

मुझे लगता है कि ऐसा करने का सबसे आसान (और सबसे अच्छा) तरीका है अपने वैश्विक दृश्य को उप hitTest:withEvent और hitTest:withEvent उपयोग करना hitTest:withEvent किसी भी स्पर्श को सुनने के लिए विधि विधि के साथ। कीबोर्ड पर टच पंजीकृत नहीं हैं, इसलिए हिटटेस्ट: withEvent केवल तभी कॉल किया जाता है जब आप स्पर्श / स्क्रॉल / स्वाइप / चुटकी ... कहीं और, तो [self endEditing:YES] कॉल करें।

यह touchesBegan का उपयोग करने से बेहतर है touchesBegan touchesBegan हैं यदि आप दृश्य के शीर्ष पर एक बटन पर क्लिक करते हैं तो touchesBegan को बुलाया नहीं जाता है। यह UITapGestureRecognizer से बेहतर है जो उदाहरण के लिए स्क्रॉलिंग इशारा नहीं पहचान सकता है। यह एक मंद स्क्रीन का उपयोग करने से भी बेहतर है क्योंकि एक जटिल और गतिशील उपयोगकर्ता इंटरफ़ेस में, आप हर जगह मंद स्क्रीन नहीं डाल सकते हैं। इसके अलावा, यह अन्य कार्रवाइयों को अवरुद्ध नहीं करता है, आपको बाहर एक बटन का चयन करने के लिए दो बार टैप करने की आवश्यकता नहीं है (जैसे UIPopover के मामले में)।

साथ ही, यह [textField resignFirstResponder] कॉल करने से बेहतर है, क्योंकि आपके पास स्क्रीन पर कई टेक्स्ट फ़ील्ड हो सकते हैं, इसलिए यह उन सभी के लिए काम करता है।


यदि दृश्य UIScrollView में बिल्कुल एम्बेड किया गया है तो आप निम्न का उपयोग कर सकते हैं:

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

जब तालिका दृश्य स्क्रॉल किया जाता है तो पूर्व कीबोर्ड से स्क्रीन को एनिमेट कर देगा और बाद में कीबोर्ड संदेश ऐप जैसे कीबोर्ड को छुपाएगा।

ध्यान दें कि ये आईओएस 7.0 या उससे ऊपर उपलब्ध हैं।


यह एक अच्छा सामान्य समाधान है:

उद्देश्य सी:

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


बाहरी को स्पर्श करके अपने कीबोर्ड को छिपाने का यह सबसे आसान तरीका होना चाहिए:

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

( जब उपयोगकर्ता टेक्स्टफील्ड के बाहर अन्य क्षेत्र को टैप करते हैं तो कीबोर्ड को कैसे खारिज कर सकते हैं? )


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

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

     }
}




uikit