ごんれのラボ

iOS、Android、Adobe系ソフトの自動化スクリプトのことを書き連ねています。

iOSでチラシっぽい価格レイアウトを再現してみた

概要

TwitterでフォロワーさんがUIStackViewで挑戦してたのを見かけた。

スレッドを遡ってみると、NSAttributedStringで実装できるんじゃないかという話があり、興味が湧いたので挑戦してみた。

作ったもの

文字のサイズ感は目見当。

chirashi.png

gist.github.com

説明

ソースコードを部分的に切り出して処理内容を説明する。

let fontSize: CGFloat = 80
let font = UIFont.systemFont(ofSize: fontSize)
let attributeText = NSMutableAttributedString(string: "各種¥(税込)280",
                                              attributes: [.font: font, .foregroundColor: UIColor.red])

はじめに attributeText に基本的な装飾と文字列を格納しておいて、装飾を変更したい部分をNSRangeで指定して、加工していく方法をとることにした。

// 各種
attributeText.addAttributes([.font: UIFont.systemFont(ofSize: fontSize * 0.4),
                             .baselineOffset: 2],
                            range: NSRange(location: 0, length: 2))

各種 の部分。
文字サイズは基本サイズの40%の大きさを指定。
や数字よりベースラインが少し下にずれて見えるので、.baselineOffset: 2 を指定して少し上にずらした。
ベースラインについては ラテン文字と欧文組版 をP14の図を参照。
雑に説明すると、.baselineOffset に正の数を与えると上に移動し、負の数を与えると下に移動する。

// ¥
attributeText.addAttributes([.font: UIFont.systemFont(ofSize: fontSize * 0.6),
                             .kern: -50],
                            range: NSRange(location: 2, length: 1))

の部分。
文字サイズは基本サイズの60%の大きさを指定。
.kern: -50 を指定して、次の文字の ( との字間を詰めた。
雑に説明すると、.kern (カーニング)は当該文字と次の文字の文字間のアキを詰める設定。
なお、パーレンにはカーニングが適用されないっぽかったので、を前にもってきてカーニング設定をしている。

// (税込)
attributeText.addAttributes([.font: UIFont.systemFont(ofSize: fontSize * 0.2),
                             .baselineOffset: (fontSize * 0.8) - (fontSize * 0.2) - 4],
                            range: NSRange(location: 3, length: 4))

(税込) の部分。
文字サイズは基本サイズの20%の大きさを指定。
ベースラインは相対値で計算したものの、それだけではうまく揃わなかったので、微調整している。

// ()のベースライン調整
attributeText.addAttributes([.baselineOffset: (fontSize * 0.8) - (fontSize * 0.2) - 3],
                            range: NSRange(location: 3, length: 1))
attributeText.addAttributes([.baselineOffset: (fontSize * 0.8) - (fontSize * 0.2) - 3],
                            range: NSRange(location: 6, length: 1))

() の部分。
ベースラインが揃わなかったので、この部分だけさらに微調整した。

文字列ごとにNSAttributedStringKeyを指定していき、最後に結合する方法でも良かったんだけど、DTP的な手法のほうが手慣れているため、この方法にしてしまったがゆえに、すごくIllustratorやInDesignを触っている気分になった。

まとめ

参考

Mastering TextKit