development

리턴 키로 UITextView의 키보드를 해제하는 방법은 무엇입니까?

big-blog 2020. 2. 26. 07:56
반응형

리턴 키로 UITextView의 키보드를 해제하는 방법은 무엇입니까?


IB의 라이브러리에서 소개는 return키를 누르면 키보드 UITextView가 사라질 것임을 알려줍니다 . 그러나 실제로 return키는 '\ n'으로 만 작동 할 수 있습니다.

버튼을 추가 [txtView resignFirstResponder]하고 키보드를 숨기는 데 사용할 수 있습니다 .

그러나 return키보드에 키에 대한 작업을 추가하여 추가 할 필요가없는 방법이 UIButton있습니까?


UITextView사용자가 리턴 키를 눌렀을 때 호출되는 메소드가 없습니다. 사용자가 한 줄의 텍스트 만 추가 할 수있게하려면을 사용하십시오 UITextField. 리턴을 치고 키보드를 숨기는 UITextView것은 인터페이스 지침을 따르지 않습니다.

그럼에도 불구하고 이렇게 하려면 대체 텍스트가 경우 해당 textView:shouldChangeTextInRange:replacementText:방법을 구현 하고 키보드를 숨기십시오.UITextViewDelegate\n

다른 방법이있을 수 있지만 나는 전혀 모른다.


대신 스 니펫을 여기에 게시 할 것이라고 생각했습니다.

UITextViewDelegate프로토콜에 대한 지원을 선언해야합니다 .

- (BOOL)textView:(UITextView *)textView shouldChangeTextInRange:(NSRange)range replacementText:(NSString *)text {

    if([text isEqualToString:@"\n"]) {
        [textView resignFirstResponder];
        return NO;
    }

    return YES;
}

스위프트 4.0 업데이트 :

func textView(_ textView: UITextView, shouldChangeTextIn range: NSRange, replacementText text: String) -> Bool {
    if text == "\n" {
        textView.resignFirstResponder()
        return false
    }
    return true
}

나는 이것이 이미 대답되었다는 것을 알고 있지만 실제로 줄 바꿈에 문자열 리터럴을 사용하는 것을 좋아하지 않으므로 여기에 내가 한 일이 있습니다.

- (BOOL)textView:(UITextView *)txtView shouldChangeTextInRange:(NSRange)range replacementText:(NSString *)text {
    if( [text rangeOfCharacterFromSet:[NSCharacterSet newlineCharacterSet]].location == NSNotFound ) {
        return YES;
    }

    [txtView resignFirstResponder];
    return NO;
}

스위프트 4.0 업데이트 :

func textView(_ textView: UITextView, shouldChangeTextIn range: NSRange, replacementText text: String) -> Bool {
if (text as NSString).rangeOfCharacter(from: CharacterSet.newlines).location == NSNotFound {
    return true
}
txtView.resignFirstResponder()
return false
}

나는 이것이 여러 번 대답되었다는 것을 알고 있지만 여기 에이 문제에 대한 2 센트가 있습니다.

나는에 의해 답을 발견 samvermetteribeto 정말 유용하고, 또한 의해 코멘트 maxpower 에서 ribeto 의 대답을. 그러나 이러한 접근 방식에는 문제가 있습니다. samvermette 의 대답 에서 매트가 언급 한 문제 는 사용자가 줄 바꿈으로 무언가를 붙여 넣으려면 키보드를 붙여 넣지 않고 숨길 수 있다는 것입니다.

그래서 내 접근 방식은 위에서 언급 한 세 가지 솔루션의 혼합이며 문자열 길이가 1 일 때 입력 한 문자열이 새 줄인지 확인하므로 붙여 넣지 않고 입력하는 것을 확인합니다.

여기 내가 한 일이 있습니다.

- (BOOL)textView:(UITextView *)textView shouldChangeTextInRange:(NSRange)range replacementText:(NSString *)text {
    NSRange resultRange = [text rangeOfCharacterFromSet:[NSCharacterSet newlineCharacterSet] options:NSBackwardsSearch];
    if ([text length] == 1 && resultRange.location != NSNotFound) {
        [textView resignFirstResponder];
        return NO;
    }

    return YES;
}

