UI周りでProtocol Extension, Genericsとかの活用を試みる

swift公開されたので中身読んでネタ探してたんですが、
間に合いそうにないんで小ネタでお茶を濁します。。

## はじめに

最近はJavaばかりでswiftが恋しいです。
Protocol Extension, Generics。便利ですね。
あんまりUIをからめた話を聞かないので試みてみます。

## 当方環境

- Xcode Version 7.2 (7C68)
- Swift 2.1.1

## 共通のUIコンポーネントを持ったViewへ共用関数を提供する

共通のUIコンポーネントを定義

```swift
protocol SomeViewType {
    var thumbnailImageView : UIImageView! { get }
    var mainLabel : UILabel! { get }
    var detailLabel : UILabel! { get }
}
```

プロトコル適用

```swift
class SomeView : UIView, SomeViewType {
    @IBOutlet weak var thumbnailImageView : UIImageView!
    @IBOutlet weak var mainLabel : UILabel!
    @IBOutlet weak var detailLabel : UILabel!
}

class SomeCell : UITableViewCell, SomeViewType {
    @IBOutlet weak var thumbnailImageView : UIImageView!
    @IBOutlet weak var mainLabel : UILabel!
    @IBOutlet weak var detailLabel : UILabel!
}
```

extensionで共用の関数追加

```swift

// 使うデータ
struct SomeData {
    let url : String = "DataA_url"
    let title : String = "DataA_title"
    let message : String = "DataA_message"
}


extension SomeViewType {
    func setData(data: SomeData) {
        // getImage関数は適当です
        self.thumbnailImageView.image = UIImage.getImage(data.url)
        self.mainLabel.text = data.title
        self.detailLabel.text = data.message
    }
}
```

```swift
let data = SomeData()

SomeView().setData(data) 
SomeCell().setData(data)
```

## 適合した型に合わせてProtocol Extensionの実装を変える

プロトコル定義

```swift
protocol SomeViewActionType {
    func someAction()
}
```

適合している型に合わせて実装を変える。

指定を`UIView`にすると、`UIView`を継承したクラスで同じようなことしたら
多重定義していると怒られます。

```swift
extension SomeViewActionType where Self: UICollectionViewCell {
    func someAction() {
        print("call UICollectionViewCell action")
    }
}

extension SomeViewActionType where Self: UITableViewCell {
    func someAction() {
        print("call UITableViewCell action")
    }
}

extension UICollectionViewCell : SomeViewActionType {}
extension UITableViewCell : SomeViewActionType {}
```

```swift
UICollectionViewCell().someAction() // call UICollectionViewCell action
UITableViewCell().someAction()      // call UITableViewCell action

```

参考
[Swift2-Protocol-Extension-Example](https://github.com/jhurray/Swift2-Protocol-Extension-Example)

## 共通のデータを持ったモデルを同じViewへ使う

共通のデータを定義

```swift
protocol SomeDataType {
    var name : String { get set }
    var category : String { get set }
    var date : NSDate { get set }
}
```

プロトコル適用

```swift
class DataA: SomeDataType {
    var name : String = "nameA"
    var category : String = "categoryA"
    var date : NSDate = NSDate()
    
    var title : String = "title"
}

struct DataB: SomeDataType {
    var name : String = "nameB"
    var category : String = "categoryB"
    var date : NSDate = NSDate()
    
    var pageIndex : Int = 0
}
```

ジェネリクスで関数を定義

```swift
class SomeView: UIView {
    @IBOutlet weak var mainLabel : UILabel!
    @IBOutlet weak var detailLabel : UILabel!
    @IBOutlet weak var dateLabel : UILabel!
    
    func setData<T: SomeDataType>(data: T) {
        self.mainLabel.text = data.name
        self.detailLabel.text = data.category
        self.dateLabel.text = data.date.description
    }
}
```
```swift
SomeView().setData(DataA())
SomeView().setData(DataB())
```

## TableViewのDataSourceにジェネリクスを使う

ちょっとViewから離れましたが。。
[Type-safe Table Views with Swift](http://blog.indragie.com/post/99740598364/type-safe-table-views-with-swift)

## 微妙でした

いけてるのが出てきませんでした。。

おしまい