BookMoa README


๐Ÿ’ซ Introduce ๐Ÿ’ซ

๐Ÿƒ๐Ÿป๐Ÿƒ๐Ÿปโ€โ™‚๏ธ๐Ÿ’จ ํ”„๋กœ์ ํŠธ ๊ธฐ๊ฐ„: 23. 05. 17 ~ 23. 06. 14

Lust3r
  • ์„œ๋น„์Šค : ์‹œ์ค‘์˜ ๋‹ค์–‘ํ•œ ์ฑ…์— ๋Œ€ํ•œ ์ •๋ณด๋ฅผ ์ œ๊ณต
    • ๋ฒ ์ŠคํŠธ ์…€๋Ÿฌ ๋ชฉ๋ก
    • ์žฅ๋ฅด๋ณ„ ๋„์„œ ๋ชฉ๋ก
    • ๊ฐœ๋ณ„ ๋„์„œ ์ƒ์„ธ ์ •๋ณด
    • ๊ฐœ๋ณ„ ๋„์„œ ๋ฉ”๋ชจ ๊ธฐ๋Šฅ
    • ๊ฐœ๋ณ„ ๋„์„œ ๋ฏธ๋ฆฌ๋ณด๊ธฐ ๊ธฐ๋Šฅ
    • ํ‚ค์›Œ๋“œ ๊ฒ€์ƒ‰(์„œ๋ช…, ์ €์ž)
    • ์ฆ๊ฒจ์ฐพ๊ธฐ ๊ธฐ๋Šฅ
  • ๊ธฐ์ˆ  ์Šคํƒ : Swift(UIKit), Figma(Design)
  • ํ”„๋กœ์ ํŠธ ํšŒ๊ณ  :
    • ์˜ค๋กฏ์ด ํ˜ผ์ž ๊ณต๋ถ€ํ•˜์—ฌ ๊ตฌํ˜„ํ•œ ์ฒซ ๊ฐœ์ธ ํ”„๋กœ์ ํŠธ
    • ์งง์€ ๊ธฐ๊ฐ„ ๋™์•ˆ ๋ชฐ์ž…ํ•˜์—ฌ ํ”„๋กœ์ ํŠธ๋ฅผ ์ˆ˜ํ–‰
    • ๊ฐœ๋ฐœ ์ „ ๊ตฌํ˜„ํ•ด์•ผ ํ•˜๋Š” ๊ธฐ๋Šฅ๊ณผ ์ถ”ํ›„ ๊ฐœ๋ฐœํ•  ๊ธฐ๋Šฅ์„ ๊ณ ๋ คํ•˜์—ฌ โ€จFigma ํŽ˜์ด์ง€ ๋ถ„๋ฆฌ ๋ฐ ๊ธฐ๋Šฅ๋ณ„ Step ๋ถ„๋ฆฌ๋กœ ์šฐ์„ ์ˆœ์œ„ ํ™•๋ฆฝ
    • ํ•˜๋‚˜์˜ Open API์ด์ง€๋งŒ ๊ธฐ๋Šฅ๋ณ„๋กœ ์‚ฌ์šฉํ•ด์•ผ ํ•˜๋Š” API๊ฐ€ ๋‹ฌ๋ผโ€จ ์žฌ์‚ฌ์šฉ ๊ฐ€๋Šฅํ•œ EndPoint ๋ฐ ๋„คํŠธ์›Œํฌ ๊ตฌ์กฐ ์„ค๊ณ„๋ฅผ ์œ„ํ•ด ๋…ธ๋ ฅ
    • ๋ฏธ์ˆ™ํ–ˆ๋˜ ๊ธฐ๋Šฅ์˜ ๊ตฌํ˜„์„ ์œ„ํ•ด ๋งŽ์€ ํ•™์Šต ์ง„ํ–‰
      • Compositional CollectionView + Diffable Data Source
      • URLSession
      • Async/Await
    • ์œ ์ง€๋ณด์ˆ˜๋ฅผ ์œ„ํ•ด ์ตœ๋Œ€ํ•œ์˜ ํŒŒ์ผ, ๊ฐ์ฒด, ๋ฉ”์„œ๋“œ ๋ถ„๋ฆฌ ๋…ธ๋ ฅ
    • Notion์„ ํ†ตํ•ด ๋ฌธ์„œํ™”๋ฅผ ์ง„ํ–‰ํ•˜์˜€์ง€๋งŒ, ์ •๋ฆฌ ๋ฏธํก
      • ๋ฏธํกํ•œ ๋‚ด์šฉ์€ ๋ณด์™„ ์˜ˆ์ •

๐Ÿ“ฑ ๊ตฌํ˜„ ํ™”๋ฉด

Simulator Screen Recording - iPhone 14 Pro - 2023-06-19 at 13 46 31


๐Ÿ›๏ธ ํ”„๋กœ์ ํŠธ ๊ตฌ์กฐ

Group 3 Group 4 Group 5


๐Ÿ”จ STEP๋ณ„ ๊ตฌํ˜„ ๋‚ด์šฉ

STEP 1 ๋ชจ๋ธ ํƒ€์ž… ๊ตฌํ˜„

  • Open API ๋ฐ์ดํ„ฐ ํ˜•์‹์„ ๊ณ ๋ คํ•˜์—ฌ ๋ชจ๋ธ ํƒ€์ž…์„ ๊ตฌํ˜„
  • ๊ตฌํ˜„ํ•œ ๋ชจ๋ธ ํƒ€์ž…์œผ๋กœ Parsingํ•  ์ˆ˜ ์žˆ๋Š”์ง€์— ๋Œ€ํ•œ ๋‹จ์œ„ ํ…Œ์ŠคํŠธ(Unit Test)๋ฅผ ์ง„ํ–‰

STEP 2 ๋„คํŠธ์›Œํ‚น ํƒ€์ž… ๊ตฌํ˜„

  • ๋„คํŠธ์›Œํฌ ํ†ต์‹ ์„ ๋‹ด๋‹นํ•  ํƒ€์ž…์„ ์„ค๊ณ„ํ•˜๊ณ  ๊ตฌํ˜„
  • Open API ๋ฐ์ดํ„ฐ ํ˜•์‹์„ ๊ณ ๋ คํ•˜์—ฌ ์„œ๋ฒ„์™€ ์‹ค์ œ๋กœ ๋ฐ์ดํ„ฐ๋ฅผ ์ฃผ๊ณ  ๋ฐ›๋„๋ก ๊ตฌํ˜„
  • ๐Ÿ—๏ธ keyword: URLSession, Network, Decode, JSON Parsing

STEP 3 ๋ฉ”์ธ ๋ชฉ๋ก ํ™”๋ฉด ๊ตฌํ˜„

  • STEP 2์—์„œ ๊ตฌํ˜„ํ•œ ๋„คํŠธ์›Œํ‚น ๊ธฐ๋Šฅ์„ ํ†ตํ•ด ์‹ค์ œ๋กœ ์ฑ… ๋ชฉ๋ก์„ API ์„œ๋ฒ„์— ์š”์ฒญํ•˜์—ฌ ๋ถˆ๋Ÿฌ์˜ค๊ธฐ
  • ๋ฆฌ์ŠคํŠธ๋ฅผ ์•„๋ž˜๋กœ ์žก์•„๋Œ์–ด์„œ ๋†“์œผ๋ฉด ๋ฆฌ์ŠคํŠธ๋ฅผ ์ƒˆ๋กœ๊ณ ์นจ ํ•˜๊ธฐ
  • ์ฒ˜์Œ ๋ชฉ๋ก์„ ๋ถˆ๋Ÿฌ์˜ฌ ๋•Œ, ์‚ฌ์šฉ์ž์—๊ฒŒ ๋นˆ ํ™”๋ฉด๋งŒ ๋ณด์—ฌ์ฃผ๋Š” ๋Œ€์‹  ๋กœ๋”ฉ ์ค‘์ž„์„ ์•Œ ์ˆ˜ ์žˆ๊ฒŒ ํ•˜๊ธฐ
  • ์ขŒ์šฐ ์Šคํฌ๋กค์ด ๊ฐ€๋Šฅํ•œ layout ๊ตฌํ˜„
  • ๋ฆฌ์ŠคํŠธ์— ํ‘œ๊ธฐํ•  ์ •๋ณด
    • ์ธ๊ธฐ ๋„์„œ(์ด๋ฏธ์ง€, ์„œ๋ช… ์ €์ž) - ์ตœ๋Œ€ 10๊ฐœ๊นŒ์ง€ ์ถœ๋ ฅ
    • ์žฅ๋ฅด
  • ๋ฉ”์ธ ๋ชฉ๋ก ํ™”๋ฉด ํ•˜๋‹จ์— 'ํ™ˆ' ํ™”๋ฉด๊ณผ '์ฆ๊ฒจ์ฐพ๊ธฐ' ํ™”๋ฉด์œผ๋กœ ๊ฐˆ ์ˆ˜ ์žˆ๋Š” ํˆด๋ฐ” ๊ตฌํ˜„
  • ๐Ÿ—๏ธ keyword: UIRefreshControl, UIActivityIndicatorView, Compositional Layout, UIToolbar