보다 우아한 방법은 사용자가 키보드 프레임 바깥 쪽을 누를 때 키보드를 닫는 것입니다.

먼저 UIBuilder의 자격 증명 관리자에서 ViewController의보기를 "UIControl"클래스로 설정하십시오. 보기를 ViewController의 헤더 파일로 Control- 드래그하고 Touch Up Inside와 같은 이벤트와 같은 동작으로 연결하십시오.

ViewController.h

-(IBAction)dismissKeyboardOnTap:(id)sender;

기본 ViewController 파일에서 ViewController.m :

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

유사한 기술을 사용하여 두 번 누르거나 길게 터치해야 할 수도 있습니다. ViewController를 UITextViewDelegate로 설정하고 TextView를 ViewController에 연결해야 할 수도 있습니다. 이 메소드는 UITextView 및 UITextField 모두에 대해 작동합니다.

출처 : 빅 얼간이 목장

편집 : 또한 UIScrollView를 사용하는 경우 위의 기술이 Interface Builder를 통해 쉽게 작동하지 않을 수 있다고 덧붙이고 싶습니다. 이 경우 UIGestureRecognizer를 사용하고 대신 [[self view] endEditing : YES] 메소드를 호출 할 수 있습니다. 예를 들면 다음과 같습니다.

-(void)ViewDidLoad{
    ....
    UITapGestureRecognizer *tapRec = [[UITapGestureRecognizer alloc] 
        initWithTarget:self action:@selector(tap:)];
    [self.view addGestureRecognizer: tapRec];
    ....
}

-(void)tap:(UITapGestureRecognizer *)tapRec{
    [[self view] endEditing: YES];
}

사용자가 키보드 외부를 두드리고 입력 공간을 두드리지 않으면 키보드가 사라집니다.


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

스위프트 :

func textView(textView: UITextView, shouldChangeTextInRange range: NSRange, replacementText text: String) -> Bool {
    if text == "\n" {
        textView.resignFirstResponder()
        return false
    }
    return true
}

이 방법도 도움이 될 수 있습니다.

/**
Dismiss keyboard when tapped outside the keyboard or textView

:param: touches the touches
:param: event   the related event
*/
override func touchesBegan(touches: NSSet, withEvent event: UIEvent) {
    if let touch = touches.anyObject() as? UITouch {
        if touch.phase == UITouchPhase.Began {
            textField?.resignFirstResponder()
        }
    }
}

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

yourtextView.delegate=self;

또한 추가 UITextViewDelegate

프로토콜을 확인하는 것을 잊지 마십시오

추가 if([text isEqualToString:@"\n"])하지 않으면 편집 할 수 없습니다


uitextview와 함께 사용하는 동안 또 다른 해결책이 있습니다. "textViewShouldBeginEditing"에서 도구 모음을 InputAccessoryView로 추가 할 수 있으며이 도구 모음의 완료 단추에서 키보드를 닫을 수 있습니다. 이에 대한 코드는 다음과 같습니다.

viewDidLoad에서

toolBar = [[UIToolbar alloc]initWithFrame:CGRectMake(0, 0, 320, 44)]; //toolbar is uitoolbar object
toolBar.barStyle = UIBarStyleBlackOpaque;
UIBarButtonItem *btnDone = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemDone target:self action:@selector(btnClickedDone:)];
[toolBar setItems:[NSArray arrayWithObject:btnDone]];

textviewdelegate 메소드에서

- (BOOL)textViewShouldBeginEditing:(UITextView *)textView
{
     [textView setInputAccessoryView:toolBar];
     return YES;
}

툴바에있는 버튼 완료의 동작은 다음과 같습니다.

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

josebama 의 답변 이이 스레드에서 사용할 수있는 가장 완전하고 깨끗한 답변 이라는 것을 알았 습니다.

다음은 Swift 4 구문입니다.

