UITextField를 편집 할 때 키보드를 해제하는 방법


181

키보드를 닫으려고 할 때 첫 번째 응답자를 사임하도록 UITextField에 지시해야하지만 사용자가 키보드에서 "완료"키를 언제 눌렀는지 알 수는 없습니다. 볼 수있는 알림이 있습니까?


2
[self.view endEditing : YES]; 접촉이 시작에 대리인이 최선의 해결책이다
자르 E Ahmer

답변:


351

의 위임 UITextField을 내 ViewController수업으로 설정했습니다.

해당 클래스 에서이 방법을 다음과 같이 구현했습니다.

- (BOOL)textFieldShouldReturn:(UITextField *)textField {
    [textField resignFirstResponder];
    return NO;
}

위의 예를 참조하십시오. IntefaceBuilder를 사용하여 컨트롤러로 사용하는 모든 작업에 연결하십시오 ... 사용자가 텍스트 입력 시스템을 닫을 때마다 (눌린 경우) 호출됩니다 ...
Jason Coco

2
둘 중 하나가 작동합니다. 사용자가 Return ( "완료") 키를 누르면 텍스트 필드가 해당 동작을 보내고 대리자 -textFieldShouldReturn :을 보냅니다.
노아 위더스푼

BTW-UISearchBar에서도 작동합니다. 예를 들어, 내 코드에는 IBOutlet searchBarTusb 멤버가 있습니다. 내 '리턴 키'(UIReturnKeySearch)를 클릭했을 때-(void) searchBarSearchButtonClicked :를 입력했습니다. [searchBarTusb resignFirstResponder]; 또한 '리턴 키'는 Interface Builder를 사용하여 NIB에서 설정되었습니다.
mobibob

NO대신에 반환 YES?
Iulian Onofrei

@IulianOnofrei 리턴 버튼의 기본 동작은 라인 리턴을 추가하고 키보드를 화면에 유지하는 것입니다. 돌아 오면 NO텍스트에 줄 바꿈을 추가하지 않아도됩니다.
kubi

47

텍스트 필드의 DidEndOnExit 이벤트를 InterfaceBuilder의 액션 (IBAction)에 연결하면 사용자가 키보드를 반환 할 때 (반환 키 사용) 메시지가 표시되고 발신자는 이벤트를 시작한 UITextField에 대한 참조가됩니다.

예를 들면 다음과 같습니다.

-(IBAction)userDoneEnteringText:(id)sender
{
    UITextField theField = (UITextField*)sender;
    // do whatever you want with this text field
}

그런 다음 InterfaceBuilder에서 텍스트 필드의 DidEndOnExit 이벤트를 컨트롤러의이 작업 (또는 UI의 이벤트를 연결하는 데 사용하는 모든 작업)에 연결하십시오. 사용자가 텍스트를 입력하고 텍스트 필드를 닫을 때마다 컨트롤러에이 메시지가 전송됩니다.


작동하는 것처럼 보이는 유일한 이벤트는 textFieldDidEndEditing이며, 이는 UITextField가 첫 번째 응답자 상태를 사임 한 후에 만 ​​전송됨을 나타냅니다. 첫 응답자 상태를 언제 사임해야하는지 어떻게 알 수 있습니까?
kubi

용어에 대해 죄송합니다. 실제 알림 (이벤트)이 아닙니다. 간단한 예와 설명으로 답변을 편집하겠습니다. 다음을 참조하십시오. :)
Jason Coco

1
이 답변을 명확히하기 위해 textField는 리턴 키를 눌렀을 때 "Did End On Exit"이벤트를 보내므로 컨트롤러에 연결해야합니다. 이 방법은 위에서 설명한 방법보다 쉽다고 생각합니다.
kubi

2
WHICH 이벤트 연결을 언급하도록이 답변을 편집 할 수 있습니까? 이것은 대의원을 설정하는 것보다 분명히 좋습니다.
Dan Rosenstark

1
이 답변을 찬성하고 싶지만 DidEndOnExit 이벤트가 언급 될 때까지는 할 수 없습니다. 편집 권한이있는 사람이 OP가 변경되지 않으면 변경하십시오.
James Hart

32

컨트롤러에서 메소드를 생성 할 수도 있습니다

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

