programing

반환 키를 사용하여 UITextView용 키보드를 해제하는 방법은 무엇입니까?

cafebook 2023. 5. 18. 23:53
반응형

반환 키를 사용하여 UITextView용 키보드를 해제하는 방법은 무엇입니까?

IB의 라이브러리에서, 서론은 우리에게 키를 누를 때, 키보드는UITextView사라질 것입니다.그러나 실제로 키는 '\n' 역할만 할 수 있습니다.

단추를 추가하여 사용할 수 있습니다.[txtView resignFirstResponder]키보드를 숨깁니다.

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

대신 여기에 스니펫을 게시하기로 했습니다.

에 대한 .UITextViewDelegate의전

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

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

    return YES;
}

Swift 4.0 업데이트:

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

UITextView에는 사용자가 반환 키를 누를 때 호출될 메서드가 없습니다.를 한 할 수 , ▁a를 사용합니다.UITextFieldUITextView인터페이스 지침을 따르지 않습니다.

, 그에도불고하구만당, ▁the,면▁even▁implement원다한▁you,▁this,textView:shouldChangeTextInRange:replacementText:UITextViewDelegate그리고 그 검사에서 대체 텍스트가\n키보드를 숨깁니다.

다른 방법이 있을 수도 있지만 저는 전혀 모릅니다.

이미 답변이 완료된 것은 알지만 새 줄에 문자열 리터럴을 사용하는 것을 별로 좋아하지 않기 때문에 다음과 같이 했습니다.

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

    [txtView resignFirstResponder];
    return NO;
}

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

이것이 여러 번 답변을 받은 것은 알지만, 여기 이 문제에 대한 제 의견이 있습니다.

저는 samvermettelibeto의 답변이 정말 유용하다는 것을 알았고, libeto의 답변에서 max power의 의견도 발견했습니다.하지만 그러한 접근법에는 문제가 있습니다.매트가 같은 버메트의 대답에서 언급한 문제는 사용자가 줄 바꿈이 있는 것을 붙여넣으려면 키보드가 아무 것도 붙이지 않고 숨는다는 것입니다.

따라서 제 접근 방식은 위에 언급된 세 가지 솔루션을 혼합하여 문자열의 길이가 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;
}

더 우아한 방법은 사용자가 키보드 프레임 외부를 누를 때 키보드를 해제하는 것입니다.

먼저 ViewController의 보기를 클래스 "로 설정합니다.UIBuilder의 ID 검사기에 "UIControl"이 있습니다.뷰를 ViewController의 헤더 파일로 제어 끌어서 다음과 같은 이벤트와 작업으로 연결합니다.

View 컨트롤러.h

-(IBAction)dismissKeyboardOnTap:(id)sender;

기본 ViewController 파일의 ViewController.m:

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

비슷한 기술을 사용하여 더블 탭 또는 롱 터치가 필요할 수 있습니다.ViewController를 UITextViewDelegate로 설정하고 TextView를 ViewController에 연결해야 할 수도 있습니다.이 메서드는 UITextView 및 UITextField 모두에서 작동합니다.

출처: 빅 너드 랜치

편집: UIScrollView를 사용하는 경우 위의 기술이 인터페이스 빌더를 통해 쉽게 작동하지 않을 수 있다는 점도 추가하고 싶습니다.이 경우 UIGesture Recognizer를 사용하여 [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"])편집할 수 없습니다.

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

를 사용하여 다른 답변과 유사합니다.UITextViewDelegate swift interface 하지고빠른인터스이페롭새더만▁but▁newer▁swift▁a.isNewline다음과 같습니다.

func textView(_ textView: UITextView, shouldChangeTextIn range: NSRange, replacementText text: String) -> Bool {
    if let character = text.first, character.isNewline {
        textView.resignFirstResponder()
        return false
    }
    return true
}

uitextview와 함께 사용하는 동안 다른 솔루션이 있습니다. "textView"에서 도구 모음을 InputAccessoryView로 추가할 수 있습니다.편집을 시작해야 합니다." 그리고 이 도구 모음의 완료 단추에서 키보드를 해제할 수 있습니다. 이에 대한 코드는 다음과 같습니다.

뷰에서 DidLoad

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

텍스트 뷰에서 대리인 방법

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

도구 모음에 있는 Button Done의 동작은 다음과 같습니다.

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

뷰DidLoad에서 관찰자 추가

[[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]신에를 \n

재빠른

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에 대한 matt comment와 마찬가지로, 저도 "\n"을 탐지하는 아이디어가 마음에 들지 않습니다."반환" 키는 UITextView에서 다음 줄로 이동하는 이유가 있습니다.

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

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

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

단계:

- XIB 파일에 도구 모음 추가 - 높이를 460으로 설정

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

-다음과 같이 단추 항목을 resignateFirstResponder에 연결하는 작업을 만듭니다.

- (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파일링 및 작업 생성(보낸 이벤트:터치업 인사이드)는 다음과 같습니다.

    (IBAction)ExitKeyboard:(id)sender;
    
  • ViewController.m같이 합니다.

    (IBAction)ExitKeyboard:(id)sender {
        [self.view endEditing:TRUE];
    }
    
  • 앱을 실행하면 TextView에서 떨어진 곳을 클릭하면 키보드가 사라집니다.

스위프트 코드

클래스에서 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()
            }
        }
    }
}

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

