๊ณต๋ถ€ ์—ฐ์Šต์žฅ :-)

extension์—์„œ Override

|

@objc

superํด๋ž˜์Šค์—์„œ extension์œผ๋กœ ํ•จ์ˆ˜๋ฅผ ์ถ”๊ฐ€ํ•˜๊ณ  subํด๋ž˜์Šค์—์„œ override ํ•˜๊ณ ์‹ถ์„๋• @objcํ‚ค์›Œ๋“œ๋ฅผ ๋ถ™์—ฌ์•ผํ•œ๋‹ค.

๋ฐœ๊ฒฌ

UIView extension์—์„œ ์ƒˆ๋กœ์šด ํ•จ์ˆ˜๋ฅผ ์„ ์–ธํ•˜๊ณ  ๋‹ค๋ฅธ ์ปค์Šคํ…€๋ทฐ(UIViewํƒ€์ž…)์—์„œ ํ•ด๋‹น ํ•จ์ˆ˜ ๋‚ด๋ถ€๋ฅผ ์ข€ ๋‹ค๋ฅด๊ฒŒ ์“ฐ๊ณ ์‹ถ์–ด์„œ override๋ฅผ ์„ ์–ธํ•˜๋‹ˆ๊นŒ, Overriding non-@objc declarations from extensions is not supported๋ผ๋Š” ์—๋Ÿฌ ๋ฐœ๊ฒฌ.

ํ•ด๊ฒฐ

๊ทธ๋Ÿผ @objc ๋ถ™์ด๋ฉด ํ•ด๊ฒฐ!

class MySuperClass {

}

extension MySuperClass {
    @objc func otherNumber() -> Int {
        return 1
    }
}

class MySubclass : MySuperClass {
    @objc override func otherNumber() -> Int {
        return 2
    }
}

var sup = MySuperClass()
var sub = MySubclass()
print(sup.otherNumber()) // 1
print(sub.otherNumber()) // 2

(๊ณ ๋ฏผ)

  • ์ฒ˜์Œ์— ์ด ๋ฐฉ๋ฒ•์„ ์“ฐ๋ ค๊ณ  ํ–ˆ๋˜๊ฑด ์ปค์Šคํ…€ ๋ทฐ ํด๋ž˜์Šค์—์„œ๋„ ๋น„์Šทํ•œ ๋™์ž‘์„ ํ•ด์•ผํ•˜์ง€๋งŒ, UIViewํด๋ž˜์Šค์— ์„ ์–ธํ•ด๋†“์€ ๊ฒƒ ์ฒ˜๋Ÿผ ์™„์ „ํžˆ ๊ฐ™๊ฒŒ ๋™์ž‘ํ•  ์ˆ˜๋Š” ์—†์–ด์„œ์˜€์Œ
  • ๋น„์Šทํ•œ ๋™์ž‘์ด๊ณ , ๊ฐ™์€ ํด๋ž˜์Šคํƒ€์ž…์ด๋‹ˆ๊นŒ ๊ฐ™์€ ์ด๋ฆ„์œผ๋กœ ์‚ฌ์šฉํ•˜๊ณ ์‹ถ์–ด์„œ overrideํ–ˆ๋˜ ๊ฒƒ์ธ๋ฐ,
  • ์• ์ดˆ์— ํ•ด๋‹น ํƒ€์ž…์—๋‹ค๊ฐ€ ํ•„์š”ํ•œ ํ•จ์ˆ˜๋ฅผ extension์œผ๋กœ ๊ตฌํ˜„ํ•ด๋†“๊ณ  ๊ทธ ํ•จ์ˆ˜๋ฅผ ๋˜ overrideํ•ด์„œ ๋ณ€๊ฒฝํ•˜๊ณ  ์‚ฌ์šฉํ•˜๋Š”๊ฒŒ ํ•ฉ๋ฆฌ์ ์ธ๊ฑธ๊นŒ?

ํƒˆ์ถœ ํด๋กœ์ € (@escaping closure)

|

@escaping

ํ•จ์ˆ˜ ์‚ฌ์ด์— ์‹คํ–‰ ์ˆœ์„œ๋ฅผ ์ •ํ•˜๊ณ  ์‹ถ์„๋•Œ Escaping Closure๋ฅผ ์‚ฌ์šฉํ•œ๋‹ค. ๋น„๋™๊ธฐ ์ฒ˜๋ฆฌ์‹œ ์œ ์šฉํ•˜๋‹ค.

