본문 바로가기

iOS 개발/Apple App Store 클론 코딩

AppleAppStore - 14. DetailViewController의 section, cell 구현 3

반응형

안녕하십니까??? Skillist입니다.

 

이번에도 탄력 받아서, section과 cell 구현을 쭉쭉 해볼게요!

 

오늘은 스크린샷 section과 cell을 구현할거에요

------------------------------------------------------------------------------------------------------------------

 

section부터 구현시작합니다.

 267라인 : item을 구현합니다.

 

272라인 : group를 구현합니다.

 

277라인 : section을 구현합니다. 스크롤을 groupPaging으로 설정하여, 페이징 스크롤이 가능합니다.

 

간단하네요 item, group, section을 순차적으로 구현해주세요!

 

------------------------------------------------------------------------------------------------------------------

 

다음은 cell입니다.

 

12라인 : imageView입니다. 직접 구현한 DownloadableImageView를 사용했습니다.

 

22라인 : 이니셜라이저입니다. 레이아웃을 설정하죠

 

32라인 : 이미지뷰 레이아웃을 구성합니다.

 

40라인 : url을 통해 이미지를 세팅합니다. 직접 구현한 DownloadableImageView를 사용했기 때문에, 가능한거에요.

url을 키값으로 캐시하고, 캐시 이미지가 없다면 url을 통해 직접 이미지를 받아와 보여줍니다.

 

------------------------------------------------------------------------------------------------------------------

 

section과 cell은 구현했어요.

하지만 더 구현해야할게 있어요.

스크린샷을 터치하면 스크린샷 상세화면으로 이동해요!!!

didSelect 코드부터 보시죠

 

524라인 : didSelect에서, 스크린샷만 구현했습니다. 

 

533라인 : DetailScreenShotsViewController을 present합니다.

 

534, 535라인 : 스크린샷 url목록을 넘겨주고, 터치한 스크린샷의 번호도 넘겨줍니다. 그래야만 터치한 스크린샷부터 보여줄수 있기 때문이죠!

 

------------------------------------------------------------------------------------------------------------------

 

다음은 스크린샷 VC를 구현할게요.

present입니다.

12라인 : 먼저 보여줄 스크린샷의 row입니다.

 

13라인 : 스크린샷 url 목록입니다.

 

15라인 : 우측 상단의 button입니다. addTarget을 통해 버튼 동작을 추가했어요. 가독성을 위해 @objc func을 23라인에 작성했는데, 위치가 약간 애매해보이네요.

 

27라인 : collectionView입니다. 스크린샷 목록을 collectionView로 보여줄거에요

그러기 위해서 레이아웃을 flowlayout으로 설정해주고, 방향을 가로로 설정했습니다.

 

37라인 : 페이징 스크롤을 위해서 설정했어요.

 

40라인 : 방금 구현한 cell을 해당 VC에서도 재사용합니다!

 

50라인 : 레이아웃을 설정합니다.

 

72라인 : 화면 이동 시 보여줄 스크린샷을 설정합니다. scrollToItem을 통해 스크롤을 이동합니다.

 

collectionView 설정입니다~ 다들 아실테니 pass하겠습니다?

 

------------------------------------------------------------------------------------------------------------------

 

이렇게, screenshot section을 구현 해봤습니다!!

왜케 힘빠지는것 같죠!!???????? 왜죠??????? 왜냐면 퇴근하고 글을 쓰고있기 때문이죠!!!!!! ㅠㅜㅜㅠ

여러분들 모두 화이팅!! 저도 화이팅!! 화이팅 하자구요!!!

 

그럼 다음에 또 놀러오세요!

 

잘못되거나 부족한 내용 등, 피드백 감사합니다!

 

Skillist의 AppleAppStore 프로젝트

https://github.com/DeveloperSkillist/AppleAppStoreCloneCode

 

GitHub - DeveloperSkillist/AppleAppStoreCloneCode: AppleAppStoreCloneCode

AppleAppStoreCloneCode. Contribute to DeveloperSkillist/AppleAppStoreCloneCode development by creating an account on GitHub.

github.com

 

 

↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓  전체 코드  ↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓

 

    
    private func createScreenShotItemSection() -> NSCollectionLayoutSection {
        let itemMargin: CGFloat = 5
        let sectionMargin: CGFloat = 15
        
        //item
        let itemSize = NSCollectionLayoutSize(widthDimension: .fractionalWidth(1), heightDimension: .fractionalHeight(1))
        let item = NSCollectionLayoutItem(layoutSize: itemSize)
        item.contentInsets = .init(top: itemMargin, leading: itemMargin, bottom: itemMargin, trailing: itemMargin)
        
        //group
        let groupSize = NSCollectionLayoutSize(widthDimension: .absolute((collectionView.frame.width - sectionMargin) / 1.5), heightDimension: .absolute(500))
        let group = NSCollectionLayoutGroup.horizontal(layoutSize: groupSize, subitems: [item])
//        group.contentInsets = .init(top: 0, leading: 0, bottom: 0, trailing: 0)
        
        //section
        let section = NSCollectionLayoutSection(group: group)
        section.orthogonalScrollingBehavior = .groupPaging
        section.contentInsets = .init(top: sectionMargin, leading: sectionMargin, bottom: sectionMargin, trailing: sectionMargin)
        
        return section
    }
    func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
        let section = sections[indexPath.section]
        
        //TODO: didSelect
        switch section.itemType {
        case .screenShots:
            guard let screenShots = section.items as? [String] else {
                return
            }
            let detailScreenshotsVC = DetailScreenShotsViewController()
            detailScreenshotsVC.screenShots = screenShots
            detailScreenshotsVC.startRow = indexPath.row
            present(detailScreenshotsVC, animated: true, completion: nil)
            
        default:
            return
        }
    }
class DetailScreenShotCollectionViewCell: UICollectionViewCell {
    
    private lazy var imageView: DownloadableImageView = {
        var imageView = DownloadableImageView()
        imageView.contentMode = .scaleAspectFill
        imageView.layer.cornerRadius = 20
        imageView.layer.borderWidth = 1
        imageView.layer.borderColor = UIColor(named: "labelgray")?.cgColor
        imageView.clipsToBounds = true
        return imageView
    }()
    
    override init(frame: CGRect) {
        super.init(frame: frame)
        
        setupLayout()
    }
    
    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
    
    private func setupLayout() {
        addSubview(imageView)
        
        imageView.snp.makeConstraints {
            $0.edges.equalToSuperview()
        }
    }
    
    func setupItem(screenUrl: String) {
        imageView.downloadImage(url: screenUrl)
    }
}
class DetailScreenShotsViewController: UIViewController {

    var startRow: Int = 0
    var screenShots: [String] = []
    
    private lazy var closeButton: UIButton = {
        let button = UIButton()
        button.setTitle("close_title".localized, for: .normal)
        button.setTitleColor(.link, for: .normal)
        button.addTarget(self, action: #selector(closeVC), for: .touchUpInside)
        return button
    }()
    
    @objc func closeVC() {
        self.dismiss(animated: true, completion: nil)
    }
    
    private lazy var collectionView: UICollectionView = {
        let flowLayout = UICollectionViewFlowLayout()
        flowLayout.scrollDirection = .horizontal
        
        let collectionView = UICollectionView(
            frame: .zero,
            collectionViewLayout: flowLayout
        )
        collectionView.delegate = self
        collectionView.dataSource = self
        collectionView.isPagingEnabled = true
        collectionView.showsHorizontalScrollIndicator = false
        
        collectionView.register(DetailScreenShotCollectionViewCell.self, forCellWithReuseIdentifier: "DetailScreenShotCollectionViewCell")
        return collectionView
    }()
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        setupLayout()
    }
    
    private func setupLayout() {
        view.backgroundColor = .systemBackground
        
        [
            closeButton,
            collectionView
        ].forEach {
            view.addSubview($0)
        }
        
        closeButton.snp.makeConstraints {
            $0.top.trailing.equalToSuperview().inset(15)
        }
        
        collectionView.snp.makeConstraints {
            $0.top.equalTo(closeButton.snp.bottom).offset(10)
            $0.leading.trailing.equalToSuperview()
            $0.bottom.equalTo(view.safeAreaLayoutGuide.snp.bottom).inset(10)
        }
        
        collectionView.reloadData()
        collectionView.layoutIfNeeded()
        collectionView.scrollToItem(
            at: IndexPath(row: startRow, section: 0), at: .centeredHorizontally, animated: false)
    }
}

extension DetailScreenShotsViewController: UICollectionViewDataSource {
    func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
        return screenShots.count
    }
    func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
        guard let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "DetailScreenShotCollectionViewCell", for: indexPath) as? DetailScreenShotCollectionViewCell else {
            return UICollectionViewCell()
        }
        cell.setupItem(screenUrl: screenShots[indexPath.row])
        return cell
    }
}

extension DetailScreenShotsViewController: UICollectionViewDelegateFlowLayout {
    
    func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
        return CGSize(width: collectionView.frame.width - 64, height: collectionView.frame.height - 100)
    }
    
    func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, insetForSectionAt section: Int) -> UIEdgeInsets {
        return UIEdgeInsets(top: 0, left: 32, bottom: 0, right: 32)
    }
    
    func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumLineSpacingForSectionAt section: Int) -> CGFloat {
        return 64
    }
}

 

 

 

반응형