swift
CustomView
を作成し、別のViewContoroller
上に表示させたは良いものの、CustomView
上に設置したButtonのアクションをどうやってそのVCで発動させるかでつまずいたので、その方法をざっくり解説します。
結論、protocol
とdelegate
を使用します。
流れ
- 前提確認
- protocol宣言
- 処理を発動するクラスでの記述
- 処理を行うクラスでの記述
- それぞれのコードと画面
- 終わりに
前提確認
MacOS Catalina 10.15.4
Xcode 12.1
Swift version 5
CustomView
(これに接続するVCをCustomViewVC
と命名)で上下矢印のUIButton
を用意し、別のVC(MainVC
と命名)上にあるUILabel
の値を変化させます。変化のさせ方は「上矢印を押せば+1、下矢印を押せば-1」(以下、処理)とします。
protocol
とdelegate
を使用しますが、CustomViewVC
が処理を発動させるクラス、MainVC
が処理を実際に行うクラスになります。
尚、CustomViewVC
の作成は主旨から外れますので他の記事に譲ります。
protocol宣言
宣言場所はどのクラスでも大丈夫ですが、import xxx
とclass xxx
の間に書くようにしましょう。
ここではMainVC
に書くことにします。
import UIKit
@objc protocol CustomViewDelegate : NSObjectProtocol {
func plus()
func minus()
}
class MainViewController: UIViewController{
処理を発動するクラスでの記述
protocol
型の変数を宣言します。変数名はdelegateTest
とします。
ここでIBOutlet
で接続させるのがミソです。
@IBOutlet var delegateTest: CustomViewDelegate?
上下矢印Button
をそれぞれIBAction
接続し、その中に+1と-1の処理を発動させます。
(発動だけで、ここで処理は行われません)
@IBAction func plus() {
delegateTest?.plus()
}
@IBAction func minus() {
delegateTest?.minus()
}
処理を行うクラスでの記述
まずは、protocol
を継承させます。
class MainViewController: UIViewController, CustomViewDelegate {
次に、MainVC
にCustomView
からdelegate
を接続させます。
これを行うことでCustomView
で発動させた処理を、MainVC
にて行うことができます。
その接続方法ですが、CustomView
を表示させているUIViewをクリックし、インスペクタバー の「Show the Connections inspector」(一番右のアイコン)を見ます。
すると、先ほどIBOutletで宣言したdelegate
変数が表示されているので、MainVC
にドラックして接続させます。
あとは行う処理を内容を記述すればOKです。
func plus() {
number += 1
label.text = "\(number)"
}
func minus() {
number -= 1
label.text = "\(number)"
}
それぞれコードと画面
import UIKit
class CustomView: UIView {
@IBOutlet var plusBtn: UIButton!
@IBOutlet var minusBtn: UIButton!
@IBOutlet var delegateTest: CustomViewDelegate?
override init(frame: CGRect) {
super.init(frame: frame)
loadNib()
}
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
loadNib()
//fatalErrorがデフォルトで入っていますが消さないとエラーになってしまうので注意してください!
}
func loadNib() {
//CustomViewの部分は各自作成したXibの名前に書き換えてください
let view = Bundle.main.loadNibNamed("CustomView", owner: self, options: nil)?.first as! UIView
view.frame = self.bounds
self.addSubview(view)
}
@IBAction func plus() {
delegateTest?.plus()
}
@IBAction func minus() {
delegateTest?.minus()
}
import UIKit
@objc protocol CustomViewDelegate : NSObjectProtocol {
func plus()
func minus()
}
class MainViewController: UIViewController, CustomViewDelegate {
@IBOutlet weak var testView: CustomView!
@IBOutlet weak var label: UILabel!
var number = 0
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
}
func plus() {
number += 1
label.text = "\(number)"
}
func minus() {
number -= 1
label.text = "\(number)"
}
}
終わりに
CustomView
は便利だと思うのですが、私自身今まで使ったことがなく、表示させたは良いものの、使い勝手悪いように感じましたので、ここで使い方の一つを解説させて頂きました。
protocol
の中身がほぼないのは良くないかもしれませんが、あくまでCustomView
の処理を別VCで行うことを主旨とするため、簡潔にさせて頂きました。
初めての投稿ですので、至らない点あるかと思いますが、何かあればご指摘・アドバイス頂けると幸いです。