こんにちは。Swiftを書いていて少し疑問に思ったことがあったので、質問をさせて頂きたく思います。よろしくお願いいたします。
結論から申し上げると、protocol
のextension
に実装したメソッドから、このprotocol
を実装したViewクラスのインスタンスを参照出来るか、あるいはそもそもオブジェクト指向的にそういう考えは誤りであるのか、という質問です。
最近iOS App開発で、Viewをxibファイルに分ける方法に挑戦しています。
当初、xibファイルを読み込んでサブビューとして追加する処理はViewクラスの中に書いていました。
lang
1// CustomView.swift 2@IBDesignable 3class CustomView: UIView { 4 private static let xibName = "CustomView" 5 6 override init(frame: CGRect) { 7 super.init(frame: frame) 8 self._loadXib() 9 } 10 required init?(coder aDecoder: NSCoder) { 11 super.init(coder: aDecoder) 12 self._loadXib() 13 } 14 15 private func _loadXib() { 16 let bundle = Bundle(for: type(of: self)) 17 let nib = UINib(nibName: CustomView.xibName, bundle: bundle) 18 let subView = nib.instantiate(withOwner: self, options: nil).first as! UIView 19 self.addSubview(subView) 20 21 // subViewをselfいっぱいに広げるためのConstraintsの設定 22 subView.translatesAutoresizingMaskIntoConstraints = false 23 let bindings = ["view": subView] 24 self.addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "H:|-0-[view]-0-|", 25 options:NSLayoutFormatOptions(rawValue: 0), 26 metrics:nil, 27 views: bindings)) 28 self.addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "V:|-0-[view]-0-|", 29 options:NSLayoutFormatOptions(rawValue: 0), 30 metrics:nil, 31 views: bindings)) 32 } 33}
しかし、xibファイルが増えてくると、それを表示するViewのクラスごとに全く同じ処理を書くことになるため、_loadXib()
の部分を分離しようと考えました。
lang
1// ViewFromXib.swift 2protocol ViewFromXib { 3 var xibName: String { get } 4} 5extension ViewFromXib { 6 func loadXib(_ superView: UIView) { 7 let bundle = Bundle(for: type(of: superView)) 8 let nib = UINib(nibName: self.xibName, bundle: bundle) 9 let subView = nib.instantiate(withOwner: superView, options: nil).first as! UIView 10 superView.addSubview(subView) 11 12 subView.translatesAutoresizingMaskIntoConstraints = false 13 let bindings = ["view": subView] 14 superView.addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "H:|-0-[view]-0-|", 15 options:NSLayoutFormatOptions(rawValue: 0), 16 metrics:nil, 17 views: bindings)) 18 superView.addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "V:|-0-[view]-0-|", 19 options:NSLayoutFormatOptions(rawValue: 0), 20 metrics:nil, 21 views: bindings)) 22 } 23}
lang
1// CustomView.swift 2@IBDesignable 3class CustomView: UIView, ViewFromXib { 4 var xibName = "CustomView" 5 6 override init(frame: CGRect) { 7 super.init(frame: frame) 8 self.loadXib(self) 9 } 10 required init?(coder aDecoder: NSCoder) { 11 super.init(coder: aDecoder) 12 self.loadXib(self) 13 } 14}
現在の私の知見の範囲内で正常に動くコードがこれなのですが、CustomView
のイニシャライザでxibファイルを読み込むメソッドを呼ぶときにself
を2回書かなければならないのが少々気になります。
これは、protocol
やextension
のあとに: UIView
をつけるとコンパイルエラーになるためです(当然ではありますが…)。
また、当初private
な変数とメソッドであった部分がprivate
でなくなってしまっているのも気になります。
extension
の中でself
がUIView
のサブクラスであることを明示して、そのメソッドを使用できるようにすることで、CustomView
から引数にself
を渡さなくて済むようにしたいのですが、それは可能なのでしょうか。あるいは、オブジェクト指向の考え方として誤った認識があるのでしょうか。
ご教授いただければ幸いです。
回答1件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2017/06/10 12:24