iOS - ปิดคีย์บอร์ดเมื่อสัมผัสด้านนอกของ UITextField


461

UITextFieldฉันสงสัยว่าวิธีที่จะทำให้แป้นพิมพ์หายไปเมื่อผู้ใช้สัมผัสด้านนอกของ


8
มิทรีมีคำตอบที่ถูกต้อง นี่ไม่ใช่ปัญหาท่าทาง - มันเป็นปัญหาของการลาออกจากการตอบกลับครั้งแรก คำตอบของ Dmirty ยังเป็นคำแนะนำที่ Mark, Nutting และ LeMarche แนะนำในการเริ่มต้นพัฒนา iOS 4ตอนที่ 4 หน้า 83
jww

คำตอบ:


760

คุณจะต้องเพิ่มUITapGestureRecogniserและกำหนดให้กับมุมมองจากนั้นโทรลาออกก่อนตอบกลับบนUITextFieldตัวเลือกของมัน

รหัส:

ใน viewDidLoad

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

[self.view addGestureRecognizer:tap];

ใน dismissKeyboard:

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

( aTextFieldฟิลด์ข้อความที่รับผิดชอบคีย์บอร์ด) อยู่ที่ไหน

รุ่นSwift 3ดูเหมือนว่า

let tapGesture = UITapGestureRecognizer(target: self, action: #selector(self.dismissKeyboard (_:)))
self.view.addGestureRecognizer(tapGesture)

สำหรับการปลดคีย์บอร์ด

func dismissKeyboard (_ sender: UITapGestureRecognizer) {
    aTextField.resignFirstResponder()
}

6
มันใช้งานได้ แต่สิ่งที่มันทำคือมันปิดหรือทำให้ปุ่มแถบนำทางไม่สามารถคลิกได้ ดังนั้นมีวิธีแก้ไขปัญหานี้หรือไม่
Parth Bhatt

137
ฉันคิดว่าดีกว่า[aTextField resignFirstResponder]จะเป็น[self.view endEditing:YES];เพราะไม่จำเป็นต้องมีการอ้างอิงไปยังฟิลด์ข้อความและจะทำงานกับฟิลด์ข้อความหลายรายการ
Julian Król

90
โดยไม่ต้องมีการกำหนดวิธีการใด ๆ หนึ่งซับจะเป็น:[self.view addGestureRecognizer:[[UITapGestureRecognizer alloc] initWithTarget:self.view action:@selector(endEditing:)]];
Subhas

8
@ParthBhatt ฉันเพิ่ม[tap setCancelsTouchesInView:NO];ต่อคำตอบของ @qiaoyi; ฉันมีปัญหากับตารางที่ไม่ตอบสนองต่อการเลือกแถว 5 ปีต่อมาฉันหวังว่านี่จะช่วยคนอื่นได้
Tom Howard

7
Swift one-liner: self.view.addGestureRecognizer(UITapGestureRecognizer(target: self.view, action: #selector(UIView.endEditing(_:))))
ความผิดปกติ

176

ฉันบดคำตอบสองสามข้อ

ใช้ ivar ที่เริ่มต้นในระหว่างนั้น viewDidLoad:

UIGestureRecognizer *tapper;

- (void)viewDidLoad
{
    [super viewDidLoad];
    tapper = [[UITapGestureRecognizer alloc]
                initWithTarget:self action:@selector(handleSingleTap:)];
    tapper.cancelsTouchesInView = NO;
    [self.view addGestureRecognizer:tapper];
}

ปิดสิ่งที่เคยแก้ไขในปัจจุบัน:

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

เยี่ยมมากมันใช้งานได้บน UITableView !! มันช่วยวันของฉัน! ในฐานะที่เป็นบันทึกด้านข้างฉันจะใช้ [UITextField เทคโนโลยีการลาออกของผู้ตอบแบบสอบถาม] แทนที่จะเป็น [UIView endEditing:] เพราะฉันมี UITextField มากขึ้นและ endEditing ให้ตำแหน่งการเลื่อนผิดแม้ว่าจะมองเห็น UITextField ใหม่
Dr.Luiji

1
ผิดพลาดเนื่องจากไม่ได้เพิ่ม UITapGestureRecognizer ในมุมมอง!

1
วัตถุประสงค์ของการยกเลิกการสัมผัสมีอะไรบ้างดูที่นี่?
Adam Johns

3
หากคุณไม่เพิ่ม cancelsTouchesInView = false ที่นี่คุณจะไม่สามารถเลือกรายการประเภทอื่นในมุมมองของคุณ การแตะของคุณจะถูกดักจับโดย gestureRecognizer
HalR

104

ตรวจสอบสิ่งนี้เป็นวิธีที่ง่ายที่สุดในการทำเช่นนั้น

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

หรือ

ไลบรารีนี้จะจัดการรวมถึงการเลื่อนอัตโนมัติของ scrollbar, แตะที่ space เพื่อซ่อนคีย์บอร์ด ฯลฯ ...

https://github.com/michaeltyson/TPKeyboardAvoiding


@ Ramesh ใช่มันทำ แต่ไม่ใช่ด้วยวิธีนี้ คุณต้องสร้างคลาสย่อยจาก UITableView และภายในคลาสนั้นใช้เมธอด touchesBegan จากนั้นเรียกใช้เมธอด endEditing มันได้ผล! อย่าลืมตั้งชั้นเรียนสำหรับตารางของคุณในปลายปากกาด้วยชั้นเรียนที่สร้างขึ้นใหม่
Prasad De Zoysa

3
ไม่ซ่อนแป้นพิมพ์เมื่อผู้ใช้สัมผัสกับส่วนควบคุมอื่น ๆ ในมุมมอง เช่นฉันมี UIButton และ UITextField บน UIView ฉันแตะที่ UITextField แล้วแตะที่ปุ่มแป้นพิมพ์ไม่ได้ซ่อนในกรณีนี้
Jacob Dam

2
@JacobDam คุณพูดถูก เป้าหมายคือลาออกจากการตอบกลับเพื่อซ่อนแป้นพิมพ์หากมีสิ่งใดเกิดขึ้นนอก aTextField

88

ฉันเห็นว่าบางคนกำลังมีปัญหาในการใช้UITapGestureRecognizerวิธีการ วิธีที่ง่ายที่สุดที่ฉันใช้งานฟังก์ชั่นนี้ได้ในขณะที่ยังคงพฤติกรรมการกดปุ่มที่มีอยู่ของฉันยังคงอยู่คือการเพิ่มเพียงหนึ่งบรรทัดในคำตอบของ @ Jensen2k:

[tap setCancelsTouchesInView:NO];

สิ่งนี้ทำให้ปุ่มที่มีอยู่ของฉันยังคงทำงานได้โดยไม่ต้องใช้วิธีการของ @Dmitry Sitnikov

อ่านเกี่ยวกับที่propertyนี่ (ค้นหาCancelsTouchesInView): การอ้างอิงระดับ UIGestureRecognizer

ฉันไม่แน่ใจว่ามันจะทำงานอย่างไรกับแถบเลื่อนเนื่องจากฉันเห็นบางอย่างมีปัญหาด้วย แต่หวังว่าจะมีบางคนทำงานในสถานการณ์เดียวกันกับฉัน


3
ฉันต้องการเพิ่มสำหรับผู้ที่มีภาพพื้นหลังที่ด้านหลังของมุมมองโดยใช้UIImageViewเพิ่ม[imageView setUserInteractionEnabled:NO];และคุณ "คลิกผ่าน" มันซึ่งทำให้วิธีนี้ใช้งานได้
Paul Peelen

55

มันจะดีกว่าที่จะทำให้UIViewอินสแตนซ์ของคุณUIControl(ในตัวสร้างส่วนต่อประสาน) จากนั้นเชื่อมต่อTouchUpInsideเหตุการณ์ของพวกเขากับdismissKeyboardวิธีการ IBActionวิธีนี้จะมีลักษณะดังนี้:

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

1
ขอบคุณ! มันใช้งานได้สำหรับฉันและวิธีแก้ปัญหาอื่นไม่ได้ ( UITapGestureRecognizerรบกวนการแตะที่ปุ่มภายในมุมมอง) touchesEndedไม่ได้ทำงานเพราะมีUIScrollViewล้อเล่นกับห่วงโซ่การตอบกลับ).
jlstrecker

1
ใช้งานได้ดี แต่ต้องเพิ่มในสิ่งที่คุณต้องการยกเลิกคีย์บอร์ด มีวิธีให้กล่องข้อความลาออกโดยอัตโนมัติหรือไม่?
Isaac Overacker

4
คุณไม่จำเป็นต้องทำให้ UIView เป็น UIControl ตรวจสอบให้แน่ใจว่า UIView เปิดใช้งานการโต้ตอบกับผู้ใช้แล้ว
Sofi Software LLC

1
@SofiSoftwareLLC ข้อเสนอแนะของคุณไม่ทำงานสำหรับฉัน ฉันต้องทำให้มันเป็น UIControl แม้ว่าจะเปิดใช้งานการโต้ตอบกับผู้ใช้แล้วก็ตาม
สามถ้วย

1
การใช้กระดานเรื่องราวฉันเปลี่ยน UIView เป็น UIControl (ที่ฉันจะเลือกคลาสย่อย UIView ที่ฉันทำไว้) มันใช้งานได้ดี ฉันไม่ได้พบปัญหาใด ๆ iOS8
ToddB

30

สวิฟท์ 4

ตั้งค่าของคุณUIViewControllerด้วยวิธีการขยายนี้หนึ่งครั้งเช่นในviewDidLoad:

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

2
พี่คุณจับมัน !! คำตอบนี้สมบูรณ์แบบและใช้งานได้ดีจริง ๆ ขอบคุณมาก
สนิม

28

รุ่น Swift นี้ทำงานร่วมกับองค์ประกอบอื่น ๆ (เช่นUIButtonหรืออย่างอื่นUITextField):

override func viewDidLoad() {
    super.viewDidLoad()

    let tapper = UITapGestureRecognizer(target: self, action:#selector(endEditing))
    tapper.cancelsTouchesInView = false
    view.addGestureRecognizer(tapper)
}

1
เป้าหมายควรเป็นselfมากกว่าself.view
EI Captain v2.0

1
เป้าหมายควรเป็นตัวเองดู มิฉะนั้นรหัสข้างต้นจะผิดพลาด
Naga Mallesh Maddali

canclesTouchesInViewเป็นคุณสมบัติที่ใช้งานง่าย ขอบคุณ
JonSlowCN

นิสัยเก่าตายยาก อัฒภาคทำอะไรที่นี่ ;)
Alexandre G.

@AlexandreG c#อันที่จริงโดยเฉพาะอย่างยิ่งตั้งแต่ฉันโดยทั่วไปการเข้ารหัส FYI นั่นคือเซมิโคลอนที่อนุญาตให้ใช้กับไวยากรณ์ แต่ก็ไม่จำเป็น
Rob

17

เกี่ยวกับสิ่งนี้: ฉันรู้ว่านี่เป็นโพสต์เก่า มันอาจช่วยใครซักคน :)

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

ฉันไม่ได้ตรวจสอบ UITextField ดังนั้นจึงใช้ได้กับอินพุตทุกประเภท ไม่เห็นปัญหาใด ๆ
แฟรงค์

15

นี่เป็นวิธีแก้ปัญหาทั่วไปที่ดี:

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://stackoverflow.com/a/18756253/417652


12

Swift 4 oneliner

view.addGestureRecognizer(UITapGestureRecognizer(target: view, action: #selector(UIView.endEditing(_:))))

รหัสดี แต่อันนี้ปิดการใช้งานฟังก์ชั่นลบ (-)
schellingerht

คุณคืออัจฉริยะ!
Abhishek Bedi

10

ฉันคิดว่าวิธีที่ง่ายที่สุด (และดีที่สุด) ในการทำเช่นนี้คือการทำ subclass ให้กับมุมมองทั่วโลกของคุณและใช้hitTest:withEventวิธีการฟังสัมผัสใด ๆ สัมผัสบนแป้นพิมพ์ไม่ได้ลงทะเบียนเพื่อ HitTest: withEvent เรียกว่าเฉพาะเมื่อคุณสัมผัส / เลื่อน / รูด / หยิก ...[self endEditing:YES]ที่อื่นแล้วโทร

สิ่งนี้ดีกว่าการใช้touchesBeganเพราะtouchesBeganไม่มีการเรียกใช้ถ้าคุณคลิกที่ปุ่มด้านบนของมุมมอง มันดีกว่าUITapGestureRecognizerที่ไม่สามารถจำท่าทางการเลื่อนได้ นอกจากนี้ยังดีกว่าการใช้หน้าจอสลัวเพราะในส่วนติดต่อผู้ใช้ที่ซับซ้อนและแบบไดนามิกคุณไม่สามารถใส่หน้าจอสลัวได้ทุกที่ ยิ่งไปกว่านั้นมันไม่ได้ปิดกั้นการกระทำอื่น ๆ คุณไม่จำเป็นต้องแตะสองครั้งเพื่อเลือกปุ่มนอก (เช่นในกรณีของ a UIPopover)

นอกจากนี้มันยังดีกว่าการโทร[textField resignFirstResponder]เพราะคุณอาจมีฟิลด์ข้อความจำนวนมากบนหน้าจอดังนั้นจึงเหมาะสำหรับพวกเขาทั้งหมด


น่าเสียดายที่สิ่งนี้ดูเหมือนว่าจะรบกวน 'X' ของ UISearchBar เพื่อล้างข้อความ
huggie

1
มีปัญหาบางอย่างกับวิธีนี้ ตัวอย่างเช่นคุณไม่สามารถเลื่อนดู scrollview โดยไม่ต้องเสียสมาธิกับ textfield ของคุณ ไม่แนะนำให้ใช้สำหรับสถานการณ์ที่ซับซ้อนมากขึ้น ... โดยส่วนตัวแล้วฉันชอบ uicontrol-version จาก Dmitry ซึ่งอาจขยายโดยผู้ที่มาจาก Sofi Software
katzenhut

ตัวอย่างหนึ่งของการเลื่อนอยู่ในแอพอีเมลเมื่อคุณพิมพ์ลงในแถบค้นหาจากนั้นเลื่อนรายการอีเมลแป้นพิมพ์จะถูกยกเลิก
Enzo Tran

มันเป็นวิธีที่ดีที่สุดและได้ทำกับโครงการอื่นของฉัน
Chandramani

8

นี่จะเป็นวิธีที่ง่ายที่สุดในการซ่อนแป้นพิมพ์โดยแตะที่ด้านนอก:

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

(จากวิธีปิดแป้นพิมพ์เมื่อผู้ใช้แตะที่พื้นที่อื่นนอกเขตข้อมูล? )


6

หากมุมมองถูกฝังอยู่ทั้งหมดUIScrollViewคุณสามารถใช้สิ่งต่อไปนี้:

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

อดีตจะทำให้แป้นพิมพ์ปิดหน้าจอเมื่อมุมมองตารางถูกเลื่อนและในภายหลังจะซ่อนแป้นพิมพ์เช่นแอปเก็บข้อความ

โปรดทราบว่าสิ่งเหล่านี้มีอยู่ใน iOS 7.0 ขึ้นไป


6

คุณสามารถทำได้โดยใช้ Storyboard ใน XCode 6 ขึ้นไป:


สร้างการกระทำเพื่อซ่อนแป้นพิมพ์

เพิ่มไปยังไฟล์ส่วนหัวของคลาสที่ใช้โดย ViewController ของคุณ:

@interface TimeDelayViewController : UIViewController <UITextFieldDelegate>

- (IBAction)dissmissKeyboardOnTap:(id)sender;

@end

จากนั้นเพิ่มสิ่งนี้ไปยังไฟล์การใช้งานของ ViewController เดียวกัน:

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

ตอนนี้จะเป็นหนึ่งใน 'การกระทำที่ได้รับ' สำหรับฉากเรื่องราวของคุณ (เช่น ViewController):

ป้อนคำอธิบายรูปภาพที่นี่


ขอการกระทำกับกิจกรรมของผู้ใช้

ตอนนี้คุณต้องเชื่อมต่อการกระทำนี้กับท่าทางของผู้ใช้ในการแตะคีย์บอร์ด

สำคัญ - คุณต้องแปลง 'UIView' ที่มีอยู่ในกระดานเรื่องราวของคุณเป็น UIControlเพื่อให้สามารถรับเหตุการณ์ได้ เลือกมุมมองจากลำดับชั้นของมุมมองฉากควบคุมของคุณ:

ป้อนคำอธิบายรูปภาพที่นี่

... และเปลี่ยนคลาส:

ป้อนคำอธิบายรูปภาพที่นี่

ตอนนี้ลากจากวงกลมเล็ก ๆ ถัดจาก 'รับการกระทำ' สำหรับฉากของคุณไปยังส่วน 'ว่าง' ของฉากของคุณ (จริง ๆ แล้วคุณกำลังลาก 'รับการกระทำ' เพื่อ UIControl) คุณจะเห็นการเลือกกิจกรรมที่คุณสามารถเชื่อมต่อการกระทำของคุณกับ:

ป้อนคำอธิบายรูปภาพที่นี่

เลือกตัวเลือก 'สัมผัสภายใน' ตอนนี้คุณได้เชื่อมโยง IBAction ที่คุณสร้างไว้กับการกระทำของผู้ใช้ในการแตะคีย์บอร์ด เมื่อผู้ใช้แตะแป้นพิมพ์ตอนนี้ผู้ใช้จะถูกซ่อน

(หมายเหตุ: หากต้องการเชื่อมโยงการกระทำกับเหตุการณ์คุณสามารถลากจากการกระทำที่ได้รับโดยตรงไปยัง UIControl ในลำดับชั้น View Controller ของคุณซึ่งแสดงเป็น 'Control' ในลำดับชั้น)


ขอบคุณสำหรับการแก้ปัญหาและคำอธิบายโดยละเอียด มีประโยชน์กับฉันจริงๆ
Yongxiang Ruan

5

ถ้าฉันมีคุณสิทธิคุณต้องการที่จะลาออกจากแป้นพิมพ์เพทุบายแตะที่ด้านนอกของแต่คุณไม่ได้มีการอ้างอิงของคุณtextfieldtextfield

ลองสิ่งนี้

  • ใช้ฟิลด์ข้อความทั่วโลกให้เรียกมันว่า 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;
    }

3

เพียงเพิ่มในรายการที่นี่รุ่นของฉันของวิธีการยกเลิกคีย์บอร์ดบนสัมผัสภายนอก

viewDidLoad:

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

ผู้แต่ง:

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

3

มีคำตอบที่ดีมากมายเกี่ยวกับการใช้ - UITapGestureRecognizerซึ่งUITextFieldปุ่มตัวแบ่ง(X) ทั้งหมด วิธีแก้ปัญหาคือการระงับตัวรู้จำท่าทางผ่านตัวแทน:

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

มันไม่ใช่ทางออกที่แข็งแกร่งที่สุด แต่ได้ผลสำหรับฉัน


ทั้งหมดข้างต้นล้มเหลวหากฉันแตะในฟิลด์ข้อความเดียวกัน มันลาออกแม้กระทั่ง textfield ก็เป็นคำตอบของฉัน และมันก็ปิดคีย์บอร์ดโดยการแตะปุ่มที่ชัดเจนภายใน textField
Mrug

return !touchViewIsButtonฉันจะลดความซับซ้อนของมันได้โดยเพียงแค่การทำทดสอบสำหรับปุ่ม: ฉันเดาว่าปุ่มอื่น ๆ ที่จำเป็นต้องยกเลิกคีย์บอร์ดควรทำในสิ่งที่กระทำ นอกจากนี้ TouchUpInside อาจไม่ถูกเรียกใช้เมื่อการเปลี่ยนแปลงโครงร่างของการถอดคีย์บอร์ด
MariánČerný

3

คุณสามารถสร้างหมวดหมู่สำหรับ 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

3

คำตอบของ @ 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:"))

2

ฉันใช้ตัวอย่างแบร์รี่สำหรับการพัฒนาใหม่ของฉัน มันใช้งานได้ดี! แต่ฉันต้องรวมการเปลี่ยนแปลงเล็กน้อยต้องยกเลิกคีย์บอร์ดเฉพาะสำหรับฟิลด์ข้อความที่ถูกแก้ไข

ดังนั้นฉันเพิ่มตัวอย่างแบร์รี่ต่อไปนี้:

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

2

หนึ่งในวิธีที่ง่ายที่สุดและสั้นที่สุดคือการเพิ่มรหัสนี้ในของคุณ viewDidLoad

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


2

ฉันลองคำตอบมากมายที่นี่และไม่มีโชค เครื่องมือรู้จำท่าทางการแตะของฉันทำให้ฉันUIButtonsไม่ตอบสนองเสมอเมื่อแตะแม้ในขณะที่ฉันตั้งค่าcancelsTouchesInViewคุณสมบัติของตัวรู้จำท่าทางให้เป็นไม่

นี่คือสิ่งที่แก้ไขปัญหาในที่สุด:

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

เคล็ดลับคือวิธีการตั้งค่า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ออกจากการดำเนินการจัดการการสัมผัส ...



1

วิธีนี้ใช้ได้ผล

ในตัวอย่างนี้ 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");
}

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

}

