ViewController에서 버튼을 누르면 다른 ViewController로 이동하는,, ViewController간 데이터 전달은 간단하다.

 

아래 처럼 왼 쪽 ViewController의 'Next Button'을 눌러 오른 쪽 하늘 색 배경의 SecondViewController로 이동하고자 하는 경우, 아래 코드로 쉽게 구현할 수 있다.

단, 코드에서 SecondViewController에 접근하기 위해, 오른쪽 인스펙터 영역에 보이는 것 처럼 Class와 Storyboard ID를 등록해주어야 한다.

이렇게 구현하는 방법을 present 방식이라 하는데, viewController간 화면 전환은 이 방법 말고도 다양하다.

 

.

.

.

 

본론으로 들어가서, 내가 작업하고 있는 상황은 위와는 조금 다르다.

 

ViewController 위에  CollectionViewCell이 있고, CollectionViewCell 위에 각각의 셀을 따로 swift 파일로 만들어서 작업하고 있었다. 말이 좀 복잡한데,, 다음과 같은 상황이다.

ViewController 위에 CollectionView가 있다. 그 위에 FirstCollectionViewCell을 추가해주었다. (Cell 등록 및 구현 방법은 코드 참고)

실행시키면 다음과 같이 나타난다.

CollectionView의 Section0에 FirstCollectionViewCell이 추가 되었다. 해당 셀의 Next Button을 눌렀을 때 Second View Controller로 화면이 이동하는 것이 목표이다.

 

간단히 정리하자면 ViewController가 FirstCollectionViewCell의 버튼 기능을 위임 받으면 된다. 이를 'Delegate Pattern'이라 칭한다. 한 객체가 다른 객체의 기능을 위임 받아 대신 동작할 수 있도록 하는 것이다.

 

 

 

 

Delegate Pattern을 적용하는 방법

 

1. 위임을 요청할 메소드를 프로토콜로서 정의한다.

   - 'Next Button'을 눌렀을 때의 동작을 위임할 것이므로 다음과 같이 정의해준다.

// ViewController.swift
protocol CollectionViewCellDelegate {
    func nextButtonDidTap(index: Int)
}

 

2. 위임받을 동작에 대한 함수를 구현 해준다.

   - 'Next Button'을 눌렀을 때 Main 스토리보드에 있는 SecondViewController로 이동하도록 한다. 맨 처음 ViewController간  화면전환 구현 코드와 동일하다. "SecondVC" 자리에 스토리보드 아이디를 입력하면 된다.

// ViewController.swift
extension ViewController: CollectionViewCellDelegate {
    func nextButtonDidTap(index: Int) {
        let secondViewController = UIStoryboard(name: "Main", bundle: nil).instantiateViewController(withIdentifier: "SecondVC") as! SecondViewController
        secondViewController.modalPresentationStyle = .fullScreen
        self.present(secondViewController, animated: true)
    }
}

 

 

2. index 프로퍼티를 생성하고 index 값을 넘겨준다.

// FirstCollectionViewCell.swift
    @IBOutlet weak var nextButton: UIButton!
    
    var index: Int = 0
    var delegate: CollectionViewCellDelegate?
    
    @IBAction func nextButtonDidTap(_ sender: Any) {
        self.delegate?.nextButtonDidTap(index: index)
    }

 

 

3. 셀 생성시 프로토콜 변수의 레퍼런스를 ViewController로 설정하고 해당 셀의 index를 위임 받을 cell의 index 프로퍼티로 설정한다.

   - 이 부분은 정확히 이해 못했는데... 셀을 등록하고 나서 주석 처리 부분 사이의 코드 두 줄을 입력해서 index를 넘겨주는 것 같다.

// ViewController.swift
func collectionView(_ collectionView: UICollectionView,
                    cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
        guard let cell = collectionView.dequeueReusableCell(
            withReuseIdentifier: FirstCollectionViewCell.identifier,
            for: indexPath) as? FirstCollectionViewCell else {
                fatalError()
            }

	// 이 부분!
        cell.index = indexPath.row
        cell.delegate = self
        //

        return cell
}

 

끝!!!!!

쫘잔..

 

 

참고 링크

https://juhyeoklee.github.io/ios/ios-post06/

 

[iOS] Delegation Pattern 을 이용한 Cell 안의 버튼 이벤트 처리

AppJam 회고

juhyeoklee.github.io

 

+ Recent posts