STEP 4 ์ƒ์„ธ ํ™”๋ฉด ๊ตฌํ˜„(๊ฐœ๋ณ„ ๋„์„œ)

  • ๋ฉ”์ธ ๋ชฉ๋ก ํ™”๋ฉด์—์„œ ์ฑ…์˜ ์ด๋ฏธ์ง€๋ฅผ ๋ˆ„๋ฅด๋ฉด ๋„์„œ ์„ธ๋ถ€ํ™”๋ฉด์œผ๋กœ ์ด๋™ํ•˜๋„๋ก ๊ตฌํ˜„
  • ์ฑ…์˜ ๋Œ€ํ‘œ ์ด๋ฏธ์ง€๋ฅผ ๋…ธ์ถœ
    • ์ด๋ฏธ์ง€๋ฅผ ํƒญํ•˜๋ฉด ์ด๋ฏธ์ง€๋ฅผ ํ™•๋Œ€ํ•ด์„œ ํ™•์ธ ๊ฐ€๋Šฅ
  • ๋ฏธ๋ฆฌ๋ณด๊ธฐ ๋ฒ„ํŠผ ์ œ๊ณต
    • ํƒญํ•˜๋ฉด ๋ฏธ๋ฆฌ๋ณด๊ธฐ๋ฅผ ํŒ์—…์œผ๋กœ ์ œ๊ณต
  • ๋„์„œ์˜ ์ค„๊ฑฐ๋ฆฌ๋ฅผ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค
    • ์ตœ๋Œ€ 100์ž๋ฅผ ๋…ธ์ถœํ•ฉ๋‹ˆ๋‹ค. ๊ทธ ์ด์ƒ์˜ ๊ธ€์ž๋Š” ๋”๋ณด๊ธฐ ๋ฒ„ํŠผ์„ ํ†ตํ•ด์„œ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค.
    • ๋”๋ณด๊ธฐ ๋ฒ„ํŠผ์„ ๋ˆ„๋ฅด๋ฉด ์ „๋ฌธ์ด ๋…ธ์ถœ๋ฉ๋‹ˆ๋‹ค.
  • ์ €์ž ์†Œ๊ฐœ๋ฅผ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค.
    • ์ตœ๋Œ€ 100์ž๋ฅผ ๋…ธ์ถœํ•ฉ๋‹ˆ๋‹ค. ๊ทธ ์ด์ƒ์˜ ๊ธ€์ž๋Š” ๋”๋ณด๊ธฐ ๋ฒ„ํŠผ์„ ํ†ตํ•ด์„œ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค.
    • ๋”๋ณด๊ธฐ ๋ฒ„ํŠผ์„ ๋ˆ„๋ฅด๋ฉด ์ „๋ฌธ์ด ๋…ธ์ถœ๋ฉ๋‹ˆ๋‹ค.
  • ํ•ด๋‹น ์ฑ…์— ๋Œ€ํ•œ ๋ฉ”๋ชจ๋ฅผ ์‚ฌ์šฉ์ž๊ฐ€ ์ง์ ‘ ์ถ”๊ฐ€ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
  • ๐Ÿ—๏ธ keyword: Presentation, gesture, UILabel

STEP 5 ์ƒ์„ธ ํ™”๋ฉด ๊ตฌํ˜„(์žฅ๋ฅด๋ณ„)

  • ๋ฉ”์ธ ๋ชฉ๋ก ํ™”๋ฉด์—์„œ ์žฅ๋ฅด ๋ฒ„ํŠผ์„ ๋ˆ„๋ฅด๋ฉด ์žฅ๋ฅด ์„ธ๋ถ€ํ™”๋ฉด์œผ๋กœ ์ด๋™ํ•˜๋„๋ก ๊ตฌํ˜„
  • ๊ฒ€์ƒ‰ ๊ธฐ๋Šฅ์„ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค
    • ๊ฒ€์ƒ‰๊ฐ€๋Šฅ ํ‚ค์›Œ๋“œ: ์ฑ… ์ œ๋ชฉ, ์ €์ž๋ช…
    • ํ•œ ํŽ˜์ด์ง€์— ์ตœ์†Œ 9๊ฑด ์ด์ƒ์˜ ๋„์„œ ๊ฒ€์ƒ‰๊ฒฐ๊ณผ๋ฅผ ๋…ธ์ถœํ•ฉ๋‹ˆ๋‹ค.
      • ์ƒํ•˜๋กœ ํŽ˜์ด์ง€ ์Šคํฌ๋กค์ด ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค. ์ตœํ•˜๋‹จ์œผ๋กœ ์Šคํฌ๋กคํ•  ๊ฒฝ์šฐ ์ถ”๊ฐ€์ ์ธ ๊ฒ€์ƒ‰๊ฒฐ๊ณผ๋ฅผ ๋ถˆ๋Ÿฌ์˜ต๋‹ˆ๋‹ค.
      • ์ฑ… ์šฐ์ธก ์ƒ๋‹จ์—๋Š” ์ฆ๊ฒจ์ฐพ๊ธฐ ์—ฌ๋ถ€๋ฅผ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋Š” ์ด๋ฏธ์ง€๋ฅผ ํ‘œ์‹œํ•ฉ๋‹ˆ๋‹ค.
    • ๊ฐ ์ฑ…์„ ๋ˆ„๋ฅด๋ฉด STEP 4์˜ ๊ฐœ๋ณ„ ๋„์„œ ์ƒ์„ธ ํ™”๋ฉด์œผ๋กœ ๊ฐˆ ์ˆ˜ ์žˆ๋„๋ก ํ•ฉ๋‹ˆ๋‹ค.
  • ๐Ÿ—๏ธ keyword: SearchController, lazy loading

STEP 6 ์ฆ๊ฒจ์ฐพ๊ธฐ ํŽ˜์ด์ง€ ๊ตฌํ˜„

  • ์ฆ๊ฒจ์ฐพ๊ธฐ ํŽ˜์ด์ง€๋Š” ๊ฒ€์ƒ‰ ๊ฒฐ๊ณผ ํ™”๋ฉด๊ณผ ๋™์ผํ•œ ํ™”๋ฉด์„ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. ๋‹ค๋งŒ ์ฆ๊ฒจ์ฐพ๊ธฐ๋œ ๋„์„œ๋“ค๋งŒ ํ‘œ์‹œํ•ฉ๋‹ˆ๋‹ค.
  • STEP 6์˜ ๊ฐ ์ฑ…์˜ ์šฐ์ธก ์ƒ๋‹จ์—๋Š” ํ•˜ํŠธ๊ฐ€ ํ‘œ์‹œ๋ฉ๋‹ˆ๋‹ค.
    • ํ•˜ํŠธ๋ฅผ ๋ˆ„๋ฅด๋ฉด ๋นจ๊ฐ„์ƒ‰์œผ๋กœ ํ•˜ํŠธ๊ฐ€ ๋ณ€ํ•˜๊ณ , ์ฆ๊ฒจ์ฐพ๊ธฐ ๋ฆฌ์ŠคํŠธ์— ๋“ค์–ด๊ฐ€๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.
    • ํ•˜ํŠธ๋ฅผ ๋ˆ„๋ฅธ ์ฑ…๋“ค์˜ ๋ชฉ๋ก์„ ๋””๋ฐ”์ด์Šค์— ์ €์žฅํ•˜์—ฌ ์•ฑ์„ ์ข…๋ฃŒํ–ˆ๋‹ค ์ผœ๋”๋ผ๋„ ์œ ์ง€๋˜๋„๋ก ํ•ฉ๋‹ˆ๋‹ค.
  • ๐Ÿ—๏ธ keyword: UserDefaults, reuseCustomCell, viewLifeCycle

๐Ÿš€ ํŠธ๋Ÿฌ๋ธ” ์ŠˆํŒ…

1. ๋„คํŠธ์›Œํฌ ๋ชจ๋ธ ๊ตฌ์„ฑ

๊ณ ๋ฏผํ•œ ์  : URL ์š”์†Œ๋ฅผ ์–ด๋–ป๊ฒŒ ๋ถ„๋ฆฌํ•˜๋Š” ๊ฒƒ์ด ์ข‹์„๊นŒ?

์ฐธ๊ณ ์ž๋ฃŒ : Apple ๊ณต์‹๋ฌธ์„œ(URLComponents)

