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

 

인스타그램에서 상대방 프로필에 들어갔을 때, 아무 게시글도 올리지 않았을 경우 'No posts yet'이라는 텍스트와 함께 뜨는 화면이 있다. 그런 화면을 'empty view'라 하는 것 같다.

 

나의 경우 컬렉션 뷰를 여러 섹션으로 나눠서 각 섹션 별로 셀을 다루는 작업을 하고 있었는데, 특정 섹션에서 셀 개수가 0일 때 empty view를 띄우는 것이 목적이었다.

이런 느낌.. section 2의 cell 개수가 0일 때 empty view 띄우는 것이 목적

특정 섹션의 셀 개수에 접근하는 부분을 코드로 어떻게 작성해야할 지 몰라 헤맸는데, 생각보다 간단했다.

// Declaration
func numberOfItems(inSection section: Int) -> Int

 

(해당 컬렉션 뷰 이름).numberOfItems(inSection: (해당 섹션 번호))

 

로 접근하면 된다.

 

실제로 사용할 땐 다음과 같이 if문을 사용하여 해당 섹션의 데이터 수가 0일 경우 이미지 뷰의 isHidden 값을 false로 바꾸어 화면에 나타나게 할 수 있다. 이미지 뷰는 컬렉션 뷰 자체에 구현해주면 된다.

if (profileCollectionView.numberOfItems(inSection: 2) == 0) {
            no_posts.isHidden = false
        }

 

그러면 다음과 같이 나타난다.

 

섹션1 색상을 하늘색으로 넣으려 했는데 실수로 뷰컨트롤러와 같은 색인 연보라 색으로 넣어서 티가 안나네.......중요한 건 아니니까 뭐..

셀 개수가 1개 이상일 때

 

셀 개수가 0개일 때

 

 

 

 

참고 링크

https://developer.apple.com/documentation/uikit/uicollectionview/1618016-numberofitems

 

Apple Developer Documentation

 

developer.apple.com

https://mini-min-dev.tistory.com/115

 

[iOS] 아무 데이터가 없을 때 나오는 화면,엠티뷰(empty view) 만들기

iOS 개발을 하면, 가장 자주 만들어야 할 화면이 바로 테이블 뷰와 컬렉션 뷰일 거다. 테이블 뷰(TableView)와 컬렉션 뷰(CollectionView)는 모두 같은 형태의 데이터를 표출할 때 큰 틀만 만들어두고, 그

mini-min-dev.tistory.com

 

+ Recent posts