7

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

我有一个UITextView用户可以在其中开始输入并单击完成并退出键盘。

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

我试过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) 中设置selectedRange可以解决问题,您只需要确保仅在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)];
    }
}
于 2014-10-21T06:11:40.137 回答
1

我在这方面的工作还不足以完全帮助您,但是当您尝试使用不同selectedRange的 s 时会发生什么?说,如果你这样做[... setSelectedRange:[NSMakeRange(0,1)]][... setSelectedRange:[NSMakeRange(1,0)]]?它会将光标移动到任何地方吗?

于 2012-04-13T04:17:44.293 回答
0

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

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