アプリを作っていて、「既存のクラスをカスタマイズして、オリジナルの変数を付けたいなぁ」ってコト、あると思います。
少なくとも私はあります。
が、バカ正直にextension
してvarで宣言すると以下のようなエラーで怒られます。

で、どうにかできないものかと。
そのクラスを継承したクラスを作ればいいんですよ、というブログエントリや質問サイトの回答も見たんですが、一応やりたいと思ったコトがやりたいと思った通りにできるのかどうか、確認しました。
結論としては、「可能」でした。
以下、サンプルです。
ソースコード
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)
}
}
}
画面イメージ
ボタン押下前 |
---|
![]() |
ボタン押下前 |
---|
![]() |
viewDidLoad()で追加したプロパティ(addedString)にセットした値が、ボタン押下時にtextにセットされ、画面に表示できています。
参考
stackoverflowの下記QAが参考になりました。
“Extensions may not contain stored properties” unless your are Apple? What am I missing? - stackoverflow
以上です〜