テーマ
UILabelの高さを文字数によって動的に変更します。
経緯
サーバーから取得した文字列をもとに、
UILabelの高さを動的に変える必要がありました。
その時のメモを共有します。
実装手順
- UILabelをStoryBoardに配置し、numberOfLinesを0(Storyboard上はLines)に変更する。
- UILabelの高さ制約(Constraints)を設定し、ソースコードと関連付ける。
- UILabelの高さを取得するextensionを作成する。
- 画面サイズとフォントサイズを指定し、高さを取得する。
- UILabelの高さを更新する。
それでは、やってみます。
1. UILabelをStoryBoardに配置し、numberOfLinesを0(Storyboard上はLines)に変更する。
この設定を忘れると、1行で表示されます。
(1行で収まらない場合は、「...」で省略される。)
2. UILabelの高さ制約(Constraints)を設定し、ソースコードと関連付ける。
高さ制約は、後で変えるので適当でも大丈夫です。
StoryBoardからOutletでソースコードと関連付けます。
UIViewController.swift
@IBOutlet weak var heightConstrainsts: NSLayoutConstraint!
@IBOutlet weak var textLabel: UILabel!
3. UILabelの高さを取得するextensionを作成する。
String.swift
import UIKit
extension String {
func getTextSize(font:UIFont, viewWidth:CGFloat, padding:CGFloat) -> CGSize {
var size = CGSizeZero
if let s:CGSize = self.makeSize(viewWidth, font: font) {
size = CGSize(width: s.width, height: s.height + padding)
}
return size
}
func makeSize(width:CGFloat, font:UIFont) -> CGSize {
var size:CGSize = CGSizeZero
if self.respondsToSelector("boundingRectWithSize:options:attributes:context:") {
let bounds:CGSize = CGSize(width: width, height: CGFloat.max)
let attributes: Dictionary = [NSFontAttributeName: font]
let options = unsafeBitCast(NSStringDrawingOptions.UsesLineFragmentOrigin.rawValue |
NSStringDrawingOptions.UsesFontLeading.rawValue, NSStringDrawingOptions.self)
let rect:CGRect = self.boundingRectWithSize(bounds, options: options, attributes: attributes, context: nil)
size = CGSize(width: rect.size.width, height: rect.size.height)
}
return size
}
}
4. 画面サイズとフォントサイズを指定し、高さを取得する。
今回は、下記のような例で説明します。
設定要素 | 設定値 |
---|---|
Viewの幅 | UILabelの幅を画面サイズの90% |
フォントサイズ | 17.0 |
UIViewController.swift
let viewWidth = UIScreen.mainScreen().bounds.width * 0.9
let textSize = text.getTextSize(UIFont.systemFontOfSize(17),viewWidth: viewWidth, padding: 8)
textLabel.text = text
5. UILabelの高さを更新する。
UIViewController.swift
heightConstrainsts.constant = textSize.height
検証してみます
まとめ
無事、動的にUILabelの高さを変更できました。
誤りやもっと良い方法があれば、ご教授ください。