iOS/UIKIT

category 누르면 그에 맞는 데이터를 테이블뷰에 보여주기

밤새는 탐험가89 2024. 7. 3. 05:30

🟧 카테고리 생성

https://explorer89.tistory.com/99

 

category 표현하기

구현 내용카테고리 내의 부분을 누르면 눌린 카테고리 색은 진하게 변하고, 그 밑에 밑줄이 생긴다. 카테고리 부분은 컬렉션 뷰로 구현되어 있다.  구현 방법1. categoryCell.swift 파일을 생성한다.

explorer89.tistory.com

 

 

구현 내용

  • 각 카테고리를 누르면, 해당 카테고리 문구가 테이블뷰에 보여지게 한다. 

 

구현 순서 

1. HomeViewController.swift 파일 내에 데이터를 저장할 배열을 생성한다. 

class HomeViewController: UIViewController {
    
    // MARK: Variables
    var randomImages: [UIImage] = []
    var tableData: [String] = []
    
    // ...
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        // Initialize the table data with default values
        tableData = Array(repeating: "Test", count: 10)
        
        // ...
    }
    
    // ...
}

 

 

2. 카테고리 선택 시 데이터를 변경하는 메서드 추가한다.

  • 카테고리가 선택되었을 때 호출되는 델리게이트 메서드에서 데이터를 변경하고 테이블 뷰를 리로드한다.
extension HomeViewController: CategoryMenuViewDelegate {
    func categoryMenuView(_ categoryMenuView: CategoryMenuCell, didselectedItemAt index: Int) {
        print("Selected category: \(index)")
        
        // Update the table data based on the selected category
        updateTableData(forCategoryIndex: index)
    }
    
    func updateTableData(forCategoryIndex index: Int) {
        switch index {
        case 0:
            tableData = Array(repeating: "Attractions", count: 10)
        case 1:
            tableData = Array(repeating: "Hotels", count: 10)
        case 2:
            tableData = Array(repeating: "Foods", count: 10)
        case 3:
            tableData = Array(repeating: "Shoppings", count: 10)
        case 4:
            tableData = Array(repeating: "Events", count: 10)
        default:
            tableData = Array(repeating: "Test", count: 10)
        }
        
        // Reload the table view with new data
        timelineTable.reloadData()
    }
}

 

 

3. 테이블 뷰 데이터 소스 메서드에서 업데이트된 데이터를 사용한다.

  • 테이블 뷰의 데이터 소스 메서드에서 업데이트된 데이터를 사용하도록 변경한다.
extension HomeViewController: UITableViewDelegate, UITableViewDataSource {
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return tableData.count
    }
    
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath)
        cell.backgroundColor = .systemBlue
        cell.textLabel?.text = tableData[indexPath.row]
        return cell
    }
}

 

 

🟥 만약에 외부 API를 통해 데이터를 받아오는 거라면? 어떻게 해야하나?

외부 API에서 데이터를 가져와서 카테고리 별로 테이블 뷰에 표시하려면 다음과 같은 단계를 따라야 한다. 

  1. API 호출을 위한 함수 추가
  2. 카테고리 선택 시 해당 카테고리에 맞는 API 호출
  3. API 호출 결과를 테이블 뷰에 표시
import UIKit

class HomeViewController: UIViewController {
    
    // MARK: Variables
    var randomImages: [UIImage] = []
    var tableData: [String] = []
    let apiUrl = "https://example.com/api/category" // 실제 API URL로 변경
    
    ...
    
    func fetchData(forCategory category: String) {
        guard let url = URL(string: "\(apiUrl)/\(category)") else { return }

        let task = URLSession.shared.dataTask(with: url) { data, response, error in
            guard let data = data, error == nil else {
                print("Error fetching data: \(error?.localizedDescription ?? "Unknown error")")
                return
            }

            do {
                // API 응답을 디코딩 (데이터 형식에 맞게 변경)
                let responseData = try JSONDecoder().decode([String].self, from: data)

                // 메인 스레드에서 테이블 뷰 갱신
                DispatchQueue.main.async {
                    self.tableData = responseData
                    self.timelineTable.reloadData()
                }
            } catch {
                print("Error decoding data: \(error.localizedDescription)")
            }
        }

        task.resume()
    }
}

extension HomeViewController: UITableViewDelegate, UITableViewDataSource {
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return tableData.count
    }
    
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath)
        cell.backgroundColor = .systemBlue
        
        // 테이블데이터의 인덱스에 맞는 데이터를 테이블 라벨에 적용 
        cell.textLabel?.text = tableData[indexPath.row]
        return cell
    }
}

...

extension HomeViewController: CategoryMenuViewDelegate {
    func categoryMenuView(_ categoryMenuView: CategoryMenuCell, didselectedItemAt index: Int) {
        print("Selected category: \(index)")

        // 카테고리 선택 시 데이터 가져오기
        switch index {
        case 0:
            fetchData(forCategory: "restaurants")
        case 1:
            fetchData(forCategory: "tourist_spots")
        case 2:
            fetchData(forCategory: "shopping")
        default:
            fetchData(forCategory: "default")
        }
    }
}

 

전체적인 흐름

  1. HomeViewController에 fetchData(forCategoryIndex:) 함수를 추가하여 API에서 데이터를 가져온다.
  2. categoryMenuView(_:didselectedItemAt:) 메서드에서 카테고리가 선택될 때 fetchData(forCategoryIndex:) 함수를 호출한다.
  3. fetchData(forCategoryIndex:) 함수는 API에서 데이터를 가져와 tableData 배열을 업데이트하고, 테이블 뷰를 리로드한다.

(이미지 파일이 있으면 비동기 처리한다.)

 

⭐️ API 응답 형식에 맞게 디코딩 부분을 조정해야 한다.

 예를 들면 API에서 반환하는 데이터가 [String] 형식이 아니라면

JSONDecoder().decode([String].self, from: data) 부분을 변경해야한다.