티스토리 뷰

/ 를 쓴 이유는 코드를 어떻게 짜느냐에 따라 그냥 다 되니까 ~

 

= data passing using protocol

= access variable in another class

 

 

우선 내가 작성한 예시는

 

ViewController

이렇게 ViewController 위에 얹혀있는 Custom Button 버튼을 누르면

그 버튼 클래스의 delegate 를 통해 ViewController에서 특정 작업을 수행하는 예시이다.

터치 이벤트는 ViewController가 아닌 CustomButton 클래스에 구현이 되어있는 상태로

 

핵심은

Custom Button 이라는 클래스에서의 동작이 ViewController 라는 다른 클래스에서 수행된다는 점이다 !!

 

이렇게 수행되도록 하는 방법에는 여러가지가 있는데

그 중에 내가 자주 사용하는 것은

 

1. Protocol

2. ViewModel 하나 만들어서 다이나믹 함수로 접근

 

이렇게 두 가지 방법이 있는데 우선 이번 포스팅은 첫 번째 방법인 프로토콜을 사용하는 방법을 작성해보려고 한다.

 

 

우선 프로토콜이 뭔지 모르겠다면 ..

https://zeddios.tistory.com/255

 

Swift ) Protocols (1)

안녕하세요 :) Zedd입니다!! 오늘은 프로토콜에 대해서 알아볼거에요! 뭔가...번역하는거 진짜 힘든데 중독되네요. 뭔가 다 번역해버리고 싶은 그런 막 그런 충동이.. 사실 associated type에 대해서 글

zeddios.tistory.com

이 글을 봐주세요 ..

 

 

코드를 직접 보는 것보다 더 좋은 건 없으니까 ~!

 

우선 Main.storyboard 에는

이렇게 뷰컨 하나만 덩그러니 놔줬고요

올려놓은 버튼은 옆에 저렇게 클래스로 CustomButton을 상속받도록 설정해두었습니다.

 

CustomButton.swift

import UIKit

protocol CustomButtonDelegate: AnyObject {
    func didTapButton()
    // func didTapButton(completion: () -> ()) 이런 식으로 활용
}

class CustomButton: UIButton {

    weak var delegate: CustomButtonDelegate?
    
    required init?(coder: NSCoder) {
        super.init(coder: coder)
        self.backgroundColor = .yellow
        self.addTarget(self, action: #selector(didTapCustomButton(_:)), for: .touchUpInside)
    }
    
    @objc func didTapCustomButton(_ sender: UIButton) {
        delegate?.didTapButton()
    }
}

Custom Button 클래스는 이렇게 생겼는데요..

 

우선 저는 저렇게 프로토콜 선언할 경우에 관련있는 클래스 명 + Delegate 로 이름을 붙이는 편이에요. (이건 각자의 스타일에 맞게 ..)

원래는 protocol이 class를 상속받게 되어있었는데 이제 AnyObject 를 상속받도록 하라고 권장하더라구요

 

여튼

CustomButtonDelegatedidTapButton( ) 이라는 함수를 갖고 있고요

 

CustomButton 클래스 안에서 delegate라는 이름의 변수를 선언해서

버튼이 탭 될 때마다 delegate의 didTapButton( ) 함수를 불러주도록 코드를 작성했습니다.

 

ViewController.swift

import UIKit

class ViewController: UIViewController {

    @IBOutlet weak var customButton: CustomButton!
    
    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view.
        customButton.delegate = self
    }
    
}

extension ViewController: CustomButtonDelegate {
    func didTapButton() {
        print("is Tapped")
    }
}

우선 IBOutlet으로 현재 스토리보드에 올라와있는 버튼을 코드와 연결(?)해 줍니다.

 

customButton은 CustomButton을 상속받으니까

그 안에 있는 변수, 함수 등등을 갖고 있겠죠

 

그래서

customButton.delegate = self

라고 써줍니다.

 

저 버튼의 delegate 는 나 (= ViewController) 가 될거라고 알려줍니다.

 

이걸 안 쓰면 CustomButton 클래스에서 delegate?.didTapButton( ) 이걸 불렀을 때

delegate 가 어디있는데??? 하면서 아무 일도 일어나지 않아요

왜 ?

delegate 가 누구라고 이야기 안 해줬잖아 ...

 

이런 불상사를 막기위해 저 줄을 꼭 써줘야합니다.

 

그리고 CustomButtonDelegate를 채택해서 저 함수를 구체적으로 작성해줍니다.

extension ViewController: CustomButtonDelegate {
	
}

 

저는 단순히 print문을 써줬는데 ViewController에서 해야하는 작업이 있다면 그걸 print 쓴 자리에서 해주면 되겠죠?

 

다시 본론으로 돌아가서,

작동흐름을 설명하자면

 

1. 버튼을 누른다

2. Custom Button 클래스에서 delegate?.didTapButton을 부른다

3. Custom Button 클래스의 delegate 는 ViewController 와 연결되어있음

4. ViewController 클래스에서 작성한 didTapButton을 수행한다.

 

이렇게 정리가 됩니다..!!!

 

그래서 버튼을 누르면

이렇게 정상적으로 동작하는 걸 확인할 수 있습니다.

 

 

이걸 제가 그림으로 그려봤는데

.. ㅠㅠ 컴퓨터로 뭔가 더 깔끔하게 그려보고 싶은데 .. 그건 다음 기회에 ...

 

그림으로 지금 상황? 관계들을 그려보면 저런 식으로 동작합니다!

 

 

이번 글은 Protocol로 서로 다른 클래스에 동작이나 데이터 등을 전달할 수 있는 방식을 써봤고,

다음에는 뷰모델 & 다이나믹 함수로 접근하는 법을 포스팅 해보려고 합니다!!

 

끗! 

댓글