ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [Swift/Study] TableView 안에 TableView
    Study/ios 2023. 7. 3. 17:07

    이번에는 테이블 뷰 셀안에 테이블 뷰를 넣는 방법을 공부해보았다.

     

    결과 화면

     

     

    먼저 기본 틀을 이렇게 만들어 주었다.

     

    위와 같이 만드는 방법은 이 글을 참고하세요..

    https://eunduk2.tistory.com/22

     

    [Swift/Study] TableView 셀을 둥글게 만들고 간격 띄우기

    이번 글에서는 테이블 뷰의 셀 테두리를 둥글게 만들고 간격을 띄워보는 법을 써보도록 하겠다. 결과 화면 먼저 셀들의 모서리를 둥글게 만들어 보겠다. 코드로 해도 되는데 나는 스토리보드에

    eunduk2.tistory.com

     

     

     

     

    학교 이름을 담고 있는 셀의 높이를 늘리고 테이블 뷰와 테이블 뷰 셀을 콘텐트에 넣어준다.

    그리고 학생 이름을 출력할 레이블을 두 번째 테이블에 배치해준다.

    이렇게 구성하면 학교 테이블 뷰 안에 학생 테이블 뷰를 넣어 표현할 수 있다. (중복 테이블 뷰)

     

     

    지금 학교 테이블 뷰 셀의 코드를 보면 다음과 같다.

    import UIKit
    
    class SchoolCell: UITableViewCell {
        
        @IBOutlet var lblSchool: UILabel!
    }

     

     

    학생 테이블 뷰가 학교 테이블 뷰 셀안에 들어가 있기 때문에 위 클래스에서 학생 테이블 뷰를 처리해줘야 한다.

    import UIKit
    
    class SchoolCell: UITableViewCell {
        
        @IBOutlet var lblSchool: UILabel!
        @IBOutlet var studentTable: UITableView! // 학생 테이블 뷰
        
        // 초기화
        override func awakeFromNib() {
            super.awakeFromNib()
            
            studentTable.delegate = self
            studentTable.dataSource = self
        }
    }

    학생 테이블 뷰를 아울렛 변수로 선언하고 처음 초기화할 때 delegate와 dataSource를 self로 선언해준다.

     

     

     

    그리고 테이블 뷰에 임시로 넣어줄 학생 배열도 만들어 준다.

    class SchoolCell: UITableViewCell {
        
        @IBOutlet var lblSchool: UILabel!
        @IBOutlet var studentTable: UITableView!
        
        var section: Int? // 학교 테이블에서 학교를 구분
        let Sstudent:[String] = ["짱구", "철수", "훈이"] // 서울대 학생
        let Kstudent:[String] = ["짱아", "유리", "슬기"] // 고려대 학생
        let Ystudent:[String] = ["형만", "봉선", "흰둥"] // 연세대 학생
        
        override func awakeFromNib() {
            super.awakeFromNib()
            
            studentTable.delegate = self
            studentTable.dataSource = self
        }
    }

     

     

    이제 테이블 뷰를 표현해주려면 다음과 같은 코드가 필요하다.

    extension SchoolCell: UITableViewDelegate, UITableViewDataSource {
        func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
            return 3
        }
        
        func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
            let cell = tableView.dequeueReusableCell(withIdentifier: "StudentCell") as! StudentCell
            
            if(section == 0) { // 서울대
                cell.lblStudent.text = Sstudent[indexPath.row]
            } else if(section == 1) { // 고려대
                cell.lblStudent.text = Kstudent[indexPath.row]
            } else { // 연세대
                cell.lblStudent.text = Ystudent[indexPath.row]
            }
            
            return cell
        }
    }

    3명의 학생이기 때문에 3개의 셀 값을 반환해주고 레이블 아울렛 변수를 가지고 있는 학생 셀 클래스를 셀로 사용한다.

    그리고 각 학교에 맞게 학생들을 학생 테이블 뷰에 출력한다.

     

     

    마지막으로 학교 테이블 뷰의 셀 높이를 조정하면?

    위와 같이 중복테이블을 구현할 수 있다!

     

     

    그런데 나는 이렇게 사용하기 위해 중복 테이블을 구현한 것이 아니다.

    학교 셀을 터치하면 학생 테이블이 나오게 하는 것이 목적이다.

     

     

    학교 테이블을 품고 있는 뷰 컨트롤러에서 코드를 추가해 보겠다.

    var selectedIndexPath: IndexPath? // 선택된 IndexPath를 저장하는 변수
    
    // 특정 셀이 선택되었을 때 동작하는 메서드
    func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
        if selectedIndexPath == indexPath {
            selectedIndexPath = nil // 이미 선택된 셀이면 선택 해제
        } else {
            selectedIndexPath = indexPath // 선택한 셀의 indexPath 저장
        }
        // 테이블뷰 업데이트
        tableView.beginUpdates()
        tableView.endUpdates()
    }
    // 테이블 뷰의 셀 높이를 설정하는 메서드
    func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
        // 선택된 셀은 높이를 220로 설정
        if selectedIndexPath == indexPath {
            return 220
        }
        return 45 // 나머지는 45
    }

    선택된 셀을 기억해서 높이를 변경해주는 코드이다.

     

     

    여기까지 하고 실행해보면??

    위와 같이 표현할 수 있다!

     

     

    전체 코드

    import UIKit
    
    class ViewController3: UIViewController {
        let school:[String] = ["서울대학교", "고려대학교", "연세대학교"]
        var selectedIndexPath: IndexPath?
    }
    
    extension ViewController3: UITableViewDelegate, UITableViewDataSource {
        // 섹션 수
        func numberOfSections(in tableView: UITableView) -> Int {
            return school.count
        }
        // 섹션에 셀의 수
        func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
            return 1
        }
        func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
            let cell = tableView.dequeueReusableCell(withIdentifier: "SchoolCell") as! SchoolCell
            
            cell.section = indexPath.section
            cell.lblSchool.text = school[indexPath.section]
            
            return cell
        }
        func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
            if(section == 0) {
                return 0.1 // 첫 번째 셀의 헤더 높이
            }
            return 0 // 각 섹션의 헤더는 0으로 하고 푸터로 간격 조정
        }
        func tableView(_ tableView: UITableView, heightForFooterInSection section: Int) -> CGFloat {
            // 섹션 푸터의 높이를 조정하는 로직을 구현
            return 10
        }
        // 특정 셀이 선택되었을 때 동작하는 메서드
        func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
            if selectedIndexPath == indexPath {
                selectedIndexPath = nil // 이미 선택된 셀이면 선택 해제
            } else {
                selectedIndexPath = indexPath // 선택한 셀의 indexPath 저장
            }
            // 테이블뷰 업데이트
            tableView.beginUpdates()
            tableView.endUpdates()
        }
        // 테이블 뷰의 셀 높이를 설정하는 메서드
        func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
            // 선택된 셀은 높이를 220로 설정
            if selectedIndexPath == indexPath {
                return 220
            }
            return 45 // 나머지는 45
        }
        
    }
    import UIKit
    
    class SchoolCell: UITableViewCell {
        
        @IBOutlet var lblSchool: UILabel!
        @IBOutlet var studentTable: UITableView!
        
        var section: Int?
        let Sstudent:[String] = ["짱구", "철수", "훈이"]
        let Kstudent:[String] = ["짱아", "유리", "슬기"]
        let Ystudent:[String] = ["형만", "봉선", "흰둥"]
        
        override func awakeFromNib() {
            super.awakeFromNib()
            
            studentTable.delegate = self
            studentTable.dataSource = self
        }
    }
    
    extension SchoolCell: UITableViewDelegate, UITableViewDataSource {
        func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
            return 3
        }
        
        func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
            let cell = tableView.dequeueReusableCell(withIdentifier: "StudentCell") as! StudentCell
            
            if(section == 0) { // 서울대
                cell.lblStudent.text = Sstudent[indexPath.row]
            } else if(section == 1) { // 고려대
                cell.lblStudent.text = Kstudent[indexPath.row]
            } else { // 연세대
                cell.lblStudent.text = Ystudent[indexPath.row]
            }
            
            return cell
        }
    }
    import UIKit
    
    class StudentCell:UITableViewCell {
        
        @IBOutlet var lblStudent: UILabel!
        
    }
Designed by Tistory.