DZNEmptyDataSetでbuttonTitleに合わせてBackgroundImageのsizeを調節する


今国際化に伴い、アプリを大幅改修しています。
こんな感じの画面を作ろうと思っていました。
ライブラリは[DZNEmptyDataSet](https://github.com/dzenbot/DZNEmptyDataSet)を使っています。


![Screen Shot 0028-07-17 at 18.37.09.png](https://qiita-image-store.s3.amazonaws.com/0/94212/558665f7-a058-cb31-2568-c3aae3264edb.png "Screen Shot 0028-07-17 at 18.37.09.png")


<br>

### 今まで
文言(画像のCreate New Streamの部分)を日本語で指定していた
=> 自ずと文言のサイズは一意的に決まる
=> そのLabelのサイズに合わせてpaddingを指定して、かつ、文言も含んだImageを用意していた

### 国際化
文言は国・地域によって変化する
=> 文言のサイズはもちろん動的に変化する
=> 背景画像だけ別で用意して、動的に変化するLabelのサイズに合わせて大きさを上手い感じに合わせる必要がある

というわけで流れとしては、

+ 背景画像の用意(Normal/Highlighted)
+ titleLabelのサイズを測って変数に格納しておく
+ backgroundImageの描画の際に、上記のサイズに合わせてimageのwidthを調節する


サクッと元のソースコードを見ながら自分でも[サンプル](https://github.com/shunsukekyuwa/testProjectForEmptyDataSet)を作ってみました。

## DZNEmptyDataSetとは
TableView, collectionViewが空の時に代わりに表示するものを作成するためのライブラリ
[参考](http://qiita.com/naoyashiga/items/5ea8b1b241bca4572d73)

## delegate method一覧

```
func titleForEmptyDataSet(scrollView: UIScrollView!) -> NSAttributedString! {
  // titleを指定する
}
```

```
func descriptionForEmptyDataSet(scrollView: UIScrollView!) -> NSAttributedString! {
  // 説明文を指定
 }
```

```
func imageForEmptyDataSet(scrollView: UIScrollView!) -> UIImage! {
  //  画像を指定
}
```

```
func buttonTitleForEmptyDataSet(scrollView: UIScrollView!, forState state: UIControlState) -> NSAttributedString! {
   // buttonのtitleを指定
}
```

```
func buttonImageForEmptyDataSet(scrollView: UIScrollView!, forState state: UIControlState) -> UIImage! {
   //  buttonに貼る画像を指定
}
```

```
func buttonBackgroundImageForEmptyDataSet(scrollView: UIScrollView!, forState state: UIControlState) -> UIImage! {
   // buttonの背景画像を指定
}
```

```
func backgroundColorForEmptyDataSet(scrollView: UIScrollView!) -> UIColor! {
    // 全体のviewの背景の色を指定
}
```

```
func verticalOffsetForEmptyDataSet(scrollView: UIScrollView!) -> CGFloat {
    // contentsの位置をviewの上端からどれくらいの距離離すかを指定
}
```

```
func spaceHeightForEmptyDataSet(scrollView: UIScrollView!) -> CGFloat {
    //  contentsが複数ある場合、それぞれの距離をどれくらい離すかを指定
}
```

```
func emptyDataSetShouldDisplay(scrollView: UIScrollView!) -> Bool {
    //  emptyDataSetのcontentsを表示するか否か
}
```

```
func emptyDataSetDidTapView(scrollView: UIScrollView!) {
     //  全体のviewをtapした時のアクションを指定
}
```

```
func emptyDataSetDidTapButton(scrollView: UIScrollView!) {
     //  作成したbuttonをtapした時のactionを指定
}
```

## buttonBackgroundImageForEmptyDataSetでtitleに合わせてsizeを変える
これが面倒だったのでshareします。
やりたいことは最初に説明した通りです。

```
func buttonTitleForEmptyDataSet(scrollView: UIScrollView!, forState state: UIControlState) -> NSAttributedString! {
        let str = "Create New Stream"
        let font = UIFont.systemFontOfSize(14.0, weight: 2.0)
        
        
        // 文言のサイズを格納しておく
        titleSize = str.widthWithConstrainedHeight(44, font: font)

        return NSAttributedString(
            string: str,
            attributes: [
                NSFontAttributeName: font,
                NSForegroundColorAttributeName: ColorUtil.rgba(172, green: 175, blue: 189)
            ]
        )
    }


func buttonBackgroundImageForEmptyDataSet(scrollView: UIScrollView!, forState state: UIControlState) -> UIImage! {

	    // 引き伸ばされたbackgroundImageとview.bounds.size.widthとの比率。
        // どの機種でもだいたい88%でした
        let ratioViewBoundsWidthAndButton: CGFloat = 0.88

        
        //  引き伸ばされたbackgroundImageのsize
        let defaultSize = view.bounds.size.width * ratioViewBoundsWidthAndButton

        
        //  titleLabelのpadding.お好みで
        let padding: CGFloat = 20
        
        
        // 背景画像を引き伸ばしてからtitleLabelに合わせてwidthを調節してUIImageを返す
        return UIImage.makeBackgroundImage(state).shrinkImageAdjustingObject(before: defaultSize, objectSize: messageSizeForEmptyDataSet, padding: padding)
    }

        

extension UIImage {

    // 引き延ばした画像を返すメソッド
	class func makeBackgroundImage(state: UIControlState) -> UIImage {

    	let baseImage = (state == UIControlState.Highlighted) ? R.image.btn_highlight()! : R.image.btn()!
    	
    	// capInsetsは引き延ばす時に引き伸ばしたくない一部分を指定できる
        // ここでは四端5.0×5.0だけそのままのサイズで他を引き延ばすイメージ
       	let capInsets = UIEdgeInsets(top: 5.0, left: 5.0, bottom: 5.0, right: 5.0)
       	
       	
       return baseImage.resizableImageWithCapInsets(capInsets, resizingMode: UIImageResizingMode.Stretch)
    }


    //  内部のobjectのサイズとpaddingを指定すれば、imageのwidthを拡大・縮小するメソッド
    func shrinkImageAdjustingObject(before imageSize: CGFloat, objectSize: CGFloat, padding: CGFloat) -> UIImage {

        var rectInsets = UIEdgeInsetsZero
        

        // imageの端と内部のオブジェクトの端までの距離(片方ずつ)
        let widthBetweenBackgroundAndLabel = (imageSize - objectSize)/2
        

        // paddingを考慮してimageをどれくらい拡大・縮小させるか、の指定
        let shrinkWidth = widthBetweenBackgroundAndLabel - padding
        rectInsets = UIEdgeInsets(top: 0, left: -shrinkWidth, bottom: 0, right: -shrinkWidth)
        
        
        return imageWithAlignmentRectInsets(rectInsets)
    }

}

```

[参考](http://qiita.com/usagimaru/items/d19eea00f85c11620c23)