ํ•ด๊ฒฐ : ๊ธฐ์กด์—๋Š” firstComponent, secondComponent ๋“ฑ์œผ๋กœ ๋‚˜๋ˆ„์–ด ๊ตฌ์„ฑํ•˜์˜€๊ธฐ์— Component์˜ ์ˆซ์ž๊ฐ€ ์ผ์ •ํ•œ ์ƒํ™ฉ์—์„œ๋Š” ์œ ์šฉํ•˜์˜€์ง€๋งŒ, ์ˆซ์ž๊ฐ€ ๋‹ค๋ฅธ ์ƒํ™ฉ์—์„œ๋Š” Component๋ฅผ ์ œ๊ฑฐํ•˜๊ฑฐ๋‚˜ ์ถ”๊ฐ€ํ•ด์•ผ ํ•˜๋Š” ๋“ฑ ์œ ์—ฐํ•˜๊ฒŒ ์‚ฌ์šฉํ•˜๊ธฐ๊ฐ€ ์–ด๋ ค์› ๋‹ค. ๊ณต์‹๋ฌธ์„œ์˜ ๋‚ด์šฉ์„ ๋”ฐ๋ผ scheme, host, path, queryItems๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•  ์ˆ˜ ์žˆ์—ˆ๋‹ค.

  • scheme
    • ๋ฆฌ์†Œ์Šค๋ฅผ ์ ‘๊ทผํ•˜๋Š”๋ฐ ์‚ฌ์šฉํ•  ํ”„๋กœํ† ์ฝœ์„ ์‹๋ณ„
    • ์Šคํ‚ค๋งˆ ๋‹ค์Œ์—๋Š” :// ๋ฅผ ๋ถ™์—ฌ์ฃผ์–ด์•ผ ํ•œ๋‹ค.
  • host
    • ๋ฆฌ์†Œ์Šค๋ฅผ ๋ณด์œ ํ•œ ํ˜ธ์ŠคํŠธ๋ฅผ ์‹๋ณ„
    • ํ˜ธ์ŠคํŠธ ์ด๋ฆ„ ๋‹ค์Œ์œผ๋กœ port number๊ฐ€ ์˜ฌ ์ˆ˜๋„ ์žˆ๋‹ค.
    • ํฌํŠธ ๋ฒˆํ˜ธ๊ฐ€ ์žˆ๋Š” ๊ฒฝ์šฐ ํ˜ธ์ŠคํŠธ ์ด๋ฆ„ ๋‹ค์Œ์œผ๋กœ :๊ณผ ํ•จ๊ป˜ ํฌํŠธ ๋ฒˆํ˜ธ๋ฅผ ๋ถ™์—ฌ ์ฃผ์–ด์•ผ ํ•œ๋‹ค.
  • path
    • ์ ‘๊ทผํ•˜๋ ค๋Š” ํŠน์ • ๋ฆฌ์†Œ์Šค๋ฅผ ์‹๋ณ„
    • ๊ฒฝ๋กœ ์ด๋ฆ„์€ / ๋กœ ์‹œ์ž‘ํ•œ๋‹ค.
  • query
    • ํŠน์ • ๋ชฉ์ ์— ์‚ฌ์šฉํ•  ์ •๋ณด์— ๋Œ€ํ•œ ๋ฌธ์ž์—ด์„ ์ œ๊ณต
    • ์ฟผ๋ฆฌ ๋ฌธ์ž์—ด์ด ์ง€์ •๋˜๋ฉด ์•ž์— ? ๊ฐ€ ์˜ค๋ฉฐ, ๊ฐ ์ฟผ๋ฆฌ๋Š” &๋กœ ์—ฐ๊ฒฐ๋œ๋‹ค.


2. Modern CollectionView ๊ตฌ์„ฑ

๊ณ ๋ฏผํ•œ ์  : ์ง€๊ธˆ๊นŒ์ง€ TableView์™€ ๊ธฐ๋ณธ CollectionView๋งŒ ์จ๋ดค๋Š”๋ฐ, ์ €๋ ‡๊ฒŒ ๋‹ค์ฑ„๋กœ์šด ๋ ˆ์ด์•„์›ƒ์„ ์–ด๋–ป๊ฒŒ ํ•˜๋ฉด ๊ตฌ์„ฑํ•  ์ˆ˜ ์žˆ์„๊นŒ? ์ฐพ์•„๋ณด๋‹ˆ Compositional์ด๋ผ๋Š” ๊ฒƒ๋„ ์žˆ๊ณ , diffable์ด๋ผ๋Š”๊ฒŒ ์žˆ๋Š”๋ฐ ์ด๊ฑด ๋ฌด์—‡์ผ๊นŒ?

์ฐธ๊ณ ์ž๋ฃŒ : - Apple ๊ณต์‹๋ฌธ์„œ(UICollectionViewCompositionalLayout) - Apple ๊ณต์‹๋ฌธ์„œ(UICollectionViewDiffableDataSource) - Apple ๊ณต์‹๋ฌธ์„œ(UICollectionLayoutSectionOrthogonalScrollingBehavior) - Apple ๊ณต์‹๋ฌธ์„œ(Implementing Modern Collection Views)

ํ•ด๊ฒฐ : Compositional Layout์€ ๊ธฐ์กด์˜ CollectionView๋กœ ๋‹ค์–‘ํ•œ ๋ ˆ์ด์•„์›ƒ์„ ๋งŒ๋“ค ๋•Œ ์–ด๋ ค์šธ ์ˆ˜ ์žˆ๋Š” ๋ถ€๋ถ„์„ ํ•ด๊ฒฐํ•˜๊ธฐ ์œ„ํ•œ ์œ ํ˜•์ด๋ผ๊ณ  ์ƒ๊ฐํ•œ๋‹ค. ๊ฐ ์š”์†Œ๋ฅผ item, group, section์œผ๋กœ ๋งŒ๋“ค์–ด ์ชผ๊ฐœ๊ณ , ๊ฐ section์€ ๋˜ ๋‹ค๋ฅธ ๋ ˆ์ด์•„์›ƒ์„ ๊ฐ€์งˆ ์ˆ˜ ์žˆ๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค. DiffableDataSource๋Š” WWDC์— ๋”ฐ๋ฅด๋ฉด ๊ธฐ์กด์—๋Š” ๋ฐ์ดํ„ฐ๋ฅผ ๋ฐ˜์˜ํ•จ์— ์žˆ์–ด IndexPath๋„ ์ค‘์š”ํ•˜๊ณ , ReloadData๋ฅผ ํ•ด์•ผ ํ•˜๋Š” ์†Œ์š”๊ฐ€ ์žˆ๋Š”๋ฐ, Snapshot์„ ํ†ตํ•ด ์ด๋ฅผ ํ•ด๊ฒฐํ–ˆ๋‹ค๊ณ  ํ•œ๋‹ค. Snapshot์„ ๋น„๊ตํ•จ์œผ๋กœ์จ ์–ด๋–ค ๋ถ€๋ถ„์ด ๋‹ฌ๋ผ์กŒ๋Š”์ง€ ํŒŒ์•…ํ•˜์—ฌ View์— ๋ฐ˜์˜์„ ํ•ด์ฃผ๋Š” ๊ฒƒ์ด๋‹ค. ๋•๋ถ„์— IndexPath ์˜ค๋ฅ˜๋ฉฐ ReloadData์˜ ํ•„์š” ์—†์ด snapshot.apply() ๋กœ ํ•ด๊ฒฐํ•  ์ˆ˜ ์žˆ๊ฒŒ ๋˜์—ˆ๋‹ค.

๋ฉ”์ธํ™”๋ฉด์—์„œ ๋ฒ ์ŠคํŠธ ์…€๋Ÿฌ ๋ชฉ๋ก์€ ๊ฐ€๋กœ๋กœ ์Šคํฌ๋กค์„ ํ•ด์•ผ ํ•˜๊ณ , ์žฅ๋ฅด๋ณ„ ์ด๋ฆ„ ๋ฆฌ์ŠคํŠธ๋Š” ์„ธ๋กœ๋กœ ์Šคํฌ๋กค์„ ํ•ด์•ผ ํ–ˆ๊ธฐ์— ์œ„์—์„œ ์–ธ๊ธ‰ํ•œ ๊ฐ section๋ณ„ ๋ณ„๋„์˜ ๋ ˆ์ด์•„์›ƒ์ด ํ•„์š”ํ–ˆ๋‹ค. ์ด๋ฅผ ์œ„ํ•ด OrthogonalScrollingBehavior๋ฅผ ํ†ตํ•ด ๋ฒ ์ŠคํŠธ ์…€๋Ÿฌ ์„น์…˜์„ ๊ฐ€๋กœ๋กœ ์Šคํฌ๋กค๋ง ํ•˜๊ฒŒ ๋งŒ๋“ค์–ด์ฃผ์–ด ํ•ด๊ฒฐํ•  ์ˆ˜ ์žˆ์—ˆ๋‹ค.



