๋ณธ๋ฌธ ๋ฐ”๋กœ๊ฐ€๊ธฐ
๐ŸŽ iOS/iOS

[iOS] ์žฌ์‚ฌ์šฉ ๊ฐ€๋Šฅํ•œ ํ…Œ์ด๋ธ”๋ทฐ ๋ฐ์ดํ„ฐ์†Œ์Šค ๋งŒ๋“ค๊ธฐ(Reusable TableView DataSource)

by Fomagran ๐Ÿ’ป 2021. 6. 3.
728x90
๋ฐ˜์‘ํ˜•

 

์•ˆ๋…•ํ•˜์„ธ์š” Foma ๐Ÿ‘Ÿ ์ž…๋‹ˆ๋‹ค!

์˜ค๋Š˜์€ ํ…Œ์ด๋ธ”๋ทฐ ๋ฐ์ดํ„ฐ์†Œ์Šค๋ฅผ ์ œ๋„ˆ๋ฆญํ•˜๊ฒŒ ๋งŒ๋“ค์–ด์„œ ๋ชจ๋“  ๋ทฐ์ปจํŠธ๋กค๋Ÿฌ์—์„œ ๊ฐ„๋‹จํ•˜๊ฒŒ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋Š”

 

๋ฐฉ๋ฒ•์— ๋Œ€ํ•ด ์ •๋ฆฌํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค!

 

๋ฐ”๋กœ ์‹œ์ž‘ํ• ๊ฒŒ์š”~


StoryBoard

 

์Šคํ† ๋ฆฌ๋ณด๋“œ๋Š” ์•„๋ž˜์™€ ๊ฐ™์ด ํ…Œ์ด๋ธ”๋ทฐ ์ปจํŠธ๋กค๋Ÿฌ๋ฅผ ๋งŒ๋“ค์–ด์ฃผ์‹œ๊ณ  ์…€์— ์ด๋ฆ„์„ ํ‘œ์‹œํ•  ๋ ˆ์ด๋ธ”์„ ์ถ”๊ฐ€ํ•ด์คฌ์Šต๋‹ˆ๋‹ค.

์•„๋ž˜์™€ ๊ฐ™์ด ๊ตฌ์„ฑ๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค.

์…€์˜ ํด๋ž˜์Šค ์ด๋ฆ„์€ NameTableViewCell๋กœ ํ•ด์ฃผ์„ธ์š”! ( ๋‚˜์ค‘์— ๋งŒ๋“ค์–ด์ค„๊ฑฐ์—์š”!)

identifier๋Š” ์…€ ์ด๋ฆ„๊ณผ ๋˜‘๊ฐ™์ด ํ•ด์ฃผ๊ฒ ์Šต๋‹ˆ๋‹ค.


NameTableVIewCell

 

์•„๋ž˜์™€ ๊ฐ™์ด ๋ ˆ์ด๋ธ”์„ ์—ฐ๊ฒฐํ•ด์ฃผ์„ธ์š”.

 

import UIKit

class NameTableViewCell: UITableViewCell {

    @IBOutlet weak var name: UILabel!

}

TableViewDataSource

 

์ด์ œ ๋ณธ๊ฒฉ์ ์œผ๋กœ ์žฌํ™œ์šฉ ๊ฐ€๋Šฅํ•œ ๋ฐ์ดํ„ฐ์†Œ์Šค ํŒŒ์ผ์„ ๋งŒ๋“ค์–ด๋ณผ๊ฒŒ์š”!

๋จผ์ € ๋ฐ์ดํ„ฐ ์†Œ์Šค๋Š” ์•„๋ž˜์™€ ๊ฐ™์ด ์–ด๋–ค ์…€์ธ์ง€ ํ™•์ธํ•  CellType๊ณผ Cell์„ ๊ตฌ์„ฑํ•˜๋Š” Item์„ ๊ฐ€์ง€๊ณ  ์žˆ๋Š” NSObject ๋งŒ๋“ค์–ด์ค๋‹ˆ๋‹ค.

class TableViewDataSource<CellType,Item>:NSObject,UITableViewDataSource where CellType:UITableViewCell {

ํ”„๋กœํผํ‹ฐ๋Š” ์•„๋ž˜์™€ ๊ฐ™์ด ์…€์˜ ์•„์ด๋ดํ‹ฐํ”ผ์–ด,์•„์ดํ…œ๋“ค, ๊ทธ๋ฆฌ๊ณ  ๋‚˜์ค‘์— ๋ทฐ์ปจํŠธ๋กค๋Ÿฌ์— ์–ด๋–ค ์…€ํƒ€์ž…๊ณผ ์•„์ดํ…œ์„ ๊ฐ€์ง€๊ณ  ์žˆ๋Š”์ง€

 

์ฝœ๋ฐฑ์œผ๋กœ ์•Œ๋ ค์ค„ configure ํด๋กœ์ ธ๋ฅผ ์„ ์–ธํ•ด์ค๋‹ˆ๋‹ค.

