LoginSignup
8
7

More than 5 years have passed since last update.

コードからもIBからも使えるUIViewのサブクラスのinitに関して

Last updated at Posted at 2016-03-26

コードで実装したUIViewのサブクラスを、コードからもIBからも使えるようにしておく時の共通の初期化のコードをどうしたら良いのかの話。

Objective-Cではこんな感じでやってたはず

@interface HogeView: UIView

@property(nonatomic)UIView *fugaView;

@end

@implementation HogeView

- (instancetype)initWithFrame:(CGFrame)frame {
    self = [super initWithFrame:frame];
    if(self) {
        [self setup];        
    }
    return self;
}

- (instancetype)initWithCoder:(NSCoder *)aDecoder {
    self = [super initWithCoder:aDecoder];
    if(self) {
        [self setup];
    }
    return self;
}

- (void)setup {
    self.fugaView = [UIView new];
    [self addSubview:self.fugaView];
}
@end

平和すぎる。

Swiftの場合

プロパティは出来るだけletにしておきたいしもちろんOptionalにもしたくないので全部initの中でやる必要があるが
共通の処理はどう書いたら良いのか...という事情があって調べたらこういう方法があった。

class HogeView: UIView {
    let fugaView: UIView

    init(_ coder: NSCoder? = nil) {
        // common initialize
        fugaView = UIView.init()

        if let coder = coder {
            super.init(coder: coder)!
        } else {
            super.init(frame: CGRect.zero)
        }

        // common setup
       addSubview(fugaView)
    }

    required convenience init?(coder aDecoder: NSCoder) {
        self.init(aDecoder)
    }
}

やったぜ。

ちなみに、この方法だとinit(frame)が失われてしまっています。
自分はAutolayoutを使わない場合のレイアウトは全てlayoutSubviews()とかviewDidLayoutSubviews()でやるので別にいらないけど...。


という感じのことが↓の記事に書かれていました。
https://theswiftdev.com/2015/08/05/swift-init-patterns/ (リンク切れ)

8
7
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
8
7