3. DiffableDataSource - snapshot expensive cost ๋ฌธ์ œ

๊ณ ๋ฏผํ•œ ์  : CollectionView๊ฐ€ ๋กœ๋”ฉ๋  ๋•Œ ๋ฐ์ดํ„ฐ๋ฅผ ๋„ฃ๋Š” ๊ณผ์ •์—์„œ ๋น„์šฉ ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ•˜๋Š”๋ฐ ์–ด๋–ค ๊ฒƒ์ด ๋ฌธ์ œ์ผ๊นŒ?

๋ฌธ์ œ ๋กœ๊ทธ: Diffable data source detected an attempt to insert or append 10 item identifiers that already exist in the snapshot.

ํ•ด๊ฒฐ : ๊ณต์‹๋ฌธ์„œ๋ฅผ ํ†ตํ•ด Diffable Data Source, snapshot์„ ๋ณด๊ณ , WWDC๋ฅผ ๋‹ค์‹œ ๋ด๋„ ๋ฌธ์ œ๊ฐ€ ๋ณด์ด์ง€ ์•Š์•˜๋‹ค. ๊ฐ™์ด ๊ณต๋ถ€ํ•˜๋Š” ๋™๋ฃŒ์—๊ฒŒ ๋ฌผ์–ด๋ณด๋‹ˆ ์ง€๊ธˆ๊นŒ์ง€ snapshot์— ๋Œ€ํ•ด ์ž˜๋ชป ์ดํ•ดํ•˜๊ณ  ์žˆ์—ˆ์Œ์„ ๊นจ๋‹ฌ์•˜๋‹ค. snapshot์„ ์ฒ˜์Œ ๋งŒ๋“ค ๋•Œ์—๋งŒ ์ƒˆ๋กœ ๋งŒ๋“ค์–ด์ฃผ๊ณ , ์ดํ›„ ์Šค๋ƒ…์ƒท๋ถ€ํ„ฐ๋Š” ๊ฐ™์€ ์Šค๋ƒ…์ƒท์— ์•„์ดํ…œ๋งŒ ์ƒˆ๋กœ ๋„ฃ์–ด์ฃผ๋ฉด ๋˜๋Š” ๊ฒƒ์ด๋ผ๊ณ  ์ƒ๊ฐํ–ˆ์—ˆ๋‹ค. ํ•˜์ง€๋งŒ snapshot โ€˜๋‚ดโ€™์˜ ์•„์ดํ…œ ๋น„๊ต๊ฐ€ ์•„๋‹Œ snapshot โ€˜๊ฐ„โ€™์˜ ๋น„๊ต์ด๊ธฐ ๋•Œ๋ฌธ์— ์ƒˆ๋กœ์šด ์•„์ดํ…œ์ด ๋‹ด๊ธด snapshot์„ ๋งŒ๋“ค์–ด์ค˜์•ผ ํ–ˆ๋˜ ๊ฒƒ์ด๋‹ค.

๋•Œ๋ฌธ์— Diffable Data Source๋Š” ์ด๋ฏธ ์Šค๋ƒ…์ƒท์— ์•„์ดํ…œ์ด ๋“ค์–ด์žˆ๋Š”๋ฐ ์™œ ๋˜ ๊ทธ ์•„์ดํ…œ์„ ๋„ฃ์œผ๋ ค๊ณ  ํ•˜๋ƒ๋ฉฐ ์ผ๋‹จ ๋“ค์–ด๋Š” ์ฃผ๋Š”๋ฐ ์ด๊ฑด expensive cost๋‹ค ํ•˜๊ณ  ์•Œ๋ ค์ค€ ๊ฒƒ์ด์—ˆ๋‹ค. ์ƒˆ๋กœ์šด snapshot์„ ๋งŒ๋“ค์–ด์„œ applyํ•ด์ฃผ์ž ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•  ์ˆ˜ ์žˆ์—ˆ๋‹ค.



4. UITextView Placeholder ๋งŒ๋“ค๊ธฐ

๊ณ ๋ฏผํ•œ ์  : ์ฑ… ์ƒ์„ธ์ •๋ณด View์—์„œ ๋ฉ”๋ชจ๋ฅผ ์œ„ํ•œ TextView๋ฅผ ๋งŒ๋“ค์—ˆ๋Š”๋ฐ, ์—ฌ๊ธฐ์— TextField์ฒ˜๋Ÿผ placeholder๋ฅผ ๋„ฃ์–ด์ฃผ๊ณ  ์‹ถ๋‹ค. ๋ฉ”๋ชจ๊ฐ€ ์—†๋‹ค๋ฉด placeholder๋ฅผ ๋ณด์—ฌ์ฃผ๊ณ , ๋ฉ”๋ชจ๋ฅผ ์‹œ์ž‘ํ•  ๋•Œ ์ง€์šฐ๋Š” ๋ฐฉ์‹์œผ๋กœ ํ•˜๊ณ ์ž ํ•œ๋‹ค. ์ฐพ์•„๋ณด๋‹ˆ Compositional์ด๋ผ๋Š” ๊ฒƒ๋„ ์žˆ๊ณ , diffable์ด๋ผ๋Š”๊ฒŒ ์žˆ๋Š”๋ฐ ์ด๊ฑด ๋ฌด์—‡์ผ๊นŒ?

์ฐธ๊ณ ์ž๋ฃŒ : - ๋ธ”๋กœ๊ทธ(๊น€์ข…๊ถŒ์˜ iOS ์•ฑ ๊ฐœ๋ฐœ ์•Œ์•„๊ฐ€๊ธฐ - TextView placeholder ์ ์šฉ ๋ฐฉ๋ฒ•)

ํ•ด๊ฒฐ : TextView Delegate๋ฅผ ํ™œ์šฉํ•˜์—ฌ TextView๊ฐ€ ํŽธ์ง‘์ค‘์ธ์ง€ ์•„๋‹Œ์ง€๋ฅผ ๋ฐ”ํƒ•์œผ๋กœ textView.text๋ฅผ ์„ค์ •ํ•˜๋Š” ๋ฐฉ์‹์œผ๋กœ ํ•ด๊ฒฐํ•  ์ˆ˜ ์žˆ์—ˆ๋‹ค. ๊ฐ€๋ น ํŽธ์ง‘์ค‘์ธ๋ฐ ํ˜„์žฌ text๊ฐ€ ์„ค์ •ํ•ด๋†“์€ placeholder text์™€ ๊ฐ™๋‹ค๋ฉด text๋ฅผ nil๋กœ ๋งŒ๋“ค๊ณ  ๊ธ€์ž ์ƒ‰์„ .black์œผ๋กœ ๋ฐ”๊พธ๊ณ , ํŽธ์ง‘์ด ๋๋‚ฌ๋Š”๋ฐ text๊ฐ€ ์•„๋ฌด๊ฒƒ๋„ ์—†๋‹ค๋ฉด placeholder text๋กœ ๋‹ค์‹œ ๋Œ๋ ค๋†“๋Š” ๊ฒƒ์ด๋‹ค.



5. ํ‚ค๋ณด๋“œ๊ฐ€ ํ™”๋ฉด์„ ๊ฐ€๋ฆฌ๋Š” ํ˜„์ƒ

๊ณ ๋ฏผํ•œ ์  : ์ฑ… ์ƒ์„ธ์ •๋ณด View์—์„œ ๋ฉ”๋ชจ๋ฅผ ํ•˜๊ธฐ ์œ„ํ•ด TextView๋ฅผ ํ„ฐ์น˜ํ•˜๋ฉด ํ‚ค๋ณด๋“œ๊ฐ€ ์˜ฌ๋ผ์˜ค๋Š”๋ฐ, ํ‚ค๋ณด๋“œ์— ๋งž์ถฐ ๋ทฐ๊ฐ€ ์›€์ง์ด๋Š” ๊ฒƒ์ด ์•„๋‹ˆ๋ผ ๊ฐ€๋ ค๋ฒ„๋ฆฌ๋Š” ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ•ด์„œ ๋ทฐ์˜ ์œ„์น˜๋ฅผ ์กฐ์ •ํ•  ํ•„์š”๊ฐ€ ์žˆ์—ˆ๋‹ค.

์ฐธ๊ณ ์ž๋ฃŒ : - ๋ธ”๋กœ๊ทธ(๊น€์ข…๊ถŒ์˜ iOS ์•ฑ ๊ฐœ๋ฐœ ์•Œ์•„๊ฐ€๊ธฐ - TextView placeholder ์ ์šฉ ๋ฐฉ๋ฒ•)