    let identifier:String
    var items:[Item]
    let configure:(CellType,Item) -> ()

 

๊ทธ ๋‹ค์Œ์œผ๋ก  ๋ฐ์ดํ„ฐ ์†Œ์Šค๋ฅผ ๊ตฌ์„ฑํ•  ๋•Œ ๋ฐ˜๋“œ์‹œ ํ•„์š”ํ•œ numberofRowsInSection๊ณผ cellForRowAt์„ ์ž‘์„ฑํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค.

 

์•„๋ž˜์™€ ๊ฐ™์ด items์˜ ๊ฐฏ์ˆ˜๋งŒํผ ์—ด์„ ๋ฐ˜ํ™˜ํ•ด์ฃผ๊ณ  ํ•ด๋‹น ์•„์ด๋ดํ‹ฐํ”ผ์–ด๋ฅผ ๊ฐ€์ง„ ์…€์œผ๋กœ ๋กœ์šฐ๋ฅผ ๊ตฌ์„ฑํ•ด์ค๋‹ˆ๋‹ค.

  func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
 	 //์•„์ดํ…œ๋งŒํผ ๋ฐ˜ํ™˜
        return self.items.count
    }
    
  func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        //์•„์ด๋ดํ‹ฐํ”ผ์–ด์— ๋”ฐ๋ผ์„œ ์…€์„ ๊ตฌ์„ฑํ•จ.
        guard let cell = tableView.dequeueReusableCell(withIdentifier: self.identifier, for: indexPath) as? CellType else { fatalError("\(self.identifier)๋ฅผ ํ™•์ธํ•ด์ฃผ์„ธ์š”!") }
        //ํ˜„์žฌ ์•„์ดํ…œ
        let item = self.items[indexPath.row]
        //์–ด๋–ค ์…€๊ณผ ์–ด๋–ค ์•„์ดํ…œ์ธ์ง€ ์•Œ๋ ค์คŒ
        self.configure(cell,item)
        //์…€์„ ๋ฐ˜ํ™˜
        return cell
    }

 

๊ทธ๋ฆฌ๊ณค ๋งŒ์•ฝ items์ด ๋ณ€๊ฒฝ๋  ๊ฒฝ์šฐ ๋ฐ์ดํ„ฐ ์†Œ์Šค๋ฅผ ์—…๋ฐ์ดํŠธ ์‹œ์ผœ์ค„ updateDataSource ๋ฉ”์†Œ๋“œ๋„ ๋งŒ๋“ค์–ด์ฃผ์„ธ์š”!

 func updateDataSource(_ items:[Item]) {
        self.items = items
    }

TableViewController

 

์ด์   ๋ฐ์ดํ„ฐ์†Œ์Šค๋ฅผ ํ…Œ์ด๋ธ”๋ทฐ ์ปจํŠธ๋กค๋Ÿฌ์— ์ ์šฉํ•ด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

 

๋จผ์ € ๋งŒ๋“ค์–ด์ค€ ๋ฐ์ดํ„ฐ ์†Œ์Šค์— ํ˜„์žฌ ํ…Œ์ด๋ธ”๋ทฐ ์ปจํŠธ๋กค๋Ÿฌ์— ๊ตฌ์„ฑํ•  ์…€๊ณผ ์•„์ดํ…œ์„ ๊ตฌ์„ฑํ•  ํƒ€์ž…์„ ๋„ฃ์–ด์ค€ ๋’ค ์„ ์–ธํ•ด์ค๋‹ˆ๋‹ค.

 

๊ทธ๋ฆฌ๊ณค names๋ผ๋Š” ์ด๋ฆ„๋“ค์„ ๊ฐ€์ง€๊ณ  ์žˆ๋Š” ์•„์ดํ…œ๋“ค์„ ๋งŒ๋“ค์–ด์ฃผ๊ฒ ์Šต๋‹ˆ๋‹ค.

import UIKit

class TableViewController: UITableViewController {
    
    private var dataSource:TableViewDataSource<NameTableViewCell,String>!
    
    var names:[String] = ["Foma","Gran","Young"]

