UIButtonを継承したオリジナルボタンをstoryboard上で使用する②

この記事は2015年11月24日に書かれたものです。内容が古い可能性がありますのでご注意ください。


では、前回の続きです。
s10_1
というエラーが出たところまで前回やりましたね。

エラー文を見てみると、
‘required’ initializer ‘init(corder:)’ must be provided by subclass of ‘UIButton’
と書かれています。簡単に訳すと、
‘required’イニシャライザである‘init(corder:)’は、必ずUIButtonのサブクラスで
用意する(つまり、実装する)必要があるよ。
」ってことになります。
requiredイニシャライザとは、これも直訳すると、必須イニシャライザという意味になります。
つまり必ず実装しないといけないもの、必ず書いてあげないといけないものなんですね。
(イニシャライザについては、別の時にまとめて説明しようと思います。)

青色のところを見てみると、「Fix-it insert “…”」と書かれていて、さらにその後ろの画面にも灰色でコードが書かれて
いるのがわかるかと思います。この時はこの青色の部分をダブルクリックをするとXcode側が判断した適切な
コード(だったり文字だったり)を補ってくれるんです。
なのでとりあえずダブルクリック。

すると、

required init?(coder aDecoder: NSCoder) {
    fatalError("init(coder:) has not been implemented")
}

というイニシャライザが挿入されてエラーが消えましたね。
(このイニシャライザについては、required init?(coder aDecoder: NSCoder) { }について考えてみよう!①
で説明しています。)

しかし、、

今度は上に自分で書いたinit()の方になにやら!マークがあるではないですか。
s10_2
またエラーですね。文言を見てみましょう。
Super.init isn’t called before returning from initializer
これは、
イニシャライザが終了するまでにスーパークラスのイニシャライザが呼ばれてないよ。
という意味になります。
いま作成している新しいMyButtonというクラスは、UIButtonクラスを引き継いで(継承して)作成しています。
継承しているということはUIButtonクラスで定義されているプロパティやメソッド(イニシャライザも)を全て使うことができるんですね。

で、スーパークラスで使用されているプロパティを初期化して使用するには、まずスーパークラスの
イニシャライザ(指定イニシャライザ)をそのまま使用して初期化する必要がある。というルールがあります。
初期化方法を新しいクラスでわざわざ記述するのではなく、もとからある(スーパークラスで定義されている)
初期化方法を使えってことですね。
(この辺のイニシャライザのルールも別の回で説明します。)

親クラス、つまりスーパークラスのイニシャライザを使用しますので、
super.init()と頭にsuperを記述します。
以下のように書いてみましょう。

    init() {
        super.init()
    }

しかしエラーは消えませんね。ただ、エラーの内容が変わっていると思いますのでちょっと見てみましょう。
s10_3
Must call a designated initializer of the superclass `UIButton`
これを訳すと
スーパークラスである`UIButton`クラスの指定イニシャライザを呼び出さなきゃダメだよ。
という意味になります。

ちょっと書き方がダメみたいです。というのもサブクラスのイニシャライザを定義する際は直近のスーパークラス
(この場合はUIButtonクラス)のイニシャライザを使用しないといけないというルールがあります。
このsuper.init()というイニシャライザは、元をたどればNSObjectクラスの(ベースクラスの)
イニシャライザになります。それを継承して使用しているんですね。

まぁ要は使えないってこと。

なのでこの部分を

    init() {
        super.init(frame: <CGRect>)
    }

というUIViewクラスのイニシャライザに変更します。<CGRect>の部分にはCGRect型の
値を入れてあげないといけないので、CGRectMake関数を用いて今はとりあえず適当な値を入れてあげます。

    init() {
        super.init(frame: CGRectMake(10, 10, 10, 10))
    }

すると無事エラーが消えました!万歳!!

現状新しく作成したファイル(画像ではMyButton.swiftファイル)は以下のようになっているはずです。
s10_4

さぁ、ここまできたらあと少しだぞー!

つづく

  • このエントリーをはてなブックマークに追加

PAGE TOP