LoginSignup
2
1

More than 5 years have passed since last update.

メソッドチェーンで遊ぶ

Last updated at Posted at 2018-02-18

スクリーンショット 2018-02-18 19.01.34.png

UILabelに愛してると表示するとき

        let label = UILabel()
        label.frame.origin = CGPoint(x: 100, y: 100)
        label.frame.size = CGSize(width: 200, height: 50)
        label.backgroundColor = .red
        label.layer.cornerRadius = 25
        label.clipsToBounds = true
        label.text = "i love you"
        label.textColor = .white
        label.textAlignment = .center
        view.addSubview(label)

labelって描くのめんどくさいとふと思いメソッドチェーンぽく描いて遊んでみた。

    let label = UILabel().chain
        .origin(x: 100, y: 100)
        .size(width: 200, height: 50)
        .backgroundColor(.red)
        .cornerRadius(25)
        .clipsToBounds()
        .text("i love you")
        .textColor(.white)
        .alignment(.center)
        .object()
    view.addSubview(label)

やっぱりメソッドチェーンはxcodeの補完でサクサクかけて楽チンだと思う。

実装


protocol Chainable {}

extension Chainable where Self: UIView {
    var chain: ChainMaker<Self> {
        return ChainMaker(self)
    }
}

class ChainMaker<T> {

    private var base: T
    init(_ base: T) {
        self.base = base
    }

    func object() -> T {
        return base
    }
}

extension UIView: Chainable {}

とりあえずこれでUIViewがchainプロパティーを持つのでChainMaker(仮)を拡張していく
object()メソッドはキャスト用で最後に使う。


extension ChainMaker where T: UIView {

    func origin(x: CGFloat, y: CGFloat)  -> ChainMaker<T> {
        base.frame.origin = CGPoint(x: x, y: y)
        return self
    }

    func size(width: CGFloat, height: CGFloat)  -> ChainMaker<T> {
        base.frame.size = CGSize(width: width, height: height)
        return self
    }

    func backgroundColor(_ color: UIColor) -> ChainMaker<T> {
        base.backgroundColor = color
        return self
    }

    func clipsToBounds() -> ChainMaker<T> {
        base.clipsToBounds = true
        return self
    }

    func cornerRadius(_ radius: CGFloat) -> ChainMaker<T> {
        base.layer.cornerRadius = radius
        return self
    }
}

extension ChainMaker where T: UILabel {

    func text(_ text: String) -> ChainMaker<T> {
        base.text = text
        return self
    }

    func textColor(_ color: UIColor) -> ChainMaker<T> {
        base.textColor = color
        return self
    }

    func alignment(_ alignment: NSTextAlignment) -> ChainMaker<T> {
        base.textAlignment = alignment
        return self
    }
}

追記

クロージャーで描いた方がスッキリしてていいですね

extension Chainable where Self: UIView {

    func chain(_ closure: (ChainMaker<Self>)->(ChainMaker<Self>)) -> Self {
        let maker = ChainMaker(self)
        return closure(maker).object()
    }
}
        let label = UILabel().chain { $0
            .origin(x: 100, y: 100)
            .size(width: 200, height: 50)
            .backgroundColor(.red)
            .cornerRadius(25)
            .clipsToBounds()
            .text("i love you")
            .textColor(.white)
            .alignment(.center)
        }
        view.addSubview(label)
2
1
2

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
2
1