그런 다음 IB의 Connection Inspector에서 "Did End On Exit"이벤트를 연결하십시오.


1
이것은 거의 틀리거나 적어도 요점을 놓칩니다. DidEndOnExit이벤트 를 구독하면 에 전화 할 필요가 없습니다 resignFirstResponder. 기호 중단 점을 설정하여이를 테스트 할 수 있습니다 [UIResponder resignFirstResponder]. resignFirstResponder를 호출하지 않더라도 여전히 시스템에 의해 호출됩니다. 이것은 Matt Neuburg의 훌륭한 책에서 설명합니다 : apeth.com/iOSBook/…
Chris Conover

19

쿠비, 고마워 코드가 작동했습니다. 그냥 (초보자 원하는 경우) 당신이 설정해야 말하는 것처럼 명시 적으로 UITextField'들 delegate의 ViewController에서 텍스트 필드 상주와 동일합니다. 당신이 원하는 곳 어디에서나 할 수 있습니다. 나는 viewDidLoad방법을 선택했다 .

- (void)viewDidLoad 
{
    // sets the textField delegates to equal this viewController ... this allows for the keyboard to disappear after pressing done
    daTextField.delegate = self;
}

스토리 보드 또는 NIB에 텍스트 필드를 추가 한 경우 텍스트 필드도 설정할 수 delegate있습니다. 위에서 설명한대로 프로그래밍 방식으로이 작업을 수행 할 필요는 없습니다. 두 가지 방법 중 어느 것이나 잘 작동합니다.
Rob

18

다음은 코드없이 자동 키보드 해제 동작을 수행하는 요령입니다. 펜촉에서 Identity 관리자의 First Responder 프록시 객체를 편집하여 새로운 첫 번째 응답자 작업을 추가합니다. 그것을 호출하자 dummy:. 이제 텍스트 필드의 종료시 종료 종료 이벤트를 dummy:첫 응답자 프록시 오브젝트 의 조치에 연결하십시오. 그게 다야! 텍스트 필드의 종료시 종료 종료 이벤트에 조치-대상 쌍이 있으므로 텍스트 필드는 사용자가 Return을 누를 때 키보드를 자동으로 닫습니다. 응답자 체인으로 전송 된 메시지에 대한 핸들러를 찾지 못하면 페널티가 없으므로, dummy:어디에도 구현이 없어도 앱이 충돌하지 않습니다 .


@matt 풀기 segue를 추가하고 didEndOnExit 이벤트를 연결하면 Return 키를 누르면 풀기 segue가 트리거됩니다. 이벤트 연결이 없으면 segue가 트리거되지 않습니다. 근데 허? 어떤 말이 있습니까? BTW : Swift (완료) 및 iOS10 (6 장) 책이 있습니다. 그들은 나를 크게 도와주었습니다!
Verticon

@Verticon 질문과 답변은 segues와 관련이 없으므로 문제를 이해하지 못합니다 ... :( 순전히 키보드 해고에 관한 것입니다.
matt

@matt 죄송합니다. 1) UITextField의 리턴 키를 처리하는 방법을 다루는 동안이 스레드를 사용했기 때문에 피기 백했습니다. 그리고 2) 그것은 당신과 상호 작용할 수있는 기회였습니다 (da book의 경우 thx). "문제"가 없습니다. 왜 / 어떻게 작동하는지에 대한 이해 부족.
Verticon

@Verticon 도움을 드릴 수 없어서 죄송합니다. 더 많은 정보 (데모 프로젝트?)로 새로운 질문을 자유롭게 작성하고 유용 할 수 있다면 날 버리십시오.
matt


11

그냥 추가

[textField endEditing:YES];

키보드를 비활성화하고 선택기보기를 표시하려는 위치


10

Swift에서는 컨트롤러에 IBAction을 작성 하고 텍스트 필드의 Exit End Exit 이벤트를 해당 조치로 설정할 수 있습니다

@IBAction func returnPressed(sender: UITextField) {
    self.view.endEditing(true)
}

5

Swift 4.2 100 % 작동합니다

import UIKit

class ViewController: UIViewController, UITextFieldDelegate {

    @IBOutlet weak var textField: UITextField!


