如何在用户输入上设置UITextView的光标位置?

Leg*_*las 6 iphone xcode cocoa-touch objective-c uitextview

我正在寻找这个问题的简单答案......

我有一个UITextView用户可以开始输入并单击DONE并重新签名键盘.

当想要再次编辑它时,我希望光标(闪烁的线)位于第一个位置,而textView不是在textView的末尾.(像占位符一样)

我试图setSelectedRangeNSMakeRange(0,0)textViewDidBeginEditing,但它不工作.

更多信息:

可以看出.当用户点击了textViewcursor在哪里用户点击的位置上来textView.

我希望它始终在起始位置闪烁textViewDidBeginEditing.

tka*_*kic 16

无法在"任何地方"分配属性selectedRange,为了使其工作,您必须实现该方法- (void)textViewDidChangeSelection:(UITextView *)textView,在您的情况下:

- (void)textViewDidChangeSelection:(UITextView *)textView
{
    [textView setSelectedRange:NSMakeRange(0, 0)];
}
Run Code Online (Sandbox Code Playgroud)

您必须检测用户何时开始编辑或选择文本

  • 这是我遇到的最好的解决方案。这确实应该是最佳答案! (2认同)

jas*_*inh 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);
}
Run Code Online (Sandbox Code Playgroud)

我想这是用户点击它时设置光标的UITextView内部机制.我们需要通过附加一个轻敲手势识别器来becomeFirstResponder代替它.


Dav*_*man 6

我面临着同样的问题 - 当成为第一响应者时,基本上会有延迟,不允许你改变selectedRange任何textView*BeginEditing:方法.如果你试图推迟setSelectedRange:(让我们说performSelector:withObject:afterDelay:)它显示丑陋的混蛋.

解决方案实际上非常简单 - 检查委托方法的顺序为您提供了提示:

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

设置selectedRange在最后一个方法(3)的伎俩,你只需要确保你重新定位光标仅在第一次时,UITextView成为第一个响应者为(3)被称为每次更新内容时间的方法.

shouldChangeTextInRange: 在方法(1),(2)之一中设置BOOL变量并检查(3)中的变量应该可以做到这一点......只是不要忘记在重新定位后重置变量以避免常量游标重置: ).

希望能帮助到你!

编辑

经过几轮测试后,我决定将BOOL标志设置为shouldChangeTextInRange:而不是(2)或(3),因为它被证明是更通用的.看我的代码:

@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)];
    }
}
Run Code Online (Sandbox Code Playgroud)


Leg*_*las 0

所以我最终添加了一个 UILabel 来UITextView充当 textView 的占位符。点击 UILabel 会将操作发送到 textView 和becomeFirstResponder。开始输入后,隐藏标签。

  • 看起来非常h​​acky。为什么不用 UIView 而不是 UILabel? (2认同)