[iOS] Delegation Pattern 을 이용한 Cell 안의 버튼 이벤트 처리
[AppJam 회고 - 02] Delegation 패턴을 이용하여 Cell내부의 버튼 이벤트 처리하기
앱잼동안 구현했던 부분중에 테이블 뷰 셀 안에 버튼을 넣어서 버튼 액션을 다르게 처리해야 했었다.
옆에 필터 같은 버튼을 누르면 테이블뷰 셀에 표시가 되었고 해당 제품의 성분정보가 테이블 뷰 상단에 보였다. 보통 많은 자료에서 이러한 문제를 해결 할때 버튼의 Target-Action을 설정하여 이벤트 처리를 하는데 Delegation 패턴을 사용하여 해결하는 방법에 대해 알아 보도록 하겠다.
Delegation패턴이란?
사전 해석에 따르면 ‘위임자’ 라고 한다. 즉, 하나의 객체가 다른 객체를 대신해 동작 또는 조정할 수 있는 기능을 제공한다. 주로 프레임워크 객체가 위임을 요청하고 커스텀 컨트롤러 객체가 위임을 받아 특정 이벤트에 대한기능을 구현한다.
TableView의 예를들면 테이블뷰의 동작을 커스텀할 때 UITableViewDelegate 프로토콜을 상속받아 상세동작을 구현할 수 있다.
패턴 적용
Delegation 패턴을 적용하여 버튼에 대한 액션을 구현해 보겠다.
먼저, 위임을 요청하는 객체는 테이블뷰 Cell의 커스텀 객체이다. 테이블뷰 구현할 때 커스텀 Cell 클래스를 작성하였을 것이다. 그리고 셀 내부를 구성하는 프로퍼티들이 있고 그 안에 우리가 이벤트를 설정할 버튼이 존재할 것이다.
하지만 어떤 동작을 위임할지 위임받는 객체는 알 수가 없기 때문에 위임을 요청 할 메소드를 프로토콜로서 정의한다.
protocol ComponentProductCellDelegate {
func selectedInfoBtn(index: Int)
}
그리고 커스텀 테이블뷰 Cell의 프로퍼티로 해당 프로토콜 객체를 생성하고 선택한 셀의 index를 통해 제품 정보를 서버에서 불러와야 하기 때문에 index프로퍼티를 생성한다. 그 다음 우리가 처리하야할 이벤트 처리에 관한 것을 이 객체가 처리하도록 하고 프로퍼티의 index 값을 넘긴다.
class ComponentProductCell: UITableViewCell {
…
@IBOutlet var selectInfoBtn: UIButton!
var index: Int = 0
var delegate: ComponentProductCellDelegate?
…
@IBAction func selectedInfoBtn(_ sender: Any) {
self.delegate?.selectedInfoBtn(index: index)
}
}
이제 뷰컨트롤러 에서 위임 받을일 만 남았다.테이블뷰가 존재하는 커스텀 뷰 컨트롤러에서는 테이블뷰의 DataSouce를 상속받아 각 Cell을 구성하게 된다. 이 때 앞서 구현한 커스템 셀로 구성을 하게 되는데 이 때 이 프로토콜 변수의 레퍼런스를 뷰 컨트롤러 로 설정하고 선택된 셀의 index를 Custom Cell클래스의 index프로퍼티로 설정한다.
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: “ComponentProductCell”) as! ComponentProductCell
…
cell.index = indexPath.row
cell.delegate = self
…
return cell
}
물론 이 전에 뷰컨트롤러 클래스는 위임받을 동작에 대한 구현을 프로토콜 상속을 통해 구현해주어야 한다.
extension ComponentProductVC: ComponentProductCellDelegate{
func selectedInfoBtn(index: Int) {
…
}
전에도 비슷한 동작을 구현했을 때는 Target-Action 으로 처리를 해주었던 기억이 있다. 뭐가 더 나은방법이라 할순 없겠지만 디자인패턴을 적용하면서 iOS에서 자주 사용하는 Delegation에 대한 이해를 더 잘 할 수 있게되어서 좋은 경험이였다.
#iOS/AppJam_회고