BOID

[iOS] 테이블 뷰 컨트롤러 구현해보기 (2/2) - HoonIOS 본문

IOS 시작기

[iOS] 테이블 뷰 컨트롤러 구현해보기 (2/2) - HoonIOS

HoonIOS 2021. 4. 27. 13:42

안녕하세요 HoonIOS입니다. :)

 

저번 포스팅에서는 테이블 뷰 컨트롤러 UI를 구현하고 간단한 모델하고 데이터 소스를 만들었습니다.

boidevelop.tistory.com/74

 

[iOS] 테이블 뷰 컨트롤러 구현해보기 (1/2) - HoonIOS

안녕하세요 HoonIOS입니다. :) 저번에는 테이블 뷰 컨트롤러의 델리게이트와 데이터 소스의 역할 및 몇 개의 메서드를 확인해봤습니다. boidevelop.tistory.com/73 [iOS] 테이블 뷰 컨트롤러에서 데이터 소

boidevelop.tistory.com

이제는 이 데이터 소스와 모델을 통해서 테이블 뷰 컨트롤러에 값을 뿌려주도록 하겠습니다.

 

제일 먼저 테이블 뷰의 개수를 지정해주도록 하겠습니다.

 

* 코드 설명

  • tableView(:numberOfSections:)는 해당 테이블 뷰의 크기를 리턴해주는 것으로 UITableViewDataSource에 구성되어있습니다.
  • 이렇게 데이터의 소스 크기에 따라 테이블뷰 크기를 설정해주면 데이터 소스가 수정될 때마다 return값을 수정해줄 필요가 없습니다.
    ( 즉 유지 보수가 편한거겠죠? )
  • 이 프로젝트에서는 총 3개의 data가 있으므로 3개의 테이블 뷰가 생깁니다.

 

테이블 뷰 셀을 custom으로 했으니 이제 각 셀의 라벨 및 UIImageView를 연결해 주기 위해 아울렛 선언을 해줘야 합니다.

 

* 코드 설명

  • 이렇게 각 라벨을 설정해준 이유는 이것은 커스텀으로 설정되어 있기 때문에 기본 테이블 뷰 셀에서는 해당 UILabel이 선언되어 있지 않습니다.
  • 따라서 테이블 뷰 셀을 상속받은 클래스에다가 구현을 해준 것입니다.

이제 테이블 뷰 행을 구성해 보겠습니다.

 

* 코드 설명

  • tableView(_:cellForRowAt:)은 테이블 뷰 셀을 구성하는 메서드로 UITableViewDatasource에 구성된 메서드입니다.
  • indexPath인자 값은 행의 순서, 정보를 가져온다고 했습니다.
     따라서. row변수를 통해 행의 번호를 가져와 해당하는 데이터 소스의 인덱스를 row변수에 넣어주면 해당하는 인덱스를 가져옵니다.
  • 이제 저번에 테이블 뷰 셀의 identifier을 설정해준 것을 여기서 사용하면 됩니다. 테이블 뷰를 재사용 큐를 사용하여 테이블 뷰의 identifier로 해준 값을 통해 테이블 뷰 셀의 인스턴스를 생성합니다.
  • 여기서 중요한 점은 테이블 뷰셀을 커스텀마이징해줬기 때문에 customPlayer로 캐스팅을 해줘야 합니다.
  • 이제 데이터 소스의 값들을 해당하는 객체에 값을 넣어주고 해당 테이블 뷰 셀을 리턴해주면 됩니다.
  • 이 메서드는 정해진 numberOfrowsInSection수 만큼 수행되는건 맞지만 한번에 실행되는게 아니라 화면에 표시되는 만큼 먼저 메서드가 실행되고 스크롤시 추가되는 테이블셀은 그때 메서드가 실행되어 테이블 셀들이 생기게 됩니다.

    그렇지만 만약에 내렸던걸 다시 위로 올리면 사라졌던 테이블 셀들이 다시 나타나 로그에 찍히게 됩니다.
    이 기능에는 재사용 매커니즘이 들어가는데요 이 메커니즘은 아래 .dequeResuableCell메서드를 통해 구현이 됩니다.

 

※ 여기서. dequeReusableCell(withIdentifier:) 메서드는 무엇일까요?

