[objective-c] 키보드를 해제하는 쉬운 방법?

내 테이블의 많은 테이블 셀에 상당히 많은 컨트롤이 흩어져 있으며 모든 컨트롤을 반복하고 첫 번째 응답자로 모두 사임하지 않고 키보드를 해제하는 더 쉬운 방법이 있는지 궁금합니다. 질문은 .. 키보드의 현재 첫 번째 응답자를 어떻게 얻습니까?



답변

시험:

[self.view endEditing:YES];


답변

현재 편집중인보기가 첫 번째 응답자 상태를로 사임하도록 강제 할 수 있습니다 [view endEditing:YES]. 키보드가 숨겨집니다.

달리 -[UIResponder resignFirstResponder], -[UIView endEditing:]현재 첫 번째로 반응을 찾아 파단 통해 검색합니다. 따라서 최상위 뷰 (예 🙂 self.view로 전송할 UIViewController수 있으며 올바른 작업을 수행합니다.

(이 답변에는 이전에 작동했지만 필요한 것보다 더 복잡한 몇 가지 다른 솔루션이 포함되어 있습니다. 혼란을 피하기 위해 제거했습니다.)


답변

응용 프로그램에 대상이 지정되지 않은 작업을 보낼 수 있으며, 현재 첫 번째 응답자 상태를 가진 뷰에 대해 걱정할 필요없이 언제든지 첫 번째 응답자를 사임합니다.

목표 -C :

[[UIApplication sharedApplication] sendAction:@selector(resignFirstResponder) to:nil from:nil forEvent:nil];

스위프트 3.0 :

UIApplication.shared.sendAction(#selector(resignFirstResponder), to: nil, from: nil, for: nil)

Mac OS X에서는 메뉴 명령으로 대상이 지정되지 않은 작업이 일반적이며, iOS에서 해당 작업이 사용됩니다.


답변

솔직히 말해서, 여기에 제안 된 솔루션에 대해서는 미치지 않습니다. TapGestureRecognizer를 사용하여 문제의 핵심이라고 생각하는 좋은 방법을 찾았습니다. 키보드 이외의 것을 클릭하면 키보드를 닫습니다.

  1. viewDidLoad에서 키보드 알림을 수신하고 UITapGestureRecognizer를 작성하도록 등록하십시오.

    NSNotificationCenter *nc = [NSNotificationCenter defaultCenter];
    
    [nc addObserver:self selector:@selector(keyboardWillShow:) name:
    UIKeyboardWillShowNotification object:nil];
    
    [nc addObserver:self selector:@selector(keyboardWillHide:) name:
    UIKeyboardWillHideNotification object:nil];
    
    tapRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self
    action:@selector(didTapAnywhere:)];
  2. 키보드 표시 / 숨기기 응답자를 추가하십시오. 여기에서 TapGestureRecognizer를 UIView에 추가하고 제거하면 탭할 때 키보드가 사라집니다. 참고 : 모든 하위 뷰 또는 컨트롤에 추가 할 필요는 없습니다.

    -(void) keyboardWillShow:(NSNotification *) note {
        [self.view addGestureRecognizer:tapRecognizer];
    }
    
    -(void) keyboardWillHide:(NSNotification *) note
    {
        [self.view removeGestureRecognizer:tapRecognizer];
    }
  3. TapGestureRecognizer는 탭을 받으면 함수를 호출하며 다음과 같이 키보드를 닫을 수 있습니다.

    -(void)didTapAnywhere: (UITapGestureRecognizer*) recognizer {
        [textField resignFirstResponder];
    }

이 솔루션의 좋은 점은 스 와이프하지 않고 탭만 필터링한다는 것입니다. 따라서 키보드 위에서 내용을 스크롤하면 스 와이프해도 여전히 스크롤되어 키보드가 표시된 상태로 유지됩니다. 키보드가 사라진 후 제스처 인식기를 제거하면 나중에보기의 탭이 정상적으로 처리됩니다.


답변

이것은 칠 때 키보드가 사라지도록하는 솔루션 return입니다한 곳에서 코드를 추가하여 모든 텍스트 필드 치울 (따라서 각 텍스트 필드에 핸들러를 추가하지 않아도 됨).


이 시나리오를 고려하십시오.

나는 viewcontroller 두 텍스트 필드 (사용자 이름 및 암호)와 함께합니다. 그리고 viewcontroller구현의 UITextFieldDelegate프로토콜

viewDidLoad 에서이 작업을 수행합니다.

- (void)viewDidLoad
{
    [super viewDidLoad];

    username.delegate = self;
    password.delegate = self;
}

뷰 컨트롤러는 다음과 같은 선택적 방법을 구현합니다.

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

내가 타 자마자 텍스트 필드에 관계없이 return 키보드 사라집니다!

귀하의 경우 모든 텍스트 필드의 대리자를 self로 설정하고 구현하는 한 동일하게 작동합니다. textFieldShouldReturn


답변

더 나은 접근 방식은 무언가 “훔친”첫 번째 응답자 상태를 유지하는 것입니다.

UIApplication은 UIResponder의 서브 클래스이므로 다음을 시도 할 수 있습니다.

[[UIApplication sharedApplication] becomeFirstResponder]
[[UIApplication sharedApplication] resignFirstResponder]

실패하면 크기가 0 인 프레임으로 새 UITextField를 만들고 어딘가에 뷰에 추가하고 비슷한 것을 수행하십시오 (사임이 됨).


답변

유틸리티 클래스에서 이것을 제거하십시오.

+ (void)dismissKeyboard {
    [self globalResignFirstResponder];
}

+ (void) globalResignFirstResponder {
    UIWindow * window = [[UIApplication sharedApplication] keyWindow];
    for (UIView * view in [window subviews]){
        [self globalResignFirstResponderRec:view];
    }
}

+ (void) globalResignFirstResponderRec:(UIView*) view {
    if ([view respondsToSelector:@selector(resignFirstResponder)]){
        [view resignFirstResponder];
    }
    for (UIView * subview in [view subviews]){
        [self globalResignFirstResponderRec:subview];
    }
}