오늘은 하루종일 ToDoList 만들기 과제에 모든 시간을 쏟아버렸다..
TableView Delegate 패턴의 적용은 간단하기도 하고 필수 구현내용이 없어서 금방 적용할 수 있었지만, Datasource의 경우 필수 구현내용 함수에서 자꾸만 에러가 나 시간을 너무 많이 잡아먹었다.
차라리 코드로 짜버리고 싶은 마음이 굴뚝 같았지만 과제 구현 사항이 Storyboard를 사용하여 구현해야 하므로 오늘 헤맸던 구간에 대해서 기록을 해두려고 한다.
Storyboard 를 사용하여 TableView 세팅하기
Storyboard 컴포넌트
VC 내 TableView를 넣어주고 오토레이아웃을 topAnchor 만 버튼의 height 만큼 (40) 넣어주고 나머지 면을 0으로 설정해 가득 차게 구성하였다.
그 이후 TableViewCell 을 넣어 셀이 들어갈 위치를 잡아준 후, 그 안에 셀의 레이블과 스위치를 위치하고 오토레이아웃을 통해 Cell 중앙에 올 수 있도록 배치하였다.
셀을 추가시킬 버튼을 상단과 오른쪽을 0으로 잡아 오토레이아웃을 잡아준 후 배치하면 전반적인 셋팅은 완료된다.
identifier 지정하기
위에서 넣어둔 TableViewCell에 접근하여 식별자를 지정해주는 것이 아주 중요하다!
그 이유는 iOS가 메모리 효율성을 위해 셀을 재사용하는데 있다고 한다.
자세한 내용은 밑에서 설명하는걸로 하고 일단 identifier 를 지정하는 방법먼저 보자
먼저 TableViewCell을 잘 선택한 다음 오른쪽 어트리뷰트 인스팩터 내 identifier 부분에 원하는 명칭을 지정해 주면 된다.
델리게이트 , 데이터소스 가져오기
식별자까지 지정을 해줬다면 이제 테이블뷰 델리게이트와 데이터 소스를 불러와야 한다.
나는 extension 을 사용하여 조금 더 깔끔하게 구성하기 위해 아래와 같이 설정하였다.
extension ViewController: UITableViewDelegate, UITableViewDataSource {
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return cellData.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
guard let cell = tableView.dequeueReusableCell(withIdentifier: "MyCell", for: indexPath) as? TableViewCell else {
return UITableViewCell()
}
return cell
}
위 두가지 함수는 UITableViewDataSource 를 가져오면서 필수로 넣어 줘야하는 메서드이다.
먼저 numberOfRowsInSection 는 섹션에 표시할 행의 수을 반환하는 메서드이다.
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
guard let cell = tableView.dequeueReusableCell(withIdentifier: "MyCell", for: indexPath) as? TableViewCell else {
return UITableViewCell()
}
return cell
}
그리고 가장 골치였던 dequeueReusableCell 는 각 행에 대한 셀을 구성하고 반환하는 메서드이다.
이 메서드는 주어진 indexPath에 대한 셀을 생성하고 반환한다.
tableView 매개변수는 해당 셀을 구성하는 데 사용되는 테이블 뷰이며, indexPath 매개변수는 구성해야 할 셀의 위치를 나타낸다.
함수 내부에서는 먼저 재사용 큐에서 "MyCell" 식별자를 가진 셀을 가져오려 시도하고
가져온 셀을 TableViewCell 클래스의 인스턴스로 캐스팅한다.
이 캐스팅이 실패하면 UITableViewCell 인스턴스를 반환하도록 구성했다.
가져온 셀이 TableViewCell로 캐스팅되었다면, 이 셀을 반환하여 테이블 뷰에 표시되게 된다.
그 후 하단에서 설정한 내용을 내 테이블뷰에 넣어주기 위해 하단의 내용을 꼭 넣어줘야 한다.
override func viewDidLoad() {
super.viewDidLoad()
myTableView.delegate = self
myTableView.dataSource = self
}
이렇게 하면 델리게이트와 데이터소스의 내용을 적용할 수 있게 된다.
오늘은 여기까지 하는데 하루 온 시간을 다 쓴 것 같다..
** 개념정리 ** Cell 재사용
iOS는 메모리 효율성을 위해 만들어둔 셀을 재사용한다. 테이블 뷰에는 화면에 보이는 셀의 개수보다 더 많은 셀이 메모리에 올라가 있지 않는다.
대신, 화면에 보이는 셀만을 메모리에 로드하고, 스크롤 시 화면 밖으로 사라진 셀은 재사용하게 된다.
각각의 셀은 재사용을 위해 고유한 식별자를 가지고 있고 이 식별자를 사용하여 테이블 뷰는 필요할 때마다 재사용 가능한 셀을 찾아내고 해당 셀에 새로운 데이터를 로드하여 표시하게 된다.
화면 밖으로 스크롤되어 사라진 셀은 다시 화면에 나타날때 재사용되며 이전에 화면에 표시되었던 셀의 내용은 새로운 데이터로 갱신되어 다시 사용된다.
'◽️ Programming > T I L' 카테고리의 다른 글
IBOutlet 임의로 변수명 변경으로 인한 오류 (0) | 2024.03.21 |
---|---|
ToDoList 앱 만들기 (2) (0) | 2024.03.21 |
앱의 생명주기 개념 정리 (0) | 2024.03.18 |
Swift Architecture , MVC 개념 정리 (0) | 2024.03.15 |
두 배열 내 요소 비교 ( contains , elementsEqual ) (0) | 2024.03.14 |