ํ•ด๊ฒฐ : Notification Center Observer๋ฅผ ํ™œ์šฉํ•˜์—ฌ ํ•ด๊ฒฐํ•  ์ˆ˜ ์žˆ์—ˆ๋‹ค. keyboardWillShowNotification, keyboardWillHideNotification์œผ๋กœ ์˜ต์ €๋ฒ„๋ฅผ ์ถ”๊ฐ€ํ•˜๊ณ , selector ๋ฉ”์„œ๋“œ์—์„œ ํ‚ค๋ณด๋“œ์˜ height์™€ tabBar์˜ height ๋งŒํผ View์˜ ์œ„์น˜๋ฅผ ์˜ฎ๊ฒจ์ฃผ๋Š” ๋ฐฉ์‹์œผ๋กœ ํ™”๋ฉด์„ ๊ตฌ์„ฑํ•˜๊ฒŒ ๋˜์—ˆ๋‹ค.

ํ•˜์ง€๋งŒ ์ฒ˜์Œ์—๋Š” ์ž˜ ์ž‘๋™ํ•˜์˜€์œผ๋‚˜ ๋‚˜์ค‘์— ๋‹ค์‹œ ํ…Œ์ŠคํŠธ ํ–ˆ์„ ๋•Œ, ํ‚ค๋ณด๋“œ ์žํŒ์„ ํ„ฐ์น˜ํ•˜๋ฉด ํ‚ค๋ณด๋“œ ์œ„์ชฝ์œผ๋กœ ์˜ฎ๊ฒจ์ง„ ๋งŒํผ์˜ ๋นˆ ๊ณต๊ฐ„์ด ๋˜ ์ƒ๊ธฐ๋Š” ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ–ˆ๋‹ค. ์‹ค๊ธฐ๊ธฐ์—์„œ๋Š” ๊ดœ์ฐฎ์•˜์œผ๋‚˜ ์‹œ๋ฎฌ๋ ˆ์ดํ„ฐ์—์„œ๋งŒ ์ค‘๋ณต์œผ๋กœ ์ฒ˜๋ฆฌ๊ฐ€ ๋˜๊ณ , ์ฝ”๋“œ์—์„œ๋Š” ๋‘ ๋ฒˆ ์ž‘๋™ํ• ๋งŒํ•œ ๋ถ€๋ถ„์ด ๋ณด์ด์ง€ ์•Š์•„ ๋‚œํ•ญ์„ ๊ฒช์—ˆ์œผ๋‚˜ view์˜ y์œ„์น˜๋ฅผ ์ฒดํฌํ•˜๋Š” ์กฐ๊ฑด๋ฌธ์„ ๋‹ฌ์•„์คŒ์œผ๋กœ์จ ํ•ด๊ฒฐํ•  ์ˆ˜ ์žˆ์—ˆ๋‹ค. ๋”๋ถˆ์–ด ์กฐ๊ฑด๋ฌธ์„ ํ†ตํ•ด ํ•ด๊ฒฐํ•˜๋ฉด์„œ ๊ฐ selector ๋ฉ”์„œ๋“œ์—์„œ ๊ฐ๊ฐ ๋†’์ด๋ฅผ ๊ตฌํ•˜๊ณ  ๋นผ๊ณ  ๋”ํ•ด์ฃผ๋Š” ์ž‘์—… ๋Œ€์‹  hide์—์„œ๋Š” view์˜ ์œ„์น˜๋ฅผ ์›๋ž˜๋Œ€๋กœ ๋Œ๋ฆฌ๋Š” ์‹์œผ๋กœ ์ฝ”๋“œ๋„ ๊ฐ„๊ฒฐํ•˜๊ฒŒ ์ฒ˜๋ฆฌํ•  ์ˆ˜ ์žˆ์—ˆ๋‹ค.



6. ๋”๋ณด๊ธฐ ๊ธฐ๋Šฅ ๊ตฌํ˜„

๊ณ ๋ฏผํ•œ ์  : UILabel์— ์–ด๋–ป๊ฒŒ ๋”๋ณด๊ธฐ๋ฅผ ๊ตฌํ˜„ํ•  ์ˆ˜ ์žˆ์„๊นŒ? ํ•˜๋Š” ์ƒ๊ฐ์œผ๋กœ ๋ฒ„ํŠผ์„ ๋งŒ๋“ค์–ด numberOfLines ๊ฐ’์„ ๋ฐ”๊ฟ”์ฃผ๋Š” ๊ฒƒ์„ ์ƒ๊ฐํ–ˆ์—ˆ๋‹ค. ํ•˜์ง€๋งŒ ์ด๋Š” ๊ธ€์ž์ˆ˜๋กœ ์ฒดํฌํ•˜๋Š” ๊ฒƒ์ด ์•„๋‹ˆ๋ผ ์ค„ ์ˆ˜๋กœ ๊ตฌ๋ถ„์„ ํ•˜๋Š” ๋ฌธ์ œ๊ฐ€ ์žˆ์—ˆ๊ณ , ๋ฒ„ํŠผ์„ ๋งˆ์ง€๋ง‰ ๊ธ€์ž ์˜†์— ์œ ๋™์ ์œผ๋กœ ์œ„์น˜ํ•˜๊ฒŒ ํ•  ์ˆ˜ ์—†์–ด Label์˜ ์•„๋ž˜์ชฝ์— ๋ ˆ์ด์•„์›ƒ์„ ์ฃผ๊ฒŒ ๋˜์—ˆ๋Š”๋ฐ ๋ฒ„ํŠผ์„ ๋ˆŒ๋ €์„ ๋•Œ hide๋ฅผ ์‹œํ‚ค๋ฉด ํ•ด๋‹น ์œ„์น˜๊ฐ€ ๋ถ• ๋œจ๋Š” ๋ฌธ์ œ๋„ ์žˆ์—ˆ๋‹ค.

์ฐธ๊ณ ์ž๋ฃŒ : - stackoverflow(Add "...Read More" to the end of UILabel)

ํ•ด๊ฒฐ : ์ˆ˜๋งŽ์€ ๋‹ต๋ณ€์ด ์žˆ์—ˆ์œผ๋‚˜ ๋ณต์žกํ•˜๊ณ  ์ดํ•ด๊ฐ€ ์•ˆ๊ฐ€๋Š” ์ฝ”๋“œ๊ฐ€ ๋งŽ์ด ์žˆ์—ˆ๋‹ค. ๊ทธ ์ค‘ UILabel์„ ๋”ฐ๋กœ ์ปค์Šคํ…€ํ•˜์—ฌ ์ •ํ•ด์ง„ ๊ธ€์ž ์ˆ˜๋งŒํผ ์ธ๋ฑ์Šค๋กœ ์ž˜๋ผ์„œ ๋ณด์—ฌ์ฃผ๊ฑฐ๋‚˜ ์ „๋ฌธ์„ ๋ณด์—ฌ์ฃผ๋Š” ๋ฐฉ์‹์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์—ˆ๋‹ค.




7. Preview ๊ธฐ๋Šฅ ๊ตฌํ˜„

๊ณ ๋ฏผํ•œ ์  : ๋ฏธ๋ฆฌ๋ณด๊ธฐ ์ด๋ฏธ์ง€๋ฅผ ์–ด๋–ป๊ฒŒ ๋ณด์—ฌ์ฃผ๋Š” ๊ฒƒ์ด ์ข‹์„๊นŒ?

์ฐธ๊ณ ์ž๋ฃŒ : - Apple Human Interface Guidelines(Materials)

ํ•ด๊ฒฐ : ๊ธฐ์กด์—๋Š” ์ด๋ฏธ์ง€์™€ ์ด์ „, ๋‹ซ๊ธฐ, ๋‹ค์Œ 3๊ฐœ์˜ ๋ฒ„ํŠผ์ด ์žˆ๋Š” ๋ทฐ๋ฅผ ์ž‘๊ฒŒ ํŒ์—…์ฒ˜๋Ÿผ ๋„์›Œ์„œ ๋ฏธ๋ฆฌ๋ณด๊ธฐ๋ฅผ ํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ–ˆ์—ˆ๋‹ค. ํ•˜์ง€๋งŒ ํ”„๋กœ์ ํŠธ ํ”ผ๋“œ๋ฐฑ์œผ๋กœ HIG์˜ ๋‚ด์šฉ๊ณผ ์‚ฌ์šฉ์„ฑ์— ๋Œ€ํ•œ ๊ฒƒ์ด ๋“ค์–ด์™”๋‹ค.