๋ฐœ๊ฒฌ

  • ์ฃผ์†Œ๋ก์•ฑ ๋ฏธ์…˜ ์ค‘ ์—ฐ๋ฝ์ฒ˜๋ฅผ fetchํ•ด์˜ค๋Š” ๊ณผ์ •์—์„œ ํ…Œ์ด๋ธ”๋ทฐ ํ™”๋ฉด์ด ํ‘œ์‹œ๋˜์ง€ ์•Š๋Š” ๋ฌธ์ œ ๋ฐœ์ƒ.
  • ํ•˜์ง€๋งŒ ๋””๋ฒ„๊น…ํ•ด๋ณด๋‹ˆ ์—ฐ๋ฝ์ฒ˜๋Š” ๋‹ค ์ •์ƒ์ ์œผ๋กœ ๊ฐ€์ ธ์™€์ง.
  • ๋ฌธ์ œ๋Š” ์—ฐ๋ฝ์ฒ˜๋ฅผ requestํ•˜๋Š” ํ•จ์ˆ˜๊ฐ€ ๋น„๋™๊ธฐ๋กœ ์ฒ˜๋ฆฌ๋˜๋Š”๊ฑฐ๋ผ ์—ฐ๋ฝ์ฒ˜๊ฐ€ ๋‹ค fetch๋˜์ง€ ์•Š์€ ์ƒํƒœ์—์„œ ํ…Œ์ด๋ธ”๋ทฐ๋ฅผ loadํ–ˆ๊ธฐ ๋•Œ๋ฌธ.
  • ์—ฐ๋ฝ์ฒ˜๊ฐ€ ๋ชจ๋‘ fetch๋˜๋Š” ๋น„๋™๊ธฐ๋กœ ์ฒ˜๋ฆฌ๋˜๋Š” ๋™์ž‘์ด ๋ชจ๋‘ ๋๋‚œ ํ›„ ๋ทฐ๋ฅผ ๋‹ค์‹œ ๋กœ๋“œํ•ด์•ผ ํ–ˆ๊ธฐ ๋•Œ๋ฌธ์— ํ•จ์ˆ˜ ์‚ฌ์ด์— ์‹คํ–‰์ˆœ์„œ๋ฅผ ๋ณด์žฅํ•˜๊ณ  ์‹ถ์–ด์„œ escaping(ํƒˆ์ถœ ํด๋กœ์ €) ์‚ฌ์šฉ.

๋‚˜๋งŒ์˜ ๊ฒฐ๋ก 

  • ํ•จ์ˆ˜๋ฅผ ๋ฒ—์–ด๋‚˜์„œ๋„ ํด๋กœ์ €๋ฅผ ์œ ํšจํ•˜๊ฒŒ ์‚ฌ์šฉ(ํ˜ธ์ถœ, ์ €์žฅ - outLive)ํ•˜๊ณ ์‹ถ์„ ๋•Œ escaping์„ ์‚ฌ์šฉํ•œ๋‹ค!
  • escaping์„ ์‚ฌ์šฉํ•˜๋ฉด A ํ•จ์ˆ˜๊ฐ€ ๋งˆ๋ฌด๋ฆฌ๋œ ์ƒํƒœ์—์„œ๋งŒ B ํ•จ์ˆ˜๊ฐ€ ์‹คํ–‰๋˜๋„๋ก ์ž‘์„ฑํ•  ์ˆ˜ ์žˆ๋‹ค.
  • ์ด๋Š” ๋น„๋™๊ธฐ๋กœ ์‹คํ–‰๋˜์–ด ์‹คํ–‰ ์งํ›„ ๋ฐ˜ํ™˜๋˜์–ด๋ฒ„๋ฆฌ๋Š” ํ•จ์ˆ˜ ๋™์ž‘๊ณผ ๊ด€๋ จํ•˜์—ฌ ๋™์ž‘ ์ˆœ์„œ๋ฅผ ์ •ํ•ด์ค„๋•Œ ๋งค์šฐ๋งค์šฐ ์œ ์šฉํ•˜๋‹ค.

์˜ˆ์‹œ ์ฝ”๋“œ

// ํ•จ์ˆ˜ ์™ธ๋ถ€์— ํด๋กœ์ €๋ฅผ ์ €์žฅํ•˜๋Š” ์˜ˆ์‹œ

// ํด๋กœ์ €๋ฅผ ์ €์žฅํ•˜๋Š” ๋ฐฐ์—ด
var completionHandlers: [() -> Void] = []

/*
ํ•จ์ˆ˜ ๋ฐ–์— ์žˆ๋Š” completionHandlers ๋ฐฐ์—ด์— ํ•ด๋‹น ํด๋กœ์ €๋ฅผ ์ €์žฅ.
์ฆ‰, ํด๋กœ์ €๊ฐ€ ํ•จ์ˆ˜์—์„œ ๋น ์ ธ๋‚˜๊ฐ.
์ด๋ ‡๊ฒŒ ํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœํ•˜๋Š” ๋„์ค‘์— ํ•ด๋‹น ํ•จ์ˆ˜ ์™ธ๋ถ€์— ํด๋กœ์ €๋ฅผ ์ €์žฅํ•˜๊ธฐ ์œ„ํ•ด์„œ๋Š”
Escaping Closure์ด์–ด์•ผ ํ•จ.
*/

func withEscaping(completion: @escaping () -> Void) {
    completionHandlers.append(completion)
}

func withoutEscaping(completion: () -> Void) {
    completion()
}

class MyClass {
    var x = 10
    func callFunc() {
        withEscaping { self.x = 100 }
        // ๋งŒ์•ฝ ์—ฌ๊ธฐ์„œ selfํ‚ค์›Œ๋“œ๋ฅผ ์•ˆ์“ฐ๋ฉด ์•„๋ž˜์˜ ์—๋Ÿฌ๊ฐ€ ๋ฐœ์ƒํ•œ๋‹ค.
        // Reference to property 'x' in closure requires explicit 'self.' to make capture semantics explicit. Insert self.
        // ํด๋กœ์ €์—์„œ ์†์„ฑ์— ์ ‘๊ทผํ• ๋•Œ๋Š” self.ํ‚ค์›Œ๋“œ ๋ช…์‹œํ•ด์•ผํ•จ
        withoutEscaping { x = 200 }
        // ๊ทผ๋ฐ ์ด๊ฒƒ๋„ ํด๋กœ์ € ์•„๋‹Œ๊ฐ€?
    }
}
let mc = MyClass()
mc.callFunc() // x=200์ฝ”๋“œ๊ฐ€ withoutEscaping์˜ ์ธ์ž๋กœ ๋“ค์–ด๊ฐ€์„œ ๊ทธ๋ƒฅ ์‹คํ–‰๋˜์–ด๋ฒ„๋ฆผ
print(mc.x) // callFunc()๋ฅผ ํ˜ธ์ถœํ•˜๋ฉด์„œ ๋ณ€๊ฒฝ๋œ x๊ฐ’ ์ถœ๋ ฅ

