언제 델리게이트 패턴을 고려해야 하는지:
델리게이트 패턴이 필요한 경우는 아래와 같습니다:
- 셀 내부의 특정 UI 요소와 상호작용할 때:
- 예를 들어, 셀 안에 버튼이 있어서 사용자가 버튼을 눌렀을 때 특정 작업을 해야 하는 경우에는 델리게이트 패턴이 유용합니다. didSelectItemAt은 셀 전체의 선택을 처리하지만, 버튼과 같은 특정 UI 요소와의 상호작용은 다루지 않습니다.
⭐️ 셀 자체를 눌렀을 때 반응한다면 => didSelectItemAt 이걸 사용하지만,
⭐️ 셀 안에 있는 버튼을 눌렀을 때 반응한다면 => 델리게이트 패턴을 사용해야 한다.
컬렉션 셀 안에 텍스트로 가득 채운 상태에서 해당 셀을 눌렀을 경우, 텍스트의 색상 변경 및 외부 API를 통한 데이터를 받는다? => 이거라면 didSelectItemAt이 낫다.
Delegate 패턴 적용
1. 프로토콜 정의 (Delegate Protocol)
2. 델리게이트 선언 및 메서드 구현 (Delegate Declaration and Implementation)
import UIKit
protocol CategoryCollectionViewDelegate: AnyObject {
func didSelected(at index: Int)
}
class CategoryCollectionViewCell: UICollectionViewCell {
// MARK: - Variables
static let identifier = "CategoryCollectionViewCell"
weak var delegate: CategoryCollectionViewDelegate?
private var index: Int?
3. 델리게이트 객체 설정 및 메서드 호출 (Setting Delegate and Calling Methods)
- cell.delegate = self
- didSelected(at: selectedIndex)
extension HomeViewController: UICollectionViewDelegate, UICollectionViewDataSource {
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return categoryButtonTitle.count
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
guard let cell = collectionView.dequeueReusableCell(withReuseIdentifier: CategoryCollectionViewCell.identifier, for: indexPath) as? CategoryCollectionViewCell else { return UICollectionViewCell() }
let title = categoryButtonTitle[indexPath.row]
let isSelected = indexPath.item == selectedIndex
cell.delegate = self
cell.configure(with: title, isSelected: isSelected, index: indexPath.item)
return cell
}
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
selectedIndex = indexPath.item
collectionView.reloadData() // 선택 상태 업데이트
didSelected(at: selectedIndex) // Delegate 호출
}
}
extension HomeViewController: CategoryCollectionViewDelegate {
func didSelected(at index: Int) {
switch index {
case 0:
loadAttractionsData()
case 1:
loadFacilitiesData()
case 2:
loadEventsData()
case 3:
loadCourseData()
case 4:
loadLeisureactivityData()
default:
break
}
}
private func loadAttractionsData() {
print("Attractions data loaded")
}
private func loadFacilitiesData() {
print("Facilities data loaded")
}
private func loadEventsData() {
print("Events data loaded")
}
private func loadCourseData() {
print("Course data loaded")
}
private func loadLeisureactivityData() {
print("Leisure activity data loaded")
}
}
⭐️ 왜 CategoryCollectionViewCell 안에 delegate 변수를 선언하는가?
셀이 선택되었을 때 CategoryCollectionViewCell은 HomeViewController에게 그 선택 이벤트를 전달해야 합니다. 이때 셀은 자신이 선택되었음을 알리기 위해 delegate를 통해 그 이벤트를 전달합니다.
즉, 셀은 **"내가 선택되었으니 뭔가 해줘"**라는 신호를 보내는 입장입니다. 그래서 셀 안에 delegate 변수가 필요합니다.
이 delegate는 HomeViewController를 가리키며, HomeViewController는 CategoryCollectionViewDelegate 프로토콜을 채택하고 있어, didSelected(at:) 메서드를 구현해 해당 셀의 선택에 대한 응답을 처리합니다.
⭐️ 컬렉션 셀은 "눌렸다"라는 이벤트를 홈 뷰컨트롤러에 전달 => "weak var delegate: CategoryCollectionViewDelegate?"
⭐️ 그리고 해당 이벤트를 홈뷰컨틀로러에서 받았을 때 2가지를 확인해야한다.
1. 받았다는 신호 => "cell.degate = self"
2. 관련된 기능을 확실히 구현 => protocol 내에 있는 함수를 제대로 구현한다.
⭐️ 근데 중요한 점은 지금은 델리게이트 패턴보다는 "didSelectItemAt" 를 사용하는게 낫다.
-> 셀 전체를 누르기 때문이다.
-> 셀 안에 이미지가 있고 그 위에 하트가 있다? 그리고 하트를 눌러야 한다? 그러면 델리게이트 패턴을 쓰자 .
https://chatgpt.com/share/2312267f-d576-41e1-a389-001f517c38b5
'Swift' 카테고리의 다른 글
데이터 모델 이름을 바꿔야 한다면? (0) | 2024.09.06 |
---|---|
enum을 통해 api 함수 관리해보기 (0) | 2024.08.31 |
콜백 함수는 언제 쓰이나요? (0) | 2024.08.23 |
Swift에서 Any와 AnyObject의 차이점은 무엇인가요? (0) | 2024.08.23 |
Storyboard와 XIB의 차이점은 무엇인가요? (0) | 2024.08.21 |