Wil*_*sch 23 iphone macos core-animation text-alignment ios
我正在开发一个我想在Mac和iOS上使用的CATextLayer.我可以控制图层中文本的垂直对齐方式吗?
在这种特殊情况下,我希望将其垂直居中 - 但有关其他垂直对齐的信息也会引起关注.
编辑:我发现了这个,但我不能让它发挥作用.
iam*_*hed 28
正确的答案,因为你已经找到,是这里的Objective-C和适用于iOS.它通过子类化CATextLayer和重写drawInContext函数来工作.
但是,我使用David Hoerl的代码作为基础对代码进行了一些改进,如下所示.这些变化仅仅是重新计算文本所代表的文本的垂直位置yDiff.我用我自己的代码测试过它.
这是Swift用户的代码:
class LCTextLayer : CATextLayer {
// REF: http://lists.apple.com/archives/quartz-dev/2008/Aug/msg00016.html
// CREDIT: David Hoerl - https://github.com/dhoerl
// USAGE: To fix the vertical alignment issue that currently exists within the CATextLayer class. Change made to the yDiff calculation.
override func draw(in context: CGContext) {
let height = self.bounds.size.height
let fontSize = self.fontSize
let yDiff = (height-fontSize)/2 - fontSize/10
context.saveGState()
context.translateBy(x: 0, y: yDiff) // Use -yDiff when in non-flipped coordinates (like macOS's default)
super.draw(in: context)
context.restoreGState()
}
}
Run Code Online (Sandbox Code Playgroud)
gbk*_*gbk 12
也许迟到的答案,但你可以计算文本的大小,然后设置textLayer的位置.你还需要将textLayer textAligment模式设置为"center"
CGRect labelRect = [text boundingRectWithSize:view.bounds.size options:NSStringDrawingUsesLineFragmentOrigin attributes:@{ NSFontAttributeName : [UIFont fontWithName:@"HelveticaNeue" size:17.0] } context:nil];
CATextLayer *textLayer = [CATextLayer layer];
[textLayer setString:text];
[textLayer setForegroundColor:[UIColor redColor].CGColor];
[textLayer setFrame:labelRect];
[textLayer setFont:CFBridgingRetain([UIFont fontWithName:@"HelveticaNeue" size:17.0].fontName)];
[textLayer setAlignmentMode:kCAAlignmentCenter];
[textLayer setFontSize:17.0];
textLayer.masksToBounds = YES;
textLayer.position = CGPointMake(CGRectGetMidX(view.bounds), CGRectGetMidY(view.bounds));
[view.layer addSublayer:textLayer];
Run Code Online (Sandbox Code Playgroud)
这是一个迟到的答案,但这些天我有同样的问题,并通过以下调查解决了这个问题.
垂直对齐取决于您需要绘制的文本以及您使用的字体,因此没有一种方法可以使所有情况都垂直.
但我们仍然可以计算不同情况下的垂直中点.
根据Apple 在iOS中的关于文本处理,我们需要知道如何绘制文本.
例如,我正在尝试为工作日字符串进行垂直对齐:Sun,Mon,Tue,....
对于这种情况,文本的高度取决于上限高度,并且这些字符没有下降.因此,如果我们需要使这些文本与中间对齐,我们可以计算顶部字符顶部的偏移量,例如字符"S"顶部的位置.
根据下图:

首都角色"S"的顶部空间将是
font.ascender - font.capHeight
Run Code Online (Sandbox Code Playgroud)
首都角色"S"的底部空间将是
font.descender + font.leading
Run Code Online (Sandbox Code Playgroud)
所以我们需要将"S"从顶部移开一点:
y = (font.ascender - font.capHeight + font.descender + font.leading + font.capHeight) / 2
Run Code Online (Sandbox Code Playgroud)
这相当于:
y = (font.ascender + font.descender + font.leading) / 2
Run Code Online (Sandbox Code Playgroud)
然后我可以使文本垂直对齐中间.
如果您的文字不包含任何超过基线的字符,例如"p","j","g",并且在帽子高度的顶部没有字符,例如"f".您可以使用上面的公式使文本对齐垂直.
y = (font.ascender + font.descender + font.leading) / 2
Run Code Online (Sandbox Code Playgroud)如果您的文字包含基线以下的字符,例如"p","j",并且没有字符超过上限高度,例如"f".那么垂直公式将是:
y = (font.ascender + font.descender) / 2
Run Code Online (Sandbox Code Playgroud)如果您的文字包含不包括在基线下方绘制的字符,例如"j","p",并且包括在封面高度线上方绘制的字符,例如"f".然后你会是:
y = (font.descender + font.leading) / 2
Run Code Online (Sandbox Code Playgroud)如果文本中出现所有字符,则y等于:
y = font.leading / 2
Run Code Online (Sandbox Code Playgroud)Swift 3版本用于常规字符串和属性字符串.
class ECATextLayer: CATextLayer {
override open func draw(in ctx: CGContext) {
let yDiff: CGFloat
let fontSize: CGFloat
let height = self.bounds.height
if let attributedString = self.string as? NSAttributedString {
fontSize = attributedString.size().height
yDiff = (height-fontSize)/2
} else {
fontSize = self.fontSize
yDiff = (height-fontSize)/2 - fontSize/10
}
ctx.saveGState()
ctx.translateBy(x: 0.0, y: yDiff)
super.draw(in: ctx)
ctx.restoreGState()
}
}
Run Code Online (Sandbox Code Playgroud)
感谢@iamktothed,它有效。以下是 swift 3 版本:
class CXETextLayer : CATextLayer {
override init() {
super.init()
}
override init(layer: Any) {
super.init(layer: layer)
}
required init(coder aDecoder: NSCoder) {
super.init(layer: aDecoder)
}
override func draw(in ctx: CGContext) {
let height = self.bounds.size.height
let fontSize = self.fontSize
let yDiff = (height-fontSize)/2 - fontSize/10
ctx.saveGState()
ctx.translateBy(x: 0.0, y: yDiff)
super.draw(in: ctx)
ctx.restoreGState()
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
14764 次 |
| 最近记录: |