๋จผ์ €, ๊ธฐ์กด์˜ ๋ฐฉ์‹์„ ์‚ฌ์šฉํ•˜๋ฉด ์œ„์— ๋ทฐ๋ฅผ ๋„์šฐ๊ธฐ๋Š” ํ–ˆ์ง€๋งŒ ๋’ค์— ์žˆ๋Š” ๋ทฐ๋„ ํ„ฐ์น˜๊ฐ€ ๊ฐ€๋Šฅํ•œ ์ด์ƒํ•œ ๋ฐฉ์‹์œผ๋กœ ๊ตฌ๋™๋˜๊ณ  ์žˆ์—ˆ๋‹ค. ๊ทธ๋ ‡๋‹ค๋ฉด ์ด๊ฒƒ์„ ๋’ท๋ถ€๋ถ„ ํ„ฐ์น˜๋ฅผ ๋ง‰์„ ๊ฒƒ์ธ๊ฐ€, ์•„๋‹ˆ๋ฉด ์ „์ฒดํ™”๋ฉด์œผ๋กœ ๋งŒ๋“ค์–ด์•ผ ํ•˜๋Š”๊ฐ€ ๊ณ ๋ฏผ์„ ๋จผ์ € ํ–ˆ๋‹ค. ์ž‘์€ ํŒ์—…์œผ๋กœ ๋„์šด ์ด์œ ๋Š” ์ด์šฉ์ž๊ฐ€ ์ด ์ฑ…์˜ ๋ฏธ๋ฆฌ๋ณด๊ธฐ๋ฅผ ๋ณด๊ณ  ์žˆ๋‹ค๋Š” ๋งฅ๋ฝ ์œ ์ง€๋ฟ๋งŒ ์•„๋‹ˆ๋ผ ์ „์ฒด ๋‚ด์šฉ ๋ณด๊ธฐ๊ฐ€ ์•„๋‹Œ ๋ฏธ๋ฆฌ๋ณด๊ธฐ๋ผ ์ž ๊น ํ›‘์–ด๋ณด๋Š” ์šฉ๋„๋กœ ์ƒ๊ฐํ•ด์„œ ํฐ ์ฐฝ์œผ๋กœ ๋ณด์—ฌ์ค„ ํ•„์š”๊ฐ€ ์—†์„ ๊ฒƒ ๊ฐ™๋‹ค๋Š” ์ƒ๊ฐ์ด์—ˆ๋‹ค. ํ•˜์ง€๋งŒ ํ”ผ๋“œ๋ฐฑ์„ ๋ฐ›์€ ์ดํ›„ ์ด๋Ÿฌํ•œ ๊ธฐ๋Šฅ์„ ์ œ๊ณตํ•˜๋Š” ๋ช‡ ์•ฑ์„ ์‚ดํŽด๋ณด๊ฒŒ ๋˜์—ˆ๊ณ  ์ „์ฒดํ™”๋ฉด์„ ํ†ตํ•ด ํฌ๊ฒŒ ๋ณด์—ฌ์คŒ์„ ์•Œ ์ˆ˜ ์žˆ์—ˆ๋‹ค. ๊ทธ๋ ‡๋‹ค๋ฉด ์ „์ฒดํ™”๋ฉด์œผ๋กœ ํ•œ๋‹ค๋ฉด, ๋ ˆ์ด์•„์›ƒ์€ ์–ด๋–ป๊ฒŒ ๊ตฌ์„ฑํ•˜๋Š” ๊ฒƒ์ด ์ข‹์„๊นŒ์— ๋Œ€ํ•œ ๊ณ ๋ฏผ์„ ํ•˜๋˜ ์ค‘, ํ”ผ๋“œ๋ฐฑ์ค‘ ํ•˜๋‚˜์˜€๋˜ HIG๊ฐ€ ๋– ์˜ฌ๋ž๋‹ค.

HIG Materials์— ๋”ฐ๋ฅด๋ฉด โ€™Translucency can help people retain their context by providing a visible reminder of the content thatโ€™s in the backgroundโ€™ โ€˜๋ฐ˜ํˆฌ๋ช…๋„๋Š” ๋ฐฐ๊ฒฝ์— ์žˆ๋Š” ์ฝ˜ํ…์ธ ๋ฅผ ์‹œ๊ฐ์ ์œผ๋กœ ์ƒ๊ธฐ์‹œ์ผœ ์‚ฌ๋žŒ๋“ค์ด ๋งฅ๋ฝ์„ ์œ ์ง€ํ•˜๋Š” ๋ฐ ๋„์›€์ด ๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹คโ€™

๋ผ๋Š” ๋ฉ˜ํŠธ๊ฐ€ ์žˆ์—ˆ๋‹ค. โ€˜์•„, ๊ทธ๋Ÿฌ๋ฉด ๋ทฐ์˜ ๋ฐฐ๊ฒฝ์— ๋ฐ˜ํˆฌ๋ช…๋„๋ฅผ ์ค˜์„œ ์ด์ „์— ์–ด๋–ค ์ฐฝ์—์„œ ๋„˜์–ด์˜จ๊ฑด์ง€ ์•Œ ์ˆ˜ ์žˆ๊ฒŒ ํ•ด์ฃผ๋ฉด ๋˜๊ฒ ๋‹คโ€™ํ•˜๋Š” ์ƒ๊ฐ์„ ํ•˜๊ฒŒ ๋˜์—ˆ๊ณ , HIG์—์„œ ์•Œ๋ ค์ค€ UIBlurEffect๋ฅผ ์ ์šฉํ•ด๋ณด๊ฒŒ ๋˜์—ˆ๋‹ค.



8. Gesture์˜ ์‚ฌ์šฉ๋ฒ•

๊ณ ๋ฏผํ•œ ์  : ๋ฒ„ํŠผ์„ ํ†ตํ•ด ์ด๋ฏธ์ง€๋ฅผ ๋„˜๊ธฐ๋Š” ๊ฒƒ์ด ์•„๋‹ˆ๋ผ ์‚ฌ์ง„์•ฑ์—์„œ ํ•˜๋“ฏ์ด ์Šค์™€์ดํ”„ ์ œ์Šค์ฒ˜๋กœ ์ด๋ฏธ์ง€๋ฅผ ๋„˜๊ธฐ๊ณ  ์‹ถ์€๋ฐ ์ œ์Šค์ฒ˜๋Š” ์–ด๋–ป๊ฒŒ ์‚ฌ์šฉํ•ด์•ผ ํ•˜๋Š” ๊ฒƒ์ผ๊นŒ?

์ฐธ๊ณ ์ž๋ฃŒ : - Apple ๊ณต์‹๋ฌธ์„œ(UIGestureRecognizer)

ํ•ด๊ฒฐ : ์ด์ „์— ํ•™์Šตํ–ˆ๋˜ touch Event, Responder Chain์ด ๋– ์˜ฌ๋ผ UIGestureRecognizer๋ฅผ ์ฐพ์•„๋ณด์•˜๋‹ค. UIGestureRecognizer์˜ ์„œ๋ธŒ ํด๋ž˜์Šค๋Š” ์ค‘์—์„œ ์Šค์™€์ดํ”„ ๋™์ž‘์„ ์‚ฌ์šฉํ•˜๊ธฐ์— ์ ํ•ฉํ•œ ๊ฒƒ์€ ์ด๋ฆ„ ๊ทธ๋Œ€๋กœ ๋‚˜ํƒ€๋‚˜ ์žˆ๋Š” UISwipeGestureRecognizer๋ผ๊ณ  ์ƒ๊ฐํ•˜์˜€๊ณ  ์ด์— ๋Œ€ํ•ด ํ•™์Šตํ•ด๋ณด์•˜๋‹ค. ๊ณต์‹๋ฌธ์„œ์— ๋”ฐ๋ฅด๋ฉด, GestureRecognizer๋Š” ํŠน์ • view ๋ฐ ๋ชจ๋“  subview์— ๋Œ€ํ•ด hit test๋ฅผ ๊ฑฐ์นœ touch์—์„œ ์ž‘๋™ํ•œ๋‹ค๊ณ  ํ•œ๋‹ค. ๋”ฐ๋ผ์„œ ํ•ด๋‹น view์™€ ์—ฐ๊ฒฐ์„ ํ•ด์•ผ ํ•˜๊ณ , ๊ทธ๋Ÿฌ๊ธฐ ์œ„ํ•ด์„œ๋Š” UIView์˜ ๋ฉ”์„œ๋“œ์ธ addGestureRecognizer(_:)๋ฅผ ํ˜ธ์ถœํ•ด์•ผ ํ•œ๋‹ค๊ณ  ํ•œ๋‹ค. ๋˜ํ•œ ์ด๋Š” view์˜ responder chain์— ์ฐธ์—ฌํ•˜์ง€ ์•Š๋Š”๋‹ค๊ณ  ํ•œ๋‹ค.