completionHandlers.first?() // array์— ์ €์žฅ๋œ ์ฒซ๋ฒˆ์งธ ํด๋กœ์ € ์‹คํ–‰
print(mc.x) // callFunc()๋ฅผ ํ˜ธ์ถœํ•˜๋ฉด์„œ withEscaping์ด ์‹คํ–‰๋˜์–ด์„œ ํด๋กœ์ €๊ฐ€ ์ €์žฅ๋˜์—ˆ๊ณ ,
            // array์— ์ €์žฅ๋œ ์ฒซ๋ฒˆ์งธ ํด๋กœ์ €๊ฐ€ ์‹คํ–‰๋˜๋ฉด์„œ ๋ณ€๊ฒฝ๋œ x=100 ์ถœ๋ ฅ

// ๊ฒฐ๊ณผ
// 200
// 100

TIL_20180611 ~ 20180616

|

2018.06.11

  • Remote notification / Local notification
    • Local
    • ์•Œ๋žŒ - ํŠน์ • ์‹œ๊ฐ„์— noti, ์œ„์น˜ - ํŠน์ • ์œ„์น˜์—์„œ noti
    • Remote
    • token์„ ๊ฐ€์ง€๊ณ  Push server์—์„œ ์ •๋ณด๋ฅผ ๋ฐ›์•„์˜ค๋Š”๋ฐ, app์˜ ์‹คํ–‰์œ ๋ฌด์™€ ๊ด€๋ จ์ด ์—†๋‹ค.
    • ios๋Š”(๋‹จ๋ง๊ธฐ) ํ‘ธ์‹œ์„œ๋ฒ„์—์„œ ์ •๋ณด๋ฅผ ๊ฐ€์ ธ์˜ค๊ธฐ์œ„ํ•ด์„œ(request๋ฅผ ํ•˜๊ธฐ์œ„ํ•ด) ์„œ๋ฒ„์— session์„ ๋ณด๋ƒ„
    • ํ‘ธ์‹œ์„œ๋ฒ„์—์„œ๋Š” ๋‹จ๋ง๊ธฐ์—์„œ token๊ฐ’์œผ๋กœ ํŒ๋‹จํ•˜์—ฌ ํ‘ธ์‹œ๋ฅผ ๋ณด๋ƒ„

2018.06.12

  • @escaping, completion handler, ๋น„๋™๊ธฐ, main thread
    • ํ•จ์ˆ˜์˜ ํŒŒ๋ผ๋ฏธํ„ฐ์— escaping์„ ์ค„๋•Œ๋Š” ํ•จ์ˆ˜ ๋‚ด๋ถ€์˜ ํด๋กœ์ €์—์„œ ๋น„๋™๊ธฐ ์ฒ˜๋ฆฌ์‹œ ๊ทธ ํด๋กœ์ € ์•ˆ์˜ ๋กœ์ง์ด ๋๋‚˜๊ณ  escaping์œผ๋กœ ์ค€ ๋กœ์ง์„ ์ฒ˜๋ฆฌํ•˜๋ผ๋Š” ๋œป์ด๋‹ค. (์ˆœ์„œ๊ฐ€ ๊ทธ๋ ‡๊ฒŒ ์ •์˜๋จ)
    • ์ด ๋•Œ๋Š” ํ•ด๋‹นํ•˜๋Š” ํด๋กœ์ € ๋‚ด์˜ scope์— escaping ํ•จ์ˆ˜๊ฐ€ ์œ„์น˜ํ•ด์•ผํ•จ(์ด๋•Œ๋Š” ๋ณดํ†ต ํด๋กœ์ € ๋‚ด๋ถ€์˜ ๊ฐ€์žฅ ๋งˆ์ง€๋ง‰ ์ค„์ด ๋˜๊ฒ ์ง€?)
    • Escaping Closure๋ฅผ ํ™œ์šฉํ•˜๋ฉด ํ†ตํ•ด์„œ ํ•จ์ˆ˜ ์‚ฌ์ด์— ์‹คํ–‰ ์ˆœ์„œ๋ฅผ ์ •ํ•  ์ˆ˜ ์žˆ๋‹ค.

2018.06.13

  • ์ง€๋ฐฉ์„ ๊ฑฐ ํˆฌํ‘œํ•˜๊ณ 
  • ๊ฐ„๋งŒ์— ๋ฐ€๋ ธ๋˜ ๋ธ”๋กœ๊ทธ ํฌ์ŠคํŒ… ์—…๋กœ๋“œ!

