iOS & Swift 공부 - UITableView (정적, 동적 데이터 활용)

김영채 (Kevin)·2021년 2월 5일
1

iOS & Swift

목록 보기
66/107

정적 데이터와 동적 데이터를 활용해서 UITableView 실습을 진행해 보았다. 첫 번째와 두 번째 Section 은 한글 (가나다라..)과 영어 (ABCD..) 배열을 정적으로 보여주고, 마지막 Section 에서는 Add Button 을 누르면 새롭게 Custom Cell 이 생성되게 만드는 것이 핵심이다.

나중에 앱 개발을 하다보면 정적인 데이터로 TableView 를 보여줘야 할 때가 있을 것이고, 또 동적인 데이터로도 TableView 를 자주 업데이트하면서 보여줘야 할 때가 있을 것이기 때문에 2개 모두를 한 번에 연습을 해 보았다.

우선 스토리보드에 Tableview 를 가져다 놓는다.

화면에 꽉 찰 수 있도록 오토레이아웃을 설정한다.

추가한 TableView 에 TableView Cell 도 하나 위쪽에 추가한다. 이 때, 해당 cell 의 고유 identifier 역시 함께 설정해야 한다. 실습에서는 cell 로 설정하였다.

방금 추가한 TableView Cell 아래에 또 하나의 Cell 을 가져다 놓는다. 이 Cell 이 동적인 데이터를 보여줄 Cell 이 될 것이고, 따로 customizing 을 할 것이기 때문에 identifier 는 customCell 로 이름을 정했다.

2개의 Table View Cell 아래에는 Button 을 하나 추가했다. 이 버튼을 누르게 되면 customCell 이 하나씩 추가될 수 있도록 후에 구현할 것이다.

다음으로 새 Cocoa Touch Class 를 만들어준다. 이 클래스에서 customCell 을 커스터마이징 할 것이다.

서브 클래스를 반드시 UITableViewCelL로 설정하고, 이름은 CustomTableViewCell 등으로 설정한다.

파일 생성을 하면 스토리보드로 돌아와서 아까 추가한 두 번째 Cell 을 누르고, Identity Inspector 에서 해당 Cell 이 CustomTableViewCell 이랑 연결될 수 있도록 설정한다.

customCell 에 2개의 레이블을 추가하였다. 왼쪽 레이블은 날짜, 우측 레이블은 시간을 표시할 수 있도록 하기 위함이다.

레이블을 추가하면 오토레이아웃도 설정해야 한다.

우측 레이블도 오토레이아웃을 설정해준다.

참, 그리고 ViewController 파일에서 처음에 만들어둔 Table View 를 IBOutlet 으로 연결해주어야 한다.

이제 CustomTableViewCell 파일이다. 해당 클래스 파일에서 아까 만든 2개의 UILabel 과 연결될 수 있도록 @IBOutlet 을 정의하고, 스토리보드와 연결해준다.

다시 ViewController 화면이다. UITableViewDelegate 와 UITableViewDataSource 프로토콜을 채택해야 테이블뷰를 제대로 쓸 수 있기 때문에 위 사진과 같이 추가하였다.

2개의 프로토콜을 구현하는 코드를 extension 으로 빼놓은 이유는 가독성을 위해서다. ViewController 클래스 내에서 한 방에 해결이 가능하기는 하지만, 그렇게 되면 코드가 정말 난잡해지는 경우를 많이 봐서 프로토콜은 따로 extension 에서 구현해준다. 이렇게 하니까 확실히 코드가 깔끔해지는 것 같다.

정적인 데이터를 추가해주었다. korean 과 english 배열을 하드코딩하였다. 이렇게 하드코딩을 해야하면 보통 정적 데이터로 불린다.

dates 배열이 이제 동적 데이터다. 우선은 빈 배열로 선언해주었다. dateFormatter 와 timeFormatter 는 customCell 의 leftLabel 과 rightLabel 에 각각 적절하게 날짜와 시간을 표시할 수 있게 필요한 인스턴스다.

