22
23

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

【swift】カスタムビューをxibで作成して各ViewControllerで使い回す

Last updated at Posted at 2019-03-27

概要

StoryboardでViewControllerのViewの一部が他のViewControllerでも同じレイアウトで表示している場合があります。その場合ViewをコピーしてViewControllerに貼り付けて利用したりしますが、それだとそのViewに変更を加えると複数利用しているため他のViewも変更しなくてはなりません。
そう行った場合、使い回せるViewをカスタムビューとしてxibで作成して利用することで、そのxibのみを変更すれば複数のViewでその変更が反映されるようになります。

実装方法

まずは、カスタムビューをxibで作成します。

SampleView_xib.png
続いて、ViewControllerで、xibのカスタムビューをインスタンス化します。

ViewController.swift
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
ViewController.swift
    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 = "あああ"
    }

■ビルド実行

Simulator Screen Shot - iPhone XS - 2019-03-26 at 14.41.56.png

カスタムビューを管理するクラスを生成する

ViewControllerでxibのViewをインスタンス化して使用するのは上記の方法ですが、多くの場合カスタムビューを管理するクラスを作成してxibとセットで利用したいと考えます。

その方法としては、withOwnerをカスタムビューを管理するクラスにします。

(SampleViewOwnerはSampleView.xibを管理するクラス)

SampleViewOwner.swift
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 = "いいい"
    }
}
ViewController.swift
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クラスの方で行うことが出来ます。

■ビルド結果

Simulator Screen Shot - iPhone XS - 2019-03-26 at 14.58.38.png

22
23
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
22
23

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?