카테고리 없음

UICollectionView 시행착오 기록

soultreemk 2022. 10. 12. 01:20
//
//  ExerciseViewController.swift
//  SlacksFit
//
//  Created by YANG on 2022/09/04.
//

import SnapKit
import UIKit
//import FirebaseDatabase
import FirebaseFirestore

class ExerciseViewController: UIViewController {
    // 0. 운동 리스트 데이터(모델) 가져오기
    var db = Firestore.firestore()
    var exercisesModel = ["day1","day2","day3","day4","day5","day6","day7","day8",
                          "day9","day10","day11","day12","day13","day14"]
    
    var exerciseTitles = ["title1","title2","title3","title4","title5","title6","title7"]
    
    var selectedIndex = 0

    
    private lazy var collectionView: UICollectionView = {

        let collectionView = UICollectionView(frame: .zero, collectionViewLayout: getLayout())
        
        collectionView.delegate = self
        collectionView.dataSource = self

        collectionView.backgroundColor = .systemBackground
        collectionView.showsHorizontalScrollIndicator = true
        
        // custom Cell 등록
        collectionView.register(ExerciseCollectionViewCell.self, forCellWithReuseIdentifier: "exerciseCell")
        //collectionView.register(CalendarCollectionViewCell.self, forCellWithReuseIdentifier: "calendarCell")
        
        // header View 등록
        collectionView.register(ExerciseCollectionHeaderView.self,
                                forSupplementaryViewOfKind: "header",
                                withReuseIdentifier: "ExerciseCollectionHeaderView")

        return collectionView
    }()
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        view.addSubview(collectionView)
        collectionView.snp.makeConstraints {
            $0.top.equalToSuperview()
            $0.width.equalToSuperview()
            $0.height.equalToSuperview()
        }
        
        //fetchData()
    }
}


extension ExerciseViewController: UICollectionViewDataSource {

    func numberOfSections(in collectionView: UICollectionView) -> Int {
        2
    }
    
    func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
        if section == 0 {
            return 14
        } else {
            return 7
        }
    }

    // cell 등록
    func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
        if indexPath.section == 0 {
            let calendarCell = collectionView.dequeueReusableCell(withReuseIdentifier: "calendarCell",
                                                                  for: indexPath) as! CalendarCollectionViewCell
            let row = indexPath.row
            let date = Date()
            calendarCell.setup(day:row+1, date: Calendar.current.date(byAdding: .day, value: row, to: date)!)
            calendarCell.isSelected = true
            return calendarCell

        } else {
            // 운동 리스트 cell : 해당 일자에 대한 운동 리스트 던지기
            let exerciseCell = collectionView.dequeueReusableCell(withReuseIdentifier: "exerciseCell", for: indexPath) as! ExerciseCollectionViewCell

            exerciseCell.setUp(exerciseTitle: exercisesModel[selectedIndex])

            return exerciseCell
        }
    }
    
    // header View 등록
    func collectionView(_ collectionView: UICollectionView, viewForSupplementaryElementOfKind kind: String, at indexPath: IndexPath) -> UICollectionReusableView {
        
        if kind == "header" {
            let view = collectionView.dequeueReusableSupplementaryView(ofKind: kind, withReuseIdentifier: "ExerciseCollectionHeaderView", for: indexPath)
            return view
        } else {
            return UICollectionReusableView()
        }
        
    }
}

extension ExerciseViewController: UICollectionViewDelegateFlowLayout {
    
    // 각 collectionView Cell 클릭 시 detialVC 로 이동
    func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
        if indexPath.section == 0 {
            selectedIndex = indexPath.item
            collectionView.reloadData() // 여기가 핵심이었던것... 컬렉션뷰가 바로 안바껴서 몇일째 삽질함.
            
            // 터치에 따라 스크롤 되도록 설정
            collectionView.scrollToItem(at: indexPath, at: .centeredHorizontally, animated: true)
        
        } else {
            let detailVC = ExerciseDetailViewController() //(exercise: exerciseTitles[indexPath.row])
            detailVC.currentIdx = indexPath.row
            present(detailVC, animated: true)
            
        }
    }
    
}


// MARK: Private - Layout Customize, 데이터 가져오기

private extension ExerciseViewController {
    
    func getLayout() -> UICollectionViewLayout {
        return UICollectionViewCompositionalLayout { (sectionIndex, env) -> NSCollectionLayoutSection? in
            if sectionIndex == 0 {
                return self.getSectionLayout1()
            }
            
            else {
                return self.getSectionLayout2()
            }
        }
    }
    
    func getSectionLayout1() -> NSCollectionLayoutSection {
        let itemSize = NSCollectionLayoutSize(widthDimension: .fractionalWidth(1), heightDimension: .fractionalHeight(1))
        let item = NSCollectionLayoutItem(layoutSize: itemSize)
        
        let groupSize = NSCollectionLayoutSize(widthDimension: .fractionalWidth(0.3), heightDimension: .fractionalWidth(0.3))
        let group = NSCollectionLayoutGroup.horizontal(layoutSize: groupSize, subitems: [item])
        group.contentInsets = .init(top: 0, leading: 5, bottom: 0, trailing: 5)
        
        let section = NSCollectionLayoutSection(group: group)
        section.orthogonalScrollingBehavior = .groupPaging
        
        return section
    }
    
