UILabelの高さを文字数によって動的に変更する

# テーマ
UILabelの高さを文字数によって動的に変更します。

# 経緯
サーバーから取得した文字列をもとに、
UILabelの高さを動的に変える必要がありました。
その時のメモを共有します。

# 実装手順
1. UILabelをStoryBoardに配置し、numberOfLinesを0(Storyboard上はLines)に変更する。
2. UILabelの高さ制約(Constraints)を設定し、ソースコードと関連付ける。
3. UILabelの高さを取得するextensionを作成する。
4. 画面サイズとフォントサイズを指定し、高さを取得する。
5. UILabelの高さを更新する。

それでは、やってみます。

# 1. UILabelをStoryBoardに配置し、numberOfLinesを0(Storyboard上はLines)に変更する。
この設定を忘れると、1行で表示されます。
（1行で収まらない場合は、「...」で省略される。）

<img width="840" alt="スクリーンショット 2015-12-17 20.53.55.png" src="https://qiita-image-store.s3.amazonaws.com/0/71694/0875fd9b-9b8f-923c-82f4-7dcd77badace.png">

<img width="286" alt="スクリーンショット 2015-12-17 20.54.12.png" src="https://qiita-image-store.s3.amazonaws.com/0/71694/6c64e72d-135f-00ad-7207-a6bb0fcc7186.png">

# 2. UILabelの高さ制約(Constraints)を設定し、ソースコードと関連付ける。
高さ制約は、後で変えるので適当でも大丈夫です。

<img width="393" alt="スクリーンショット 2015-12-17 20.55.08.png" src="https://qiita-image-store.s3.amazonaws.com/0/71694/6d0f68fd-9c12-764d-aef1-f4bc73452f78.png">

**StoryBoardからOutletでソースコードと関連付けます。**

``` UIViewController.swift
    @IBOutlet weak var heightConstrainsts: NSLayoutConstraint!
    @IBOutlet weak var textLabel: UILabel!

```

関連付けができたら、制約が下記のような表示に変わります。
<img width="322" alt="スクリーンショット 2015-12-17 21.00.48.png" src="https://qiita-image-store.s3.amazonaws.com/0/71694/6670da33-5f80-4639-e057-8a294882610d.png">


# 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
```

# 検証してみます

**[3行表示の場合]**
<img width="307" alt="スクリーンショット 2015-12-17 21.42.49.png" src="https://qiita-image-store.s3.amazonaws.com/0/71694/ae1a8239-6f82-c2fb-f353-7d5615527de9.png">

**[ちょっと長めの文字列を設定した場合]**
<img width="308" alt="スクリーンショット 2015-12-17 21.42.33.png" src="https://qiita-image-store.s3.amazonaws.com/0/71694/ae32a58f-bbae-b786-c8a6-18d9883d5fd8.png">

**[改行コードが含まれる文字列を設定した場合]**
<img width="307" alt="スクリーンショット 2015-12-17 21.42.00.png" src="https://qiita-image-store.s3.amazonaws.com/0/71694/7c5c6cb1-e5ac-5f51-bbba-1b026be747fe.png">

# まとめ
無事、動的にUILabelの高さを変更できました。

誤りやもっと良い方法があれば、ご教授ください。