- 이것은 인자 값으로 입력받은 identifer을 통해 스토리 보드에 정의된 프로토타입 셀을 찾고 이를 인스턴스로 생성해서 제공을 합니다.

- 이때 재사용 큐 객체가 관여를 하는데 이 재사용 큐는 한차례 사용된 테이블 셀 인스턴스를 폐기하지 않고 대기하는 공간으로 보내는 것입니다. ( 캐시 같은 역할을 하네요 )

( 다시 말해 이 메서드가 호출되었을 때 identifer에 해당하는 인스턴스가 큐에 있다면 꺼내서 재사용하고 없으면 새로운 인스턴스를 생성하여 제공하는 방식입니다. )

 

- 해당하는 프로토타입 셀이 존재하지 않을 때 결괏값은 옵셔널 타입으로 반환을 합니다. 그렇지만 개발자가 identifer를 제대로 입력만 했다면 nil을 반환할 가능성이 없기 때문에 강제 언래핑인! 를 사용하여 옵셔널 타입을 해제합니다.

 

 

※ 이제 재사용 큐란 무엇일까요?...( 뭐 이리 어려운 개념들이 연속으로 ㅠ)

- 만약에 테이블 뷰에 준비된 데이터 소스가 1000개라면 그에 해당하는 테이블 뷰를 일일이 만들지는 않습니다.

다 만들면 시간 + 메모리 낭비겠죠?

 

- 셀 객체를 저장하는 공간을 만들어 놓고 여기에 셀 객체를 저장해 두었다가 필요할 때마다 꺼내서 사용하고 필요 없는 셀 객체는 다시 저장하는데 저장소가 바로 재사용 큐입니다.

 

- 따라서 리스트를 생성하되 재활용 가능한 셀이 있으면 새로 만들지 않고 꺼내서 재활용하는 법칙입니다.

 

 

자 이제 앱을 실행해 볼까요? 실행은 되지만 앱을 실행할 때마다 테이블 뷰 셀들의 높이를 잡아주라고 아래와 같이 경고창이 뜨네요

 

 

프로그래밍에서 경고란 없애야 개발자가 편안해지니깐 테이블 뷰셀의 높이를 잡아주겠습니다.

 

* 코드 설명

  • tableView(_:heightRowAt:)의 메서드는 행의 높이를 잡아주는 것으로 UITableViewDelegate에 구성되어 있습니다.
  • 테이블이 여러 개면 테이블에 따라 다르게 잡아줄 수도 있고 indexPath인자값을 통해 테이블 뷰 셀에 따라 테이블 뷰 셀의 높이를 다르게 잡아줄수도 있습니다.

 

그럼 이제 결과를 한번 봐볼까요?

 

 

 

꾸미 지를 않아서 그냥 허접하네요.... ㅎㅎㅎ 그래도 테이블 뷰 컨트롤러를 공부한 것이니 값이 잘 나타내는 것만 확인하고 넘어가겠습니다.

 

이제 사용자가 해당 테이블 뷰 셀을 클릭했을 때 몇 번째 행에서 발생하는 건지 log를 찍어보겠습니다.

 

* 코드 설명

  • tableView(_:didSelectRowAt:) 메서드는 테이블 뷰셀을 터치했을 때 발생하는 메서드로 UITableViewDelegate에 구성되어 있습니다.
  • 인자 값을 통해 어느 테이블 뷰의 어느 행을 터치했을 때 이벤트를 발생하게 예외처리를 할 수 있습니다.
  • 따라서 이 메서드를 통해서 해당 열을 눌렀을 때 어느 페이지로 이동을 할 때 유용하게 사용이 됩니다.
  • 여기서는 우선 간단하게 로그만 찍히도록 코드를 사용했습니다. :)

 

이렇게 터치 이벤트가 발생할 때마다 로그가 찍히는 것을 볼 수 있고 행의 인덱스는 0부터 시작을 하는 것도 확인을 할 수 있습니다.

 

이렇게 테이블 뷰 컨트롤러를 만들어보고 델리게이트, 데이터 소스 메서드를 구현도 해봤습니다. :)

 

테이블 뷰 컨트롤러는 앱에서 뺄 수 없는 부분이므로 잘 익혀놓는 게 좋다고 생각합니다 긴 글 읽어져 주셔서 감사합니다.

반응형
Comments