2018.06.14

  • ์ฃผ์†Œ๋ก ์•ฑ ๋งˆ์ง€๋ง‰ ๋‹จ๊ณ„ ์„ค๊ณ„
    • ์ฃผ์†Œ๋ก ๊ฐ์ฒด์˜ ์ด๋ฆ„๋Œ€๋กœ ์ •๋ ฌํ•˜๋Š” ๊ธฐ๋Šฅ ๊ตฌํ˜„ํ•˜๊ธฐ
    • ํ•œ๊ธ€ ์œ ๋‹ˆ์ฝ”๋“œ๋Œ€๋กœ ์ •๋ ฌ
    • [์ดˆ์„ฑ:[์—ฐ๋ฝ์ฒ˜]] ํ˜•ํƒœ์˜ ์ฝœ๋ ‰์…˜ ๋งŒ๋“ค๊ธฐ
    • ํ•œ๊ธ€์ดˆ์„ฑ(ใ„ฑ~ใ…Ž), ์˜์–ด ์ดˆ์„ฑ(A~Z)์ด ๋ชจ๋‘ ๋“ค์–ด์žˆ๋Š” ๋ฐฐ์—ด ๋งŒ๋“ค์–ด์„œ ๋”•์…”๋„ˆ๋ฆฌ์˜ ํ‚ค๊ฐ’์œผ๋กœ ํ™œ์šฉ

2018.06.15

  • ์ฃผ์†Œ๋ก ์•ฑ ๋งˆ์ง€๋ง‰ ๋‹จ๊ณ„ ์ด์Šˆ ํ•ด๊ฒฐ
    • [AddressData]๋ฅผ ์ด๋ฆ„ ์ดˆ์„ฑ์ด ๊ฐ™์€ ๊ฒƒ ๋ผ๋ฆฌ ๋ชจ์•„์„œ ๋”•์…”๋„ˆ๋ฆฌ[์ดˆ์„ฑ:[์—ฐ๋ฝ์ฒ˜]]๋กœ ๋งŒ๋“ค๊ธฐ
    • reduceํ™œ์šฉ: reduce๋ฅผ์จ์„œ ํ•  ์ˆ˜ ์žˆ์ง€ ์•Š์„๊นŒ ํ•ด์„œ reduce ์‚ฌ์šฉ๋ฒ• ๊ณต๋ถ€โ€ฆ ์•„์ง๋„ ์–ด๋ ต๋‹ค ใ… ใ… 
    • reduce์— ์กฐ๊ฑด ๋„ฃ์–ด์„œ ํ•„ํ„ฐ๋ง ํ•˜๋Š” ๋ฒ•!

2018.06.16

  • UILabel์— bold์Šคํƒ€์ผ์œผ ํฐํŠธ๋ฅผ ์ ์šฉํ•˜๊ณ ์‹ถ์–ด์„œ ์ฐพ์•„๋ณด๋‹ค๊ฐ€ preferredFont(forTextStyle:)์•Œ๊ฒŒ๋จ.
    • ์‚ฌ์ด์ฆˆ๋ฅผ ๊ฐœ๋ฐœ์ž๊ฐ€ ์ƒ์ˆ˜๋กœ ์ง€์ •ํ•˜๋Š”๊ฒŒ ์•„๋‹ˆ๋ผ ์‚ฌ์šฉ์ž๊ฐ€ ์ง€์ •ํ•œ ํฐํŠธ์Šคํƒ€์ผ์— ๋งž์ถฐ์„œ ์ ์šฉ๋จ.
    • Returns an instance of the system font for the specified text style and scaled appropriately for the userโ€™s selected content size category.
    • UIFont.TextStyle ์˜ต์…˜์œผ๋กœ ๋ญ”๊ฐ€๊ฐ€ ์ ์šฉ๋œ๋‹ค.
    • label.font = UIFont.preferredFont(forTextStyle: .headline) ์ด๋Ÿฐ์‹์œผ๋กœ ์จ๋ณด๋ฉด๋ ๋“ฏ
    • ์ฐธ๊ณ 1, ์ฐธ๊ณ 2

UITableView API๋ฌธ์„œ ๋ฒˆ์—ญ, ์ •๋ฆฌ(2) - UITableViewController, Delegate, DataSource, IndexPath

|

์›๋ฌธ์ž๋ฃŒ - Table View Programming Guide for iOS ๋ฅผ ๋ฒˆ์—ญ, ์ •๋ฆฌํ–ˆ์Šต๋‹ˆ๋‹ค. ์ž์Šต์šฉ์œผ๋กœ ์ •๋ฆฌํ•œ ์ž๋ฃŒ์ด๋‹ˆ ๊ฐ€๋ณ๊ฒŒ ์ฐธ๊ณ ๋งŒํ•ด์„œ ๋ณด์‹œ๋ฉด ๋  ๊ฒƒ ๊ฐ™๊ณ , ํ‹€๋ฆฐ ์ ์€ ๋Œ“๊ธ€๋กœ ์•Œ๋ ค์ฃผ์‹œ๋ฉด ๊ฐ์‚ฌํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค! :)

ํ…Œ์ด๋ธ”๋ทฐ API

