LoginSignup
16
15

More than 5 years have passed since last update.

Swiftでメソッドチェーンを実装する

Last updated at Posted at 2016-07-26

パラメータを渡すといい感じに処理してくれるようなコードを書こうとすると、結構な数のパラメータが必要な場合があるかと思います。

単純に必要な数だけ引数を用意してもいいのですが、一度にすべての引数を使わない場合や、ライブラリとして公開する場合などは、もう少しスマートに対応したいところです。

そんな場合の対応方法のひとつとして、メソッドチェーンにて設定できるようにする方法があるかと思います。

サンプル

UIViewを作成するサンプルです。

呼び出し側のコード

ViewBuilder(parent: view)
    .setFrame(CGRect(x: 50, y: 50, width: 100, height: 100))
    .setBackgroundColor(UIColor.green())
    .setBorderColor(UIColor.lightGray())
    .setBorderWidth(4.0)
    .setCornerRadius(14.0)
    .build()

実行するとこうなります。

screen.png


実装側のコード

import UIKit

public class ViewBuilder {
    private var parentView: UIView
    private var frameRect: CGRect?
    private var backgroundColor: UIColor?
    private var borderColor: UIColor?
    private var borderWidth: CGFloat?
    private var cornerRadius: CGFloat?

    public init(parent: UIView) {
        self.parentView = parent
    }

    public func setFrame(_ frameRect: CGRect) -> Self {
        self.frameRect = frameRect
        return self
    }

    public func setBackgroundColor(_ backgroundColor: UIColor) -> Self {
        self.backgroundColor = backgroundColor
        return self
    }

    public func setBorderColor(_ borderColor: UIColor) -> Self {
        self.borderColor = borderColor
        return self
    }

    public func setBorderWidth(_ borderWidth: CGFloat) -> Self {
        self.borderWidth = borderWidth
        return self
    }

    public func setCornerRadius(_ cornerRadius: CGFloat) -> Self {
        self.cornerRadius = cornerRadius
        return self
    }

    public func build() {
        let view = UIView()

        if let frameRect = frameRect {
            view.frame = frameRect
        }

        if let backgroundColor = backgroundColor {
            view.backgroundColor = backgroundColor
        }

        if let borderColor = borderColor {
            view.layer.borderColor = borderColor.cgColor
        }

        if let borderWidth = borderWidth {
            view.layer.borderWidth = borderWidth
        }

        if let cornerRadius = cornerRadius {
            view.layer.cornerRadius = cornerRadius
        }

        parentView.addSubview(view)
    }
}
  • 設定値を保持するプロパティを用意
  • 設定値を受け取るメソッドを用意
  • チェーンできるように設定値を保持しつつ、自身を返却
  • 終端メソッドにて、存在するパラメータを設定

みたいに実装すれば良いかと!

16
15
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
16
15