    func getSectionLayout2() -> NSCollectionLayoutSection {
        let itemSize = NSCollectionLayoutSize(widthDimension: .fractionalWidth(1), heightDimension: .fractionalHeight(1))
        let item = NSCollectionLayoutItem(layoutSize: itemSize)
        item.contentInsets = .init(top: 5, leading: 10, bottom: 5, trailing: 10)
        
        let groupSize = NSCollectionLayoutSize(widthDimension: .fractionalWidth(1), heightDimension: .estimated(200))
        let group = NSCollectionLayoutGroup.vertical(layoutSize: groupSize, subitems: [item])
        //group.contentInsets = .init(top: 5, leading: 10, bottom: 5, trailing: 10)

        let section = NSCollectionLayoutSection(group: group)
        
        // header View Layout 조정
        let headerSize = NSCollectionLayoutSize(widthDimension: .fractionalWidth(1), heightDimension: .estimated(200))
        let header = NSCollectionLayoutBoundarySupplementaryItem(layoutSize: headerSize,
                                                                 elementKind: "header",
                                                                 alignment: .top)
        section.boundarySupplementaryItems = [header]
        section.orthogonalScrollingBehavior = .none
        
        return section
    }
    
    
    
    
    func fetchData() {
        let fileLocation = "/Users/yang/Desktop/SlacksFit/SlacksFit/Data/Exercise.json"
        //Bundle.main.url(forResource: "Exercise", withExtension: "json") else { return }
        do {
            let data = try String(contentsOfFile: fileLocation).data(using: .utf8)
            let jsonDecoding = try JSONSerialization.data(withJSONObject: data)
            //let exerciseList = try JSONDecoder().decode([Exercise].self, from: jsonDecoding)
            print("json decoding",jsonDecoding)
        } catch {
            print("ERROR")
        }

    }

}


/*
 
 func fetchData() {
     // FireStore 에서 가져오기
     db.collection("day1").getDocuments { snapshot, error in
         guard let documents = snapshot?.documents else {
             print("Firestore Fetching Error \(String(describing: error))")
             return
         }
         
         self.exercisesTotal = documents.compactMap { doc -> Exercise? in
             do {
                 let jsonData = try JSONSerialization.data(withJSONObject: doc.data(), options: [])
                 let jsonParsing = try JSONDecoder().decode(Exercise.self, from:jsonData)
                 //print("json파싱결과",jsonParsing.title)
                 return jsonParsing
                 
             } catch let error {
                 print("JSON Parsing Error \(error)")
                 return nil
             }
             
         }
         DispatchQueue.main.async {
             self.exerciseCollectionView.reloadData()
         }
         //print("테스트",self.exercisesTotal.count) // 정상
     }
 }
 //print("테스트2",self.exercisesTotal.count)
 
 
 */




/*
ref = Database.database().reference()

ref.observe(.value) { snapshot in
    guard let value = snapshot.value as? [String:[String:Any]] else { return }
    
    do {
        let jsonData = try JSONSerialization.data(withJSONObject: value)
        let exerciseData = try JSONDecoder().decode( Exercise.self, from: jsonData)
        self.exercise_Total = [exerciseData]
        
        DispatchQueue.main.async {
            self.exerciseCollectionView.reloadData()
        }
        
    } catch let error {
        print("ERROR JSON Parsing \(error.localizedDescription)")
    }
    
}
exerciseCollectionView.reloadData()
 */





/*
// 1. 날짜 collectionView 생성
private lazy var calendarCollectionView: UICollectionView = {
    let layout = UICollectionViewFlowLayout()
    layout.scrollDirection = .horizontal
    
    let collectionView = UICollectionView(frame: .zero, collectionViewLayout: layout)

    collectionView.delegate = self
    collectionView.dataSource = self

    collectionView.backgroundColor = .systemBackground
    // custom Cell 등록
    collectionView.register(CalendarCollectionViewCell.self, forCellWithReuseIdentifier: "calendarCell")

    collectionView.showsHorizontalScrollIndicator = false
    
    return collectionView

}()

// 2. 운동 리스트 collectionView 생성
private lazy var exerciseCollectionView: UICollectionView = {

    collectionView.delegate = self
    collectionView.dataSource = self

    collectionView.backgroundColor = .systemBackground
    // custom Cell 등록
    collectionView.register(ExerciseCollectionViewCell.self, forCellWithReuseIdentifier: "exerciseCell")
    // header View 등록
    collectionView.register(ExerciseCollectionHeaderView.self, forSupplementaryViewOfKind: UICollectionView.elementKindSectionHeader, withReuseIdentifier: "ExerciseCollectionHeaderView")

    return collectionView

}()
*/

/*
// 각 섹션 별 cell 크기 지정
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
    if indexPath.section == 0 {
        let width = collectionView.bounds.width / 7
        return CGSize(width: width, height: 100)
    } else {
        let width = collectionView.frame.width - 32
        return CGSize(width: width, height: width/2)
    }
}

// view와 cell 사이 여백
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, insetForSectionAt section: Int) -> UIEdgeInsets {
    UIEdgeInsets(top: 30, left: 0, bottom: 0, right: 0)
}
 
 // header view size
 func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, referenceSizeForHeaderInSection section: Int) -> CGSize {
     if section == 0 {
         return CGSize(width: collectionView.frame.width - 32.0, height: 100 )
     } else {
         return CGSize.zero
     }
 }
 
*/