    override func viewDidLoad() {
        super.viewDidLoad()

        self.textField.delegate = self

    }

    // hide key board when the user touches outside keyboard

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

    // user presses return key

    func textFieldShouldReturn(_ textField: UITextField) -> Bool {
        textField.resignFirstResponder()
        return true
    }

}

4

당신은 또한 사용할 수 있습니다

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

   [self.yourTextField resignFirstResponder];

  }

Uitextfield가 많은 경우 가장 좋습니다.

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

2

다음은 키보드가 작동하기 위해해야 ​​할 일이며 키보드에 숫자 패드가있는 사람 (또는 완료된 버튼이없는 다른 사람)에게는 필요하다고 생각합니다.

  1. ViewController의 UIView를 UIControl로 변경했습니다.
  2. 라는 함수를 만들었습니다.

    -(IBAction)backgroundIsTapped:(id)sender

이것은 .h 파일에서도 정의되었습니다.

그런 다음 Interface Builder의 ViewController에 대한 '터치 다운'비트에 연결했습니다.

'background is tapped'기능에서 다음을 넣습니다.

    [answerField resignFirstResponder];

'answerField'를 키보드를 제거하려는 UITextField의 이름으로 변경하십시오 (UITextField가 아래와 같이 정의되어 있는지 확인하십시오).

    IBOutlet UITextField * <nameoftextfieldhere>;

나는이 주제가 아마 오래 전에 죽었다는 것을 알고있다. 그러나 이것이 누군가 어딘가에 도움이되기를 바라고있다!


..하지만 사용자가 다른 컨트롤을 탭하면 제대로 작동하지 않습니다.
ragnarius

2

"textFieldShouldReturn"메소드는 DONE 키를 눌렀 던 텍스트 필드 객체를 제공합니다. TAG를 설정하면 해당 텍스트 필드를 켤 수 있습니다. 또는 객체의 포인터를 생성자가 저장 한 멤버 값과 추적하고 비교할 수 있습니다.

본인의 접근 방식은 다음과 같습니다.

- (BOOL)textFieldShouldReturn:(UITextField *)textField {
    NSLog(@"%s", __FUNCTION__);

    bool fDidResign = [textField resignFirstResponder];

    NSLog(@"%s: did %resign the keyboard", __FUNCTION__, fDidResign ? @"" : @"not ");

    return fDidResign;
}

한편, 사임을 부인하는 "유효성 검증"테스트를 따릅니다. 단지 설명을위한 것이므로 사용자가 NO를 입력하면 필드에 들어가면 해제되지 않습니다. 동작은 내가 원하는대로 였지만 출력 순서는 예상과 다릅니다.

- (BOOL)textFieldShouldEndEditing:(UITextField *)textField {
    NSLog(@"%s", __FUNCTION__);

    if( [[textField text] isEqualToString:@"NO!"] ) {
        NSLog(@"%@", textField.text);
        return NO;
    } else {
        return YES;
    }
}

다음은이 거부에 대한 내 NSLog 출력과 수락입니다. 사직 결과를 반환하고 있음을 알 수 있지만 발신자에게 다시보고하기 위해 FALSE를 반환 할 것으로 예상 했습니까?! 그 외에는 필요한 동작이 있습니다.

13.313 StudyKbd [109 : 207]-[StudyKbdViewController textFieldShouldReturn :]
13.320 StudyKbd [109 : 207]-[StudyKbdViewController textFieldShouldEndEditing :]
13.327 StudyKbd [109 : 207] 아니요!
13.333 StudyKbd [109 : 207]-[StudyKbdViewController textFieldShouldReturn :] : 키보드를 사임했습니다
59.891 StudyKbd [109 : 207]-[StudyKbdViewController textFieldShouldReturn :]
59.897 StudyKbd [109 : 207]-[StudyKbdViewController textFieldShouldEnd 편집 :]
59.917 StudyKbd [109 : 207]-[StudyKbdViewController doneEditText] : 아니요
59.928 StudyKbd [109 : 207]-[StudyKbdViewController textFieldShouldReturn :] : 키보드를 사임했습니다