์™œ Gesture Recognizer๋Š” ํฌํ•จ๋˜์ง€ ์•Š์„๊นŒ? ๊ณต์‹๋ฌธ์„œ์— ์•„๋ž˜์™€ ๊ฐ™์€ ๋‚ด์šฉ์ด ์žˆ๋‹ค. Gesture recognizers๋Š” view๋ณด๋‹ค ๋จผ์ € ํ„ฐ์น˜ ๋ฐ ๋ˆ„๋ฅด๊ธฐ ์ด๋ฒคํŠธ๋ฅผ ์ˆ˜์‹ ํ•œ๋‹ค. view์˜ Gesture recognizers๊ฐ€ ์ผ๋ จ์˜ ํ„ฐ์น˜๋ฅผ ์ธ์‹ํ•˜์ง€ ๋ชปํ•˜๋ฉด UIKit์ด ํ„ฐ์น˜๋ฅผ View๋กœ ๋ณด๋‚ธ๋‹ค. view๊ฐ€ ํ„ฐ์น˜๋ฅผ ์ฒ˜๋ฆฌํ•˜์ง€ ์•Š์œผ๋ฉด UIKit์€ Responder chain ์œ„๋กœ ํ„ฐ์น˜๋ฅผ ์ „๋‹ฌํ•œ๋‹ค. ์ฆ‰ Gesture recognizer๋Š” view๋ณด๋‹ค ์•ž์„œ ํ„ฐ์น˜ ์ด๋ฒคํŠธ๋ฅผ ์ˆ˜์‹ ํ•˜๊ธฐ ๋•Œ๋ฌธ์— Responder Chain์— ํฌํ•จ๋˜์ง€ ์•Š๋Š” ๊ฒƒ์ด๊ณ , ์—ฌ๊ธฐ์„œ ํ„ฐ์น˜ ์ด๋ฒคํŠธ๋ฅผ ์ฒ˜๋ฆฌํ•˜์ง€ ๋ชปํ•˜๋ฉด view๋กœ ์ „๋‹ฌ, view๋„ ์•ˆ๋˜๋ฉด ์œ„์˜ ๊ทธ๋ฆผ๊ณผ ๊ฐ™์ด chain์— ๋”ฐ๋ผ ์ฒ˜๋ฆฌํ•  ๊ฐ์ฒด๋ฅผ ์ฐพ๊ฒŒ ๋˜๋Š” ๊ฒƒ์ด๋‹ค.

๊ทธ๋Ÿฌ๋ฉด, SwipeGestureRecognizer๋ž€ ๋ฌด์—‡์ผ๊นŒ? ํ•˜๋‚˜ ์ด์ƒ์˜ ๋ฐฉํ–ฅ์œผ๋กœ ๋ฐ€๊ธฐ ์ œ์Šค์ฒ˜๋ฅผ ํ•ด์„ํ•˜๋Š” ๋ถˆ์—ฐ์† ์ œ์Šค์ฒ˜ ์ธ์‹๊ธฐ๋กœ ์‚ฌ์šฉ์ž๊ฐ€ ํ—ˆ์šฉ ๊ฐ€๋Šฅํ•œ ๋ฐฉํ–ฅ์œผ๋กœ ์ง€์ •๋œ ํ„ฐ์น˜๋ฅผ ์ด๋™ํ•  ๋•Œ ์Šค์™€์ดํ”„๋ฅผ ์ธ์‹ํ•œ๋‹ค. ์Šค์™€์ดํ”„๋Š” ๋ณ„๊ฐœ์˜ ์ œ์Šค์ฒ˜์ด๋ฏ€๋กœ ์‹œ์Šคํ…œ์€ ์ œ์Šค์ฒ˜๋‹น ํ•œ ๋ฒˆ๋งŒ ์—ฐ๊ฒฐ๋œ ์ž‘์—… ๋ฉ”์‹œ์ง€๋ฅผ ๋ณด๋‚ธ๋‹ค. UISwipeGestureRecognizer ํด๋ž˜์Šค๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์Šค์™€์ดํ”„ ์ œ์Šค์ฒ˜๋ฅผ ๊ฐ์ง€ํ•˜๊ณ  view์˜ addGestureRecognizer(_:) ๋ฉ”์„œ๋“œ๋ฅผ ํ˜ธ์ถœํ•œ๋‹ค. ์ด๋Š” ํ™”๋ฉด์—์„œ ๊ฐ€๋กœ ๋˜๋Š” ์„ธ๋กœ๋กœ ์‚ฌ๋žŒ์˜ ์†๊ฐ€๋ฝ ๋™์ž‘์„ ์ถ”์ ํ•œ๋‹ค. ์ด ์ œ์Šค์ฒ˜๋Š” ๋ณ„๊ฐœ์ด๋ฏ€๋กœ ๋™์ž‘ ๋ฉ”์„œ๋“œ๋Š” ์ œ์Šค์ฒ˜๊ฐ€ ์„ฑ๊ณต์ ์œผ๋กœ ์ข…๋ฃŒ๋œ ํ›„์—๋งŒ ํ˜ธ์ถœ๋˜๊ณ  ๊ฒฐ๊ณผ์ ์œผ๋กœ ์Šค์™€์ดํ”„๋Š” ์‚ฌ๋žŒ์˜ ์†๊ฐ€๋ฝ ์›€์ง์ž„์„ ์ถ”์ ํ•˜์ง€ ์•Š๊ณ  ์ œ์Šค์ฒ˜์˜ ๊ฒฐ๊ณผ์—๋งŒ ์‹ ๊ฒฝ์„ ์“ธ ๋•Œ ๊ฐ€์žฅ ์ ํ•ฉํ•˜๋‹ค๊ณ  ํ•œ๋‹ค.

์ฆ‰, ์ด ํ”„๋กœ์ ํŠธ์—์„œ ํ„ฐ์น˜๋ฅผ ์–ด๋–ค ์‹์œผ๋กœ ํ•˜๋“  ๊ทธ ๊ณผ์ •๋ณด๋‹ค ์™ผ์ชฝ์œผ๋กœ ํ–ˆ๋Š”์ง€, ์˜ค๋ฅธ์ชฝ์œผ๋กœ ํ–ˆ๋Š”์ง€ ์—ฌ๋ถ€๊ฐ€ ์ค‘์š”ํ•˜๊ธฐ ๋•Œ๋ฌธ์— ์ ํ•ฉํ•˜๋‹ค๊ณ  ๋ณผ ์ˆ˜ ์žˆ๋‹ค.



9. addArrangedSubview๋ž€?

๊ณ ๋ฏผํ•œ ์  : addArrangedSubview๋ฅผ ํ–ˆ์„ ๋•Œ ๋ ˆ์ด์•„์›ƒ์„ ์–ด๋–ป๊ฒŒ addSubviewํ–ˆ์„ ๋•Œ์ฒ˜๋Ÿผ ํ•  ์ˆ˜ ์žˆ์„๊นŒ?

์ฐธ๊ณ ์ž๋ฃŒ : Xcode lldb

ํ•ด๊ฒฐ : ์ฒ˜์Œ์—๋Š” UIView์—๋Š” addSubview, StackView์—๋Š” addArrangedSubview๋ฅผ ์“ฐ๋ฉฐ, ์ „์ž๋Š” translatesAutoresizingMaskIntoConstraints๋ฅผ false๋ฅผ ์ฃผ์–ด ๋ ˆ์ด์•„์›ƒ ์ œ์•ฝ์„ ์ง์ ‘ ์ฃผ๋Š” ๋ฐ˜๋ฉด, ํ›„์ž๋Š” arranged ๋ฐฉ์‹์„(axis, alignment, distribution) ์คŒ์œผ๋กœ์จ ์ œ์•ฝ์„ ๋”ฐ๋กœ ์ฃผ์ง€ ์•Š๋Š” ๋ฐฉ์‹์ด๋ผ๊ณ  ์ƒ๊ฐํ–ˆ๋‹ค.

addArrangedSubview๋„ ์ œ์•ฝ์„ ์ค„ ์ˆ˜ ์žˆ๋‹ค๋Š” ๊ฒƒ์„ ๋ถ€ํŠธ ์บ ํ”„ ํ•™์Šต ๋„์šฐ๋ฏธ ๋•๋ถ„์— ์•Œ๊ฒŒ ๋˜์—ˆ์ง€๋งŒ, ๊ทธ๋ž˜๋„ ์ดํ•ด๊ฐ€ ๊ฐ€์ง€ ์•Š๋Š” ์ ์ด ์žˆ์—ˆ๋‹ค. ๋‘˜ ๋‹ค ์ œ์•ฝ์„ ์ง์ ‘ ์ค„ ์ˆ˜ ์žˆ์œผ๋ฉด arrangedSubview๋„ translates๋ฅผ false์ฒ˜๋ฆฌ ํ•ด์ค˜์•ผ ํ• ๊ฑฐ๊ณ , ๊ทธ๋ ‡๋‹ค๋ฉด ๋˜‘๊ฐ™์ด ์ฝ”๋“œ๊ฐ€ ๋งŽ์•„์ง€๊ณ  ์ง€์ €๋ถ„ํ•ด์งˆํ…๋ฐ ๊ตณ์ด ์ด๊ฑธ ์“ฐ๋Š” ์žฅ์ ์ด ์žˆ์„๊นŒ? ํ•˜๋Š” ๊ฒƒ์ด์—ˆ๋‹ค.

