boraBong

[iOS] iOS에서 UICollectionView cell을 코드로 자동 선택하는 방법과 선택된 cell을 표시하는 방법 💡🤸🏻 본문

iOS

[iOS] iOS에서 UICollectionView cell을 코드로 자동 선택하는 방법과 선택된 cell을 표시하는 방법 💡🤸🏻

보라봉_ 2023. 2. 14. 03:11
728x90

1.

UICollectionView의 선택된 셀(아이템)을 표시하는 방법에 대해 알아보겠습니다.

collectionView의 대리자가 잘 위임되었다면 우리가 cell을 클릭할(누를) 때마다 실행되는 메서드가 있죠!

바로 collectionView(didSelectItemAt:) 입니다.

collectionView(didSelectItemAt:)

지정된 인덱스 경로의 항목이 선택되었음을 대리자에게 알립니다.

우리가 cell을 눌러 이 메서드가 실행되었을 때 우리가 누른 cell은 과연 선택된(isSelected) 상태일까요?

cell이 눌렸음을(선택되었음을) 알릴 때 실행되는

didSelectItemAt 메서드 내에서 로그를 찍어보며 알아봅시다!

func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
			if let cell = collectionView.cellForItem(at: indexPath) as? UICollectionViewCell {
            print("cell isSelected?", indexPath, cell.isSelected)
        }
    }

 

cell을 누를 때마다 로그가 잘 찍히는 것을 보아, 우리가 cell을 누를 때 해당 cell은 isSelected(선택된) 상태로 바뀌어져 있는 것을 확인할 수 있습니다!

그렇다면 이제 didSelectItemAt의 반대 메서드인 didDeselectItemAt를 살펴봅시다.

 

collectionView(didDeselectItemAt:)

// 다중 선택을 허용하지 않겠다
collectionView.allowsMultipleSelection = false 

라는 가정 하에 (default value가 false입니다!)

func collectionView(_ collectionView: UICollectionView, didDeselectItemAt indexPath: IndexPath) {
        if let cell = collectionView.cellForItem(at: indexPath) as? UICollectionViewCell {
            print("cell deselct", indexPath, cell.isSelected)
        }
    }

셀이 한번 선택되고 난 후 다른 셀을 선택할 때면 동시에 deselect가 수행되는 것을 확인할 수 있습니다.

즉, 이미 선택한 셀이 존재할 경우 → 다른 셀을 선택할 때 didSelectItemAt이 호출되어 새로운 셀이 선택됨과 동시에 didDeselectItemAt도 호출되어 이전에 선택된 셀을 선택 해제한다는 것입니다!

 

💡[ 요약 ]

  • 우리가 cell을 직접 누를 때
    • collectionView의 delegate 메서드인 didSelectItemAt이 호출되며, 해당 메서드가 호출되었을 때 cell의 isSelected 상태는 true로 설정되어져 있다. (didSelectItemAt 메서드가 cell의 isSelected 상태를 바꾸는 것은 아님을 유의!!)
  • 이미 선택된 cell이 존재하는데 다른 cell을 누를 때
    • collectionView의 delegate 메서드인 didSelectItemAt, didDeselectItemAt이 동시에 호출된다. 이 때 didDeselectItemAt은 이전에 선택된 cell을 선택 해제한다. (이전 선택된 cell의 isSelected 상태가 false로 바뀌어져 있다.) (마찬가지로 didDeselectItemAt 메서드가 cell의 isSelected 상태를 바꾸는 것은 아님을 유의!!)

 

그렇다면 우리의 목표였던 UICollectionView의 선택된 셀(아이템)을 표시하기 위해서는 didSelectItemAt, didDeselectItemAt 메서드를 활용해주면 되겠죠?

 

선택할 때는 didSelectItemAt 메서드에서 선택한 cell의 background color를 지정하고, 선택 해제될 때는 didDeselectItemAt 메서드에서 선택 해제되는 cell의 background color를 해제해주는 식으로 말이죵 !!

/// didSelectItemAt
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
				if let cell = collectionView.cellForItem(at: indexPath) as? UICollectionViewCell {
            cell.backgroundColor = .blue
        }
    }
/// didDeselectItemAt
func collectionView(_ collectionView: UICollectionView, didDeselectItemAt indexPath: IndexPath) {
        if let cell = collectionView.cellForItem(at: indexPath) as? UICollectionViewCell {
            cell.backgroundColor = .clear
        }
    }

 

 

