7

この問題に対する簡単な答えを探しています...

UITextViewユーザーが入力を開始し、[完了] をクリックしてキーボードを辞任できるようにしました。

もう一度編集したいときは、カーソル(点滅する行)をtextViewtextView の最後ではなく、の最初の位置に配置します。(プレースホルダーのように振る舞う)

onで試しsetSelectedRangeてみましたが、うまくいきません。NSMakeRange(0,0)textViewDidBeginEditing

より詳しい情報:

ユーザーが をタップすると、ユーザーが をタップしtextViewcursor位置に が表示されることがわかりますtextView

のときは常に開始位置で点滅させたいtextViewDidBeginEditing

4

6 に答える 6

19

プロパティ selectedRange を「任意の場所」に割り当てることはできません。それを機能させるには、メソッドを実装する必要があり- (void)textViewDidChangeSelection:(UITextView *)textViewます。

- (void)textViewDidChangeSelection:(UITextView *)textView
{
    [textView setSelectedRange:NSMakeRange(0, 0)];
}

ユーザーがテキストの編集または選択を開始したときを検出する必要があります

于 2012-10-17T08:39:05.523 に答える
11

私の解決策:

- (void) viewDidLoad {
    UITextView *textView = [[UITextView alloc] initWithFrame: CGRectMake(0, 0, 200, 200)];
    textView.text = @"This is a test";
    [self.view addSubview: textView];
    textView.delegate = self;
    [textView release];
    UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget: self action: @selector(tapped:)];
    [textView addGestureRecognizer: tap];
    [tap release];
}
- (void) tapped: (UITapGestureRecognizer *) tap {
    [textView becomeFirstResponder];
} 

- (void) textViewDidBeginEditing:(UITextView *)textView {
    textView.selectedRange = NSMakeRange(0, 0);
}

ユーザーがカーソルをタップしたときにカーソルを設定するのは、UITextViewの内部メカニズムだと思います。タップ ジェスチャ レコグナイザをアタッチして代わりに呼び出すことで、これをオーバーライドする必要がありますbecomeFirstResponder

于 2012-04-13T04:33:22.913 に答える
6

selectedRange私は同じ問題に直面していました-基本的に、最初の応答者になると遅延が発生し、どの方法でも変更できなくなりますtextView*BeginEditing:setSelectedRange:(としましょう)を遅らせようとすると、performSelector:withObject:afterDelay:醜いジャークが表示されます。

解決策は実際には非常に単純です。デリゲート メソッドの順序を確認すると、ヒントが得られます。

  1. textViewShouldBeginEditing:
  2. textViewDidBeginEditing:
  3. textViewDidChangeSelection:

最後のメソッド (3) で設定するとうまくいきます。コンテンツを更新するたびにメソッド (3) が呼び出されるため、最初のレスポンダーselectedRangeになるときにのみカーソルの位置を変更する必要があります。UITextView

shouldChangeTextInRange: メソッド (1)、(2) のいずれかで設定された BOOL 変数と、(3) で変数をチェックすることでうまくいくはずです。常にカーソルがリセットされるのを避けるために、再配置後に変数をリセットすることを忘れないでください。 )。

それが役に立てば幸い!

編集

数回のテストの後shouldChangeTextInRange:、(2) または (3) の代わりに BOOL フラグを設定することにしました。私のコードを見てください:

@interface MyClass
{
    /** A flag to determine whether caret should be positioned (YES - don't position caret; NO - move caret to beginning). */
    BOOL _isContentGenerated;
}

- (BOOL)textView:(UITextView *)textView shouldChangeTextInRange:(NSRange)range replacementText:(NSString *)text
{
    // deleting
    if([text length] == 0)
    {
        // deleting last character
        if(range.length == [[textView text] length])
        {
            // reached beginning
            /** 
             code to show placeholder and reset caret to the beginning 
            */
            _isContentGenerated = NO;
        }
    }
    else
    {
        // adding
        if(range.location == 0)
        {
            /** 
             code to hide placeholder
            */
            _isContentGenerated = YES;
        }
    }
    return YES;
}

- (void)textViewDidChangeSelection:(UITextView *)textView
{
    if(!_isContentGenerated)
    {
        [textView setSelectedRange:NSMakeRange(0, 0)];
    }
}
于 2014-10-21T06:11:40.137 に答える
1

私はあなたを完全に助けるのに十分な作業をしていませんが、別selectedRangeの で遊んでみるとどうなりますか? あなたがする[... setSelectedRange:[NSMakeRange(0,1)]]か、または[... setSelectedRange:[NSMakeRange(1,0)]]?カーソルをどこかに移動しますか?

于 2012-04-13T04:17:44.293 に答える
0

UITextViewそのため、textView のプレースホルダーとして機能する UILabel を追加することになりました。UILabel をタップすると、アクションが textView およびbecomeFirstResponder. 入力を開始したら、ラベルを非表示にします。

于 2012-06-08T18:35:57.063 に答える
-4
[_detailAreaView setTextContainerInset:UIEdgeInsetsMake(8, 11, 8, 11)];
于 2015-12-21T10:54:43.537 に答える