iyOmSd/Title: Swift

[Swift] TableView를 이용한 Expandable 효과 만들기

냄수 2019. 8. 24. 17:30
반응형

안녕하세요😄😄

 

프로젝트를 하다보면 뷰가 늘어나는 효과를 줘야할 때가있어요

안드로이드에서는 지원해주고 라이브러리들도 많아요

저는 iOS공부하면서 알맞은 라이브러리를 찾기도 힘들더라구요

 

그래서 직접 만들어서 구현해보기로 했습니다.!!

 

 

우선 스토리보드에 셀2개를 생성할거에요

클릭하기전에 보여질 셀과 클릭후 펼쳐질 셀이 될거에요

 

이제 셀에 넣어줄 데이터가 있어야겠죠??

 

구조체를 하나만들거에요

struct Notice{
    let date: String
    let title: String
    let content: String
    var open = false
    
    mutating func dateFormat() -> String{
        guard let s = self.date.split(separator: " ").first else {return "??"}
        
        return String(s)
    }
}

open은 셀의 클릭된상태를 확인할 변수에요!

추가해주세요

 

 

 

우선 Expandable의 원리를 설명해볼게요

섹션을 데이터 개수만큼만들고

섹션에 해당하는 데이터의 open상태에 따라서 섹션의 셀갯수를 조절할거에요 (펼처질 셀갯수)

 

여기까지하면

을통해 기본으로 셀이1개가 생성되있고( 클릭할 셀 )

클릭햇을때 셀갯수를 를통해서 조절할 수 있어요

이러한 원리를 이용해서 동작하게 만들거에요!!

 

 

 

//section 수
func numberOfSections(in tableView: UITableView) -> Int {
        return items.count
    }
    
//cell 수
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    if items[section].open == true {
        return 1 + 1
    }else{
        return 1
    }
}

//cell 크기
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
    if indexPath.row == 0 {
        return 60
    }else {
        return 250
    }
}

위의 코드를 통해서 섹션의 수와 셀수를 정했어요

open이 true상태일때 펼쳐질 거구요

클릭하면 총 2개의 셀의 보일거에요 [ 1(기본셀) + 1(펼쳐질셀) ]

 

그리고 셀크기도 정해줍니다!!

row 가 0 이면 클릭하게될 셀입니다

알맞게 설정해주세요

 

 

 

//cell구현
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    
    if indexPath.row == 0 {
        let cell: NoticeTitleTableViewCell = tableView.dequeueReusableCell(withIdentifier: "noticeTitle", for: indexPath) as! NoticeTitleTableViewCell
        
        cell.titleLabel.text = items[indexPath.section].title
        
        return cell
    }else {
        //클릭시 펼쳐질 셀
        let cell: NoticeContentTableViewCell = tableView.dequeueReusableCell(withIdentifier: "noticeContent", for: indexPath) as! NoticeContentTableViewCell
        
        cell.dateLabel.text = items[indexPath.section].dateFormat()
        cell.titleLabel.text = items[indexPath.section].title
        cell.contentTextView.text = items[indexPath.section].content
        
        return cell
    }
}

위의코드는 cell을 구현하는코드에요

여기서 클릭될 셀과 클릭후 펼쳐질 셀의 데이터를 넣어주면 됩니다.!!!

어떻게 구분하냐구요??

 

indexPath.row의 값으로 구분합니다!!!

섹션의 0번째는 무조건 클릭하게될 셀이 될거에요

펼쳐짐에 따라서 1, 2, 3.... 늘어나겠죠?? 

 

    //cell 확장효과
    func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
        guard let cell = tableView.cellForRow(at: indexPath) as? NoticeTitleTableViewCell else {return}
        guard let index = tableView.indexPath(for: cell) else { return }
        
        if index.row == indexPath.row {
            if index.row == 0 {
                if items[indexPath.section].open == true {
                    items[indexPath.section].open = false
                    cell.arrowImg.image = UIImage(named: "uparrow")
                    let section = IndexSet.init(integer: indexPath.section)
                    tableView.reloadSections(section, with: .fade)
                    
                }else {
                    items[indexPath.section].open = true
                    cell.arrowImg.image = UIImage(named: "downarrow")
                    let section = IndexSet.init(integer: indexPath.section)
                    tableView.reloadSections(section, with: .fade)
                }
            }
        }
        
    }

마지막으로 !!

위의코드는 클릭됬을때 해당 셀의 상태를 변화시키는 거에요

저는 클릭하면 아래로 펼쳐지고 올라감에따라서 화살표 이미지를 변경했어요

그리고 눌린셀의 open값을 변경해줘야되요 toggle값처럼 펼쳤다가 접었다가 할것이기 때문에 꼭해주셔야해요

변경하고나서는 모든 데이터를 새로고침하는건 비효율적이죠!!

해당하는 section만 다시 새로고침하도록 하는게 좋아요

 

 

 

 

반응형