如何计算 UITextView 相对于原点的第一个基线位置
How to calculate UITextView first baseline position relatively to the origin
如何计算 UITextView
第一个基线位置?
我试过这样计算:
self.textView.font!.descender + self.textView.font!.leading
但是,我得到的值不正确。有什么想法、提示吗?
Apple 有图document
根据我的理解,font.descender + font.leading
给出了第一条基线和第二条线起点之间的距离。
如果UITextField
没有秘密填充,我会想象font.lineHeight
会给你正确的数字。
编辑
UITextField
和 UITextView
共享相同的 UIFont
属性.
对于UITextView
,可以设置一个额外的textContainerInset
。
编辑 2
进一步查看 UITextView
可以提供有关可以实现的目标的更多线索:
其实有一个textContainer
属性,也就是一个NSTextContainer
.
The NSTextContainer class defines a region in which text is laid out. An NSLayoutManager object uses one or more NSTextContainer objects to determine where to break lines, lay out portions of text, and so on.
并且被layoutManager
使用,理论上第一行文本顶部的填充可以通过usedRectForTextContainer(_:)
找到。
一旦我手头有Mac,我就需要测试一下。 :)
根据 zcui93 提供的文档,font.ascender
将为您提供字体内基线的偏移量。要在 UITextView
中获取字体的基线,您需要添加 textContainerInset.top
:
extension UITextView {
func firstBaseline() -> CGFloat {
let font = self.font ?? UIFont.systemFontOfSize(UIFont.systemFontSize())
return font.ascender + textContainerInset.top
}
}
如果没有设置字体,这里有一些默认系统字体的假设,但我不确定更好的猜测是什么。
运行下面在playground中演示效果:
class Container : UITextView {
override func drawRect(rect: CGRect) {
let context = UIGraphicsGetCurrentContext()
CGContextSaveGState(context)
let containerRect = UIEdgeInsetsInsetRect(bounds, textContainerInset)
UIColor(red: 1, green: 0, blue: 0, alpha: 0.25).setFill()
CGContextFillRect(context, containerRect)
let baseline = firstBaseline()
UIColor(red: 1, green: 0, blue: 0, alpha: 0.75).setStroke()
CGContextSetLineWidth(context, 1)
CGContextMoveToPoint(context, containerRect.origin.x, baseline)
CGContextAddLineToPoint(context, containerRect.origin.x + containerRect.width, baseline)
CGContextStrokePath(context)
super.drawRect(rect)
}
}
let textView = Container(frame: CGRect(x: 0, y: 0, width: 100, height: 30))
textView.font = UIFont.systemFontOfSize(UIFont.systemFontSize())
textView.text = "My Text"
结果:
在我的例子中,我扩展了 UITextField class,我只是想在文本字段基线中画一条线,我成功地完成了以下块:
self.svwLine = UIView(frame: CGRectMake(0,self.frame.size.height+(self.font?.descender)!,self.frame.size.width,2))
self.svwLine.backgroundColor = UIColor.whiteColor()
self.addSubview(self.svwLine)
如何计算 UITextView
第一个基线位置?
我试过这样计算:
self.textView.font!.descender + self.textView.font!.leading
但是,我得到的值不正确。有什么想法、提示吗?
Apple 有图document
根据我的理解,font.descender + font.leading
给出了第一条基线和第二条线起点之间的距离。
如果UITextField
没有秘密填充,我会想象font.lineHeight
会给你正确的数字。
编辑
UITextField
和 UITextView
共享相同的 UIFont
属性.
对于UITextView
,可以设置一个额外的textContainerInset
。
编辑 2
进一步查看 UITextView
可以提供有关可以实现的目标的更多线索:
其实有一个textContainer
属性,也就是一个NSTextContainer
.
The NSTextContainer class defines a region in which text is laid out. An NSLayoutManager object uses one or more NSTextContainer objects to determine where to break lines, lay out portions of text, and so on.
并且被layoutManager
使用,理论上第一行文本顶部的填充可以通过usedRectForTextContainer(_:)
找到。
一旦我手头有Mac,我就需要测试一下。 :)
根据 zcui93 提供的文档,font.ascender
将为您提供字体内基线的偏移量。要在 UITextView
中获取字体的基线,您需要添加 textContainerInset.top
:
extension UITextView {
func firstBaseline() -> CGFloat {
let font = self.font ?? UIFont.systemFontOfSize(UIFont.systemFontSize())
return font.ascender + textContainerInset.top
}
}
如果没有设置字体,这里有一些默认系统字体的假设,但我不确定更好的猜测是什么。
运行下面在playground中演示效果:
class Container : UITextView {
override func drawRect(rect: CGRect) {
let context = UIGraphicsGetCurrentContext()
CGContextSaveGState(context)
let containerRect = UIEdgeInsetsInsetRect(bounds, textContainerInset)
UIColor(red: 1, green: 0, blue: 0, alpha: 0.25).setFill()
CGContextFillRect(context, containerRect)
let baseline = firstBaseline()
UIColor(red: 1, green: 0, blue: 0, alpha: 0.75).setStroke()
CGContextSetLineWidth(context, 1)
CGContextMoveToPoint(context, containerRect.origin.x, baseline)
CGContextAddLineToPoint(context, containerRect.origin.x + containerRect.width, baseline)
CGContextStrokePath(context)
super.drawRect(rect)
}
}
let textView = Container(frame: CGRect(x: 0, y: 0, width: 100, height: 30))
textView.font = UIFont.systemFontOfSize(UIFont.systemFontSize())
textView.text = "My Text"
结果:
在我的例子中,我扩展了 UITextField class,我只是想在文本字段基线中画一条线,我成功地完成了以下块:
self.svwLine = UIView(frame: CGRectMake(0,self.frame.size.height+(self.font?.descender)!,self.frame.size.width,2))
self.svwLine.backgroundColor = UIColor.whiteColor()
self.addSubview(self.svwLine)