※この記事はAutoLayoutを使う上で役に立つ小技を紹介してます。AutoLayoutを少し触ったことがある方向けです。
- 小技1 画面サイズに応じて拡縮する
- 小技2 画面サイズに応じてマージンを取る
- 小技3 画面サイズに応じてフォントサイズ・行間を変更する(この記事)
第3弾です。
今回はAutoLayoutと、UILabelを使った際に、画面サイズに応じてViewのサイズが変化するのはもちろんのこと、フォントサイズと行間も変更がかかるようにします。
早速やっていきましょう。
まず、毎度おなじみの方法で、配置したUILabelが画面サイズに応じて拡縮するようにします。※わかりづらいので背景色はDark Gray、文字色はWhiteにしてます。
今回は下記のような条件で配置したいと思ってます。
1 2 |
基準にするのは4インチの画面(横幅320) その際のフォントサイズは17、行間は30 |
行間が30で三行なので、UILabelのheightは90にしています。
フォントサイズや行間を変更する場合、Storyboardと、AutoLayoutだけでは対処できません。UILabelのサブクラスを作る必要があります。
今回、行間をStoryboardから入力できるようにしたいので、「@IBInspectable」と「@IBDesignable」を使います。
それぞれ簡単に説明しますと、
「@IBInspectable」をつけたメンバー変数はStoryboardから入力できるようになります。
「@IBDesignable」をつけたクラスは、Storyboard上で実行結果がレンダリングされるようになります。
はい、というわけで、こちらがUILabelのサブクラスです。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 |
import UIKit @IBDesignable class ISTDynamicLabel : UILabel { // 基準とする画面横幅 let baseScreenWidth : CGFloat = 320.0 @IBInspectable var lineHeight : CGFloat = 0.0 { didSet { // lineHeightの値が変更された際に呼び出す fixLineHeight() } } override init(frame: CGRect) { super.init(frame: frame) changeFontSize() } required init(coder aDecoder: NSCoder) { super.init(coder: aDecoder)! changeFontSize() } override func awakeFromNib() { super.awakeFromNib() fixLineHeight() } override var text: String? { didSet { fixLineHeight() } } /** 画面比率に応じて、フォントサイズを変更します */ private func changeFontSize() { self.font = UIFont(name: font.fontName, size: self.font.pointSize * getScreenRatio()) } /** 画面比率に応じて行間を変更します */ private func fixLineHeight() { if lineHeight > 0.0 { let paragrahStyle = NSMutableParagraphStyle() paragrahStyle.alignment = self.textAlignment let fixedLineHeight = floor(lineHeight * getScreenRatio()) paragrahStyle.minimumLineHeight = fixedLineHeight paragrahStyle.maximumLineHeight = fixedLineHeight let attributedText = NSMutableAttributedString(attributedString: self.attributedText!) attributedText.addAttribute(NSParagraphStyleAttributeName, value: paragrahStyle, range: NSRange(location: 0, length: attributedText.length)) self.attributedText = attributedText } } /** baseScreenWidthと、画面の横幅との比率を返します - returns: 画面比率 */ private func getScreenRatio() -> CGFloat { return UIScreen.mainScreen().bounds.size.width / baseScreenWidth } } |
※ただしレンダリングはされるのですが、フォントサイズと、行間はStoryboardのViewControllerのサイズを変更しても反映されません。実際実行した時に反映されます。
あくまで基準としている4インチサイズで見た時、調整がしやすいように「@IBDesignable」を使用しています。
そしてこのクラスを先ほどStoryboardに配置した、UILabelのクラスに割り当てます。
こうすることでlineHeightが入力できるようになります。
こちらに行間を入力しましょう。入力した値によって変化するのがわかると思います。
今回は30にします。UILabelのheightを90にしているのでピッタリ入ります。
ここまで来たら完了です。
フォントサイズはコード側で変更してくれるので、実際実行した画面を並べてみます。どの画面でも同じように表示されてます。
(5S、6S、6S plusの順、拡大したい場合は画像をクリックして下さい)
画面サイズに応じてUILabelのサイズ、フォントのサイズ、行間が変化しているのがわかると思います。
といってもわかりづらいので、ただのフォントサイズだけ変化しない場合どうなるかも貼っておきます。
最後に
Storyboard上で全てを確認できないのが痛いですが、こうすることでUILabelも一つのStoryboardで対応できるようになるので、保守が楽になって良いと思います。