質問

IB の図書館の序文には、 戻る キーが押されると、キーボードが UITextView 消えるだろう。しかし実際には、 戻る キーは「 」としてのみ機能します。

ボタンを追加して使用できます [txtView resignFirstResponder] キーボードを非表示にします。

しかし、アクションを追加する方法はありますか? 戻る 追加する必要がないようにキーボードを入力します UIButton?

役に立ちましたか?

解決

UITextViewは、ユーザーがリターンキーを打つときに呼び出されるすべてのメソッドを持っていません。あなたは、ユーザーがテキストの唯一の1行を追加することができるようにしたい場合は、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 セントです。

私が答えを見つけたのは、 サンベルメット そして リベト 本当に役に立ちました、そして、によるコメントも マックスパワー の中に リベトさんの答え。しかし、これらのアプローチには問題があります。という問題 マットな での言及 サンベルメットの答えは、ユーザーが内部に改行を含む何かを貼り付けたい場合、何も貼り付けずにキーボードが非表示になるということです。

したがって、私のアプローチは上記の3つの解決策を組み合わせたもので、文字列の長さが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のビュー「Uicontrolのは、」UIBuilderにおけるアイデンティティインスペクタで設定します。 ViewControllerのヘッダファイルにビューをコントロール - ドラッグして、タッチアップインサイドなどのイベントでアクションとしてそれをリンクする、といったます:

ViewController.h

-(IBAction)dismissKeyboardOnTap:(id)sender;

メインのViewControllerファイルで、ViewController.mます:

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

あなたは、同様の技術を使用してダブルタップまたはロングタッチを要求することができます。あなたはUITextViewDelegateなるとのViewControllerにのTextViewを接続するために、あなたのViewControllerを設定する必要があるかもしれません。この方法は、UITextViewで、UITextFieldの両方で動作します。

出典:ビッグオタクランチ

編集:私はまた、あなたがUIScrollViewのを使用している場合は、上記の技術は、Interface Builderを通過ように簡単に動作しない可能性があることを追加したいと思います。その場合、あなたはUIGestureRecognizerを使用することができますし、[[セルフビュー] 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;
}
  

ツールバーにある[Done]ボタンのアクションで、次のされます:

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

私は josebama にすることによって答えは、このスレッドで利用可能な最も完全かつクリーンな答えであることが判明しました。

以下であるのスウィフト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
}

SWIFT

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

 と設定」 loading=

キーボードを閉じバーをホストするためにナビゲーションコントローラを使用します:

.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で理由があり、それは当然の次の行に行くことです。

キーボード上のツールバー(ボタン)を追加することです -

私の意見では最良の解決策は、iPhoneのメッセージアプリを模倣することです。

私は次のブログ記事からコードを得ました

http://www.iosdevnotes.com/2011/02/iphone -keyboard-ツールバー/

手順:

あなたのXIBファイルに

-Addツールバー - 460に高さを設定する

-Addツールバーボタン項目(まだ追加されていない場合)。あなたに必要がある場合も、それを右揃えXIBに柔軟なバーボタンアイテムを追加し、ツールバーのボタンの項目を移動する

次のようにresignFirstResponderにあなたのボタンの項目をリンク-Create行動ます:

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

-Thenます:

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

この問題を別の方法で解決しました。

  • 背景に配置するボタンを作成する
  • 属性インスペクターからボタンのタイプをカスタムに変更すると、ボタンが透明になります。
  • ボタンを展開してビュー全体をカバーし、ボタンが他のすべてのオブジェクトの背後にあることを確認します。これを行う簡単な方法は、ビュー内のリスト ビューの上部にボタンをドラッグすることです。
  • Control ボタンをドラッグして viewController.h ファイルを作成し、アクション (送信イベント:内側をタッチアップ) のような:

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

次に、セレクターを使用して「 」を確認します。

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

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

「 」を使用し、特にリターンキーをチェックしませんが、これで問題ないと思います。

アップデート

以下を使用する ribto の回答を参照してください。 [NSCharacterSet newlineCharacterSet] 代わりに \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のデリゲートとしてのコントローラを登録する必要があります。上記の例から続けて、ここでは

...私は、デリゲートとしてUITextViewEditorControllerを初期化している方法です
- (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のデリゲートを設定します
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()
            }
        }
    }
}

編集 workarround用とハックのコードが完成した後の状態をリセットしないようにテキストフィールドにユーザーの入力を変更することをお勧めことはありませんので、私は、コードを更新します。

あなたはまた、キーボードを非表示にすることができたときにビュー画面でタッチます:

- (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 Ctrl キーを押しながら「」からドラッグします退出時に終了しました'を以下の方法に変更します。

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

コールのaddToolBarForTextView()ののviewDidLoad の中や他のいくつかのライフ・サイクル・メソッドます。

それは私のための完璧なソリューションだったようです。

乾杯、

ミュラ

私はそれがこの質問に正確な答えはありません知っているが、私は答えのためのインターネットを追い詰めるした後、このスレッドを発見しました。私は他の人がその気持ちを共有すると仮定します。

これは、私が信頼性が高く、使いやすい見つけるUITapGestureRecognizerの私の分散である - ただのViewControllerへのTextViewのデリゲートを設定する

。 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の場合。、スウィフト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()
        }
    }

あなたは、むしろ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()
}
-(BOOL)textFieldShouldReturn:(UITextField *)textField; // called from textfield (keyboard)

-(BOOL)textView:(UITextView *)textView shouldChangeTextInRange:(NSRange)range replacementText:(NSString *)text; // good tester function - thanks
ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top