检测的时刻,在换行开始的UITextView

问题描述 投票:15回答:7

我尝试当马车去在UITextView的新行检测。我可以通过与UITextView的宽度比较总以后宽度检测它:

CGSize size = [textView.text sizeWithAttributes:textView.typingAttributes];
if(size.width > textView.bounds.size.width)
      NSLog (@"New line");

但由于-sizeWithAttributes:textView只返回的字母宽度无压痕宽度也没有作用有道。请帮助解决这个问题。

ios objective-c nsstring uitextview
7个回答
30
投票

这是我会怎么做:

  • 获取最后一个字符的UITextPosition
  • 呼叫caretRectForPositionUITextView
  • 创建一个CGRect变量,最初存储CGRectZero在里面。
  • 在你textViewDidChange:方法,通过将caretRectForPosition:调用UITextPosition
  • 与存储在CGRect变量的当前值进行比较。如果caretRect的新y原点是比上一个更大的,这意味着一个新行已经达到。

示例代码:

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

    UITextPosition* pos = yourTextView.endOfDocument;//explore others like beginningOfDocument if you want to customize the behaviour
    CGRect currentRect = [yourTextView caretRectForPosition:pos];

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

}

此外,你应该阅读UITextInput协议参考here的文档。这是神奇的,我告诉你。

让我知道,如果您有任何这方面的其他问题。


8
投票

对于斯威夫特使用本

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

    }

6
投票

Swift-4 @ n00bProgrammer的答案更精确的断线检测。

@ n00bProgrammer答案是,除了一两件事,当用户开始在第一行中键入它的反应不同完美,它呈现了Started New Line了。 克服的问题,这里是细化码

    var previousRect = CGRect.zero
    func textViewDidChange(_ textView: UITextView) {
        let pos = textView.endOfDocument
        let currentRect = textView.caretRect(for: pos)
        self.previousRect = self.previousRect.origin.y == 0.0 ? currentRect : self.previousRect
        if currentRect.origin.y > self.previousRect.origin.y {
            //new line reached, write your code
            print("Started New Line")
        }
        self.previousRect = currentRect
    }

4
投票

斯威夫特3

接受答案,并迅速版本工作正常,但这里是一个斯威夫特3版本懒惰的人在那里。

class CustomViewController: UIViewController, UITextViewDelegate {

    let textView = UITextView(frame: .zero)
    var previousRect = CGRect.zero

    override func viewDidLoad(){
        textView.frame = CGRect(
            x: 20, 
            y: 0, 
            width: view.frame.width, 
            height: 50
        )
        textView.delegate = self
        view.addSubview(textView)
    }

    func textViewDidChange(_ textView: UITextView) {
        let pos = textView.endOfDocument
        let currentRect = textView.caretRect(for: pos)
        if previousRect != CGRect.zero {
            if currentRect.origin.y > previousRect.origin.y {
                print("new line")
            }
        }
        previousRect = currentRect
    }
}

3
投票

您可以使用UITextViewDelegate

- (BOOL)textView:(UITextView *)textView shouldChangeTextInRange:(NSRange)range replacementText: (NSString *)text
{
     BOOL newLine = [text isEqualToString:@"\n"];
     if(newLine)
     {
          NSLog(@"User started a new line");
     }
     return YES;
}

0
投票

你需要得到的文本,而不是宽度的高度。二者必选其一sizeWithFont:constrainedToSize:lineBreakMode:(如果你需要支持的iOS 6或更早版本),或使用boundingRectWithSize:options:attributes:context:如果你只支持iOS的7。


0
投票

SWIFT 4

如果你不希望使用previousRect。让我们试试这个:

func textViewDidChange(_ textView: UITextView) {
    let pos = textView.endOfDocument
    let currentRect = textView.caretRect(for: pos)
    if (currentRect.origin.y == -1 || currentRect.origin.y == CGFloat.infinity){
       print("Yeah!, I've gone to a new line") 
       //-1 for new line with a char, infinity is new line with a space
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.