func textView(_ textView: UITextView, shouldChangeTextIn _: NSRange, replacementText text: String) -> Bool {
    let resultRange = text.rangeOfCharacter(from: CharacterSet.newlines, options: .backwards)
    if text.count == 1 && resultRange != nil {
        textView.resignFirstResponder()
        // Do any additional stuff here
        return false
    }
    return true
}

빠른

func textView(textView: UITextView, shouldChangeTextInRange range: NSRange, replacementText text: String) -> Bool {
    if text == "\n" {
        textView.resignFirstResponder()
    }
    return true
}

구성


탐색 컨트롤러를 사용하여 바를 호스팅하여 키보드를 닫습니다.

.h 파일에서 :

UIBarButtonItem* dismissKeyboardButton;

.m 파일에서 :

- (void)viewDidLoad {
    dismissKeyboardButton = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemDone target:self action:@selector(dismissKeyboard)];
}

-(void)textViewDidBeginEditing:(UITextView *)textView {
    self.navigationItem.rightBarButtonItem = dismissKeyboardButton;
}

-(void)textFieldDidBeginEditing:(UITextField *)textField {
    self.navigationItem.rightBarButtonItem = dismissKeyboardButton;
}

-(void)dismissKeyboard {
    [self.textField resignFirstResponder];
    [self.textView resignFirstResponder];
    //or replace this with your regular right button
    self.navigationItem.rightBarButtonItem = nil;
}

samvermette에 대한 무언의 주석처럼 "\ n"도 감지하는 것을 좋아하지 않습니다. UITextView에는 "return"키가 있습니다. 즉, 다음 줄로 넘어갑니다.

제 생각에 가장 좋은 해결책은 키보드에 도구 모음 (및 버튼)을 추가하는 iPhone 메시지 앱을 모방하는 것입니다.

다음 블로그 게시물에서 코드를 얻었습니다.

http://www.iosdevnotes.com/2011/02/iphone-keyboard-toolbar/

단계 :

XIB 파일에 툴바 추가-높이를 460으로 설정

도구 모음 버튼 항목을 추가합니다 (아직 추가하지 않은 경우). 오른쪽 정렬이 필요한 경우 유연한 막대 버튼 항목을 XIB에 추가하고 도구 모음 버튼 항목을 이동하십시오.

다음과 같이 버튼 항목을 resignFirstResponder에 연결하는 조치를 작성하십시오.

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

-그때:

- (void)viewWillAppear:(BOOL)animated {
    [super viewWillAppear:animated];

    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillShow:) name:UIKeyboardWillShowNotification object:nil];
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillHide:) name:UIKeyboardWillHideNotification object:nil];
}

- (void)viewWillDisappear:(BOOL)animated {
    [super viewWillDisappear:animated];

    [[NSNotificationCenter defaultCenter] removeObserver:self name:UIKeyboardWillShowNotification object:nil];
    [[NSNotificationCenter defaultCenter] removeObserver:self name:UIKeyboardWillHideNotification object:nil];
}

- (void)keyboardWillShow:(NSNotification *)notification {
    [UIView beginAnimations:nil context:NULL];
    [UIView setAnimationDuration:0.3];

    CGRect frame = self.keyboardToolbar.frame;
    frame.origin.y = self.view.frame.size.height - 260.0;
    self.keyboardToolbar.frame = frame;

    [UIView commitAnimations];
}

- (void)keyboardWillHide:(NSNotification *)notification {
    [UIView beginAnimations:nil context:NULL];
    [UIView setAnimationDuration:0.3];

    CGRect frame = self.keyboardToolbar.frame;
    frame.origin.y = self.view.frame.size.height;
    self.keyboardToolbar.frame = frame;

    [UIView commitAnimations];
}

