美文网首页
每行文字下方画线的 UITextView

每行文字下方画线的 UITextView

作者: 努力奔跑的____ | 来源:发表于2018-12-06 21:22 被阅读0次

    每行文字下方画线的 UITextView, 如下图:


    屏幕快照 2018-12-06 下午9.20.37.png
    import UIKit
    
    @IBDesignable
    public class LinedTextView: UITextView {
        @IBInspectable public var separatorLineHeight: CGFloat = 1
        @IBInspectable public var separatorLineColor: UIColor = UIColor.gray
        
        // should be called after setting all font attributes
        public func getRealHeight(numberOfLine: Int) -> CGFloat {
            guard let realLineHeight = realLineHeight, numberOfLine >= 0 else {
                return 0
            }
            return realLineHeight * CGFloat(numberOfLine) + textContainerInset.top + textContainerInset.bottom + separatorLineHeight / 2
        }
        
        public var realLineHeight: CGFloat? {
            guard let currentFont = font else {
                return nil
            }
            var lineHeight: CGFloat = currentFont.lineHeight
            var range: NSRange = NSRange(location: 0, length: text.lengthOfBytes(using: .unicode))
            if let paragraphStyle = attributedText.attribute(NSAttributedStringKey.paragraphStyle, at: 0, effectiveRange: &range) as? NSParagraphStyle {
                // priority order: maximumLineHeight > minimumLineHeight > lineHeightMultiple
                if paragraphStyle.lineHeightMultiple != 0 {
                    lineHeight = paragraphStyle.lineHeightMultiple * currentFont.lineHeight
                }
                if paragraphStyle.minimumLineHeight != 0 {
                    lineHeight = max(lineHeight, paragraphStyle.minimumLineHeight)
                }
                if paragraphStyle.maximumLineHeight != 0 {
                    lineHeight = min(lineHeight, paragraphStyle.maximumLineHeight)
                }
            }
            return lineHeight
        }
        
        override public func draw(_ rect: CGRect) {
            super.draw(rect)
            guard let context = UIGraphicsGetCurrentContext(), let realLineHeight = realLineHeight, realLineHeight > 0 else {
                return
            }
            let firstVisibleLine: Int = max(1, Int(contentOffset.y / realLineHeight))
            let lastVisibleLine: Int = Int(ceil((contentOffset.y + bounds.size.height) / realLineHeight))
            guard firstVisibleLine < lastVisibleLine else {
                return
            }
            
            context.setLineWidth(separatorLineHeight)
            context.setStrokeColor(separatorLineColor.cgColor)
            context.beginPath()
            let startPointX: CGFloat = bounds.origin.x + textContainer.lineFragmentPadding + textContainerInset.left
            let endPointX: CGFloat = bounds.size.width - textContainer.lineFragmentPadding - textContainerInset.right
    
            for lineIndex in firstVisibleLine ..< lastVisibleLine {
                let linePointY: CGFloat = textContainerInset.top + realLineHeight * CGFloat(lineIndex)
                context.move(to: CGPoint(x: startPointX, y: linePointY))
                context.addLine(to: CGPoint(x: endPointX, y: linePointY))
            }
            
            context.closePath()
            context.strokePath()
        }
        
        // adjust position of cursor
        override public func caretRect(for position: UITextPosition) -> CGRect {
            guard let lineHeight = font?.lineHeight, let realLineHeight = realLineHeight, realLineHeight > 0 else {
                return super.caretRect(for: position)
            }
            var rect = super.caretRect(for: position)
            rect.origin.y = rect.origin.y + (realLineHeight - lineHeight)
            rect.size.height = lineHeight
            return rect
        }
    }
    

    参考:https://www.jianshu.com/p/a80b5bd9f307

    相关文章

      网友评论

          本文标题:每行文字下方画线的 UITextView

          本文链接:https://www.haomeiwen.com/subject/wuyacqtx.html