我尝试在UITextView中检测何时在换行处进行运输。我可以通过比较总后期宽度与 UITextView 宽度来检测它:
CGSize size = [textView.text sizeWithAttributes:textView.typingAttributes];
if(size.width > textView.bounds.size.width)
NSLog (@"New line");
但它不能正常工作,因为-sizeWithAttributes:textView
只返回字母宽度而没有缩进宽度。请帮忙解决这个问题。
这就是我会这样做的:
- 获取最后一个字符的
UITextPosition
。 - 拨打
UITextView
上的caretRectForPosition
。 - 创建一个
CGRect
变量,并最初在其中存储CGRectZero
。 - 在
textViewDidChange:
方法中,通过传递UITextPosition
来调用caretRectForPosition:
。 - 将其与存储在
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
协议参考的文档。这很神奇,我告诉你。
如果您对此有任何其他问题,请告诉我。
@n00bProgrammer Swift-4
的答案,具有更精确的换行符检测。
@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
}
对于 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
}
您可以使用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;
}
Swift 3
接受的答案和 swift 版本工作正常,但这里是为懒惰的人准备的 Swift 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
}
}
SWIFT 5
让我们不要把事情复杂化。
func textView(_ textView: UITextView, shouldChangeTextIn range: NSRange, replacementText text: String) -> Bool {
if text == "n" {
// return pressed
}
}
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
}
}
您需要获取文本的高度,而不是宽度。使用sizeWithFont:constrainedToSize:lineBreakMode:
(如果您需要支持 iOS 6 或更早版本)或使用boundingRectWithSize:options:attributes:context:
(如果您仅支持 iOS 7)。