이 문제를 다른 방식으로 해결했습니다.

  • 백그라운드에 배치 할 버튼을 만듭니다
  • 속성 관리자에서 버튼 유형을 사용자 정의로 변경하면 버튼이 투명 해집니다.
  • 단추를 펼쳐 전체보기를 덮고 단추가 다른 모든 오브젝트 뒤에 있는지 확인하십시오. 이를 수행하는 쉬운 방법은보기에서 단추를 목록보기의 맨 위로 끌어 오는 것입니다
  • 컨트롤을 버튼을 viewController.h파일로 드래그하고 다음 과 같은 액션 (Sent Event : Touch Up Inside)을 만듭니다.

    (IBAction)ExitKeyboard:(id)sender;
    
  • 에서이 ViewController.m같이해야한다 :

    (IBAction)ExitKeyboard:(id)sender {
        [self.view endEditing:TRUE];
    }
    
  • 응용 프로그램을 실행하고 TextView에서 멀리 클릭하면 키보드가 사라집니다.

viewDidLoad에 옵저버 추가

[[NSNotificationCenter defaultCenter] addObserver: self selector: @selector(textViewKeyPressed:) name: UITextViewTextDidChangeNotification object: nil];

그런 다음 셀렉터를 사용하여 "\ n"을 확인하십시오.

-(void) textViewKeyPressed: (NSNotification*) notification {

  if ([[[notification object] text] hasSuffix:@"\n"])
  {
    [[notification object] resignFirstResponder];
  }
}

"\ n"을 사용하고 특별히 리턴 키를 확인하지는 않지만 이것이 정상이라고 생각합니다.

최신 정보

아래 [NSCharacterSet newlineCharacterSet]대신 사용하는 ribto의 답변을 참조하십시오.\n


이 시도 :

 - (BOOL)textView:(UITextView *)textView shouldChangeTextInRange:(NSRange)range replacementText:(NSString *)text{
    if ([text isEqualToString:@"\n"]) {
        [self.view endEditing:YES];
    }

    return YES;

}

// 이것을 사용할 수 있습니다 ...

1 단계. 첫 번째 단계는 UITextViewDelegate프로토콜 지원을 선언하는 것입니다 . 이것은 헤더 파일에서 수행되며 예를 들어 헤더는

EditorController.h :

@interface EditorController : UIViewController  {
  UITextView *messageTextView;
}

@property (nonatomic, retain) UITextView *messageTextView;

@end

2 단계. 다음으로 컨트롤러를 UITextView의 대리자로 등록해야합니다. 위의 예에서 계속해서 , 대리인으로 UITextViewwith EditorController초기화하는 방법은 다음 같습니다.

