UITextView(编辑) - 检测下一行事件发生

时间:2011-02-02 11:16:36

标签: iphone ipad uitextview

我有一个可编辑的UITextView。现在我有一个要求,要求我找到(当我一直打字时)关于下一行何时开始(可能是因为我点击了返回键,或者是自动wordwrap换行符)。是否有任何通知可以获取以确定下一行何时开始输入?

我尝试搜索解决方案以找出文本视图中的光标位置,但使用selectedRange和位置属性来查找它并没有帮助我。位置值和新行之间根本没有相关性。键入时位置值会不断增加。有什么想法吗?

谢谢!

7 个答案:

答案 0 :(得分:10)

只要在textView中输入新文本,就会调用以下委托。

设置UITextView的委托,然后编码如下

- (BOOL)textView:(UITextView *)textView shouldChangeTextInRange:(NSRange)range replacementText:(NSString *)text;
{
    if ( [text isEqualToString:@"\n"] ) {
        //Do whatever you want
    }
    return YES;
}

答案 1 :(得分:5)

对于Swift使用此

previousRect = CGRectZero

 func textViewDidChange(textView: UITextView) {

        var pos = textView.endOfDocument
        var currentRect = textView.caretRectForPosition(pos)
        if(currentRect.origin.y > previousRect?.origin.y){
            //new line reached, write your code
        }
        previousRect = currentRect

    }

对于目标C

CGRect previousRect = CGRectZero;
- (void)textViewDidChange:(UITextView *)textView{

    UITextPosition* pos = textView.endOfDocument;
    CGRect currentRect = [textView caretRectForPosition:pos];

    if (currentRect.origin.y > previousRect.origin.y){
            //new line reached, write your code
        }
    previousRect = currentRect;

}

答案 2 :(得分:2)

将检测来自任何东西的线条变化以达到“返回”,退格以减少行数,键入直到行尾并发生自动换行等。(*注意:必须调整字体大小的变量,I建议不要使用硬编码的数字,如下例所示。)

previousNumberOfLines = ((hiddenText.contentSize.height-37+21)/(21));//numbers will change according to font size
NSLog(@"%i", previousNumberOfLines);

答案 3 :(得分:1)

我参加派对有点晚了,但我有类似的要求,经过一番调查后我发现KingofBliss'答案与

结合
-[id<NSLayoutManagerDelegate> layoutManager:shouldBreakLineByWordBeforeCharacterAtIndex:];
-[id<NSLayoutManagerDelegate> layoutManager:shouldBreakLineByHyphenatingBeforeCharacterAtIndex:];

为我做了诀窍。

您可以将任何对象设置为UITextView布局管理器的委托,如下所示:

textView.textContainer.layoutManager.delegate = (id<NSLayoutManagerDelegate>)delegate

希望这证明是有用的。

答案 4 :(得分:0)

向视图添加第二个隐藏文本视图。为可见文本视图实现shouldChangeTextInRange,并将隐藏视图上的文本设置为新文本。比较新文本与旧文本的contentSize以检测自动换行。

答案 5 :(得分:0)

- (BOOL)textView:(UITextView *)textView shouldChangeTextInRange:(NSRange)range
 replacementText:(NSString *)text
{

    if ([text isEqualToString:@"\n"]) {
        textView.text=[NSString stringWithFormat:@"%@\n",textView.text];
        // Return FALSE so that the final '\n' character doesn't get added
        return NO;
    }
    // For any other character return TRUE so that the text gets added to the view
    return YES;
}

答案 6 :(得分:0)

Sourav Gupta的解决方案对我来说部分起作用,但是它有一些陷阱,即如果编辑发生在文本主体的中间,则它不能正确调用目标代码(例如:编写一堆文本,移动将光标移到中间,然后按回车键三下),以及处理插入事件(如粘贴和文本更正)。结果,我自己进行了一些测试,发现了一些其他情况,在这些情况下,我们可以假定编辑已移至下一行。

注意:这种方法有一些误报,但是我发现在使用它来中继代码时,它可以容忍得多,因此不必要地布局比不响应好得多

雨燕5


private var previousRect:CGRect = CGRect.zero
private func checkIfReturnOrLineWrap(textView:UITextView) {
    let currentRect = textView.caretRect(for:textView.endOfDocument)
    if (currentRect.origin.y != previousRect.origin.y && (previousRect.origin.y != CGFloat.infinity || currentRect.origin.y > 0) ||
        currentRect.origin.y == CGFloat.infinity) {
        //React to the line change!
    }
    previousRect = currentRect
}

//MARK: UITextViewDelegate methods (be sure to hook up your textviews!)
func textViewDidChange(_ textView: UITextView) {
    checkIfReturnOrLineWrap(textView: textView)
}

func textView(_ textView: UITextView, shouldChangeTextIn range: NSRange, replacementText text: String) -> Bool {
    checkIfReturnOrLineWrap(textView: textView)
    return true
}