RB의 iOS 개발 이야기

Swift - TableView / UIListContentConfiguration이란 무엇인가 본문

iOS/Swift

Swift - TableView / UIListContentConfiguration이란 무엇인가

RaeBaek 2023. 9. 15. 18:25

안녕하세요!

오늘 다뤄볼 내용은 기존에 사용했던 tableView, collectionView를 살펴보고 더 편한(?) 새로운(?) 최신의 기술들을 한번 끄적여볼까 합니다 ㅎㅎ

가장 먼저 기볍게 tableView 먼저 보겠습니다.

 

그럼 바로 확인해보도록 하겠습니다!

기존의 TableView와 CollectionView

  • 이해를 돕기 위한 예제 코드입니다!
    • 그대로 복붙하시면 컴파일 런타임 오류가 일어나고 문법적으로도 잘못된 문법도 있습니다!
  • storyboard base가 아닌 code base의 코드들입니다.
import UIKit
import SnapKit

class SimpleViewController {
    
    let forwards = [Player(name: "Haaland", position: "Forwards", backNumber: 9),
                    Player(name: "alvarez", position: "Forwards", backNumber: 19)]
    
		let tableView = UITableView()
		let collectionView = UICollectionView()

		override func viewDidLoad() {
        super.viewDidLoad()

				view.addSubview(tableView)

				tableView.delegate = self
        tableView.dataSource = self

				tableView.snp.makeConstraints {
            $0.edges.equalToSuperview()
        }

				or

				view.addSubview(collectionView)

        collectionView.delegate = self
        collectionView.dataSource = self

				collectionView.snp.makeConstraints {
            $0.edges.equalToSuperview()
        }
        
    }
}

extension SimpleViewController: UITableViewDelegate, UITableViewDataSource {
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return list.count
    }
    
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        guard let cell = tableView.dequeueReusableCell(withIdentifier: "cell") else { return UITableViewCell() }
        
        cell.textLabel?.text = forwards[indexPath.row].name
        cell.detailTextLabel?.text = "\\(forwards[indexPath.row].backNumber)"
        
        return cell
    }  
}

extension SimpleViewController: UITableViewDelegate, UITableViewDataSource {
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return list.count
    }
    
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        guard let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "cell", for: indexPath) else { return UICollectionViewCell() }
        
				cell.textLabel?.text = mancity.forwards[indexPath.row].name
        cell.detailTextLabel?.text = "\\(mancity.forwards[indexPath.row].backNumber)"
    }
}
  • 위의 코드와 같이 많이들 사용하시는 tableView와 collectionView는 객체를 생성하고 delegate, dataSource 프로토콜을 채택한 후 extension(익스텐션에 프로토콜 함수 정의는 개인 취향)에 함수를 정의하여 사용했습니다.
  • tableView와 collectionView를 조금이라도 다뤄보신 분들은 아래의 키워드를 정말 많이 보셨을 겁니다!
    • tableView
    • collectionView
    • delegate
    • dataSource
    • numberOfRowsInSection
    • cellForRowAt

 

그렇다면 새로운 방법은 무엇인지 보겠습니다.

Custom한 cell을 사용하는 것이 아닌 System적인 cell을 사용할때라면

tableView 함수의 cellForRawAt 부분을 수정해볼 수 있습니다.

extension MancityViewController: UITableViewDelegate, UITableViewDataSource {
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return mancity.forwards.count
    }
    
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = UITableViewCell()
        var content = cell.defaultContentConfiguration()
        content.text = list[indexPath.row]
            .name
        content.secondaryText = "\\(list[indexPath.row].age)"
        cell.contentConfiguration = content
        
        return cell
    }
}
  • cellForRowAt 내부 코드의 차이가 보이시나요?
  • cell에 UITableViewCell 클래스를 선언하기만 하고 어떠한 identifier를 가지고 있는 cell을 사용해야하는지 입력하는 부분은 찾아볼 수 없습니다.
  • 또한 cell.defaultContentConfiguration()을 보시면 defaultContentConfiguration() 라는 처음보는 메서드를 확인할 수 있는데요 

  • 정의로 들어가보니 UIListContentConfiguration을 반환하는 메서드임을 확인할 수 있습니다!
  • 단어만 봐서는 뭔지 잘 모르겠으니 더 보겠습니다.
  • content.text / content.secondaryText 그 뒤에는 값을 넣어주고 있는데요.
  • 짐작이 가기에 cell.textLabel?.text 와 cell.textLabel?.detailText를 대신하여 사용하는 것 같습니다.
  • 그리고 마지막으로 cell.contentConfiguration = content로 content를 대입해주고 있습니다.

 

여기서 중요한 부분은 defaultContentConfiguration() 일 것 같습니다. 왜 기존의 코드를 사용하지 않고 굳이 defaultContentConfiguration()를 사용하고 있는가 싶다면

  • 띠용?
  • textLabel은 미래의 iOS의 버전에서 더이상 사용되지 않을 것으로 경고문을 띄워주고 있습니다..
  • 그러므로 저희는 system적인 cell의 내용을 작성하게 된다면 앞으로 defaultContentConfiguration()을 사용해야 할 것을 유추할 수 있습니다.
  • 언제가 될지는 모르겠지만 앞으로의 tableView의 cell에 system적인 content를 다룰때에는 기존의 방법을 내려놔야할 시기가 다가오기 때문에 새로운 방법을 익혀두시는 것도 좋을 것 같습니다.
  • 참고로 UIListContentConfiguration 는 iOS 14 이후에 등장했다고 합니다.

 

사실 오늘 다룬 tableView에서의 UIListContentConfiguration 사용보다 다음에 다뤄볼 collectionView 에서의 UIListContentConfiguration 사용이 더욱 빈번할 것이라고 생각합니다 ㅎㅎ

List라는 단어의 본연의 뜻을 생각해보면 머릿속에 그려지는 그림 자체가 collecionView 보다는 tableView에 가까울 것이라고 생각됩니다.

하지만!

Apple에서 collectionView에서도 tableView와 같은 list 형태와 더 많은 형태를 iOS 14 이후로 부터 새롭게 제공해주고 있었습니다.

다음 포스트는 UICollectionLayoutListConfiguration 를 다뤄보도록 하겠습니다.

 

감사합니다.