    override func viewDidLoad() {
        super.viewDidLoad()

์•„๋ž˜์™€ ๊ฐ™์ด ํ˜„์žฌ ํ…Œ์ด๋ธ”๋ทฐ ์ปจํŠธ๋กค๋Ÿฌ์—  ๋ฐ์ดํ„ฐ ์†Œ์Šค๋ฅผ ์„ธํŒ…ํ•˜๋Š” setTableViewDataSource๋ฅผ ๋งŒ๋“ค์–ด์ค๋‹ˆ๋‹ค.

 

๋ฐ์ดํ„ฐ์†Œ์Šค๋Š” ์œ„์—์„œ ์„ ์–ธํ•œ ๋ฐ์ดํ„ฐ ์†Œ์Šค์— ํ˜„์žฌ ๋„์šธ ์…€์˜ ์•„์ด๋ดํ‹ฐํ”ผ์–ด์™€ ์•„์ดํ…œ๋“ค์„ ๋„ฃ์–ด์ค๋‹ˆ๋‹ค.

 

์ฝœ๋ฐฑ์œผ๋กœ ๋ฐ›์€ ์…€๊ณผ ์•„์ดํ…œ์„ ์—ฐ๊ฒฐํ•ด์„œ ์ด๋ฆ„์„ ๋„์›Œ์ฃผ๋„๋ก ํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค.

 

์ด๋ ‡๊ฒŒ ์„ธํŒ…ํ•œ ๋ฐ์ดํ„ฐ์†Œ์Šค๋ฅผ ํ˜„์žฌ ํ…Œ์ด๋ธ”๋ทฐ ๋ฐ์ดํ„ฐ ์†Œ์Šค๋กœ ์„ค์ •ํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค.

  func setTableViewDataSource() {
        self.dataSource = TableViewDataSource(identifier: "NameTableViewCell", items: names, configure: { cell, name in
            cell.name.text = name
        })
        self.tableView.dataSource = dataSource
    }

 

๋ทฐ๋””๋“œ๋กœ๋“œ์— ์‹คํ–‰์‹œํ‚ค๋Š”๊ฑฐ ์žŠ์ง€ ๋ง์•„์ฃผ์„ธ์š”!

override func viewDidLoad() {
        super.viewDidLoad()
        setTableViewDataSource()
    }

์‹คํ–‰ํ™”๋ฉด

 

์ด๋ ‡๊ฒŒ ์‹คํ–‰ํ•˜๋ฉด ์•„๋ž˜์™€ ๊ฐ™์ด ์ •์ƒ์ ์œผ๋กœ ์ด๋ฆ„๋“ค์ด ํ…Œ์ด๋ธ”๋ทฐ์— ์ ์šฉ๋œ ๊ฑธ ๋ณผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค!

 

 


Update

 

TableViewController

 

๊ทธ ๋‹ค์Œ ํ…Œ์ด๋ธ”๋ทฐ ์ปจํŠธ๋กค๋Ÿฌ์— ์•„๋ž˜์™€ ๊ฐ™์ด ์•„์ดํ…œ์ด ์ˆ˜์ •๋  ๋•Œ updateDataSource ๋ฉ”์†Œ๋“œ์— ํŒŒ๋ผ๋ฏธํ„ฐ๋กœ ๋ฐ”๋€ ์•„์ดํ…œ๋“ค์„

 

๋„ฃ์–ด ํ˜ธ์ถœํ•ด์ค๋‹ˆ๋‹ค.

 func addName(_ name:String) {
        self.names.append(name)
        self.dataSource.updateDataSource(names)
    }

์˜ค๋Š˜์€ ์ด๋ ‡๊ฒŒ ๋ฐ์ดํ„ฐ์†Œ์Šค๋ฅผ ์žฌํ™œ์šฉํ•ด ํ…Œ์ด๋ธ”๋ทฐ์— ์ ์šฉํ•˜๋Š” ๋ฒ•์— ๋Œ€ํ•ด์„œ ๋‹ค๋ค„๋ณด์•˜๋Š”๋ฐ์š”.

 

์ด๋ ‡๊ฒŒ ๋ฏธ๋ฆฌ ๋ฐ์ดํ„ฐ์†Œ์Šค๋ฅผ ๋งŒ๋“ค์–ด๋†“๊ณ  ์ ์šฉํ•˜๋‹ˆ ํ…Œ์ด๋ธ”๋ทฐ ์ปจํŠธ๋กค๋Ÿฌ ์ฝ”๋“œ๋„ ์งง์•„์ง€๊ณ  ๋˜ ์–ด๋–ค ์…€์ด๋“  ๋˜‘๊ฐ™์€ ๋ฐฉ์‹์œผ๋กœ

 

์ ์šฉํ•  ์ˆ˜ ์žˆ๊ณ  ํŠนํžˆ MVVM ๋””์ž์ธ ํŒจํ„ด์œผ๋กœ ๊ตฌ์กฐ๋ฅผ ์งค๋•Œ ์•„์ดํ…œ์— ๋ทฐ๋ชจ๋ธ๋“ค์„ ์ ์šฉํ•˜๊ธฐ ์‰ฌ์›Œ์„œ ๋„ˆ๋ฌด ๋„ˆ๋ฌด

 

์œ ์ตํ•œ ์ •๋ณด์˜€์Šต๋‹ˆ๋‹ค!!

 

ํ˜น์‹œ๋ผ๋„ ๊ถ๊ธˆํ•˜์‹  ์ ์ด ์žˆ๊ฑฐ๋‚˜ ํ‹€๋ฆฐ ๋ถ€๋ถ„์ด ์žˆ๋‹ค๋ฉด ๋Œ“๊ธ€๋กœ ์•Œ๋ ค์ฃผ์„ธ์š”!

 

 

728x90
๋ฐ˜์‘ํ˜•

๋Œ“๊ธ€