首页 文章

如何限制UITextView中的行数?

提问于
浏览
7

我的屏幕上有一个UITextView,用户应该只填充 two lines ,当用户在第二行时,返回键应该变为 Done .

如何在UITextView中限制 lines 的数量?我搜索了很多,没有结果有用!

我找到了Swift的答案:

locationNoteTextView.textContainer.maximumNumberOfLines = 2
self.locationNoteTextView.textContainer.lineBreakMode = NSLineBreakMode.ByClipping

它不起作用,通过这种方式用户可以输入无限字符,但在屏幕上查看的只是两行!

因此,如果您尝试打印textView文本,您将找到灾难文本 .

6 回答

  • 11

    你需要实现 textView:shouldChangeTextInRange:replacementText: . 只要文本要更改,就会调用此方法 . 您可以使用其text属性访问文本视图的当前内容 .

    使用 [textView.text stringByReplacingCharactersInRange:range withString:replacementText] 从传递的范围和替换文本构造新内容 .

    然后,您可以计算行数并返回 YES 以允许更改或 NO 拒绝它 .

    EDIT: 关于OP请求:

    func sizeOfString (string: String, constrainedToWidth width: Double, font: UIFont) -> CGSize {
        return (string as NSString).boundingRectWithSize(CGSize(width: width, height: DBL_MAX),
            options: NSStringDrawingOptions.UsesLineFragmentOrigin,
            attributes: [NSFontAttributeName: font],
            context: nil).size
    }
    
    
    func textView(textView: UITextView, shouldChangeTextInRange range: NSRange, replacementText text: String) -> Bool {
        let newText = (textView.text as NSString).stringByReplacingCharactersInRange(range, withString: text)
        var textWidth = CGRectGetWidth(UIEdgeInsetsInsetRect(textView.frame, textView.textContainerInset))
        textWidth -= 2.0 * textView.textContainer.lineFragmentPadding;
    
        let boundingRect = sizeOfString(newText, constrainedToWidth: Double(textWidth), font: textView.font!)
        let numberOfLines = boundingRect.height / textView.font!.lineHeight;
    
        return numberOfLines <= 2;
    }
    
  • -3

    适用于iOS 7

    textView.textContainer.maximumNumberOfLines = 10;
    textView.textContainer.lineBreakMode = NSLineBreakByTruncatingTail;
    

    要么

    textView.textContainer.maximumNumberOfLines = 10;
    [textView.layoutManager textContainerChangedGeometry:textView.textContainer];
    
  • 0

    这是@Abhinav的回答,但在 Swift

    func textView(textView: UITextView, shouldChangeTextInRange range: NSRange, replacementText text: String) -> Bool {
    
    
        let newText = (textView.text as NSString).stringByReplacingCharactersInRange(range, withString: text)
    
        let textAttributes = [NSFontAttributeName: textView.font]
    
        var textWidth: CGFloat = CGRectGetWidth(UIEdgeInsetsInsetRect(textView.frame, textView.textContainerInset))
    
        textWidth -= 2.0 * textView.textContainer.lineFragmentPadding
    
        let boundingRect: CGRect = newText.boundingRectWithSize(CGSizeMake(textWidth, 0), options: NSStringDrawingOptions.UsesLineFragmentOrigin|NSStringDrawingOptions.UsesFontLeading, attributes: textAttributes, context: nil)
    
      var numberOfLines = CGRectGetHeight(boundingRect) / textView.font.lineHeight;
    
        return numberOfLines <= 2;
    }
    
  • 14

    如果有人想要实时行数,这就是你用RxSwift和RxCocoa做的

    let disposeBag = DisposeBag()
    
        textView.rx_text.asDriver().driveNext { text in
    
            let text = text as NSString
    
            var textWidth: CGFloat = CGRectGetWidth(UIEdgeInsetsInsetRect(self.textView.frame, self.textView.textContainerInset))
    
            textWidth -= 2.0 * self.textView.textContainer.lineFragmentPadding
    
            let textAttributes = [NSFontAttributeName: UIFont(name: “Set your font here”, size: 26.0)!]
    
            let boundingRect: CGRect = text.boundingRectWithSize(CGSizeMake(textWidth, 0), options: [NSStringDrawingOptions.UsesLineFragmentOrigin, NSStringDrawingOptions.UsesFontLeading], attributes: textAttributes, context: nil)
    
            let font = UIFont(name: “Set your font here”, size: 26.0)
    
            guard let lineHeight = font?.lineHeight else {return}
    
            let numberOfLines = CGRectGetHeight(boundingRect) / lineHeight
    
            if numberOfLines <= 2 {
    
    
                self.textView.typingAttributes = [NSFontAttributeName: UIFont(name: “Set your font here”, size: 26.0)!, NSForegroundColorAttributeName: “Set your color here”]
    
            } else {
    
                self.textView.typingAttributes = [NSFontAttributeName: UIFont(name: “Set your font here”, size: 18.0)!, NSForegroundColorAttributeName: “Set your color here”]
    
            }
    
        }.addDisposableTo(disposeBag)
    
  • 0

    这是@ Abhinav的回答更新 Swift 3

    func textView(_ textView: UITextView, shouldChangeTextIn range: NSRange, replacementText text: String) -> Bool {
    
        guard maxLines > 0 else {
            return true
        }
    
        let newText = (textView.text as NSString).replacingCharacters(in: range, with: text)
    
        let textAttributes = [NSAttributedStringKey.font : textView.font!]
    
        var textWidth: CGFloat = UIEdgeInsetsInsetRect(textView.frame, textView.textContainerInset).width
    
        textWidth -= 2.0 * textView.textContainer.lineFragmentPadding
    
        let boundingRect: CGRect = newText.boundingRect(with: CGSize(width: textWidth, height: 0), options: [.usesLineFragmentOrigin, .usesFontLeading], attributes: textAttributes, context: nil)
    
        let numberOfLines = Int(floor(boundingRect.height / textView.font!.lineHeight))
    
        return numberOfLines <= maxLines
    
    }
    

    其中 maxLines 是您要将textView限制为的行数 . 如果它是0那么无限数量的行 .

  • 0

    在下面找到Abhinav答案的Objective C版本:

    -(BOOL)textView:(UITextView *)textView shouldChangeTextInRange:(NSRange)range replacementText:(NSString *)text
    {
        NSString *newText = [textView.text stringByReplacingCharactersInRange:range withString:text];
        CGFloat textWidth = CGRectGetWidth(UIEdgeInsetsInsetRect(textView.frame, textView.textContainerInset));
        textWidth -= 2.0 * textView.textContainer.lineFragmentPadding;
    
        CGSize boundingRect = [self sizeOfString:newText constrainedToWidth:textWidth font:textView.font];
        NSInteger numberOfLines = boundingRect.height / textView.font.lineHeight;
    
        return numberOfLines <= 2;
    }
    
    -(CGSize)sizeOfString:(NSString *)string constrainedToWidth:(double)width font:(UIFont *)font
    {
        return  [string boundingRectWithSize:CGSizeMake(width, DBL_MAX) options:NSStringDrawingUsesLineFragmentOrigin attributes:@{NSFontAttributeName: font} context:nil].size;
    }
    

相关问题