同じカスタムViewで表示コンテンツだけ変えて複数個表示させたいという場合などに便利な方法をご紹します。
@IBInspectable、@IBDesignableを使用することでレイアウトの実装が便利になります。
カスタムViewを作成
まずはカスタムViewを作成します。
Xcodeのメニューから File > New > File... を選択してください。
Cocoa Touch Classを選択してNext
![](https://freelance-style.net/wp-content/uploads/2022/01/スクリーンショット-2022-01-29-14.06.12.png)
クラス名を入力してNext
![](https://freelance-style.net/wp-content/uploads/2022/01/スクリーンショット-2022-01-29-14.06.54.png)
次に、またXcodeのメニューから File > New > File... を選択してViewを選択してNext
![](https://freelance-style.net/wp-content/uploads/2022/01/スクリーンショット-2022-01-29-14.09.30.png)
先ほど作成したクラスと同じ名前でxibファイルを作成します。
![](https://freelance-style.net/wp-content/uploads/2022/01/スクリーンショット-2022-01-29-14.09.51.png)
xibファイルが開いたら最初にSizeをFreedomに設定しておきます。
![](https://freelance-style.net/wp-content/uploads/2022/01/スクリーンショット-2022-01-29-14.11.17-1.png)
File's OwnerのCustom ClassにカスタムViewのクラス名を入力してください。(xibファイルと実装ファイルの関連づけがされます)
レイアウトは自由に作成してください。(今回は以下のようにしました)
![](https://freelance-style.net/wp-content/uploads/2022/01/スクリーンショット-2022-01-29-15.51.39-1.png)
カスタムViewの実装ファイル側は以下のようになります。(Viewの紐付けは適宜行ってください。)
import UIKit
class CustomView: UIView {
@IBOutlet weak var colorView: UIView!
@IBOutlet weak var separatorView: UIView!
@IBOutlet weak var imageView: UIImageView!
@IBOutlet weak var label: UILabel!
override init(frame: CGRect) {
super.init(frame: frame)
loadNib()
}
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)!
loadNib()
}
func loadNib() {
if let view = Bundle(for: type(of: self)).loadNibNamed(String(describing: type(of: self)), owner: self, options: nil)?.first as? UIView {
view.frame = self.bounds
self.addSubview(view)
}
}
}
![](https://www18.a8.net/0.gif?a8mat=3N1T0Z+G5OISY+50+2HLQJL)
カスタムViewをstoryboard上に配置
試しにViewController側にViewを3つ配置します。
それぞれのViewのCustom ClassにカスタムViewのクラス名の入力します。
![](https://freelance-style.net/wp-content/uploads/2022/01/スクリーンショット-2022-01-29-15.25.39-1.png)
この状態で実行すると以下のように表示されます。
この状態だと表示コンテンツが設定されていないため、全てカスタムViewのxibファイルで定義された状態でそのまま表示されます。
![](https://freelance-style.net/wp-content/uploads/2022/01/Simulator-Screen-Shot-iPhone-8-2022-01-29-at-15.53.16.png)
@IBInspectableを設定
ここからが本題です!!!
@IBInspectableでプロパティを定義して反映させたい箇所にセットするように実装を追加します。
/// Viewの背景色
@IBInspectable private var color: UIColor? {
didSet {
colorView.backgroundColor = color
}
}
/// セパレータの表示フラグ
@IBInspectable private var separator: Bool = true {
didSet {
separatorView.isHidden = !separator
}
}
/// 画像
@IBInspectable private var image: UIImage? {
didSet {
imageView.image = image
}
}
/// タイトル
@IBInspectable private var title: String? {
didSet {
label.text = title
}
}
するとInterface Builderの右上にカスタムView用の設定エリアが追加されます。
ここでそれぞれのViewに対して異なる表示コンテンツの設定を行うことができます。
![](https://freelance-style.net/wp-content/uploads/2022/01/スクリーンショット-2022-01-29-15.42.40-2.png)
それぞれ設定した状態で実行すると以下のように表示することができました。
![](https://freelance-style.net/wp-content/uploads/2022/01/Simulator-Screen-Shot-iPhone-8-2022-01-30-at-11.24.23.png)
@IBInspectableで設定できる型
- Bool
- Int
- Double
- String
- Float
- CGPoint
- CGSize
- CGRect
- UIColor
- UIImage
@IBDesignableを設定
さらに、@IBDesignableをクラス自体に設定するとInterface Builder上でカスタムViewに設定された表示コンテンツをリアルタイムで確認することができるようになります。
@IBDesignable class CustomView: UIView {
以下のようにInterface Builder上で表示を確認できるようになります。
![](https://freelance-style.net/wp-content/uploads/2022/01/スクリーンショット-2022-01-29-16.00.18.png)
最終的なソースコードは以下のようになります。
import UIKit
@IBDesignable class CustomView: UIView {
/// Viewの背景色
@IBInspectable private var color: UIColor? {
didSet {
colorView.backgroundColor = color
}
}
/// セパレータの表示フラグ
@IBInspectable private var separator: Bool = true {
didSet {
separatorView.isHidden = !separator
}
}
/// 画像
@IBInspectable private var image: UIImage? {
didSet {
imageView.image = image
}
}
/// タイトル
@IBInspectable private var title: String? {
didSet {
label.text = title
}
}
@IBOutlet weak var colorView: UIView!
@IBOutlet weak var separatorView: UIView!
@IBOutlet weak var imageView: UIImageView!
@IBOutlet weak var label: UILabel!
override init(frame: CGRect) {
super.init(frame: frame)
loadNib()
}
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)!
loadNib()
}
func loadNib() {
if let view = Bundle(for: type(of: self)).loadNibNamed(String(describing: type(of: self)), owner: self, options: nil)?.first as? UIView {
view.frame = self.bounds
self.addSubview(view)
}
}
}