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

时间:2012-04-13 04:05:33

标签: iphone objective-c xcode cocoa-touch uitextview

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

我有一个UITextView,用户可以在其中开始输入并点击DONE并退出键盘。

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

我在setSelectedRange上使用NSMakeRange(0,0)尝试了textViewDidBeginEditing,但它不起作用。

更多信息:

可以看出......当用户点击textViewcursor出现在用户点按textView的位置。

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

5 个答案:

答案 0 :(得分:16)

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

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

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

答案 1 :(得分: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

答案 2 :(得分:6)

我遇到了同样的问题 - 在成为第一响应者时,基本上有一个延迟,它不允许您在任何selectedRange方法中更改textView*BeginEditing:。如果你试图推迟setSelectedRange:(让我们说performSelector:withObject:afterDelay:),那就会显示丑陋的混蛋。

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

  1. textViewShouldBeginEditing:
  2. textViewDidBeginEditing:
  3. textViewDidChangeSelection:
  4. 在最后一个方法(3)中设置selectedRange可以解决问题,只需要确保在UITextView成为第一响应者时第一次重新定位光标(3) )每次更新内容时都会调用。

    shouldChangeTextInRange: 中设置的BOOL变量方法(1),(2)中的一个并检查(3)中的变量应该可以做到这一点......只需要#&# 39;忘记在重新定位后重置变量,以避免光标复位:)。

    希望它有所帮助!

    修改

    经过几轮测试后,我决定在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)];
        }
    }
    

答案 3 :(得分:1)

我没有做足够的工作来帮助你,但是当你尝试使用不同的selectedRange s时会发生什么?比方说,如果你[... setSelectedRange:[NSMakeRange(0,1)]][... setSelectedRange:[NSMakeRange(1,0)]]?它是否将光标移动到任何位置?

答案 4 :(得分:0)

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