web-dev-qa-db-ja.com

UITextViewにフォーカスを失ったときにキーボードを非表示にする

したがって、ユーザーがテキストを送信できるようにするために使用しているUITextViewがあります。

私の問題は、UITextViewからタップしてユーザーが「キャンセル」できるようにする方法を理解できないようです。

45
tuzzolotron

簡略化 tuzzolotronの答え :次のコンセントがxibで適切に接続されている場所

    IBOutlet UITextView *myTextView;

View Controllerでこれを使用します。

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

    UITouch *touch = [[event allTouches] anyObject];
    if ([myTextView isFirstResponder] && [touch view] != myTextView) {
        [myTextView resignFirstResponder];
    }
    [super touchesBegan:touches withEvent:event];
}

テキストビューの外側にあるView Controllerのビューをタップすると、最初のレスポンダーが辞任し、キーボードが閉じます。

107
ohhorob

UITableViews、Searchbar、キーボードを操作するときによく使用した別のアプローチはこれです。テキストフィールドに適用できると思います

UITapGestureRecognizer *gestureRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(hideKeyboard)];
[self.tableView addGestureRecognizer:gestureRecognizer];
gestureRecognizer.cancelsTouchesInView = NO;  // this prevents the gesture recognizers to 'block' touches
[gestureRecognizer release];

そして、ここに簡単なコールバック関数があります

- (void)hideKeyboard {
    [myTextField resignFirstResponder];
}

それが役に立てば幸い

30
Sr.Richie

私からしてみれば:

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
    UITouch *touch = [touches anyObject];

    // pass touches up to viewController
    [self.nextResponder touchesBegan:touches withEvent:event];
}

私のViewControllerで:

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

    UITouch *touch = [[event allTouches] anyObject];
    if (keyboardShown && [touch view] != self.TextView) 
    {
         [self.TextView resignFirstResponder];
    }
    [super touchesBegan:touches withEvent:event];
}

- (void)keyboardWasShown:(NSNotification*)aNotification
{    
        keyboardShown = YES;
}
7
tuzzolotron

これは古い投稿ですが、もっと簡単なものを見つけたときにこのソリューションを実装していました(当時は利用できなかったかもしれません)。

[self.myTextView endEditing:YES];

UITableViewを使用しているので、この行をdidSelectRowAtIndexPath:メソッドに追加します。ここまでは順調ですね...

3
Carlos B
override func touchesBegan(touches: NSSet, withEvent event: UIEvent) {
    var touch = event.allTouches()?.anyObject() as UITouch

    if( textfield.isFirstResponder() && touch.view != textfield) {
        textfield.resignFirstResponder()
        NSLog("Resigning first responder since touches began outside")
    }

    super.touchesBegan(touches, withEvent: event)
}

ohhorobの答えは私にも役立ちました。簡単なSwiftと同等です。

2
atomic_ice

Swift 3コード

override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
    if let touch = touches.first {
        if textField.isFirstResponder && touch.view != textField {
            textField.resignFirstResponder()
        }
    }
    super.touchesBegan(touches, with: event)
}
2
mythicalcoder

アウトレットに依存せず、コントローラー内の任意の数のUITextFieldオブジェクトで機能する、より良いソリューションを次に示します。

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

    UITouch *touch = [[event allTouches] anyObject];

    if (![[touch view] isKindOfClass:[UITextField class]]) {
        [self.view endEditing:YES];
    }
    [super touchesBegan:touches withEvent:event];
}
1
Yas T.

非常に簡単

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

私は、各ビューに特定のアウトレットを必要とせずに、任意のビューから辞​​退するために機能するこのバージョンが必要でした。

MonoTouch C#を使用していますが、Objective-Cに変換する方法は明らかです

    private void findAndResignFirstResponder(UIView node=null) {
        if (node == null) { return; }
        if (node.IsFirstResponder) {
            node.ResignFirstResponder();
            return;
        }

        foreach (UIView view in node.Subviews) {
            findAndResignFirstResponder(node:view);
        }
    }

    private bool haveDrag = false;
    public override void TouchesEnded(NSSet touches, UIEvent evt) {
        if (!haveDrag) {
            UITouch touch = (UITouch)evt.AllTouches.AnyObject;
            if (!touch.View.CanBecomeFirstResponder) {
                this.findAndResignFirstResponder(this);
                Console.WriteLine("resign");
            }
        }
        base.TouchesEnded (touches, evt);
    }
    public override void TouchesMoved(NSSet touches, UIEvent evt) {
        haveDrag = true;
        base.TouchesMoved (touches, evt);
    }

    public override void TouchesBegan(NSSet touches, UIEvent evt) {
        haveDrag = false;
        base.TouchesBegan (touches, evt);
    }
0
David Jeske

私のやり方...

  • ViewControllerの@interfaceでTextViewへの参照を追加します。

    @property (weak, nonatomic) IBOutlet UITextView *yourTextView;
    
  • ViewControllerの@implementationでこのメソッドをオーバーライドします。

    - (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView
    {
        if ([self.yourTextView isFirstResponder]) {
          [self.yourTextView resignFirstResponder];
        }
    }
    
0