如何计算相对于原点的 UITextView 第一个基线位置
Posted
技术标签:
【中文标题】如何计算相对于原点的 UITextView 第一个基线位置【英文标题】:How to calculate UITextView first baseline position relatively to the origin 【发布时间】:2016-03-10 16:37:51 【问题描述】:如何计算UITextView
第一个基线位置?
我试过这样计算:
self.textView.font!.descender + self.textView.font!.leading
但是,我得到的值不正确。有什么想法、提示吗?
【问题讨论】:
descender
如果偏离基线,肯定不应该参与计算。 leading
或 lineHeight
可能够了吗?
我想是self.textView.font?.ascender
【参考方案1】:
有一张来自苹果document的图
据我了解,font.descender + font.leading
给出了第一条基线和第二条线起点之间的距离。
如果UITextField
没有秘密填充,我会想象font.lineHeight
会给你正确的数字。
编辑
UITextField
和 UITextView
共享相同的 UIFont
属性。
对于UITextView
,可以额外设置一个textContainerInset
。
编辑 2
进一步查看UITextView
可以提供更多关于可以实现什么的线索:
它实际上有一个textContainer
属性,即NSTextContainer
。
NSTextContainer 类定义了一个放置文本的区域。 NSLayoutManager 对象使用一个或多个 NSTextContainer 对象来确定在哪里换行、布局文本部分等等。
并且被layoutManager
使用过,理论上第一行文本顶部的填充可以被usedRectForTextContainer(_:)
找到。
一旦我手头有一台 Mac,我将需要对此进行测试。 :)
【讨论】:
你在写UITextField
,我在问UITextView
。它还会起作用吗?问题是该图仅解释了 UIFont。 UITextView 添加自己的顶部填充。
很抱歉,他们都共享相同的font : UIFont
属性,所以我相信如果一个有效,另一个应该有效。【参考方案2】:
根据 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"
结果:
【讨论】:
左边的缩进怎么办?我找不到解决方案...【参考方案3】:在我的例子中,我正在扩展 UITextField 类,我只是想在文本字段基线中画一条线,我成功地使用了以下块:
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 第一个基线位置的主要内容,如果未能解决你的问题,请参考以下文章
为啥更改 UITextView 的框架原点会完全破坏我的整个框架大小?
输入:B相对于A的坐标(加入以A为原点,B的坐标)。 输出:B的世界坐标