カテゴリー: iOS

Swift3 [XIBファイル] コードでの呼び出し方まとめ

はじめに

どうもはじめです。
今回は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ファイルを定義しておきます。

override func viewDidLoad() {
    super.viewDidLoad()
    // "TableViewCell"はXIBファイルのファイル名、"Cell"はこのXIBを使用する際のID(自由に決められます)
    myTableView.register(UINib(nibName: "TableViewCell", bundle: nil), forCellReuseIdentifier: "Cell")
}

TableViewで表示するCellを返す際に先ほど定義したXIBを使用します。

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には何も書く必要がないこと

コードの全文はこちらです。

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
    }
}
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を呼び出す際に必要なイニシャライザは用意できました。

import UIKit

class CollectionViewCell: UICollectionViewCell {

    override func awakeFromNib() {
        super.awakeFromNib()
        // Initialization code
    }

}

 

CollectionViewCellには枠線がないので、
わかりやすいように背景色とLabelを設定しておきます。

ViewControllerの準備

こちらもTableViewの時とほぼ同じです。

CollectionView設置後以下を行います。
・Delegate、DataSourceの紐付け
・CollectionViewをOutLet接続

・viewDidLoadにてXIBファイルの定義

// "CollectionViewCell"はXIBファイルのファイル名、"Cell"はこのXIBを使用する際のID(自由に決められます)
myCollectionView.register(UINib(nibName: "CollectionViewCell", bundle: nil), forCellWithReuseIdentifier: "Cell")

・XIBの呼び出し

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の時と同じです。

コードの全文は以下になります。

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
    }
}
import UIKit

class CollectionViewCell: UICollectionViewCell {

    override func awakeFromNib() {
        super.awakeFromNib()
        // Initialization code
    }

}

 

UIView

次はUIViewです。
こやつは少し違ってきます。

カスタムクラスの作成

Command + N

Swift File

Create

作成したファイルに以下を記述

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接続します。

最後にカスタムクラスに以下を追記します。

private func commonInit(frame: CGRect) {
 // "XibView"はXIBのファイル名
    Bundle.main.loadNibNamed("XibView", owner: self, options: nil)
    // contentViewはOutLet接続したXIBのUIView
    addSubview(contentView)
}

 

ViewControllerで呼び出し

以下のコードを記述するだけで呼び出しが可能です。

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で呼び出しをしてしまうと
レイアウトが生成される前のフレームサイズで初期化を行ってしまうため、レイアウトが崩れてしまうからです。

以上で完成です。
コードの全文はこちらになります。

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.
    }

}
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には苦戦することがおおいです。
使いこなせるようになるとかなり便利なものなので、理解していこうと思います。

hajimenagasawa

シェア
執筆者:
hajimenagasawa
タグ: Swift

最近の投稿

フロントエンドで動画デコレーション&レンダリング

はじめに 今回は、以下のように…

3週間 前

Goのクエリビルダー goqu を使ってみる

はじめに 最近携わっているとあ…

1か月 前

【Xcode15】プライバシーマニフェスト対応に備えて

はじめに こんにちは、suzu…

2か月 前

FSMを使った状態管理をGoで実装する

はじめに 一般的なアプリケーシ…

3か月 前