15
19

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.

【Swift3.0】xibを使ったカスタムビューの作り方

Last updated at Posted at 2017-01-27

#はじめに
Swift初心者の自分用の備忘録的な記事となります。
一度ネットで調べながら作成し、疑問点が出てきたためteratailで質問し、改良したものです。

#要件
・UIViewをカスタムしてダイアログのように表示したい
・デザインはxibを使いたい
スクリーンショット 2017-01-27 16.11.12.png

#最初に作ったもの

CustomDialog.swift
required init?(coder aDecoder: NSCoder) {
    commonInitialize()
    super.init(coder: aDecoder)
}

override init(frame: CGRect) {
    commonInitialize()
    super.init(frame: frame)
}

func setUp(frame: CGRect, name: String) {

    let customDialog: UIView = Bundle.main.loadNibNamed("CustomDialog", owner: self, options: nil)?.first as! UIView

    self.frame = frame
    customDialog.frame = frame
    dialogName = name

    addSubview(customDialog)
}

func commmonInitialize() {
    dialogName = ""
}
ViewController.swift
var customDialog: CustomDialog = CustomDialog()
override func viewDidLoad() {
    super.viewDidLoad()

    customDialog.setUp(frame: self.view.frame, name: "hoge")
}

func showDialog() {
    self.view.addSubview(customDialog)
}

#途中まで作ってみて
#####疑問点
・イニシャライザ(requiredとdesignered)が2度呼ばれてしまう
・ViewControllerの上に「CustomDialogそのもの」と「xibから呼び出したCustomDialog」が乗っていることになってしまう

#####聞いてみた
【Swift3.0】カスタムビューの作成の際のベストプラクティスについて

#####とりあえずの結論
CustomDialog.swiftをxibのFile's ownerとすることでUIViewそのものではなく、CustomDialogを呼び出すクラスとして使う

#改良したもの

CustomDialog.swift
import UIKit

protocol CustomDialogDelegate: class {
    func shouldDismissCustomDialog -> Void
}

class CustomDialog: NSObject {
    
    private static let className = "CustomDialog"
    
    var name: String
    
    weak var customDialogDelegate: CustomDialogDelegate?
    
    @IBOutlet var dialog: UIView!
    
    // CustomDialogのパーツ
    @IBOutlet var nameLabel: UILabel!
    
    // MARK: IBActions
    
    @IBAction func closeButtonTapped(sender: UIButton) {
        customDialogDelegate?.shouldDismissCustomDialog()
    }
    
    // MARK: Initialize
    
    override init() {
        name = ""
        super.init()
        Bundle.main.loadNibNamed(CustomDialog.className, owner: self, options: nil)
    }
    
    // MARK: Public Methods
    
    func show(presentedView: UIView?, requestName: String) {
        if let unwrappedPresentedView = presentedView {
            customDialog.frame = unwrappedPresentedView.frame
            name = requestName
            
            unwrappedPresentedView.addSubview(customDialog)
        } else {
            fatalError("View is Nil!")
        }
    }
    
    func hide() {
        customDialog.removeFromSuperview()
    }

}
ViewController.swift
import UIKit

class ViewController: UIViewController, CustomDialogDelegate {
    
    @IBOutlet var tableView: UITableView!
    
    var customDialog: CustomDialog = CustomDialog()

    override func viewDidLoad() {
        super.viewDidLoad()
        
        customDialog.customDialogDelegate = self
    }
    
    func showCustomDialog() {
        customDialog.show(presentedView: self.navigationController?.view, requestName: "hoge")
    }
    
    func shouldDismissCustomDialog() {
        customDialog.hide()
    }
    
}

改善案等ございましたらコメントいただけると嬉しいです。

15
19
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
15
19

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?