Table View - ํ…Œ์ด๋ธ”๋ทฐ

  • TableView๋Š” UITableViewClass์˜ ์ธ์Šคํ„ด์Šค์ด๋‹ค.
  • UITableViewClass์˜ ๋ฉ”์†Œ๋“œ๋ฅผ ํ†ตํ•ด ํ…Œ์ด๋ธ”๋ทฐ์˜ ์™ธ๊ด€(appearance)์„ ์„ค์ •ํ•  ์ˆ˜ ์žˆ๋‹ค.
    • (for example, specifying the default height of rows or providing a subview used as the header for the table)
  • ๋˜ ๋‹ค๋ฅธ ๋ฉ”์†Œ๋“œ๋กœ๋Š” ํ˜„์žฌ ์„ ํƒ๋œ ์—ด(row), ํŠน์ •ํ•œ ์—ด์ด๋‚˜ ์…€์— ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ๋‹ค.
  • ๋ฉ”์†Œ๋“œ๋กœ๋Š” ์„ ํƒ๋œ ์…€์„ ๊ด€๋ฆฌํ•˜๊ณ , ๋ทฐ๋ฅผ ์Šคํฌ๋กคํ•˜๊ฑฐ๋‚˜, ์—ด์ด๋‚˜ ์„น์…˜์„ ์ถ”๊ฐ€ํ•˜๊ฑฐ๋‚˜ ์ œ๊ฑฐํ•  ์ˆ˜ ์žˆ๋‹ค.
  • UITableView๋Š” UIScrollView๋ฅผ ์ƒ์†๋ฐ›์•„ ์Šคํฌ๋กค๋ง์„ ๊ตฌํ˜„ํ•˜๋Š”๋ฐ, ํ…Œ์ด๋ธ”๋ทฐ๋Š” ํŠน๋ณ„ํ•˜๊ฒŒ ์ˆ˜์ง์  ์Šคํฌ๋กค๋ง(vertical scrolling)๋งŒ ํ—ˆ์šฉ๋œ๋‹ค.

Table View Controller - ํ…Œ์ด๋ธ”๋ทฐ ์ปจํŠธ๋กค๋Ÿฌ

The UITableViewController class manages a table view and adds support for many standard table

  • UITableViewController ํด๋ž˜์Šค๋Š” ํ…Œ์ด๋ธ”๋ทฐ๋ฅผ ๊ด€๋ฆฌํ•˜๋Š” ๋™์ž‘์„ ํ•œ๋‹ค. ์„ ํƒ ๊ด€๋ฆฌ(selection management), ์—ด ์ˆ˜์ •, ํ…Œ์ด๋ธ” ์„ค์ • ๋“ฑ์˜ ๋™์ž‘๋“ค๊ณผ ๊ด€๋ จํ•ด์„œ ํ…Œ์ด๋ธ”๋ทฐ๋ฅผ ์„œํฌํŠธํ•œ๋‹ค.
  • ํ…Œ์ด๋ธ”๋ทฐ์ปจํŠธ๋กค๋Ÿฌ๋ฅผ ์ง์ ‘์ ์œผ๋กœ ์‚ฌ์šฉํ•˜์ง€๋Š” ์•Š๊ณ , UITableViewController๋ฅผ ์ƒ์†๋ฐ›์•„์„œ ์ปค์Šคํ…€ํด๋ž˜์Šค๋ฅผ ๊ตฌํ˜„ํ•œ๋‹ค.

Data Source and Delegate - ๋ฐ์ดํ„ฐ์†Œ์Šค์™€ ๋ธ๋ฆฌ๊ฒŒ์ดํŠธ

  • ํ…Œ์ด๋ธ”๋ทฐ๋ฅผ ์‚ฌ์šฉํ•˜๊ธฐ์œ„ํ•ด์„œ๋Š” Data Source and Delegate๋ฅผ ๋ฐ˜๋“œ์‹œ ๊ตฌํ˜„ํ•ด์•ผํ•œ๋‹ค.
  • MVCํŒจํ„ด์— ๋”ฐ๋ผ, data source๋Š” ์•ฑ์˜ model๊ณผ table view์˜ ์ค‘๊ฐ„์ž ์—ญํ• ์„ ํ•œ๋‹ค.
  • Delegate๋Š” ํ…Œ์ด๋ธ”๋ทฐ์˜ ๋™์ž‘๊ณผ ์ถœํ˜„(appearance)์„ ๋‹ด๋‹นํ•œ๋‹ค. view๊ฐ€ ๋ณ€๊ฒฝ๋˜๋Š” ์‚ฌํ•ญ์„ ๋ธ๋ฆฌ๊ฒŒ์ดํŠธ๊ฐ€ ๋‹ด๋‹นํ•˜๊ณ , ๋ทฐ๋Š” ๊ทธ ๋ธ๋ฆฌ๊ฒŒ์ดํŠธ์— ์˜์กดํ•˜์—ฌ ๋ทฐ๋ฅผ ์—…๋ฐ์ดํŠธํ•œ๋‹ค.
  • Data source์™€ Delegate๋Š” ๊ฐ™์€ ๊ฐ์ฒด์ผ์ˆ˜ ์žˆ๊ณ ,(ํ•œ ํด๋ž˜์Šค์—์„œ ๊ตฌํ˜„ํ•  ์ˆ˜๋„ ์žˆ๊ณ ) ๊ทธ ํด๋ž˜์Šค๋Š” UITableViewController๋ฅผ ์ƒ์†๋ฐ›๋Š”๋‹ค.
  • Data source๋Š” UITableViewDataSourceํ”„๋กœํ† ์ฝœ์„ ๋”ฐ๋ฅธ๋‹ค.
  • Delegate๋Š” UITableViewDelegateํ”„๋กœํ† ์ฝœ์„ ๋”ฐ๋ฅด๋ฉฐ, required๋ฉ”์†Œ๋“œ๋Š” ์—†๊ณ  optional๋ฉ”์†Œ๋“œ๋ฅผ ํ•„์š”์— ๋”ฐ๋ผ ๊ตฌํ˜„ํ•˜๋ฉด ๋œ๋‹ค.