ํ•˜์ง€๋งŒ ๊ณต์‹๋ฌธ์„œ์™€ ๋ธ”๋กœ๊ทธ์—๋Š” ๊ด€๋ จํ•œ ์ •๋ณด๊ฐ€ ์—†์—ˆ๊ณ , stackoverflow์—๋„ ์˜ˆ์ „ ์ž๋ฃŒ๋กœ addArrangedSubview๋Š” ๊ธฐ๋ณธ์œผ๋กœ ํ•ด๋‹น ์†์„ฑ์ด false ์ฒ˜๋ฆฌ๋œ๋‹ค๋Š” ๋ง์ด ๊ทผ๊ฑฐ๊ฐ€ ๋‹ฌ๋ฆฌ์ง€ ์•Š์€ ์ฑ„ ์žˆ์—ˆ๋‹ค.

ํ•ด๋‹ต์„ ์–ป๊ธฐ ์œ„ํ•ด lldb๋ฅผ ํ†ตํ•ด addSubview ํ•  ๋•Œ์™€ addArrangedSubview๋ฅผ ํ•  ๋•Œ ํ”„๋กœํผํ‹ฐ์˜ ํ•ด๋‹น ์†์„ฑ์„ ์ฐ์–ด๋ณด์•˜๊ณ , stackoverflow์—์„œ์˜ ๋ง์ด ๋งž์Œ์„ ์•Œ ์ˆ˜ ์žˆ์—ˆ๋‹ค. ์ด๋ฅผ ํ†ตํ•ด addArrangedSubview๋Š” ๋ฌผ๋ก  lldb์˜ ์‚ฌ์šฉ๋ฒ•์— ๋Œ€ํ•ด์„œ๋„ ์ข€ ๋” ์•Œ๊ฒŒ ๋˜์—ˆ๋‹ค.



10. ํฐ ํ™”๋ฉด์„ ๊ฐ€์ง„ ๊ธฐ๊ธฐ ๋Œ€์‘

๊ณ ๋ฏผํ•œ ์  : ํƒ€๊ฒŸ ์‹œ๋ฎฌ๋ ˆ์ดํ„ฐ ๋ง๊ณ  ๋” ์ž‘๊ฑฐ๋‚˜ ํฐ ๊ธฐ๊ธฐ์—์„œ์˜ ๋ ˆ์ด์•„์›ƒ ๋Œ€์‘์„ ํ•˜๊ธฐ ์œ„ํ•ด์„œ๋Š” ์–ด๋–ป๊ฒŒ ํ•ด์•ผํ• ๊นŒ?

์ฐธ๊ณ ์ž๋ฃŒ : Apple ๊ณต์‹๋ฌธ์„œ(NSCollectionLayoutEnvironment)

ํ•ด๊ฒฐ : ๊ธฐ์กด์—๋Š” CollectionView์˜ Layout์„ ๊ตฌ์„ฑํ•  ๋•Œ groupSize๋ฅผ absolute๋‚˜ estimated๋กœ ์ง์ ‘ ๊ฐ’์„ ํ• ๋‹นํ•˜์˜€๋Š”๋ฐ, ๊ธฐ๊ธฐ ์‚ฌ์ด์ฆˆ์— ๋งž๊ฒŒ ๋™์ ์œผ๋กœ ์ฃผ๊ณ  ์‹ถ์—ˆ๋‹ค. ๊ด€๋ จํ•˜์—ฌ ๊ฒ€์ƒ‰ํ•˜๋‹ค ๋ณด๋‹ˆ ๊ณตํ†ต์ ์œผ๋กœ layoutEnvironment๋ผ๋Š” ํ‚ค์›Œ๋“œ๊ฐ€ ๋‚˜์™”๊ณ , collectionViewLayout์„ ๋งŒ๋“ค ๋•Œ ์‚ฌ์šฉํ•˜๋Š” layoutEnvironment๋ฅผ ํ™œ์šฉํ•  ์ˆ˜ ์žˆ๋Š” ๋ฐฉ๋ฒ•์„ ์• ํ”Œ ๋ฌธ์„œ์—์„œ ์ฐพ๊ฒŒ ๋˜์—ˆ๋‹ค.

NSCollectionLayoutEnvironment๋Š” ๋ ˆ์ด์•„์›ƒ์˜ ์ปจํ…Œ์ด๋„ˆ ๋ฐ ํ™˜๊ฒฝ ํŠน์„ฑ(์˜ˆ: ํฌ๊ธฐ ํด๋ž˜์Šค ๋ฐ ๋””์Šคํ”Œ๋ ˆ์ด ๋ฐฐ์œจ ์ธ์ˆ˜)์— ๋Œ€ํ•œ ์ •๋ณด๋ฅผ ์ œ๊ณตํ•˜๋Š” ๋ฐ ์‚ฌ์šฉ๋˜๋Š” ํ”„๋กœํ† ์ฝœ์ด๋‹ค.

ํ•˜์œ„ ์†์„ฑ์— ์žˆ๋Š” traitCollection์— ๋ณด๋ฉด horizontalSizeClass, verticalSizeClass๋ฅผ ํ†ตํ•ด ์‚ฌ์ด์ฆˆ ์ •๋ณด๋ฅผ ์–ป์„ ์ˆ˜ ์žˆ๊ณ , ๊ทธ ์†์„ฑ์œผ๋กœ compact์™€ regular๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์—ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ์ด ๋‘˜์˜ ๊ธฐ์ค€์ด ๋ฌด์—‡์ธ์ง€๋Š” ์•Œ ์ˆ˜ ์—†์—ˆ๋‹ค.

๊ณต์‹๋ฌธ์„œ UITraitCollection์—์„œ ๋‹ต์„ ์–ป์„ ์ˆ˜ ์žˆ์—ˆ๋‹ค. ์•„์ดํฐ์ด ์„ธ์›Œ์ ธ ์žˆ์„ ๋•Œ ๊ฐ€๋กœ ์‚ฌ์ด์ฆˆ, ๋ˆ•ํ˜€์ ธ ์žˆ์„ ๋•Œ ๊ฐ€๋กœ/์„ธ๋กœ ์‚ฌ์ด์ฆˆ๋Š” Compact, ์•„์ดํŒจ๋“œ์—์„œ๋Š” ์„ธ๋กœ/๊ฐ€๋กœ ์‚ฌ์ด์ฆˆ๊ฐ€ ๋ชจ๋‘ Regular์˜€๋‹ค. ํ•˜์ง€๋งŒ ์•„์ดํฐ๋„ SE๋ถ€ํ„ฐ Max๊นŒ์ง€ ๋‹ค์–‘ํ•˜๊ธฐ์— lldb๋ฅผ ํ™œ์šฉํ•ด๋ณด๊ธฐ๋กœ ํ–ˆ๋‹ค. ์‹ค์ œ ๊ฒฐ๊ณผ๋Š” iPhone Pro Max์˜ ๊ฒฝ์šฐ ๋ˆ•ํ˜”์„ ๋•Œ ๊ฐ€๋กœ ์‚ฌ์ด์ฆˆ๊ฐ€ Regular๋กœ ๋“ค์–ด๊ฐ€๋Š” ๊ฒƒ์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ์—ˆ๋‹ค.


[๊ณต์‹๋ฌธ์„œ ์ œ๊ณต ์ด๋ฏธ์ง€]
[iPhone 14 Pro lldb]

[iPhone 14 Pro Max lldb]

๐Ÿ™‹๐Ÿป ์ถ”ํ›„ ๊ณ„ํš

  • ์ฝ”๋“œ ๋ฆฌํŒฉํ„ฐ๋ง์„ ํ†ตํ•œ ์ปจ๋ฒค์…˜ ์‹ค์ˆ˜ ๊ต์ •
  • ๋™์ผํ•œ ๊ตฌ์„ฑ์„ ๊ฐ€์ง„ ViewController์˜ ๊ฐ์ฒด๋ช… ๋ถ„๋ฆฌ
  • AutoLayout ์ •๋ฆฌ
  • UserDefaults ๋Œ€์‹  CoreData ์‚ฌ์šฉ
  • ๊ฒ€์ƒ‰์ฐฝ ๋กœ์ง ๋ณ€๊ฒฝ
  • README ์ถ”๊ฐ€ ์ •๋ฆฌ