1
설명 할 수 있습니까 .. 두 경우 모두 NO 또는 YES를 반환하면 textFieldShouldReturn 대리자 메서드에서 yes를 반환해야하는 경우가 발생합니다.
K. Jaiswal

1

Return 키를 사용하거나 백그라운드를 터치하여 에디션을 종료하는 매우 깨끗한 방법입니다.

인터페이스 빌더에서 UIFormView 클래스의보기에 필드를 임베드하십시오.

이 수업은 무엇입니까?

  • 필드 위임으로 자동으로 첨부 (nib에서 깨어 났거나 수동으로 추가)
  • 현재 편집 된 필드에 대한 참조 유지
  • 키보드를 닫거나 백그라운드에서 터치

코드는 다음과 같습니다.

상호 작용

#import <UIKit/UIKit.h>

@interface UIFormView : UIView<UITextFieldDelegate>

-(BOOL)textFieldValueIsValid:(UITextField*)textField;
-(void)endEdit;

@end

이행

#import "UIFormView.h"

@implementation UIFormView
{
    UITextField* currentEditingTextField;
}

// Automatically register fields

-(void)addSubview:(UIView *)view
{
    [super addSubview:view];
    if ([view isKindOfClass:[UITextField class]]) {
        if ( ![(UITextField*)view delegate] ) [(UITextField*)view setDelegate:self];
    }
}

// UITextField Protocol

-(void)textFieldDidBeginEditing:(UITextField *)textField
{
    currentEditingTextField = textField;
}

-(void)textFieldDidEndEditing:(UITextField *)textField
{
    currentEditingTextField = NULL;
}

-(void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
{
    [self endEdit];
}

- (BOOL)textFieldShouldReturn:(UITextField *)textField
{
    if ([self textFieldValueIsValid:textField]) {
        [self endEdit];
        return YES;
    } else {
        return NO;
    }
}

// Own functions

-(void)endEdit
{
    if (currentEditingTextField) {
        [currentEditingTextField endEditing:YES];
        currentEditingTextField = NULL;
    }
}


// Override this in your subclass to handle eventual values that may prevent validation.

-(BOOL)textFieldValueIsValid:(UITextField*)textField
{
    return YES;
}

@end
  • 양식을 서브 클래스 화하고 textFieldValueIsValid:메소드를 대체 하면 값이 제공된 필드에 올바르지 않은 경우 개정 종료를 피할 수 있습니다.

  • 필드에 Interface Builder에 위임이 설정되어 있으면 양식이 변경되지 않습니다. 특정 필드에 다른 대리자를 설정해야하는 이유는 많지 않지만…

이 양식보기 클래스를 향상시키는 방법에는 여러 가지가 있습니다-델리게이트 연결, 레이아웃 수행, 키보드가 필드를 덮을 때 처리 (currentEditingTextField 프레임 사용), 다음 필드의 판을 자동으로 시작합니다 ...

나는 개인적으로 그것을 내 프레임 워크에 보관하고, 항상 기능을 추가하기 위해 서브 클래스로 만듭니다.

도움이 되길 바랍니다. 건배


1
유용한 수업. 하나의 작은 요점은 자신의 클래스 앞에 "UI"를 붙여서는 안됩니다. objective-c에서는 Swift에서 고유 한 접두사 ( "TL"?)를 사용해야합니다.
kubi

감사합니다 @kubi. 맞습니다. 내 프레임 워크에서 MF입니다. MooseFactory;)
Moose

1

UIViewController에서 모든 편집을 원한다면 사용할 수 있습니다.

[[self view]endEditing:YES];

그리고 perticular UITextField 키보드 숨기기를 해제하려면 사용하십시오.

1. viewcontroller.h에 델리게이트 추가

<UITextFieldDelegate>
  1. 텍스트 필드에 위임을 할 수 없도록합니다.

    self.yourTextField.delegate = 자기;

  2. 이 메소드를 뷰 컨트롤러에 추가하십시오.

    -(BOOL) textFieldShouldEndEditing : (UITextField *) textField {[textField resignFirstResponder]; YES를 반환;}


1

신속한 3에서 UITextField의 대리자를 프로그래밍 방식으로 설정

