LoginSignup
7

More than 3 years have passed since last update.

【Swift】 既存クラスにstored propertiesを追加する

Posted at

アプリを作っていて、「既存のクラスをカスタマイズして、オリジナルの変数を付けたいなぁ」ってコト、あると思います。
少なくとも私はあります。

が、バカ正直にextensionしてvarで宣言すると以下のようなエラーで怒られます。

スクリーンショット 2019-10-16 17.02.08.png

で、どうにかできないものかと。
そのクラスを継承したクラスを作ればいいんですよ、というブログエントリや質問サイトの回答も見たんですが、一応やりたいと思ったコトがやりたいと思った通りにできるのかどうか、確認しました。

結論としては、「可能」でした。

以下、サンプルです。

ソースコード

Sample.swift

import UIKit

class ViewController: UIViewController {

    // このUILabelにプロパティを追加します。
    let testLabel = UILabel()

    let testButton = UIButton()

    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view.

        testLabel.addedString = "プロパティ追加、成功!"
        testLabel.textColor = .black

        testButton.setTitle("tap me!",
                            for: .normal)
        testButton.frame = CGRect(x: 0,
                                  y: 0,
                                  width: 0,
                                  height: 0)
        testButton.sizeToFit()
        testButton.center = view.center
        testButton.setTitleColor(.blue,
                                 for: .normal)
        testButton.addTarget(self,
                             action: #selector(displayTest),
                             for: .touchUpInside)

        view.addSubview(testButton)
    }

    @objc func displayTest() {
        // 追加したプロパティから.textにセットして表示します。
        testLabel.text = testLabel.addedString
        testLabel.font = .systemFont(ofSize: 30)
        testLabel.textAlignment = .center
        testLabel.frame = CGRect(x: 0,
                                 y: 100,
                                 width: UIScreen.main.bounds.width,
                                 height: 50)
        view.addSubview(testLabel)
    }


}

// UILabelにプロパティ追加するextension
extension UILabel {
    private struct additional {
        static var addedString: String = ""
    }

    var addedString: String {
        get {
            guard let theName = objc_getAssociatedObject(self, &additional.addedString) as? String else {
                return ""
            }
            return theName
        }
        set {
            objc_setAssociatedObject(self, &additional.addedString, newValue, .OBJC_ASSOCIATION_RETAIN)
        }
    }
}


画面イメージ

ボタン押下前
Simulator Screen Shot - iPad Air 2 - 2019-10-16 at 16.55.13.png
ボタン押下前
Simulator Screen Shot - iPad Air 2 - 2019-10-16 at 16.55.16.png

viewDidLoad()で追加したプロパティ(addedString)にセットした値が、ボタン押下時にtextにセットされ、画面に表示できています。

参考

stackoverflowの下記QAが参考になりました。
“Extensions may not contain stored properties” unless your are Apple? What am I missing? - stackoverflow

以上です〜

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
7