IndexPath Class

  • Swift์—์„œ๋Š” NSIndexPath ๋Œ€์‹  IndexPath๋ฅผ ์‚ฌ์šฉ.
  • ํ…Œ์ด๋ธ”๋ทฐ์˜ ๋ฉ”์†Œ๋“œ๋“ค์€ Indexpath๋ฅผ ํŒŒ๋ผ๋ฏธํ„ฐ๋‚˜ ๋ฆฌํ„ด๋ฐธ๋ฅ˜๋กœ ์‚ฌ์šฉํ•œ๋‹ค.
  • ์…€์„ index path๋ฅผ ์ด์šฉํ•˜์—ฌ ์ •๋ ฌํ• ๋•Œ ์‚ฌ์šฉํ•œ๋‹ค.
  • index path๋Š” ์ค‘์ฒฉ๋œ ์–ด๋ ˆ์ด(์ด์ค‘๋ฐฐ์—ด, nested array)์˜ ํŠน์ •ํ•œ ๋…ธ๋“œ๋กœ ๊ฐ€๋Š” ๊ฒฝ๋กœ๋ฅผ ํ™•์ธํ•˜๊ณ (identify), foundationํ”„๋ ˆ์ž„์›Œํฌ ๋‚ด์—์„œ๋Š” NSIndexPathํด๋ž˜์Šค์ด๋‹ค.
  • IndexPath์˜ section๊ณผ row: ํ–‰๋ ฌํ˜•ํƒœ๋กœ ์ดํ•ดํ•˜๊ณ  ๋ณด๋ฉด ์‰ฌ์›€
    • section: ์…€์ด ์œ„์น˜ํ•ด์•ผํ•  ์„น์…˜. (The section in the table that the cell is going to be placed into.)
    • row: ์„น์…˜ ๋‚ด์—์„œ์˜ ์…€์˜ ์œ„์น˜(์ˆœ์„œ) (The row (in the section) that the cell will be placed into.)
    • ์ฐธ๊ณ ๋งํฌ - Stackoverflow

Table View Cells - ํ…Œ์ด๋ธ”๋ทฐ ์…€

  • ์…€์€ UITableViewCellํด๋ž˜์Šค๋ฅผ ์ƒ์†๋ฐ›๋Š”๋‹ค.
  • UITableViewCellํด๋ž˜์Šค๋Š” ์…€ ์„ ํƒ๊ณผ ํŽธ์ง‘, ์•…์„ธ์„œ๋ฆฌ ๋ทฐ ๊ด€๋ฆฌ, ์…€ ์„ค์ •(configuration) ๋ฉ”์†Œ๋“œ๋ฅผ ์ œ๊ณตํ•œ๋‹ค.
  • predefined style์„ ์ด์šฉํ•ด์„œ ๋ฏธ๋ฆฌ ์ •์˜๋œ ์Šคํƒ€์ผ๋กœ ์…€์„ ์„ค์ • ํ•  ์ˆ˜ ์žˆ์Œ
  • ์ด๋ฏธ ๊ธฐ์กด์— ์žˆ๋Š” ์…€(โ€œoff-the-shelfโ€ cell object)์— ์ปค์Šคํ…€์„œ๋ธŒ๋ทฐ๋ฅผ ์˜ฌ๋ ค์„œ ๊ตฌํ˜„ํ•  ์ˆ˜๋„ ์žˆ๋‹ค.
  • UITableViewCellํด๋ž˜์Šค๋ฅผ ์ƒ์†๋ฐ›์€ ์ปค์Šคํ…€๋ทฐ๋ฅผ ๋งŒ๋“ค์–ด์„œ ์…€์˜ ์™ธ๊ด€(appearance)์ด๋‚˜ ๋™์ž‘์„ ๋งŒ๋“ค ์ˆ˜๋„ ์žˆ๋‹ค.
  • ํ…Œ์ด๋ธ”๋ทฐ ์…€์— ๋Œ€ํ•œ ๋” ์ž์„ธํ•œ ๋‚ด์šฉ - A Closer Look at Table View Cells

UITableView API๋ฌธ์„œ ๋ฒˆ์—ญ, ์ •๋ฆฌ(1) - TableViewStyles ๊ธฐ๋ณธ

|

์›๋ฌธ์ž๋ฃŒ - Table View Programming Guide for iOS ๋ฅผ ๋ฒˆ์—ญ, ์ •๋ฆฌํ–ˆ์Šต๋‹ˆ๋‹ค. ์ž์Šต์šฉ์œผ๋กœ ์ •๋ฆฌํ•œ ์ž๋ฃŒ์ด๋‹ˆ ๊ฐ€๋ณ๊ฒŒ ์ฐธ๊ณ ๋งŒํ•ด์„œ ๋ณด์‹œ๋ฉด ๋  ๊ฒƒ ๊ฐ™๊ณ , ํ‹€๋ฆฐ ์ ์€ ๋Œ“๊ธ€๋กœ ์•Œ๋ ค์ฃผ์‹œ๋ฉด ๊ฐ์‚ฌํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค! :)