사용해 보십시오.

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

    return YES;

}

//사용할 수 있습니다...

첫는 1단계 입니다. 첫 번째 단계는 다음에 대한 지원을 선언하는 것입니다.UITextViewDelegate은 당신의 됩니다. 를 들어, 에는 " 작은헤파서수에행다니됩일더이업의전"라는 가 있습니다. 예를 들어 다음과 같은 헤더가 있습니다.

편집기 컨트롤러.h:

@interface EditorController : UIViewController  {
  UITextView *messageTextView;
}

@property (nonatomic, retain) UITextView *messageTextView;

@end

2단계. 다음 단계에서는 컨트롤러를 UITextView의 대리인으로 등록해야 합니다.위의 예를 계속해서, 다음은 제가 초기화한 방법입니다.UITextView와 함께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;
}

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

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

    }

문제는 반환 키로 어떻게 하는지를 묻는 것이지만, 이것은 UITextView를 사용할 때 키보드를 사라지게 하려는 의도를 가진 누군가에게 도움이 될 수 있다고 생각합니다.

private func addToolBarForTextView() {
    let textViewToolbar: UIToolbar = UIToolbar()
    textViewToolbar.barStyle = .default
    textViewToolbar.items = [
        UIBarButtonItem(title: "Cancel", style: .done,
                  target: self, action: #selector(cancelInput)),
        UIBarButtonItem(barButtonSystemItem: .flexibleSpace,
                  target: self, action: nil),
        UIBarButtonItem(title: "Post Reply", style: .done,
                  target: self, action: #selector(doneInput))
    ]
    textViewToolbar.sizeToFit()
    yourTextView.inputAccessoryView = textViewToolbar
}

@objc func cancelInput() { print("cancel") }
@objc func doneInput() { print("done") }

override func viewDidLoad() {
    super.viewDidLoad()
    addToolBarForTextView()
}

뷰DidLoad 또는 다른 수명 주기 메서드에서 addToolBarForTextView()를 호출합니다.

그것이 저에게 완벽한 해결책이었던 것 같습니다.

건배.

뮈라트

좋아요. 모두가 속임수로 답을 주었지만, 저는 이것을 달성하는 올바른 방법은

다음 작업을 의 "종료 시 종료" 이벤트에 연결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;
    }
}

추가해야 합니다.UIToolbar맨 위로 이동UITextView를 사용하지 않고 쉽게shouldChangeTextIn

인 스위프트 4

let toolbar = UIToolbar(frame: CGRect(x: 0, y: 0, width: UIScreen.main.bounds.width, height: 50))
        toolbar.barStyle = .default
        toolbar.items = [
            UIBarButtonItem(barButtonSystemItem: .flexibleSpace, target: nil, action: nil),
            UIBarButtonItem(title: "Done", style: .done, target: self, action: #selector(doneAction))
        ]
        textView.inputAccessoryView = toolbar
@objc func doneAction(){
 self.textView.resignFirstResponder()
}

이 질문에 대한 정확한 답이 아니라는 것을 알지만, 저는 답을 찾기 위해 인터넷을 검색한 후 이 스레드를 발견했습니다.다른 사람들도 그런 감정을 공유하는 것 같아요.

이것은 내가 신뢰할 수 있고 사용하기 쉽다고 생각하는 UITapGesture Recognizer의 변형입니다. 텍스트 보기의 대리자를 보기 컨트롤러로 설정하면 됩니다.

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

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

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

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

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

이것이 도움이 되길 바랍니다.너무 당연한 것 같지만 웹상 어디에서도 이 솔루션을 본 적이 없습니다. 제가 잘못하고 있나요?

텍스트 보기에 대한 대리자를 설정하는 것을 잊지 마십시오. 그렇지 않으면 첫 번째 응답자를 사임할 수 없습니다.

이거 먹어봐요.

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

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

반응형