1

เพิ่มรหัสนี้ในไฟล์ViewController.mของคุณ:

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

1

ในกรณีนี้สามารถใช้ScrollViewและเพิ่มลง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.
    }
}

สตอรี่บอร์ดของคุณดูอย่างนั้น

ป้อนคำอธิบายรูปภาพที่นี่


1

คุณสามารถใช้วิธี UITapGestureRecongnizer สำหรับการเลิกใช้คีย์บอร์ดโดยคลิกที่ด้านนอกของ UITextField โดยใช้วิธีนี้เมื่อใดก็ตามที่ผู้ใช้จะคลิกนอก UITextField จากนั้นแป้นพิมพ์จะถูกยกเลิก ด้านล่างนี้เป็นข้อมูลโค้ดสำหรับการใช้งาน

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

    [self.view addGestureRecognizer:tap];


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

}

1
  • ตั้งค่าผู้รับมอบสิทธิ์ฟิลด์ข้อความในมุมมองที่โหลด:

    override func viewDidLoad() 
    {
      super.viewDidLoad()
      self.userText.delegate = self
    }
  • เพิ่มฟังก์ชั่นนี้:

    func textFieldShouldReturn(userText: UITextField!) -> Bool 
    {
     userText.resignFirstResponder()
     return true;
    }
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.