ํ‹ฐ์Šคํ† ๋ฆฌ ๋ทฐ

๋ฐ˜์‘ํ˜•

ios-og


๐ŸŽค Swift ํ”„๋กœ๊ทธ๋ž˜๋ฐ ์–ธ์–ด - Part 1


๐Ÿ•น Concentration Game UI ๋ณ€๊ฒฝ


  • 2๊ฐ•๊นŒ์ง€ ์™„์„ฑํ•œ ๊ฒŒ์ž„์˜ UI๋Š” ๊ดœ์ฐฎ์€ ๊ฒƒ ์ฒ˜๋Ÿผ ๋ณด์ž…๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ ํ™”๋ฉด์„ ํšŒ์ „ํ•˜๊ฑฐ๋‚˜ ๋‹ค๋ฅธ ๊ธฐ๊ธฐ์—์„œ ์ž‘๋™์‹œํ‚ค๋ฉด ํ™”๋ฉด์ด ์ด์ƒํ•˜๊ฒŒ ๋‚˜์˜ค๋Š” ๊ฒƒ์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

โ€‹ ์œ„์˜ ๊ทธ๋ฆผ์ฒ˜๋Ÿผ ์™ผ์ชฝ ์œ„๋ฅผ ๊ธฐ์ค€์œผ๋กœ UI๊ฐ€ ๋ฐฐ์น˜๋˜๋Š” ๊ฒƒ์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด๊ฒƒ์„ ํ•ด๊ฒฐํ•˜๊ธฐ ์œ„ํ•ด์„œ Stack View๋ฅผ ํ™œ์šฉํ•ด ๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

  • ๋จผ์ € ๋ฌถ์–ด์ฃผ๊ณ  ์‹ถ์€ ์š”์†Œ๋“ค์„ ๋ธ”๋ก์ฒ˜๋ฆฌํ•œ ํ›„ ์•„๋ž˜ ๊ทธ๋ฆผ์ฒ˜๋Ÿผ ๋ฒ„ํŠผ์„ ํด๋ฆญํ•ฉ๋‹ˆ๋‹ค.


    ์ด์ œ 4๊ฐœ์˜ ๋ฒ„ํŠผ์ด ํ•˜๋‚˜์˜ View์— ๋‹ด๊ฒผ์Šต๋‹ˆ๋‹ค. Spacing์„ standard๋กœ ํ•ด์ฃผ๊ณ  fill equally ์˜ต์…˜์„ ์ค€ ํ›„ ์•„๋ž˜ ๋‘์ค„์—๋„ ๊ฐ™์€ ์ž‘์—…์„ ์ง„ํ–‰ํ•ฉ๋‹ˆ๋‹ค.

    ๊ทธ ๊ฒฐ๊ณผ๋กœ ๊ฐ€๋กœ๋กœ 3์ค„์˜ Stack View๊ฐ€ ์ƒ๊ฒผ์Šต๋‹ˆ๋‹ค. ์ด Stack View๋ฅผ ๋ฌถ์–ด ํ•˜๋‚˜์˜ Stack View์— ๋‹ค์‹œ ๋‹ด๊ฒ ์Šต๋‹ˆ๋‹ค.

  • ์ „์ฒด๋ฅผ ๋‹ด์€ Stack View๋ฅผ ์˜ฌ๋ฐ”๋ฅธ ์œ„์น˜์— ๊ณ ์ •์‹œ์ผœ๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค. View์— ์กด์žฌํ•˜๋Š” ๋ฒ„ํŠผ์—์„œ Controller์— target์„ ๋งŒ๋“ค์–ด ์ค„ ๋•Œ ํ–ˆ๋˜ ๊ฒƒ์ฒ˜๋Ÿผ Ctrl์„ ๋ˆ„๋ฅธ ์ƒํƒœ์—์„œ ๋“œ๋ž˜๊ทธ๋ฅผ ํ•˜๋ฉด View์—์„œ๋„ ๊ด€๊ณ„๋ฅผ ํ˜•์„ฑํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

    Top Sace to Safe Area ์˜ต์…˜์„ ์„ ํƒํ•ด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.


    ๋ณด์กฐ์„ ์ด ๋” ์ž˜๋ณด์ด๊ฒŒ ํ•˜๊ธฐ ์œ„ํ•ด์„œ ๋ฐฐ๊ฒฝ์„ ํ•˜์–€์ƒ‰์œผ๋กœ ๋ณ€๊ฒฝํ–ˆ์Šต๋‹ˆ๋‹ค. ์œ„์˜ ๋Œ€๋ฌธ์ž I ๊ฐ™์€ ๋ชจ์–‘์˜ ๊ทœ์•ฝ์ด ์ƒ์„ฑ๋˜์—ˆ์Šต๋‹ˆ๋‹ค. ์ด์ œ ๋‹ค๋ฅธ ๋ฐฉํ–ฅ๋„ ์ด๋Ÿฌํ•œ ์˜ต์…˜์„ ์ถ”๊ฐ€ํ•ด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.


    ์ขŒ, ์šฐ, ์ƒ์— ๊ฐ™์€ ๊ทœ์•ฝ์„ ์ฃผ๊ณ  constraint๋กœ ์ขŒ ์šฐ์— ๊ฐ™์€ ์ˆซ์ž๋ฅผ ์ž…๋ ฅํ•œ ๊ฒฐ๊ณผ ์œ„์˜ ๊ทธ๋ฆผ์ฒ˜๋Ÿผ ์ž๋ฆฌ๋ฅผ ์žก์•˜์Šต๋‹ˆ๋‹ค. ์ด์ œ ์•„๋ž˜ ๋ฐฉํ–ฅ์ด ๋ฌธ์ œ์ธ๋ฐ Flips๊ฐ€ ๋ณด์ด๋Š” label์ด ์žˆ์œผ๋ฏ€๋กœ ๋งˆ์ฐฌ๊ฐ€์ง€ ๋ฐฉ๋ฒ•์œผ๋กœ Flips label์— ๋ฐ”๋‹ฅ๊ณผ contraint๋ฅผ ์ฃผ๊ฒ ์Šต๋‹ˆ๋‹ค.

    ํ•˜์ง€๋งŒ ์œ„์˜ ๊ฒฝ์šฐ์™€ ๋‹ค๋ฅด๊ฒŒ ๋นจ๊ฐ„์ค„์˜ ์—๋Ÿฌ๊ฐ€ ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค. ์ด์œ ๋Š” ์ € label์˜ ํฌ๊ธฐ๊ฐ€ ๊ทœ์ •๋˜์–ด ์žˆ์ง€ ์•Š๊ธฐ ๋•Œ๋ฌธ์— bottom๊ณผ์˜ constraint๊ฐ€ label์˜ ์œ„์น˜์™€ ํฌ๊ธฐ๋ฅผ ๊ฒฐ์ •ํ•˜์ง€ ๋ชปํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋ž˜์„œ ์ถ”๊ฐ€์ ์œผ๋กœ ์˜ต์…˜์„ ์ฃผ๋Š”๋ฐ ๊ธฐ์กด๊ณผ ๋‹ค๋ฅด๊ฒŒ Auto fixing์„ ์‚ฌ์šฉํ•ด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.


    ํด๋ฆญํ•˜๋ฉด


    ์ฒ˜๋Ÿผ ๋ฉ”์„ธ์ง€๊ฐ€ ๋‚˜์˜ค๊ณ  Add Missing Constraints๋ฅผ ํ†ตํ•ด ์ž๋™์ ์œผ๋กœ ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•˜๊ฒŒ ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์•„๋ž˜์— ์žˆ๋Š” Localization Issue์˜ ๊ฒฝ๊ณ  ์—ญ์‹œ ํ•ด๊ฒฐ ๊ฐ€๋Šฅํ•œ๋ฐ ํด๋ฆญํ•˜๋ฉด


    ์˜ ๋ฉ”์„ธ์ง€๊ฐ€ ๋œจ๊ณ  Fix ๋ฒ„ํŠผ์„ ํ†ตํ•ด ๊ฒฝ๊ณ ๋ฅผ ํ•ด๊ฒฐํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

  • ์ด๋ฒˆ์—” Flips label๊ณผ Stack View์˜ ์œ„์น˜๋ฅผ ์„ค์ •ํ•ด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค. ๊ธฐ์กด๊ณผ ๋งˆ์ฐฌ๊ฐ€์ง€๋กœ Ctrl + ๋“œ๋ž˜๊ทธ๋ฅผ ํ†ตํ•ด ๋‘ ์š”์†Œ์˜ ๊ด€๊ณ„๋ฅผ ์„ค์ •ํ•ด์ค๋‹ˆ๋‹ค. vertical spacing์„ ํ†ตํ•ด ์ˆ˜์ง์˜ ์œ„์น˜๋ฅผ ์„ค์ •ํ•˜๊ณ  ๊ทธ ๊ด€๊ณ„๋ฅผ Equal์ด ์•„๋‹Œ Greater Than or Equal๋กœ ์„ค์ •ํ•ด์ค๋‹ˆ๋‹ค. ์ด๋ ‡๊ฒŒ ํ•˜๋ฉด ๋ฌด์กฐ๊ฑด Stack View๊ฐ€ Flips Label ์œ„์— ์œ„์น˜ํ•˜๋Š” ๊ตฌ์กฐ๊ฐ€ ๋ฉ๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ ๋ฐ”๋กœ ์œ„์— ์žˆ์„ ํ•„์š”๋Š” ์—†๊ฒŒ ๋ฉ๋‹ˆ๋‹ค. ์ด์ œ UI๊ฐ€ ๋‹ค๋ฅธ ๊ธฐ๊ธฐ์—์„œ๋„ ๋ฌธ์ œ์—†์ด ์ž‘๋™ํ•ฉ๋‹ˆ๋‹ค.