ViewController.Swift 파일에서 UITextFieldDelegate를 구현하십시오 (예 : 클래스 ViewController : UIViewController, UITextFieldDelegate {)

 lazy var firstNameTF: UITextField = {

    let firstname = UITextField()
    firstname.placeholder = "FirstName"
    firstname.frame = CGRect(x:38, y: 100, width: 244, height: 30)
    firstname.textAlignment = .center
    firstname.borderStyle = UITextBorderStyle.roundedRect
    firstname.keyboardType = UIKeyboardType.default
    firstname.delegate = self
    return firstname
}()

lazy var lastNameTF: UITextField = {

    let lastname = UITextField()
    lastname.placeholder = "LastName"
    lastname.frame = CGRect(x:38, y: 150, width: 244, height: 30)
    lastname.textAlignment = .center
    lastname.borderStyle = UITextBorderStyle.roundedRect
    lastname.keyboardType = UIKeyboardType.default
    lastname.delegate = self
    return lastname
}()

lazy var emailIdTF: UITextField = {

    let emailid = UITextField()
    emailid.placeholder = "EmailId"
    emailid.frame = CGRect(x:38, y: 200, width: 244, height: 30)
    emailid.textAlignment = .center
    emailid.borderStyle = UITextBorderStyle.roundedRect
    emailid.keyboardType = UIKeyboardType.default
    emailid.delegate = self
    return emailid
}()

// Mark :-델리게이트 textField 처리 ..

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

func textFieldShouldReturn(_ textField: UITextField) -> Bool {

    if textField == firstNameTF {

        lastNameTF.becomeFirstResponder()
    }

    else if textField == lastNameTF {

        emailIdTF.becomeFirstResponder()
    }
    else {
        view.emailIdTF(true)
    }
    return true
}

0

hidekeyboard 함수를 만들어 .xib 파일의 텍스트 필드에 연결하고 DidEndOnExit를 선택하십시오.

-(IBAction)Hidekeyboard    
{    
      textfield_name.resignFirstResponder;    
}  

0

Interface Builder를 사용하여 뷰를 생성 한 경우 다음을 사용하십시오.

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

보기에서 텍스트 필드를 마우스 오른쪽 단추로 클릭하고 이벤트를 종료시 종료로 설정하고 "dismissKeyboard"메소드에 연결하십시오.

초보자를위한 최고의 가이드는 "Head First iPhone 및 iPad Development, 2nd Edition"입니다.


0

이 시도

- (BOOL) textView: (UITextView*) textView shouldChangeTextInRange: (NSRange) range replacementText: (NSString*) text
{
    if ([text isEqualToString:@"\n"]) {
        [textView resignFirstResponder];
        return NO;
    }
    return YES;
}

0
//====================================================
//                  textFieldShouldReturn:
//====================================================
-(BOOL) textFieldShouldReturn:(UITextField*) textField { 
    [textField resignFirstResponder];
    if(textField.returnKeyType != UIReturnKeyDone){
        [[textField.superview viewWithTag: self.nextTextField] becomeFirstResponder];
    }
    return YES;
}

0

스위프트 3을 찾는 사람

1) UITextField의 델리게이트 가 스토리 보드의 ViewController에 연결 되어 있는지 확인하십시오.

2) ViewController.Swift 파일에 UITextFieldDelegate 를 구현 하십시오 (예 : 클래스 ViewController : UIViewController, UITextFieldDelegate {)

3) 아래의 델리게이트 방법을 사용하십시오.

func textFieldShouldReturn(textField: UITextField) -> Bool { 
   textField.resignFirstResponder()  
return false }

0

이것이 Swift 4.2에서 키보드를 닫는 방법이며 다음과 같이 작동합니다.

    override func viewDidLoad() {
    super.viewDidLoad()

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

    view.addGestureRecognizer(tap)
    }

    @objc func dismissKeyboard (_ sender: UITapGestureRecognizer) {
    numberField.resignFirstResponder()
    }

-2

스위프트 3, iOS 9+

@IBAction private func noteFieldDidEndOnExit(_ sender: UITextField) {}

UPD : 여전히 잘 작동합니다. 이 답변에 헌신 한 사람은 스토리 보드의 UITextField 에이 작업을 바인딩해야한다는 것을 이해하지 못했다고 생각합니다.


당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.