ํ…Œ์ด๋ธ”๋ทฐ์™€ ์…€ ์Šคํƒ€์ผ ๊ธฐ๋ณธ

ํ…Œ์ด๋ธ”๋ทฐ ์ƒ์„ฑ

  • ์Šคํ† ๋ฆฌ๋ณด๋“œ์—์„œ UITableViewController ์ถ”๊ฐ€ํ•˜์—ฌ ์ด์šฉ
  • ์ฝ”๋“œ๋กœ๋Š” ์ปค์Šคํ…€ ํด๋ž˜์Šค์— UITableViewDataSource์™€ UITableViewDelegate ํ”„๋กœํ† ์ฝœ ๊ตฌํ˜„ํ•˜์—ฌ ํ…Œ์ด๋ธ”๋ทฐ์ปจํŠธ๋กค๋Ÿฌ๋กœ ์ด์šฉ
  • ์ปค์Šคํ…€ ํด๋ž˜์Šค๋ฅผ ๋”ฐ๋กœ ํ”„๋กœํ† ์ฝœ์„ ๊ตฌํ˜„ํ•˜์ง€์•Š๊ณ  ํ”„๋กœ์ ํŠธ ๋‚ด์— ํŒŒ์ผ ์ถ”๊ฐ€์‹œ Cocoa Touch Class๋ฅผ ์„ ํƒํ•˜์—ฌ UITableViewController๋ฅผ ์ถ”๊ฐ€ํ•˜๋Š” ๋ฐฉ๋ฒ•๋„ ์žˆ๋‹ค.
    • ์ฐธ๊ณ : class UITableViewController : UIViewController, UITableViewDelegate, UITableViewDataSource

Static Cells / Dynamic Prototypes

ํ…Œ์ด๋ธ”๋ทฐ์˜ ํŠน์„ฑ์€ ๋™์  ํ”„๋กœํ† ํƒ€์ž… / ์ •์  ์…€ ์ด ์žˆ๋‹ค. ์ƒˆ๋กœ์šด ํ…Œ์ด๋ธ”๋ทฐ๋ฅผ ์ƒ์„ฑํ•  ๋•Œ ๊ธฐ๋ณธ ์„ค์ • ๊ฐ’์€ ๋™์  ํ”„๋กœํ† ํƒ€์ž…์ด๋‹ค.

  • Dynamic Prototypes (๋™์  ํ”„๋กœํ† ํƒ€์ž…)
    • ํ–‰(์…€)์˜ ๊ฐœ์ˆ˜๊ฐ€ ๊ณ ์ •๋˜์–ด์žˆ์ง€ ์•Š๋Š” ํ…Œ์ด๋ธ”๋ทฐ์— ์‚ฌ์šฉ.
    • ์•ฑ์ด ์‹คํ–‰๋˜๋Š” ๋„์ค‘ ์ƒํƒœ๊ฐ€ ๋ฐ”๋€Œ๋ฉด (ex. ์‚ฌ์šฉ์ž๊ฐ€ ๋ชฉ๋ก์—์„œ ํ•ญ๋ชฉ์„ ์‚ญ์ œํ•˜๊ฑฐ๋‚˜ ์ถ”๊ฐ€ํ•˜๋Š” ํ–‰๋™์„ ํ• ๋•Œ) ์…€์˜ ๊ฐœ์ˆ˜๊ฐ€ ์ƒํ™ฉ์— ๋”ฐ๋ผ ๋ณ€๊ฒฝ๋œ๋‹ค.
    • UITableViewDataSource ์ธ์Šคํ„ด์Šค์— ์˜ํ•ด ์ฝ˜ํ…์ธ ๋ฅผ ๊ด€๋ฆฌ
    • ์…€ ํ•˜๋‚˜๋ฅผ ๋””์ž์ธํ•ด ์ด๋ฅผ ๋‹ค๋ฅธ ์…€์˜ ํ…œํ”Œ๋ฆฟ์œผ๋กœ ์‚ฌ์šฉ
  • Static Cells (์ •์  ์…€)
    • ๋ง๊ทธ๋Œ€๋กœ ์ •์ . ๊ณ ์ •๋œ ๋ ˆ์ด์•„์›ƒ๊ณผ ํ–‰(์…€)์˜ ์ˆ˜๋ฅผ๋ฅผ ๊ฐ€์ง€๋Š” ํ…Œ์ด๋ธ”๋ทฐ์— ์‚ฌ์šฉํ•œ๋‹ค.
    • ํ…Œ์ด๋ธ”๋ทฐ๋ฅผ ๋งŒ๋“œ๋Š” ์‹œ์ ์— ํ…Œ์ด๋ธ”์˜ ํ˜•ํƒœ์™€ ์…€์˜ ์ˆ˜๊ฐ€ ์ •ํ•ด์ ธ์žˆ๋Š” ๊ฒฝ์šฐ ์‚ฌ์šฉํ•œ๋‹ค. ์•ฑ์ด ์‹คํ–‰๋˜๋ฉด์„œ ์ƒํƒœ๊ฐ€ ๋ฐ”๋€๋‹ค๊ณ ํ•ด์„œ ํ…Œ์ด๋ธ”๋ทฐ์˜ ์…€์˜ ์ˆ˜๊ฐ€ ๋ณ€ํ™”๋˜๊ฑฐ๋‚˜ ํ•˜์ง€ ์•Š๋Š”๋‹ค.

