LoginSignup
13
10

More than 5 years have passed since last update.

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

Last updated at Posted at 2015-12-15

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

はじめに

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

当方環境

  • Xcode Version 7.2 (7C68)
  • Swift 2.1.1

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

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

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

プロトコル適用

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で共用の関数追加


// 使うデータ
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
    }
}
let data = SomeData()

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

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

プロトコル定義

protocol SomeViewActionType {
    func someAction()
}

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

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

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 {}
UICollectionViewCell().someAction() // call UICollectionViewCell action
UITableViewCell().someAction()      // call UITableViewCell action

参考
Swift2-Protocol-Extension-Example

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

共通のデータを定義

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

プロトコル適用

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
}

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

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
    }
}
SomeView().setData(DataA())
SomeView().setData(DataB())

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

ちょっとViewから離れましたが。。
Type-safe Table Views with Swift

微妙でした

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

おしまい

13
10
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
13
10