UITableViewDelegate 와 UITableViewDataSource 프로토콜을 구현하는 블럭이다.

numberOfSections 함수는 말 그대로 테이블 뷰에 몇 개의 Section 이 있을건지 알려주는 함수다.

tableView(...numberOfRowsInSection ..) 함수는 각 Section 별로 몇 개의 rows 가 있는지 알려줘야 한다. 첫 번째 Section 은 korean 배열의 개수만큼, 두 번째 Section 은 english 배열의 개수만큼, 그리고 3번 째 Section 은 dates 배열의 개수만큼 rows 가 있으면 된다.

여기서 korean.count 랑 english.count 는 항상 그 수가 같겠지만, dates.count 는 Add 버튼을 몇 번 누르느냐에 따라 항상 바뀌는 동적인 수다.

위 tableView(...cellForRowAt..) 함수는 테이블뷰 안에 넣을 cell 을 직접적으로 요청하는 함수다. 즉, UITableViewCell 타입의 cell 을 만들고, return 해야한다.

첫 번째 또는 두 번째 Section 이면 아까 identifier 가 cell 인 일반 cell 을 만들어서 return 하면 된다.

if indexPath.section < 2{
            
            let cell = tableView.dequeueReusableCell(withIdentifier: cellIdentifier, for: indexPath)
            let text = indexPath.section == 0 ? korean[indexPath.row] : english[indexPath.row]
            
            cell.textLabel?.text = text
            
            return cell
        }

첫 번째 Section 이면 korean 배열 안에 있는 값들로 text를 하나씩 채우고, 두 번째 Section 이면 english 배열 안에 있는 값들로 text를 채우게 설정하였다.

마지막 Section이 살짝 다르다. 마지막 Section 은 CustomTableViewCell 과 연결되어 있는 customCell 을 추가할 것이기 때문에, cell 을 만들 때 as! CustomTableViewCell 을 마지막에 붙여 Type Casting 을 꼭 해줘야 한다. 그렇지 않으면 cell.leftLabel, cell.rightLabel 에 접근이 불가하다.

else{
            
            let cell = tableView.dequeueReusableCell(withIdentifier: self.customCellIdentifier, for: indexPath) as! CustomTableViewCell
            
            
            cell.leftLabel.text = dateFormatter.string(from: dates[indexPath.row])
            
            cell.rightLabel.text = timeFormatter.string(from: dates[indexPath.row])
           
            return cell
        }

어쨌든 어떤 Section 이느냐에 따라 각기 다른 종류의 cell 을 return 하도록 설정하면 된다.

func tableView(...titleForHeaderInSection..) 함수는 각 Section 의 Header 를 설정해주는 함수다.

위 사진과 같은 영역에 타이틀을 설정할 수 있는 것이다.

func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
        
        if section < 2{
            return section == 0 ? "한글" : "영어"
        }
        return nil
    }

마지막으로 Add Data 버튼을 연결해 주어야 한다. @IBAction 으로 연결한다.

@IBAction func pressedAddButton(_ sender: UIButton) {
    
    dates.append(Date())
    tableView.reloadSections(IndexSet(2...2), with: UITableView.RowAnimation.automatic)
}

버튼을 누를 때마다 dates 배열에 현재 날짜를 추가할 수 있도록 먼저하고, 그 다음에 마지막 Section 이 reload 될 수 있도록 하는 코드를 작성하였다.

이렇게 정적 데이터와 동적 데이터를 동시에 다룰 수 있는 TableView 를 완성하였다.

profile
맛있는 iOS 프로그래밍

3개의 댓글

comment-user-thumbnail
2022년 4월 1일

안녕하세요 포스트로 많은 도움이 되었습니다! 혹시 이해를 더 해보려 하는데 이 프로젝트 클론을 이용할 수 있을까요?

1개의 답글