๐Ÿ›  Access Control


  • ๊ฐ์ฒด์ง€ํ–ฅ์˜ ๊ฐœ๋ฐœ์„ ํ•  ๋•Œ์— ์ค‘์š”ํ•œ ๊ฒƒ์ด ์ ‘๊ทผ ์ œ์–ด(Access Control)์ž…๋‹ˆ๋‹ค. ์–ด๋–ค ์š”์†Œ๋Š” ๊ทธ ์š”์†Œ๋ฅผ ํฌํ•จํ•˜๋Š” ๊ฐ์ฒด ์•ˆ์—์„œ๋งŒ ์‚ฌ์šฉ๋˜๊ณ , ์–ด๋–ค ์š”์†Œ๋Š” ๋‹ค๋ฅธ ๊ฐ์ฒด์—์„œ ๋ฐ˜๋“œ์‹œ ํ•„์š”ํ•  ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค. ๋ฌธ์ œ๋Š” ๋ชจ๋“  ์š”์†Œ๋“ค์„ ์„œ๋กœ ์ ‘๊ทผ์ด ๊ฐ€๋Šฅํ•˜๊ฒŒ ํ•œ๋‹ค๋ฉด ์€๋‹‰ํ™”๋ฅผ ์ง€ํ‚ค๊ธฐ๊ฐ€ ์–ด๋ ต์Šต๋‹ˆ๋‹ค. ๊ฐœ๋…์ ์ธ ๋ฌธ์ œ ๋ฟ๋งŒ ์•„๋‹ˆ๋ผ ๊ตฌ์กฐ์ ์œผ๋กœ๋„ ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด๊ฒƒ์„ ๋ฐฉ์ง€ํ•˜๊ธฐ ์œ„ํ•ด ์š”์†Œ๋งˆ๋‹ค ์–ด๋Š ์ •๋„์˜ ์ ‘๊ทผ์ด ๊ฐ€๋Šฅํ•œ์ง€ ์ •์˜ํ•˜๋Š” ๊ฒƒ์ด ์ ‘๊ทผ ์ œ์–ด ์ž…๋‹ˆ๋‹ค. ์•„๋ž˜๋Š” Swift ์ ‘๊ทผ ์ œ์–ด ํ‚ค์›Œ๋“œ์ž…๋‹ˆ๋‹ค.
    1. internal: default๋กœ app๋‚˜ framework ๋‚ด์—์„œ ๋ˆ„๊ตฌ๋‚˜ ์ด object์— ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ฆ‰ unlimited usability๋ฅผ ๊ฐ€์ง‘๋‹ˆ๋‹ค.(usable by anhy object in my app or framework)
    2. private: ์ด object ๋‚ด๋ถ€์—์„œ๋งŒ ์‚ฌ์šฉ ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค.(only callable from within this object)
    3. private(set): ๊ธฐ๋ณธ์ ์œผ๋กœ object ๋‚ด๋ถ€์—์„œ๋งŒ ์‚ฌ์šฉ ๊ฐ€๋Šฅํ•˜์ง€๋งŒ(get, set) ๊ฐ€์ ธ์˜ค๋Š” ์ž‘์—…(get)์€ object ์™ธ๋ถ€์—์„œ๋„ ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค.(readable only outside of object)
    4. fileprivate: ํ•ด๋‹น ํŒŒ์ผ ์•ˆ์—์„œ๋งŒ ์‚ฌ์šฉ ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค.(accessible by any code in this source file)
    5. public/open: ์ด๊ฒƒ์€ framework writers๋ฅผ ์œ„ํ•œ ๊ฒƒ์ž…๋‹ˆ๋‹ค. public์€ framework ์™ธ๋ถ€ ์‚ฌ์šฉ์ž๊ฐ€ ๋ถˆ๋Ÿฌ์˜ฌ ์ˆ˜ ์žˆ๋Š” ๊ฒƒ์„ ์˜๋ฏธํ•˜๋ฉฐ open์€ public์—์„œ ๋” ๋‚˜์•„๊ฐ€์„œ subclass, override ๋“ฑ ๋ชจ๋“  ๊ฒƒ์„ ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๐Ÿ“Œ Assertion(๋‹จ์–ธ๋ฌธ)


  • ๋‹จ์–ธ๋ฌธ์€ ์–ด๋–ค ๊ฒƒ์ด ์ฐธ์ž„์„ ๋‹จ์–ธํ•˜๋Š” ํ•จ์ˆ˜์ž…๋‹ˆ๋‹ค. assert ๋ฉ”์†Œ๋“œ๋ฅผ ํ†ตํ•ด ๋ฌธ์ œ๊ฐ€ ์žˆ์„ ๊ฒฝ์šฐ(false์˜ ๊ฒฝ์šฐ) ํŠน์ • ๋ฉ”์„ธ์ง€๊ฐ€ ์ถœ๋ ฅ๋˜๊ฒŒ ๋งŒ๋“ค ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์•„๋ž˜๋Š” chooseCard ๋ฉ”์†Œ๋“œ์ž…๋‹ˆ๋‹ค.

    func chooseCard(at index: Int) {
            assert(cards.indices.contains(index), "Concentration.chooseCard(at:\(index)): chosen index not in the cards")
            if !cards[index].isMatched {
                if let matchIndex = indexOfOneAndOnlyFaceUpCard, matchIndex != index {
                    if cards[matchIndex].identifier == cards[index].identifier {
                        cards[matchIndex].isMatched = true
                      ...

    assert ๋ฉ”์†Œ๋“œ๋ฅผ ์ค‘๊ฐ„์— ์‚ฝ์ž…ํ•˜์—ฌ ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. cards.indices๋Š” cards๊ฐ€ ๊ฐ€์ง„ index์˜ sequence์ด๋ฉฐ ์ด๊ฒƒ์˜ ๋ฒ”์œ„์— ํฌํ•จ๋˜์ง€ ์•Š๋Š” index์ผ ๊ฒฝ์šฐ ์˜ค๋ฅธ์ชฝ์˜ ๋ฉ”์„ธ์ง€์— index ๋‚ด์šฉ์„ ํ‘œ์‹œํ•ด์ค๋‹ˆ๋‹ค. ์ฆ‰, ์™ผ์ชฝ์—๋Š” Bool ๊ฐ’์„ ํ†ตํ•ด ํŒ๋ณ„ํ•˜๊ณ  ์˜ค๋ฅธ์ชฝ์— ํ™•์ธํ•˜๋Š” ๋ฉ”์„ธ์ง€๋ฅผ ์ถœ๋ ฅ์‹œํ‚ต๋‹ˆ๋‹ค.


๐Ÿ“ Mutating


  • Swift์˜ Value type์€ Copy on write์„ ๊ธฐ๋ณธ์œผ๋กœ ํ•ฉ๋‹ˆ๋‹ค. ์ฆ‰, ๋ณต์ œ๋˜์„œ ์ด๋™ ๋  ๋•Œ ๋ฌด์กฐ๊ฑด ๋ณต์‚ฌํ•˜๋Š” ๊ฒƒ์ด ์•„๋‹ˆ๋ผ ๋ณ€๊ฒฝ๋  ๋•Œ ์‹ค์ œ ๋ณต์‚ฌ๊ฐ€ ์ง„ํ–‰๋ฉ๋‹ˆ๋‹ค. ๊ทธ๋ž˜์„œ ์–ด๋–ค ๋ฉ”์†Œ๋“œ์—์„œ ์‹ค์ œ ๋ณ€๊ฒฝ์ด ์ผ์–ด๋‚  ์ˆ˜ ์žˆ๋Š”์ง€ ๋ช…์‹œํ•  ํ•„์š”๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค. ๊ทธ๊ฒƒ์ด mutating์„ ๋ถ™์ด๋Š” ์ด์œ ์ž…๋‹ˆ๋‹ค. Enum์—์„œ ๊ฐ’์„ ๋ณ€๊ฒฝ์‹œ์ผœ์ค„ ๋•Œ ๋ฉ”์†Œ๋“œ๋ฅผ ํ†ตํ•œ ๋ฐฉ๋ฒ• ๋ฐ–์— ์—†๊ณ  ์ด ๋•Œ mutating func์„ ์ด์šฉํ•ฉ๋‹ˆ๋‹ค.

Reference: Stanford CS193p by Paul Hegarty

๋ฐ˜์‘ํ˜•
๋Œ“๊ธ€
๋ฐ˜์‘ํ˜•
๊ณต์ง€์‚ฌํ•ญ
์ตœ๊ทผ์— ์˜ฌ๋ผ์˜จ ๊ธ€
์ตœ๊ทผ์— ๋‹ฌ๋ฆฐ ๋Œ“๊ธ€
Total
Today
Yesterday
๋งํฌ
TAG more
ยซ   2025/01   ยป
์ผ ์›” ํ™” ์ˆ˜ ๋ชฉ ๊ธˆ ํ† 
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31
๊ธ€ ๋ณด๊ด€ํ•จ