22924


理想は以下のように実装したいのです。

[code]

    enum MyImageType:String{
         case OnButton  = "on_btn.png"
         case OffButton = "off_btn.png"    
    }
    
    class MyImage: UIImage {
    
        init?(typed type:MyImageType){
            super.init(named:type.rawValue) //<-ここでエラーがでます。
        }
    
        required init?(coder aDecoder: NSCoder) {
            fatalError("init(coder:) has not been implemented")
        }
    
        required convenience init(imageLiteral name: String) {
            fatalError("init(imageLiteral:) has not been implemented")
        }
    }
    
    //使用する際
    let myImg = MyImage(typed:.OnButton)
    
[/code]

しかし、  
Must call a designated initializer of the superclass 'UIImage'  
というエラーが出てしまいます。

指定イニシャライザを呼べということなのですが、

[code]

    class MyImage: UIImage {
    
        init?(typed type:MyImageType){
            super.init()
        }
    
        required init?(coder aDecoder: NSCoder) {
            fatalError("init(coder:) has not been implemented")
        }
    
        required convenience init(imageLiteral name: String) {
            fatalError("init(imageLiteral:) has not been implemented")
        }
    }
    
[/code]

このように書き直すと、エラーはでないのですが、自分のやりたいことが実現できません。  
何か方法はありませんでしょうか。


CC BY-SA 3.0
2016-03-08T07:44:20.087
22920
2016-03-08T17:00:59.690
13404
question
swift
UIImageを継承したクラスを作成したい


やりたいことは`MyImageType`を引数に取れるイニシャライザを追加したい、ということだと思いますので、おそらくサブクラス化するより、エクステンションを使ってカスタムイニシャライザを追加する方が簡単だと思います。

[code]

    extension UIImage {
        convenience init?(typed: MyImageType) {
            self.init(named: typed.rawValue)
        }
    }
    
[/code]

^ 上記のようなエクステンションを書くと、

[code]

    let myImg = UIImage(typed: .OnButton)
    
[/code]

^ のように使用することができます。

どうしても継承を使いたいという場合は下記のようにする感じでしょうか。  
イニシャライザのうち`UIImage(named:)`は継承されない（おそらくファクトリメソッドをコンバートしたイニシャライザのため）ので内部で`UIImage(named:)`を使って生成したインスタンスでさらに自分自身を初期化するという、少しトリッキーな実装になっています。

[code]

    class MyImage: UIImage {
        convenience init?(typed: MyImageType) {
            guard let image = UIImage(named: typed.rawValue), let CGImage = image.CGImage else {
                return nil
            }
            self.init(CGImage: CGImage)
        }
    }
    
[/code]


CC BY-SA 3.0
2016-03-08T08:34:56.190
22924
2016-03-08T17:00:59.690
2016-03-08T17:00:59.690
5519
5519
22920
answer