- (id) init {
    if (self = [super init]) {
        // define the area and location for the UITextView
        CGRect tfFrame = CGRectMake(10, 10, 300, 100);
        messageTextView = [[UITextView alloc] initWithFrame:tfFrame];
        // make sure that it is editable
        messageTextView.editable = YES;

        // add the controller as the delegate
        messageTextView.delegate = self;
    }

3 단계. 이제 퍼즐의 마지막 부분은 shouldCahngeTextInRange다음과 같이 메시지 에 응답하여 조치를 취하는 것입니다 .

- (BOOL)textView:(UITextView *)textView shouldChangeTextInRange:(NSRange)range 
  replacementText:(NSString *)text
{
    // Any new character added is passed in as the "text" parameter
    if ([text isEqualToString:@"\n"]) {
        // Be sure to test for equality using the "isEqualToString" message
        [textView resignFirstResponder];

        // Return FALSE so that the final '\n' character doesn't get added
        return FALSE;
    }
    // For any other character return TRUE so that the text gets added to the view
    return TRUE;
}

스위프트 코드

클래스 / 뷰에서 UITextViewDelegate를 구현하십시오.

class MyClass: UITextViewDelegate  { ...

textView 델리게이트를 self로 설정

myTextView.delegate = self

그런 다음 다음을 구현하십시오.

  func textViewDidChange(_ textView: UITextView) {
    if textView.text.characters.count >= 1 {

        if let lastChar = textView.text.characters.last {

            if(lastChar == "\n"){

              textView.text = textView.text.substring(to: textView.text.index(before: textView.text.endIndex))
              textView.resignFirstResponder()
            }
        }
    }
}

편집 텍스트 필드의 사용자 입력을 해결 방법으로 변경하고 해킹 코드가 완료 된 후 상태를 재설정하지 않는 것이 좋기 때문에 코드를 업데이트했습니다.


보기 화면에서 터치 할 때 키보드를 숨길 수도 있습니다.

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
     UITouch * touch = [touches anyObject];
     if(touch.phase == UITouchPhaseBegan) {
        [txtDetail resignFirstResponder];
      }
 }

신속한 답변 :

override func viewDidLoad() {
    super.viewDidLoad()
    let tapGestureReconizer = UITapGestureRecognizer(target: self, action: "tap:")
    view.addGestureRecognizer(tapGestureReconizer)
}

func tap(sender: UITapGestureRecognizer) {
    view.endEditing(true)
}

이 코드를 사용하여 응답자를 변경했습니다.

 - (BOOL)textView:(UITextView*) textView shouldChangeTextInRange: (NSRange) range replacementText: (NSString*) text
    {
        if ([text isEqualToString:@"\n"]) {
            //[textView resignFirstResponder];
            //return YES;
            NSInteger nextTag = textView.tag + 1;
            // Try to find next responder
            UIResponder* nextResponder = [self.view viewWithTag:nextTag];
            if (nextResponder) {
                // Found next responder, so set it.
                [nextResponder becomeFirstResponder];
            } else {
                // Not found, so remove keyboard.
                [textView resignFirstResponder];
            }
            return NO; 


            return NO;
        }
        return YES;

    }

확인. 모두가 트릭으로 답변을 주었지만 이것을 달성하는 올바른 방법은

의 " 종료 종료시 종료 "이벤트에 다음 조치를 연결하십시오 Interface Builder. ( TextField' 종료시 종료했습니다 '에서 다음 cntrl-drag를 마우스 오른쪽 단추로 클릭하십시오 .

-(IBAction)hideTheKeyboard:(id)sender
{
    [self.view endEditing:TRUE];
}

- (BOOL)textView:(UITextView *)textView shouldChangeTextInRange:(NSRange)range  replacementText:(NSString *)text
{
    if (range.length==0) {
        if ([text isEqualToString:@"\n"]) {
            [txtView resignFirstResponder];
            if(textView.returnKeyType== UIReturnKeyGo){

                [self PreviewLatter];
                return NO;
            }
            return NO;
        }
    }   return YES;
}

+ (void)addDoneButtonToControl:(id)txtFieldOrTextView
{
    if([txtFieldOrTextView isKindOfClass:[UITextField class]])
    {
        txtFieldOrTextView = (UITextField *)txtFieldOrTextView;
    }
    else if([txtFieldOrTextView isKindOfClass:[UITextView class]])
    {
        txtFieldOrTextView = (UITextView *)txtFieldOrTextView;
    }

    UIToolbar* numberToolbar = [[UIToolbar alloc]initWithFrame:CGRectMake(0,
                                                                          0,
                                                                          [Global returnDeviceWidth],
                                                                          50)];
    numberToolbar.barStyle = UIBarStyleDefault;


    UIBarButtonItem *btnDone = [[UIBarButtonItem alloc] initWithImage:[UIImage imageNamed:@"btn_return"]
                                                                style:UIBarButtonItemStyleBordered
                                                               target:txtFieldOrTextView
                                                               action:@selector(resignFirstResponder)];

    numberToolbar.items = [NSArray arrayWithObjects:btnDone,nil];
    [numberToolbar sizeToFit];

    if([txtFieldOrTextView isKindOfClass:[UITextField class]])
    {
         ((UITextField *)txtFieldOrTextView).inputAccessoryView = numberToolbar;
    }
    else if([txtFieldOrTextView isKindOfClass:[UITextView class]])
    {
         ((UITextView *)txtFieldOrTextView).inputAccessoryView = numberToolbar;
    }
}

질문은 리턴 키를 사용하여 수행하는 방법을 묻지 만 UITextView를 사용할 때 키보드를 사라지게하려는 의도를 가진 사람에게 도움이 될 수 있다고 생각합니다.

@IBOutlet weak var textView: UITextView!

private func addToolBarForTextView() {
  let textViewToolbar: UIToolbar = UIToolbar()
  textViewToolbar = UIBarStyle.Default
  textViewToolbar = [
    UIBarButtonItem(title: "Cancel", style: UIBarButtonItemStyle.Done, target: self, action: #selector(self.cancelInput)),
    UIBarButtonItem(barButtonSystemItem: UIBarButtonSystemItem.FlexibleSpace, target: self, action: nil),
    UIBarButtonItem(title: "Done", style: UIBarButtonItemStyle.Done, target: self, action: #selector(self.doneInput))
  ]
  textViewToolbar()
  self.textView.inputAccessoryView = textViewToolbar //do it for every relevant textView if there are more than one
}

func doneInput() {
  self.textView.resignFirstResponder()
}

func cancelInput() {
  self.textView.text = ""
  self.textView.resignFirstResponder()
}

viewDidLoad 또는 다른 라이프 사이클 메소드 에서 addToolBarForTextView ()호출 하십시오 .

그것은 나를위한 완벽한 솔루션 인 것 같습니다.

건배,

무라트


나는 이것이이 질문에 대한 정확한 대답이 아니라는 것을 알고 있지만 대답을 찾기 위해 인터넷을 사냥 한 후에이 스레드를 발견했습니다. 나는 다른 사람들이 그 느낌을 공유한다고 가정합니다.

이것은 신뢰할 수 있고 사용하기 쉬운 UITapGestureRecognizer의 변형입니다. TextView의 대리자를 ViewController로 설정하십시오.

TextView가 편집을 위해 활성화되면 ViewDidLoad 대신 UITapGestureRecognizer를 추가합니다.

-(void)textViewDidBeginEditing:(UITextView *)textView{
    _tapRec = [[UITapGestureRecognizer alloc]initWithTarget:self action:@selector(tap:)];

    [self.view addGestureRecognizer: _tapRec];
    NSLog(@"TextView Did begin");
}

TextView 외부를 탭하면 뷰가 편집 모드를 종료하고 UITapGestureRecognizer가 자동으로 제거되므로 뷰의 다른 컨트롤과 계속 상호 작용할 수 있습니다.

-(void)tap:(UITapGestureRecognizer *)tapRec{
    [[self view] endEditing: YES];
    [self.view removeGestureRecognizer:tapRec];
    NSLog(@"Tap recognized, tapRec getting removed");
}

이게 도움이 되길 바란다. 너무 분명해 보이지만 웹 어디에서 나이 솔루션을 본 적이 없습니다.


textView에 대리자를 설정하는 것을 잊지 마십시오. 그렇지 않으면 resignfirstresponder가 작동하지 않습니다.


이 시도 .

NSInteger lengthOfText = [[textView.text stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]] length];

Xcode 6.4.의 경우 Swift 1.2. :

   override func touchesBegan(touches: Set<NSObject>, withEvent event: UIEvent)
    {
        super.touchesBegan(touches, withEvent: event)
        if let touch = touches.first as? UITouch
        {
            self.meaningTextview.resignFirstResponder()
        }
    }

-(BOOL)textFieldShouldReturn:(UITextField *)textField; // called from textfield (keyboard)

-(BOOL)textView:(UITextView *)textView shouldChangeTextInRange:(NSRange)range replacementText:(NSString *)text; // good tester function - thanks

이것에 대한 내 해킹 :

1- 전체보기를 덮는 버튼을 만듭니다. 2- 속성을보기의 배경으로 보내십시오. 3- 속성 관리자에서 유형을 "라운드 사각형"에서 "사용자 정의"로 변경하십시오.

- (IBAction)bgTouched:(id)sender 
{
    //to dismiss keyboard on bg btn pressed
    [_userInput resignFirstResponder];
}

여기서 _userInput은 TextField 콘센트입니다.

참고 URL : https://stackoverflow.com/questions/703754/how-to-dismiss-keyboard-for-uitextview-with-return-key



반응형