2.

UICollectionView cell을 코드로 자동 선택되게 하는 방법에 대해 알아보겠습니다.

위 사진은 뷰의 첫 로드시의 스크린샷입니다.

 

위 collectionView에서 셀을 선택하면 선택된 셀이 [0,0] 인덱스에 표시가 되도록 구현되어 있습니다.

위 과정에서 셀 선택시에 셀이 흐려지게 만드는 과정도 함께 구현해보았죠!

 

이제 해당 collectionView가 로드됨과 동시에 [0,1] 인덱스의 cell을 코드로(자동으로) 선택되게 하는 방법에 대해 알아봅시다.

 

아까 살펴본 didSelectItemAt 메서드를 통해 cell의 isSelected 상태가 true인 것을 확인했으므로 viewDidLoad에서 해당 메서드를 호출해주어 [0,1] 인덱스의 cell을 선택하게끔 만들어줘볼까요?

collectionView(friendsCV.self, didSelectItemAt: IndexPath(item: 1, section: 0))

해당 줄이 실행되면 didSelectItemAt이 호출되면서 로그가 찍힙니다. 그런데, cell의 isSelect 상태가 false네요…!!

이렇게 되면 위의 didSelectItemAt에서 구현해놓았던 선택 셀 흐림 효과가 해당 셀에 계속해서 남아있는 문제가 생기게 됩니다.

 

영상으로 살펴봅시다 !

다른 셀을 눌렀을 때 deselectItemAt 메서드는 [0,1] cell을 선택했었다는 정보를 알 수 없기에 다른 셀이 중복 선택되는 것처럼 보여지는 것이죠.

위에서 didSelectItemAt 메서드가 isSelected 상태를 바꾸는 것은 아님을 유의하라는 말이 여기서 이해가 되는군요!!

 

해당 문제를 어떻게 해결할 수 있을까요?

 

selectItem 메서드를 활용해봅시다!

seletItem(at:animated:scrollPosition:)

지정된 인덱스 경로에서 항목을 선택하고 선택적으로 보기로 스크롤합니다.

 

코드로 cell의 선택상태를 설정하고자 할 때 didSelectItemAt만 호출한다고 해서 cell의 isSelected 상태가 설정되지는 않기에 selectItem 메서드를 사용하여 cell을 선택하도록 하여야 합니다!

(didSelectItemAt은 그저 cell이 선택되었음을 대리자에게 알리는 메서드일 뿐이니까요)

 

그러나 공식문서에도 나와있듯이, selectItem 메서드를 사용하면

선택과 관련된 delegate methods (ex. didSelectItemAt, didDeselectItemAt ..)는 호출되지 않습니다,,,

 

 

따라서 셀을 선택했을 때 선택과 관련된 delegate methods에서 정의해둔 동작들이 있다면

didSelectItemAt, didDeselectItemAt은 직접 호출하여 사용해야 해요!

 

 

정리하자면..UICollectionView cell을 코드로 자동 선택되게 하는 방법은 !!!

 

1. 특정 IndexPath의 cell을 선택해주고

2. 특정 IndexPath의 cell이 선택되었음을 알리는 didSelectItemAt 메서드를 호출해준다.

 

friendsCV.selectItem(at: [0,1], animated: false, scrollPosition: .init()) // 특정 IndexPath의 cell 선택하기 
collectionView(friendsCV.self, didSelectItemAt: IndexPath(item: 1, section: 0)) // 특정 IndexPath의 cell이 선택되었음을 알리는 didSelectItemAt 메서드 호출하기

해당 코드를 넣고 동작시킨 결과입니다. 위에서 발생한 문제가 해결되어 말끔하게 동작하는 것을 확인할 수 있습니다~ㅎㅎ

 

 

 

이렇게 UICollectionView의 선택된 셀(아이템)을 표시하는 방법과, UICollectionView cell을 코드로 자동 선택되게 하는 방법에 대해 알아보았습니다!

 

 

<참고 자료>

Apple Developer Documentation

 

Apple Developer Documentation

 

developer.apple.com

Apple Developer Documentation

 

Apple Developer Documentation

 

developer.apple.com

Apple Developer Documentation

 

Apple Developer Documentation

 

developer.apple.com

 

반응형
Comments