はじめに
どうもはじめです。
今回はTableViewCell,CollectionViewCell,UIViewのXibファイルを
コードで呼び出す方法をまとめてみます。
ではさっそくー
前提条件
Xcode 8.3.3
Swift 3.1
TableViewCell
まずはTableViewCellからやってみます。
ちなみにこれは前回も書きました。
XIBの準備
Command + N
↓
Cocoa Touch Class
↓
[Subclass of:]にUITableViewCellを選択
↓
[Also create XIB file]にチェックを入れる
↓
Nextを押して、ディレクトリを指定してCreate
上記手順でTableViewCellを呼び出す際に必要なイニシャライザや、
クラスとXIBファイルの紐付けが自動で行われます。
今回はCellの中心にLabelを追加するだけにしておきます。
ViewControllerでの呼び出し
まずはViewControllerにTableViewを設置して、
ViewControllerにOutLet接続します。
TableViewのDelegateとDataSourceをViewControllerに紐付けすることをお忘れ無く。
viewDidLoadにてXIBファイルを定義しておきます。
1 2 3 4 5 | override func viewDidLoad() { super.viewDidLoad() // "TableViewCell"はXIBファイルのファイル名、"Cell"はこのXIBを使用する際のID(自由に決められます) myTableView.register(UINib(nibName: "TableViewCell", bundle: nil), forCellReuseIdentifier: "Cell") } |
TableViewで表示するCellを返す際に先ほど定義したXIBを使用します。
1 2 3 4 5 | func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { // ”Cell"はviewDidLoadにで自分で決めたID、[as! TableViewCell]はXIBのカスタムクラス let cell = myTableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath) as! TableViewCell return cell } |
これで完成!!
注意点としては以下になります。
・XIBの[File’s Owner]には何も記載しないこと
・XIBファイルにあるTableViewCellに対してCustom Classを指定すること
・IdentityやTableViewCell.Identifierには何も書く必要がないこと
コードの全文はこちらです。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 | import UIKit class ViewController: UIViewController { @IBOutlet weak var myTableView: UITableView! override func viewDidLoad() { super.viewDidLoad() myTableView.register(UINib(nibName: "TableViewCell", bundle: nil), forCellReuseIdentifier: "Cell") } override func didReceiveMemoryWarning() { super.didReceiveMemoryWarning() } } extension ViewController: UITableViewDataSource { func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { return 10 } func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { let cell = myTableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath) as! TableViewCell return cell } } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | import UIKit class TableViewCell: UITableViewCell { override func awakeFromNib() { super.awakeFromNib() // Initialization code } override func setSelected(_ selected: Bool, animated: Bool) { super.setSelected(selected, animated: animated) // Configure the view for the selected state } } |
CollectionView
次はCollectionViewをやってみます。
ほぼほぼTableViewと同じです。
XIBの準備
TableViewCellのXIBを作った時と違う点は一箇所だけです。
・[Subclass of:]にはUICollectionViewCellを選択
以上でCollectionViewCellのXIBを呼び出す際に必要なイニシャライザは用意できました。
1 2 3 4 5 6 7 8 9 10 | import UIKit class CollectionViewCell: UICollectionViewCell { override func awakeFromNib() { super.awakeFromNib() // Initialization code } } |
CollectionViewCellには枠線がないので、
わかりやすいように背景色とLabelを設定しておきます。
ViewControllerの準備
こちらもTableViewの時とほぼ同じです。
CollectionView設置後以下を行います。
・Delegate、DataSourceの紐付け
・CollectionViewをOutLet接続
・viewDidLoadにてXIBファイルの定義
1 2 | // "CollectionViewCell"はXIBファイルのファイル名、"Cell"はこのXIBを使用する際のID(自由に決められます) myCollectionView.register(UINib(nibName: "CollectionViewCell", bundle: nil), forCellWithReuseIdentifier: "Cell") |
・XIBの呼び出し
1 2 3 4 5 | func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell { // "Cell"はviewDidLoadで決めたID,[ as! CollectionViewCell]にはXIBのカスタムクラス let cell = myCollectionView.dequeueReusableCell(withReuseIdentifier: "Cell", for: indexPath) as! CollectionViewCell return cell } |
以上で完成です!
注意点はTableViewCellの時と同じです。
コードの全文は以下になります。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | import UIKit class CollectionViewController: UIViewController { @IBOutlet weak var myCollectionView: UICollectionView! override func viewDidLoad() { super.viewDidLoad() myCollectionView.register(UINib(nibName: "CollectionViewCell", bundle: nil), forCellWithReuseIdentifier: "Cell") } override func didReceiveMemoryWarning() { super.didReceiveMemoryWarning() } } extension CollectionViewController: UICollectionViewDataSource { func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int { return 10 } func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell { let cell = myCollectionView.dequeueReusableCell(withReuseIdentifier: "Cell", for: indexPath) as! CollectionViewCell return cell } } |
1 2 3 4 5 6 7 8 9 10 | import UIKit class CollectionViewCell: UICollectionViewCell { override func awakeFromNib() { super.awakeFromNib() // Initialization code } } |
UIView
次はUIViewです。
こやつは少し違ってきます。
カスタムクラスの作成
Command + N
↓
Swift File
↓
Create
作成したファイルに以下を記述
1 2 3 4 5 6 7 8 9 10 11 12 13 | import UIKit class XibView: UIView { override init(frame: CGRect) { super.init(frame: frame) self.commonInit(frame: frame) } required init?(coder aDecoder: NSCoder) { super.init(coder: aDecoder) } private func commonInit(frame: CGRect) { } } |
XIBの準備
Command + N
↓
View
↓
Create
一番親となるUIViewのSizeをFreeformに設定し、
width,heightを200にします。
その上にViewとLabelを配置し、わかりやすいようにViewの背景色を設定します。
XIBとカスタムクラスの紐付け
・XIBの[File’s Owner]のCostomClassに作成したカスタムクラスのクラス名を指定
※そのほかにクラス名を指定する必要はありません。
一番親となるUIViewをOutLet接続します。
最後にカスタムクラスに以下を追記します。
1 2 3 4 5 6 | private func commonInit(frame: CGRect) { // "XibView"はXIBのファイル名 Bundle.main.loadNibNamed("XibView", owner: self, options: nil) // contentViewはOutLet接続したXIBのUIView addSubview(contentView) } |
ViewControllerで呼び出し
以下のコードを記述するだけで呼び出しが可能です。
1 2 3 4 5 6 7 8 | override func viewWillAppear(_ animated: Bool) { super.viewWillAppear(animated) let frame = CGRect(x: 50, y: 50, width: 200, height: 200) let xibView = XibView(frame: frame) self.view.addSubview(xibView) } |
なぜviewWillAppearに記載したかというと、viewDidLoadで呼び出しをしてしまうと
レイアウトが生成される前のフレームサイズで初期化を行ってしまうため、レイアウトが崩れてしまうからです。
以上で完成です。
コードの全文はこちらになります。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | import UIKit class XibViewController: UIViewController { override func viewDidLoad() { super.viewDidLoad() } override func viewWillAppear(_ animated: Bool) { super.viewWillAppear(animated) let frame = CGRect(x: 50, y: 50, width: 200, height: 200) let xibView = XibView(frame: frame) self.view.addSubview(xibView) } override func didReceiveMemoryWarning() { super.didReceiveMemoryWarning() // Dispose of any resources that can be recreated. } } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | import UIKit class XibView: UIView { @IBOutlet var contentView: UIView! override init(frame: CGRect) { super.init(frame: frame) self.commonInit(frame: frame) } required init?(coder aDecoder: NSCoder) { super.init(coder: aDecoder) } private func commonInit(frame: CGRect) { Bundle.main.loadNibNamed("XibView", owner: self, options: nil) addSubview(contentView) } } |
さいごに
まだまだXIBには苦戦することがおおいです。
使いこなせるようになるとかなり便利なものなので、理解していこうと思います。