ํ…Œ์ด๋ธ”๋ทฐ ์Šคํƒ€์ผ

  • plain
    • ํ•˜๋‚˜ ์ด์ƒ์˜ ์„น์…˜์„ ๊ฐ€์งˆ ์ˆ˜ ์žˆ์Œ
    • ์„น์…˜ ๋˜ํ•œ ํ•˜๋‚˜ ์ด์ƒ์˜ ์—ด(row)์„ ๊ฐ€์งˆ ์ˆ˜ ์žˆ๊ณ , ๊ฐ ์„น์…˜์€ header์™€ footer๋ฅผ ๊ฐ€์งˆ ์ˆ˜ ์žˆ์Œ
    • (ํ—ค๋”์™€ ์„น์…˜์— ์ด๋ฏธ์ง€๋ฅผ ๋„ฃ๊ณ ์‹ถ์œผ๋ฉด ์ปค์Šคํ…€๋ทฐ๋ฅผ ๊ฐ€์ง€๊ฒŒ ํ•  ์ˆ˜๋„ ์žˆ๋‹ค.)
    • indexed list : ์ฃผ์†Œ๋ก์ฒ˜๋Ÿผ ์ธ๋ฑ์Šค๊ฐ€ ์„น์…˜์˜ ํ—ค๋” ํƒ€์ดํ‹€์ด๊ณ  ์˜ค๋ฅธ์ชฝ ์Šคํฌ๋กค์— ์ธ๋ฑ์Šค๊ฐ€ ํ‘œ์‹œ๋จ
    • selection list
  • grouped
    • ์„น์…˜์ด ๊ทธ๋ฃนํ•‘๋˜์–ด์žˆ๋Š” ํ˜•ํƒœ๋กœ, ๊ฐ๊ฐ์˜ ์„น์…˜์ด ์‹œ๊ฐ์ ์œผ๋กœ ๊ตฌ๋ถ„๋˜์–ด ๋ณด์ž„
    • ๊ตฌ๋ถ„๋œ ์„น์…˜์€ ํšŒ์ƒ‰์œผ๋กœ ๋ฐฐ๊ฒฝ์ด ์ฒ˜๋ฆฌ๋˜๊ณ  ๊ทธ๋ฃน ๋‚ด์˜ ์…€๋“ค์€ ํฐ์ƒ‰ ๋ฐฐ๊ฒฝ

์…€ ์Šคํƒ€์ผ

  • ํ…Œ์ด๋ธ”์—์„œ ์—ด(row)ํ˜•ํƒœ๋กœ ๊ทธ๋ ค์ง„ ์…€. ์…€ ์Šคํƒ€์ผ์€ ๋„ค๊ฐ€์ง€๊ฐ€ ์ œ๊ณต๋œ๋‹ค.
  • UITableViewCellํด๋ž˜์Šค๋ฅผ ์ด์šฉํ•˜์—ฌ ์…€์˜ content์™€ background๋ฅผ ๊ด€๋ฆฌํ•œ๋‹ค.
  • ๊ฐ€์žฅ ๊ฐ„๋‹จํ•œ ๋ฐฉ๋ฒ•์€ predefined styles์„ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์ด๋‹ค.
    • UITableViewCellStyleDefault: ์™ผ์ชฝ์— ์ด๋ฏธ์ง€, ์ด๋ฏธ์ง€ ์˜†์€ ํƒ€์ดํ‹€ ํ•œ๊ฐœ ์žˆ๋Š” ํ˜•ํƒœ
    • UITableViewCellStyleSubtitle: default์Šคํƒ€์ผ๊ณผ ๋™์ผํ•˜์ง€๋งŒ ํƒ€์ดํ‹€ ์•„๋ž˜์— subtitle(์ƒ์„ธ ์„ค๋ช…. ์ž‘์€ ๊ธ€์”จ)์ด ์žˆ๋Š” ํ˜•ํƒœ
    • UITableViewCellStyleValue1: ์ด๋ฏธ์ง€๊ฐ€ ์—†๊ณ  ์…€ ์™ผ์ชฝ์— ํƒ€์ดํ‹€์ด ์žˆ๊ณ  ์˜ค๋ฅธ์ชฝ์— subtitle์ด ์žˆ๋Š” ํ˜•ํƒœ. ์ด๋ฏธ์ง€๋ฅผ ๋„ฃ์„ ์ˆ˜ ์—†๋‹ค.
    • UITableViewCellStyleValue2: ๋งˆ์ฐฌ๊ฐ€์ง€๋กœ ์ด๋ฏธ์ง€๋ฅผ ๋„ฃ์„ ์ˆ˜ ์—†์œผ๋ฉฐ, ์…€ ์™ผ์ชฝ์— subtitle์ด ์žˆ๊ณ  ์˜ค๋ฅธ์ชฝ์—๋Š” description์ด ์žˆ๋Š” ํ˜•ํƒœ.
  • ํ…Œ์ด๋ธ” ๋ทฐ ์…€์— ๋Œ€ํ•œ ์ƒ์„ธ์„ค๋ช… - Table View Programming Guide - A Closer Look at Table View Cells

์•…์„ธ์„œ๋ฆฌ ๋ทฐ

accessory-type constants๋กœ ์ œ๊ณต๋˜๋Š” ์„ธ ๊ฐœ์˜ ํ‘œ์ค€ ๋ทฐ๊ฐ€ ์žˆ๋‹ค.