본문 바로가기

iOS

[iOS/Swift] 선택된 셀이 표시되는 UICollectionView

 

사용하는 곳

UICollectionView를 사용할때, 현재 선택된 사진 혹은 셀을 사용자에게 알려주기 위해 선택된 셀만 하이라이트 표시해주곤 합니다.
위의 예제에서는 화면 가운데에는 현재 선택된 사진이 크게 나타나고 하단에는 이미지 리스트들이 존재하는데 현재 선택된 이미지 셀만 투명도가 없고 선택되지 않은 셀들에 대해서는 투명도가 존재하여 흐릿하게 보입니다.

 

샘플 앱

보다 더 직관적으로 설명하기 위해서 위와 같은 화면으로 구현하겠습니다. 해당 포스트에서는 스토리보드를 사용하지 않고 코드로만 뷰를 작성합니다.

 

ViewController.swift

// ViewController.swift
import UIKit

class ViewController: UIViewController {
    
    private lazy var mainView = MainView.init(frame: self.view.frame)

    static func instance() -> ViewController {
        return ViewController.init(nibName: nil, bundle: nil)
    }
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        view = mainView
        setupCollectionView()
    }
    
    private func setupCollectionView() {
        mainView.collectionView.delegate = self
        mainView.collectionView.dataSource = self
        mainView.collectionView.register(MainCell.self, forCellWithReuseIdentifier: MainCell.registerId)
    }
}

extension ViewController: UICollectionViewDelegate, UICollectionViewDataSource, UICollectionViewDelegateFlowLayout {
    func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
        return 5
    }
    
    func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
        guard let cell = collectionView.dequeueReusableCell(withReuseIdentifier: MainCell.registerId, for: indexPath) as? MainCell else {
            return UICollectionViewCell()
        }
        
        return cell
    }
        
    func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
        return CGSize.init(width: 100, height: 100)
    }
    
}

 

MainView.swift

// MainView.swift
import UIKit
import Then
import SnapKit

class MainView: UIView {
    
    let collectionView = UICollectionView(frame: .zero, collectionViewLayout: UICollectionViewFlowLayout()).then {
        let layout = UICollectionViewFlowLayout()
        layout.scrollDirection = .horizontal
        
        $0.backgroundColor = .white
        $0.contentInset = UIEdgeInsets.init(top: 0, left: 20, bottom: 0, right: 0)
        $0.showsHorizontalScrollIndicator = false
        $0.collectionViewLayout = layout
    }
    
    
    override init(frame: CGRect) {
        super.init(frame: frame)
        setup()
        bindConstraints()
    }
    
    required init?(coder: NSCoder) {
        super.init(coder: coder)
        setup()
        bindConstraints()
    }
    
    func setup() {
        backgroundColor = .white
        addSubview(collectionView)
    }
    
    func bindConstraints() {
        collectionView.snp.makeConstraints { (make) in
            make.left.right.equalToSuperview()
            make.centerY.equalToSuperview()
            make.height.equalTo(200)
        }
    }
}

 

MainCell.swift

// MainCell.swift
import UIKit

class MainCell: UICollectionViewCell {
    
    static let registerId = "\(MainCell.self)"
    
    let main = UIView().then {
        $0.backgroundColor = .red
    }
    
    
    override init(frame: CGRect) {
        super.init(frame: frame)
        setup()
        bindConstraints()
    }
    
    required init?(coder: NSCoder) {
        super.init(coder: coder)
        setup()
        bindConstraints()
    }
    
    private func setup() {
        backgroundColor = .clear
        addSubview(main)
    }
    
    private func bindConstraints() {
        main.snp.makeConstraints { (make) in
            make.edges.equalTo(0)
        }
    }
    
    override var isSelected: Bool {
        didSet {
            if isSelected {
                main.backgroundColor = .black
            } else {
                main.backgroundColor = .red
            }
        }
    }
}

 

잘 봐야하는 점

// MainCell.swift
// ... 
override var isSelected: Bool {
    didSet {
        if isSelected {
            main.backgroundColor = .black
        } else {
            main.backgroundColor = .red
        }
    }
}

Cell 클래스 내부에 있는 isSelected 변수 입니다. 
UICollectionViewCell기본 클래스 내부에 있는 isSelected변수는 cell이 선택되어있을 경우에는 true 다른 cell이 선택되어있을 경우에는 false값으로 설정됩니다. 이 변수를 사용해서 선택된 셀과 선택되지 않은 셀들에 대하여 배경색을 변경하는 로직을 설정해줍니다.

 

터치에 따라 스크롤되도록 설정

// ViewController.swift
extension ViewController: UICollectionViewDelegate, UICollectionViewDataSource, UICollectionViewDelegateFlowLayout {    

// ...
// ...

    func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
        collectionView.scrollToItem(at: indexPath, at: .left, animated: true)
    }
}

 셀이 선택됨에 따라서 콜렉션뷰가 스크롤되도록 설정하게 하였습니다.