Mac と iOS の両方で使用したい CATextLayer に取り組んでいます。レイヤー内のテキストの垂直方向の配置を制御できますか?
この特定のケースでは、垂直方向の中央に配置したいと考えていますが、他の垂直方向の配置に関する情報も興味深いでしょう。
編集:これを見つけましたが、機能させることはできません。
Mac と iOS の両方で使用したい CATextLayer に取り組んでいます。レイヤー内のテキストの垂直方向の配置を制御できますか?
この特定のケースでは、垂直方向の中央に配置したいと考えていますが、他の垂直方向の配置に関する情報も興味深いでしょう。
編集:これを見つけましたが、機能させることはできません。
通常の文字列と属性付き文字列の 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()
}
}
@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()
}
}
サブレイヤーとして CATextLayer を持つ汎用 CALayer (コンテナー) を使用して CALayer 階層を作成することを妨げるものは何もありません。
CATextLayer のフォント サイズを計算する代わりに、CALayer 内の CATextLayer のオフセットを計算して、垂直方向の中央に配置します。テキスト レイヤーの配置モードを中央揃えに設定し、テキスト レイヤーの幅を囲んでいるコンテナーと同じにすると、テキスト レイヤーも水平方向に中央揃えになります。
let container = CALayer()
let textLayer = CATextLayer()
// create the layer hierarchy
view.layer.addSublayer(container)
container.addSublayer(textLayer)
// Setup the frame for your container
...
// Calculate the offset of the text layer so that it is centred
let hOffset = (container.frame.size.height - textLayer.frame.size.height) * 0.5
textLayer.frame = CGRect(x:0.0, y: hOffset, width: ..., height: ...)
サブレイヤー フレームはその親に相対的であるため、計算はかなり簡単です。この時点では、フォント サイズを気にする必要はありません。これは、レイアウト コードではなく、CATextLayer を処理するコードによって処理されます。
gbk のコードは機能します。以下は、XCode 8 beta 6 用に更新された gbk のコードです。2016 年 10 月 1 日現在
ステップ 1. CATextLayer をサブクラス化します。以下のコードでは、サブクラスに「MyCATextLayer」という名前を付けました。View Controller クラスの外に、以下のコードをコピーして貼り付けます。
class MyCATextLayer: 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 init() {
super.init()
}
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()
}
}
ステップ 2. 「.swift」ファイルのビュー コントローラー クラス内で、CATextLabel を作成します。コード例では、サブクラスに「MyDopeCATextLayer」という名前を付けました。
let MyDopeCATextLayer: MyCATextLayer = MyCATextLayer()
ステップ 3. 新しい CATextLayer を目的のテキスト/色/境界/フレームで設定します。
MyDopeCATextLayer.string = "Hello World" // displayed text
MyDopeCATextLayer.foregroundColor = UIColor.purple.cgColor //color of text is purple
MyDopeCATextLayer.frame = CGRect(x: 0, y:0, width: self.frame.width, height: self.frame.height)
MyDopeCATextLayer.font = UIFont(name: "HelveticaNeue-UltraLight", size: 5) //5 is ignored, set actual font size using ".fontSize" (below)
MyDopeCATextLayer.fontSize = 24
MyDopeCATextLayer.alignmentMode = kCAAlignmentCenter //Horizontally centers text. text is automatically centered vertically because it's set in subclass code
MyDopeCATextLayer.contentsScale = UIScreen.main.scale //sets "resolution" to whatever the device is using (prevents fuzzyness/blurryness)
ステップ 4.完了
したがって、これを行う「直接的な」方法はありませんが、テキスト メトリックを使用して同じことを達成できます。
...たとえば、テキストのサイズを見つけて、その情報を使用して、親レイヤーの必要な場所に配置します。お役に立てれば。
私の知る限り、私の質問に対する答えは「いいえ」です。