代码运行效果如图:
import Foundation
class TestVC: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
let testV = MyCustomTextView(frame: CGRect(x: 0, y: 130, width: SCREEN_WIDTH - 50, height: 170))
self.view.addSubview(testV)
testV.backgroundColor = .darkGray
let ps = NSMutableParagraphStyle()
ps.lineSpacing = 7
ps.alignment = .left
let attr = NSMutableAttributedString(string: "字", attributes: [
.font: UIFont.systemFont(ofSize: 20),
.foregroundColor: UIColor.blue,
.paragraphStyle: ps.copy()
])
testV.attributedText = attr
}
}
extension TestVC: UITextViewDelegate {
func textViewDidChange(_ textView: UITextView) {
let text = textView.text ?? ""
let ps = NSMutableParagraphStyle()
ps.lineSpacing = 7
ps.alignment = .left
let attr = NSMutableAttributedString(string: text, attributes: [
.font: UIFont.systemFont(ofSize: 20),
.foregroundColor: UIColor.blue,
.paragraphStyle: ps.copy()
])
textView.attributedText = attr
}
}
class MyCustomTextView: UITextView {
override func caretRect(for position: UITextPosition) -> CGRect {
var rect = super.caretRect(for: position)
var text = self.text
// 计算字符串为空时的textView rect, 避免删完字符串时出现的光标变高和上移问题
// 如果自己还要做换行效果, 那么只在self.text.isEmpty时用sizeToFit
if self.text.isEmpty {
// 用"AAgg"可以算出字符串最大高度, 因为一个往上占据位置, 一个往下占据位置.
text = "AAgg"
}
let label = UILabel()
label.font = self.font
label.text = text
label.sizeToFit()
rect.size.height = label.height
return rect
}
}