概要
StoryboardでViewControllerのViewの一部が他のViewControllerでも同じレイアウトで表示している場合があります。その場合ViewをコピーしてViewControllerに貼り付けて利用したりしますが、それだとそのViewに変更を加えると複数利用しているため他のViewも変更しなくてはなりません。
そう行った場合、使い回せるViewをカスタムビューとしてxibで作成して利用することで、そのxibのみを変更すれば複数のViewでその変更が反映されるようになります。
実装方法
まずは、カスタムビューをxibで作成します。
続いて、ViewControllerで、xibのカスタムビューをインスタンス化します。
class ViewController: UIViewController {
weak var sampleView: UIView!
override func loadView() {
super.loadView()
sampleView = UINib(nibName: "SampleView", bundle: Bundle.main).instantiate(withOwner: self, options: nil).first as? UIView
sampleView.backgroundColor = .yellow
view.addSubview(sampleView)
}
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
}
override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
sampleView.frame = CGRect.init(x: 100.0, y: 100.0, width: 100.0, height: 100.0)
}
}
この時に、withOwnerでselfを指定しているので、xibで生成したlabelを@IBOutletで繋ぐことが出来ます。
UINib(nibName: "SampleView", bundle: Bundle.main).instantiate(withOwner: self, options: nil).first as? UIView
weak var sampleView: UIView!
@IBOutlet weak var label: UILabel!
override func loadView() {
super.loadView()
sampleView = UINib(nibName: "SampleView", bundle: Bundle.main).instantiate(withOwner: self, options: nil).first as? UIView
sampleView.backgroundColor = .yellow
view.addSubview(sampleView)
label.text = "あああ"
}
■ビルド実行
カスタムビューを管理するクラスを生成する
ViewControllerでxibのViewをインスタンス化して使用するのは上記の方法ですが、多くの場合カスタムビューを管理するクラスを作成してxibとセットで利用したいと考えます。
その方法としては、withOwnerをカスタムビューを管理するクラスにします。
(SampleViewOwnerはSampleView.xibを管理するクラス)
class SampleViewOwner: NSObject {
@IBOutlet weak var label: UILabel!
var sampleView: UIView!
override init() {
super.init()
sampleView = UINib(nibName: "SampleView", bundle: Bundle.main).instantiate(withOwner: self, options: nil).first as? UIView
label.text = "いいい"
}
}
class ViewController: UIViewController {
var sampleViewOwner: SampleViewOwner!
override func loadView() {
super.loadView()
sampleViewOwner = SampleViewOwner()
sampleViewOwner.sampleView.backgroundColor = .yellow
view.addSubview(sampleViewOwner.sampleView)
}
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
}
override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
sampleViewOwner.sampleView.frame = CGRect.init(x: 100.0, y: 100.0, width: 100.0, height: 100.0)
}
}
こうすることで各ViewControllerでownerクラスをインスタンス化して使用すれば、xib上のlabel等の変更は、管理するownerクラスの方で行うことが出来ます。
■ビルド結果