DEV_Larva

HACKING WITH SWIFT - WeSplit(3) ๋ณธ๋ฌธ

SwiftUI & UIKit/Tutorials

HACKING WITH SWIFT - WeSplit(3)

NelchuPapa 2022. 8. 23. 22:39
๋ฐ˜์‘ํ˜•

๐Ÿง‘‍๐Ÿ’ป์ด์ „ ์‹œ๊ฐ„์— ์ด์–ด์„œ ์ด๋ฒˆ ์‹œ๊ฐ„์—๋„ ๋™์ผํ•˜๊ฒŒ ๊ณ„์† ์ง„ํ–‰ํ•ด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค~!

 

 


๋ณธ๊ฒฉ์ ์œผ๋กœ WeSplit ํ”„๋กœ์ ํŠธ๋ฅผ ์‹œ์ž‘ํ•ด๋ณด์ž!

 

๋จผ์ € @State๋ฅผ ์ด์šฉํ•˜์—ฌ ์‚ฌ์šฉ์ž๊ฐ€ ์•ฑ์— ์ž…๋ ฅํ•  ๊ฒƒ์œผ๋กœ ์˜ˆ์ƒ๋˜๋Š” ๋ฐ์ดํ„ฐ์— ๋Œ€ํ•ด ์†์„ฑ์„ ์ถ”๊ฐ€ํ•ด์•ผ ํ•œ๋‹ค.

@State private var checkAmount = 0.0
@State private var numberOfPeople = 2
@State private var tipPercentage = 20

๊ทธ๋ž˜์„œ ๋‹ค์Œ๊ณผ ๊ฐ™์ด ๊ธˆ์•ก์˜ ๊ธฐ๋ณธ๊ฐ’์œผ๋กœ 0.0, ์ธ์›์ˆ˜์˜ ๊ธฐ๋ณธ๊ฐ’์ธ 2, ํŒ ๋น„์œจ์˜ ๊ธฐ๋ณธ๊ฐ’์ธ 20์œผ๋กœ ์ง€์ •ํ•˜์—ฌ ์ง„ํ–‰ํ•˜์˜€๋‹ค. 

๊ทธ๋ฆฌ๊ณ  ํŒ์— ๋Œ€ํ•œ ๋น„์œจ์„ ๋‹ค๋ฅด๊ฒŒ ์„ค์ •ํ•˜๊ธฐ ์œ„ํ•ด์„œ ๋ฐฐ์—ด์„ ์ด์šฉํ•˜์—ฌ ํŒ์— ๋Œ€ํ•œ ๋น„์œจ์„ 4๋ฒˆ์งธ ์†์„ฑ์œผ๋กœ ์ถ”๊ฐ€ํ•˜์˜€๋‹ค. 

 

var body: some View {
        Form {
            Section {
                TextField("Amount", value: $checkAmount, format: .currency(code: Locale.current.currencyCode ?? "USD"))
                    .keyboardType(.decimalPad)
            }

            Section {
                Text(checkAmount, format: .currency(code: Locale.current.currencyCode ?? "USD"))
            }
        }
    }
}

ContentView ๋‚ด๋ถ€์˜ ์ฝ”๋“œ๋ฅผ ํ•œ๋ฒˆ ์‚ดํŽด๋ณด์ž

 

๋จผ์ € ์šฐ๋ฆฌ๊ฐ€ ์ด์ „ ์‹œ๊ฐ„๋ถ€ํ„ฐ ์•Œ์•„๋ณด์•˜๋˜ Form๊ณผ Section, TextField๋ฅผ ํ†ตํ•ด ์‚ฌ์šฉ์ž๊ฐ€ ๊ธˆ์•ก์„ ์ž…๋ ฅํ•  ์ˆ˜ ์žˆ๊ฒŒ๋” ๋งŒ๋“ค์–ด ๋ณด์•˜๋‹ค. ๊ทธ๋ฆฌ๊ณ  ๋ฐ”๋กœ ์•„๋ž˜ Section์—์„œ๋Š” ํ•ด๋‹น ๊ธˆ์•ก์— ๋Œ€ํ•œ ์ •ํ™•ํ•œ ๊ธˆ์•ก์„ ๋ฐฑ๋ถ„์œจ๋กœ ํ‘œ์‹œํ•˜์˜€๋‹ค.

์ฝ”๋“œ ์ค‘ Locale์€ ์‚ฌ์šฉ์ž๊ฐ€ ์‚ฌ์šฉํ•˜๋Š” ๋‹ฌ๋ ฅ, ์ˆ˜์ฒœ ์ž๋ฆฌ์˜ ์ˆซ์ž๋ฅผ ๊ตฌ๋ถ„ํ•˜๋Š” ๋ฐฉ๋ฒ•, ๋ฏธํ„ฐ๋ฒ• ์‚ฌ์šฉ ์—ฌ๋ถ€ ๋“ฑ ๋ชจ๋“  ์‚ฌ์šฉ์ž์˜ ์ง€์—ญ ์„ค์ •์„ ์ €์žฅํ•˜๋Š” iOS์— ๋‚ด์žฅ๋œ ํ•˜๋‚˜์˜ ๊ตฌ์กฐ์ฒด์ด๋‹ค. ์ดํ›„ ์‚ฌ์šฉ์ž์—๊ฒŒ ์„ ํ˜ธํ•˜๋Š” ํ†ตํ™” ์ฝ”๋“œ ์šฐ๋ฆฌ๋‚˜๋ผ์˜ ๊ฒฝ์šฐ "USD"๊ฐ€ ์•„๋‹Œ "KRW"์„ ์„ ํƒํ•˜๊ฒ ์ง€๋งŒ ๊ทธ๋ ‡์ง€ ์•Š์€ ๊ฒฝ์šฐ "USD"๋กœ ๋Œ€์ฒดํ•˜๊ฒŒ ๋œ๋‹ค. 

 

 

๊ทธ๋ฆฌ๊ณ  ํ…์ŠคํŠธ ํ•„๋“œ์—์„œ ์ฒซ ๋ฒˆ์งธ ๋งค๊ฐœ๋ณ€์ˆ˜๋Š” Placeholder๋กœ ์‚ฌ์šฉ๋˜๋Š” ๋ฌธ์ž์—ด์ด๋‹ค. ๋‘ ๋ฒˆ์งธ ๋งค๊ฐœ๋ณ€์ˆ˜๋Š” ์†์„ฑ์— ๋Œ€ํ•œ ์–‘๋ฐฉํ–ฅ ๋ฐ”์ธ๋”ฉ์ธ checkAmount์ด๋‹ค. ์•ž์„œ ๋ฐฐ์› ๋“ฏ์ด ์‚ฌ์šฉ์ž๊ฐ€ ๋ฐ์ดํ„ฐ๋ฅผ ์ž…๋ ฅํ•˜๊ฒŒ ๋˜๋ฉด ํ•ด๋‹น ์†์„ฑ์ด ์—…๋ฐ์ดํŠธ ๋œ๋‹ค. 

๋งˆ์ง€๋ง‰์œผ๋กœ ์„ธ๋ฒˆ์งธ ๋งค๊ฐœ๋ณ€์ˆ˜๋Š” ํ…์ŠคํŠธ ์„œ์‹์„ ์ง€์ •ํ•˜์—ฌ ํ†ตํ™”๋กœ ๋งŒ๋“œ๋Š” ๋ฐฉ์‹์„ ์ œ์–ดํ•˜๋Š” ๋งค๊ฐœ ๋ณ€์ˆ˜์ด๋‹ค. 

 

 

๋ฐ”๋กœ ์‹คํ–‰ ํ•˜์—ฌ ๋ฐ์ดํ„ฐ๋ฅผ ์ž…๋ ฅ ํ•ด๋ณด๋ฉด ๋‘๋ฒˆ์งธ ์„น์…˜์—์„œ ์ž๋™์œผ๋กœ ๋ฐ”๋กœ ๋™๊ธฐํ™”๋ฅผ ํ†ตํ•ด ๋‚ด๊ฐ€ ์›ํ–ˆ๋˜ ์ž‘์—…์„ ์‹œํ–‰ ํ•˜๊ฒŒ ๋œ๋‹ค. 

์—ฌ๊ธฐ์„œ ๊ทธ๋Ÿผ ๋™๊ธฐํ™”๊ฐ€ ๋ฐœ์ƒ ํ•˜๋Š” ์ด์œ ์™€ ๊ณผ์ •์— ๋Œ€ํ•ด์„œ ๊ฐ„๋‹จํ•˜๊ฒŒ ์งš๊ณ  ๋„˜์–ด๊ฐ€์ž!

  1. ํ…์ŠคํŠธ ํ•„๋“œ์—๋Š” checkAmount์†์„ฑ์— ๋Œ€ํ•œ ์–‘๋ฐฉํ–ฅ ๋ฐ”์ธ๋”ฉ์ด ์žˆ๋‹ค.
  2. checkAmount์†์„ฑ์€ @State๊ฐ’์˜ ๋ณ€๊ฒฝ ์‚ฌํ•ญ์„ ์ž๋™์œผ๋กœ ๊ฐ์‹œํ•œ๋‹ค. 
  3. ์†์„ฑ์ด ๋ณ€๊ฒฝ ๋˜๋ฉด SwiftUI๋Š” ์†์„ฑ์„ ๋‹ค์‹œ ํ˜ธ์ถœํ•œ๋‹ค.(ui ๋‹ค์‹œ๋กœ๋“œ)
  4. ๋”ฐ๋ผ์„œ Text view์—์„œ ์—…๋ฐ์ดํŠธ๋œ checkAmount๊ฐ’์„ ๊ฐ€์ ธ์˜จ๋‹ค.

 

 

์—ฌ๊ธฐ์„œ ํ…์ŠคํŠธ ํ•„๋“œ์—์„œ ๋‚ด๊ฐ€ ํ•„์š”ํ•œ๊ฑด ์•ŒํŒŒ๋ฒณ ํ‚ค๋ณด๋“œ๊ฐ€ ์•„๋‹Œ ์ˆซ์ž์™€ ์†Œ์ˆ˜์ ์„ ํ‘œ์‹œํ•  . ๋งŒ ์žˆ์œผ๋ฉด ๋œ๋‹ค. 

๊ทธ๋ž˜์„œ ์—ฌ๊ธฐ์„œ ๋‹ค๋ฅธ ์ข…๋ฅ˜์˜ ํ‚ค๋ณด๋“œ๋ฅผ ๊ฐ•์ œ๋กœ ์ ์šฉํ•  ์ˆ˜์žˆ๋Š” ์ˆ˜์ •์ž๊ฐ€ ์žˆ๋Š”๋ฐ keyboardType()์„ ์ด์šฉํ•˜์—ฌ ํ‚ค๋ณด๋“œ ์ข…๋ฅ˜๋ฅผ ์ง€์ •ํ•˜๋Š” ๋งค๊ฐœ๋ณ€์ˆ˜๋ฅผ ์ œ๊ณตํ•ด์ฃผ๋ฉด ๋œ๋‹ค. ์ด ์ƒํ™ฉ์—์„œ๋Š” .numberPad ๋‚˜  .decialPad ์ธ๋ฐ ๋‘๊ฐ€์ง€ ๋‹ค ์‚ฌ์šฉ์ž๊ฐ€ ์„ ํƒํ• ์ˆ˜์žˆ๋Š” ๋ฐ์ดํ„ฐ๋Š” ์ˆซ์ž ๋ฟ์ด์ง€๋งŒ, ์ฐจ์ด๊ฐ€ ์žˆ๋‹ค. .decialPad์˜ ๊ฒฝ์šฐ ์ •์ˆ˜ ๋ฟ๋งŒ ์•„๋‹ˆ๋ผ $57.50๊ฐ™์€ ์†Œ์ˆ˜์ ๋„ ์ž…๋ ฅ์ด ๊ฐ€๋Šฅํ•ด์ง„๋‹ค. 

 

TextField("Amount", value: $checkAmount, format: .currency(code: Locale.current.currencyCode ?? "USD"))
    .keyboardType(.decimalPad)

 

๋”ฐ๋ผ์„œ ์ฒซ๋ฒˆ์งธ Section์˜ ํ…์ŠคํŠธํ•„๋“œ์— ์ˆ˜์ •์ž๋ฅผ ์ถ”๊ฐ€ํ•˜์—ฌ ๋‹ค์Œ๊ณผ ๊ฐ™์ด ์‹คํ–‰ ํ•ด๋ณด๋ฉด ํ…์ŠคํŠธ ํ•„๋“œ์— ์ˆซ์ž๋งŒ ์ž…๋ ฅํ•  ์ˆ˜์žˆ์–ด์•ผ ํ•˜๋Š”๋ฐ...

์™œ ํ‚ค๋ณด๋“œ๊ฐ€ ์•ˆ๋œฐ๊นŒ..?๐Ÿ™€

 

์ฝ”๋“œ๋ฅผ ๋‹ค์‹œ ์‚ดํŽด ๋ณด๊ธฐ๋„ ํ•˜์˜€๊ณ  .decialPad ๊ฐ€ ์•„๋‹Œ .numberPad๋กœ๋„ ํ•ด๋ณด์•˜์ง€๋งŒ ๊ฒฐ๊ณผ๋Š” ๋™์ผ ํ•˜์˜€๋‹ค. ๊ทธ๋ž˜์„œ ์•„๋ž˜ ๋กœ๊ทธ์ฐฝ์„ ํ™•์ธํ•ด๋ณด๋‹ˆ

Can't find keyplane that supports type 8 for keyboard iPhone-PortraitChoco-DecimalPad; using 27100_PortraitChoco_iPhone-Simple-Pad_Default 

๊ณผ ๊ฐ™์€ ๋ฌธ๊ตฌ๋ฅผ ํ™•์ธ ํ•˜์˜€๊ณ  ๋ชจ๋ฅด๊ฒ ๋‹ค๋ฉด ๊ตฌ๊ธ€๋ง์„ ํ•ด๋ด์•ผ๊ฒ ์ฃ ??ํ•˜๊ณ  stack overflow์—์„œ ์ฐพ์•„๋ณด๋‹ˆ ์›์ธ์€ ์ž˜ ๋ชจ๋ฅด๊ฒ ์œผ๋‚˜ ํ•ด๊ฒฐ๋ฒ•์€ ๋„ˆ๋ฌด ๊ฐ„๋‹จํ–ˆ๋‹ค. iOS Simulator๋ฅผ ์„ ํƒํ•œ ๋‹ค์Œ

โฌ‡๏ธโฌ‡๏ธ

I/O๋ฅผ ์„ ํƒํ•˜๋ฉด ์•„๋ž˜์™€ ๊ฐ™์ด Connect Hardware Keyboard์— ์ฒดํฌ๊ฐ€ ๋˜์–ด์žˆ์„ํ…๋ฐ ์ด๊ฑธ ๊บผ์ฃผ๋ฉด???

 

์ž˜๋œฌ๋‹ค!!!

์ด๋ ‡๊ฒŒ ์›ํ–ˆ๋˜ ์ˆซ์ž ํŒจ๋“œ๊ฐ€ ์ž˜ ๋‚˜์˜ค๋Š”๊ฒƒ์„ ํ™•์ธ ํ•  ์ˆ˜์žˆ๋‹ค.

 

 


์ด๋ฒˆ์—๋Š” ๋ฐ”๋กœ ์‚ฌ์šฉ์ž๊ฐ€ ์‹์‚ฌ ์ธ์› ์ฆ‰ ๋”์น˜ํŒจ์ด ์ธ์›์„ ์„ ํƒ ํ•  ์ˆ˜์žˆ๋„๋ก ํ•ด๋ณด์ž. ์—ฌ๊ธฐ์„œ ์ด์ „์— ๋ฐฐ์› ๋˜ Picker์™€ ForEach๋ฅผ ์ด์šฉํ•˜๊ฒŒ ๋˜๋ฉฐ ์„ ํƒ ํ•  ์ˆ˜์žˆ๋Š” ์‚ฌ๋žŒ์˜ ์ˆ˜๋Š” 2๋ช… ์ด์ƒ 99๋ช… ์ดํ•˜๋กœ ํ•œ๋ฒˆ ์„ค์ • ํ•ด๋ณผ๋ ค๊ณ  ํ•œ๋‹ค. ๊ทธ๋Ÿฌ๊ธฐ ์œ„ํ•ด์„œ๋Š” ์ฒซ๋ฒˆ์งธ Section์„ ์ผ๋ถ€ ์ˆ˜์ • ํ•ด๋ณด์•˜๋‹ค. ๊ทธ ์ˆ˜์ • ์ฝ”๋“œ๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™๋‹ค. 

 

Section {
    TextField("Amount", value: $checkAmount, format: .currency(code: Locale.current.currencyCode ?? "USD"))
        .keyboardType(.decimalPad)

    Picker("Number of people", selection: $numberOfPeople) {
        ForEach(2 ..< 100) {
            Text("\($0) people")
        }
    }
}

 

ํ•ด๋‹น ์ฝ”๋“œ๋ฅผ ์ถ”๊ฐ€ํ•˜๊ณ  ์‹คํ–‰ ํ•ด๋ณด๋ฉด ์•„๋ž˜์™€ ๊ฐ™์€ ๊ฒฐ๊ณผ๋ฌผ์„ ๋ณผ ์ˆ˜์žˆ๋‹ค. 

 

์ž ์—ฌ๊ธฐ์„œ ์ด์ƒํ•œ ์ ์€ ์‚ฌ๋žŒ ์ˆ˜๋ฅผ ์ž…๋ ฅํ• ๋ ค๊ณ  ๋ณด๋ฉด ์šฐ๋ฆฌ๊ฐ€ ์ดˆ๊ธฐ์— ์„ค์ • ํ•ด๋‘์—ˆ๋˜ numberOfPeople ์˜ ์ดˆ๊ธฐ๊ฐ’์€ ๋ถ„๋ช…ํžˆ 2์˜€๋‹ค. ๊ทธ๋Ÿฐ๋ฐ ์™œ ์ €๊ธฐ์„œ๋Š” ๊ธฐ๋ณธ๊ฐ’์ด 2๊ฐ€ ์•„๋‹Œ 4์ผ๊นŒ? ๊ทธ๋ฆฌ๊ณ  ์ถ”๊ฐ€์ ์œผ๋กœ ์„ ํƒํ• ๋ ค๊ณ  ํ„ฐ์น˜๋ฅผ ํ•ด๋ณด๋ฉด ์•„๋ฌด์ผ๋„ ์ผ์–ด๋‚˜์ง€ ์•Š๋Š”๋‹ค.

 

 

๋จผ์ € ์ดˆ๊ธฐ๊ฐ’์ด 2์˜€๋Š”๋ฐ ํ˜„์žฌ ์ถœ๋ ฅ๋˜๋Š”๊ฐ’์ด 4์ธ ๊ฒƒ๋ถ€ํ„ฐ ํ•ด๊ฒฐ ํ•ด๋ณด์ž๋ฉด 

ForEach(2..<100) { ๋ถ€๋ถ„์—์„œ ์šฐ๋ฆฌ๋Š” 2์—์„œ 100๊นŒ์ง€ ๊ณ„์‚ฐ ํ•˜์—ฌ ํ–‰์„ ๋งŒ๋“ค๋„๋ก ํ•˜์˜€๋Š”๋ฐ ์ด๊ฑด 0๋ฒˆ์งธํ–‰์— "2๋ช…"์ด ์ด๋ฏธ ํฌํ•จ ๋˜์–ด์žˆ์œผ๋ฏ€๋กœ  numberOfPeople์˜ ๊ฐ’์— 2๋ฅผ ์ฃผ์—ˆ์„๋•Œ ์‹ค์ œ๋กœ๋Š” "4๋ช…"์ธ ์„ธ ๋ฒˆ์งธ ํ–‰์œผ๋กœ ์„ค์ • ํ–ˆ๋‹ค๋Š”๊ฒƒ์ด ๋ฌธ์ œ์˜€๋‹ค. ๋‹ค๋ฅธ ๋ฌธ์ œ๋กœ Picker๋ฅผ ์ด์šฉํ•˜์˜€๋Š”๋ฐ๋„ ๋ถˆ๊ตฌ ํ•˜๊ณ  ํƒญ์„ ํ•ด๋„ ์•„๋ฌด์ผ๋„ ์ผ์–ด๋‚˜์ง€ ์•Š์€ ๊ฒƒ์ด๋‹ค. 

์ด๋Š” ์šฐ๋ฆฌ๊ฐ€ NavigationView๋ฅผ ์ถ”๊ฐ€ ํ•˜์ง€ ์•Š๊ณ  Picker๋ฅผ ์ด์šฉํ•œ๊ฒƒ์ด๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค. ๋”ฐ๋ผ์„œ NavigationView๋ฅผ ์ถ”๊ฐ€ํ•˜๊ณ  ๋‹ค์‹œ ์‹คํ–‰ ํ•ด๋ณด๋ฉด

 

 

๋‚ด๊ฐ€ ์›ํ–ˆ๋˜ ์‚ฌ๋žŒ ์ˆ˜๋ฅผ ์„ ํƒํ•  ์ˆ˜์žˆ๋Š” ํŽ˜์ด์ง€๋กœ ์ „ํ™˜๋˜๋ฉด์„œ ์„ ํƒ์„ ๋งˆ์น˜๋ฉด ์ž๋™์ ์œผ๋กœ ์‚ฌ๋žŒ ์ˆ˜๋Š” ๋‹น์—ฐํžˆ ๋‚ด๊ฐ€ ์„ ํƒํ•œ ์‚ฌ๋žŒ์˜ ์ˆ˜๋กœ ๋ฐ”๋€Œ๊ฒŒ๋œ๋‹ค.

 

์ฒ˜์Œ์—๋Š” 4๋ช… ํ˜„์žฌ๋Š” 8๋ช…์œผ๋กœ ๋ฐ”๋€๊ฒƒ์„ ํ™•์ธ ํ•  ์ˆ˜์žˆ๋‹ค.

 


 

 

์ด๋ฒˆ์—๋Š” ํŒ ๋น„์œจ์„ ํ‘œ์‹œํ•˜๊ธฐ ์œ„ํ•ด ์ด๋ฏธ ์ถ”๊ฐ€ํ•œ 2๊ฐœ์˜ Section ์•„๋ž˜์— ์ƒˆ๋กœ์šด Section์„ ์ถ”๊ฐ€ํ•ด๋ณด์ž!

Section {
    Picker("Tip percentage", selection: $tipPercentage) {
        ForEach(tipPercentages, id: \.self) {
            Text($0, format: .percent)
        }
    }
}

 

์ด๋Š” ๋ฐฐ์—ด์˜ ๋ชจ๋“  ์˜ต์…˜์„ ForEach๋ฅผ ์ด์šฉํ•˜์—ฌ ๊ฐ ์˜ต์…˜์„ .percentํ˜•์‹์˜ ํ…์ŠคํŠธ ๋ณด๊ธฐ๋กœ ๋ณ€ํ™˜ ํ•˜์˜€๋‹ค. ์ด์ „ Picker์™€ ๋™์ผํ•˜๊ฒŒ ์ƒˆ ์˜ต์…˜ ํ™”๋ฉด์„ ๋„ฃ์–ด์ฃผ์—ˆ๋‹ค. 

 

๊ทธ๋ ‡๊ฒŒ ํ•˜๋ฉด ์ด์ „์˜ Picker์™€ ๋™์ผํ•˜๊ฒŒ ์ƒˆ๋กœ์šด ํŽ˜์ด์ง€์—์„œ ๋‹ค์Œ๊ณผ ๊ฐ™์ด ํŒ ๋น„์œจ์— ๋Œ€ํ•œ ์„ ํƒ์ง€๋ฅผ ์‚ฌ์šฉ์ž๊ฐ€ ์„ ํƒ ํ•  ์ˆ˜์žˆ๋‹ค. 

 

๊ทธ๋Ÿฐ๋ฐ ์ด๋ฒˆ์—๋Š” ์ด๋ ‡๊ฒŒ ํ•˜์ง€๋ง๊ณ  ๋‹ค๋ฅธ ๋ฐฉ์‹์œผ๋กœ Picker๋ฅผ ๋ณด์—ฌ์ฃผ๊ณ  ์‹ถ์—ˆ๋‹ค. ๊ทธ๋Ÿฌ๊ธฐ ์œ„ํ•ด ์•„๋ž˜์˜ ์ฝ”๋“œ๋งŒ ์ถ”๊ฐ€ ํ•˜๋ฉด ๋œ๋‹ค. 

.pickerStyle(.segmented)

๊ทธ๋Ÿผ ์–ด๋–ป๊ฒŒ ๋˜๋Š”์ง€ ๋ฐ”๋กœ ๊ฒฐ๊ณผ ํ™”๋ฉด์œผ๋กœ ์ฐจ์ด์ ์„ ๋น„๊ตํ•ด๋ณด์ž.

 

์•„๋งˆ๋„ ์œ„ Section์— ์žˆ๋Š” Picker์™€ ๋น„๊ตํ•ด๋ณด๋ฉด ๋” ์‰ฝ๊ฒŒ ์ฐจ์ด์ ์„ ์•Œ ์ˆ˜์žˆ์„๊ฒƒ์ด๋‹ค. 

์—ฌ๊ธฐ์„œ ์‚ฌ์šฉ์ž๊ฐ€ ๋” ์ดํ•ดํ•˜๊ธฐ ์œ„ํ•ด์„œ Section์— ๋จธ๋ฆฌ๊ธ€์„ ์ถ”๊ฐ€ ํ•ด๋ณด์ž. 

์‚ฌ์šฉ์ž์—๊ฒŒ ์–ผ๋งˆ๋‚˜ ํŒ์„ ๋‚จ๊ธธ๊ฒƒ์ธ์ง€์— ๋Œ€ํ•œ ์งˆ๋ฌธ์„ ๋ฏธ๋ฆฌ ํ•จ์œผ๋กœ์„œ ํ•ด๋‹น Picker๊ฐ€ ์–ด๋–ค ์—ญํ• ์„ ํ•˜๋Š”์ง€ ์•Œ ์ˆ˜์žˆ๋‹ค.

๋ฐ”๋กœ ์ถ”๊ฐ€ํ•˜์—ฌ ๊ฒฐ๊ณผ๋ฅผ ํ™•์ธํ•ด๋ณด์ž!

 

 

 

 

 

 


 

๋งˆ์ง€๋ง‰ ํŒŒํŠธ์—์„œ๋Š” ์‚ฌ์šฉ์ž๊ฐ€ ์ž…๋ ฅํ•œ ๊ธˆ์•ก๊ณผ ์ œ๊ณตํ•  ํŒ ๋น„์œจ์„ ์ •ํ•˜๋Š” ๋ถ€๋ถ„, ๊ทธ๋ฆฌ๊ณ  ๋งˆ์ง€๋ง‰์œผ๋กœ ๊ทธ์— ์— ๋Œ€ํ•œ ๊ณ„์‚ฐ ๊ฒฐ๊ณผ๋กœ ํ•œ์‚ฌ๋žŒ๋‹น ๋‚ด์•ผํ•˜๋Š” ๊ธˆ์•ก์„ ๊ณ„์‚ฐ ํ•˜๋Š” ๋ถ€๋ถ„์„ ๊ฐœ๋ฐœ ํ•˜๋ฉด์„œ ๋งˆ๋ฌด๋ฆฌ ์ง€์–ด ๋ณด์ž.

 

 

 

์ด ๋ถ€๋ถ„์—์„œ๋Š” ์•ฝ๊ฐ„์˜ ๊ณ„์‚ฐ์ด ํ•„์š”ํ•œ๋ฐ 1์ธ๋‹น ์ง€๋ถˆํ•ด์•ผ ํ•˜๋Š” ์ด ๊ธˆ์•ก์€ ์ฃผ๋ฌธ ๊ธˆ์•ก์— ํŒ ๋น„์œจ์„ ๋”ํ•œ ๊ฐ’์„ ์ธ์›์ˆ˜๋กœ ๋‚˜๋ˆˆ ๊ฐ’๊ณผ ๊ฐ™๋‹ค. 

 

1์ธ๋‹น ์ง€๋ถˆ ๊ธˆ์•ก = ์ฃผ๋ฌธ๊ธˆ์•ก + ํŒ / ์ธ์› ์ˆ˜ 

 

 

์ด์ „์— ๋ฌธ์ œ ์˜€๋˜ ๊ณ„์‚ฐ ์ธ์›์„ ์„ ์ • ํ• ๋•Œ numberOfPeople์ด ์ด๋ฏธ +2 ๋งŒํผ ์ฐจ์ด ๋‚ฌ๋˜๊ฒƒ ์ฒ˜๋Ÿผ ๊ฐ’ 3๋ช…์„ ์ €์žฅ ํ• ๋•Œ 5๋ช…์„ ์˜๋ฏธํ•˜์˜€๋Š”๋ฐ 

๋”ฐ๋ผ์„œ ์ƒˆ๋กœ์šด ์†์„ฑ์ธ totalPerPerson์„ ๋งŒ๋“ค๊ฑฐ๋‹ค. ์ด๋Š” Doubleํ˜•์œผ๋กœ ์ž…๋ ฅ๋ฐ›์„ ๊ฒƒ์ด๋‹ค.

 

var totalPerPerson: Double {

        let peopleCount = Double(numberOfPeople + 2 )
        let tipSelection = Double(tipPercentage)
        
        let tipValue = checkAmount / 100 * tipSelection
	let grandTotal = checkAmount + tipValue
	let amountPerPerson = grandTotal / peopleCount

return amountPerPerson
}

 

๊ทธ๋ฆฌ๊ณ  ์šฐ๋ฆฌ๋Š” numberOfPeople์„ ์ฝ๊ณ  ๊ฑฐ๊ธฐ์— 2๋ฅผ ๋”ํ•˜๋ฉด์„œ ์–ผ๋งˆ๋‚˜ 2์—์„œ 100๊นŒ์ง€์˜ ๋ฒ”์œ„๋ฅผ ๊ฐ–์ง€๋งŒ ์‹ค์ œ๋กœ๋Š” 0์—์„œ ๊ณ„์‚ฐ ๋œ๋‹ค๋Š”๊ฒƒ์„ ์•Œ๊ฒŒ ๋œ๋‹ค. ๊ฒฐ๊ณผ๊ฐ’์€ Double๋กœ ๋ณ€ํ™˜ ํ•ด์•ผํ•˜๋Š”๋ฐ ์ด๋Š” checkAmount์™€ ํ•จ๊ป˜ ์‚ฌ์šฉํ•˜๊ธฐ ๋•Œ๋ฌธ์— ๊ทธ๋ ‡๋‹ค. ์•„๋ž˜ ์ค„์˜ tipSelection ๋˜ํ•œ ๋™์ผ ํ•˜๋‹ค.

 

tipSelection๊ฐ’์„ 100์œผ๋กœ ๊ณฑํ•˜๊ณ  checkAmount ์œผ๋กœ ๋‚˜๋ˆˆ๊ฐ’์„ tipValue์— ์ €์žฅ ํ•ด๋‘์ž. 

๊ทธ๋ฆฌ๊ณ  ํŒ๊ฐ’์„ checkAmount์— ์ถ”๊ฐ€ํ•˜์—ฌ ๊ธˆ์•ก์˜ ์ด ํ•ฉ๊ณ„๋ฅผ ๊ณ„์‚ฐ ํ•˜์˜€๋‹ค.

๊ทธ๋ฆฌ๊ณ  ์ด์•ก์„ peopleCount๋กœ ๋‚˜๋ˆ ์„œ 1์ธ๋‹น ๊ธˆ์•ก์„ ๊ณ„์‚ฐ ํ•œ๋‹ค. 

 

๊ทธ๋ฆฌ๊ณ  ์ด์ „์— return 0 ์˜€๋˜๊ฒƒ์„ anountPerPerson์œผ๋กœ ๋ฐ”๊ฟ”์ค€๋‹ค. 

 

 

์ด์   ์ด์ „์—

Section {
    Text(checkAmount, format: .currency(code: Locale.current.currencyCode ?? "USD"))
}

์ฝ”๋“œ๋ฅผ ์•„๋ž˜์™€ ๊ฐ™์ด ๋ฐ”๊ฟ”์ฃผ์ž. 

Section {
    Text(totalPerPerson, format: .currency(code: Locale.current.currencyCode ?? "USD"))
}

 

์ง€๊ธˆ๊นŒ์ง€ ํ•œ ๋ถ€๋ถ„์„ ํ•œ๋ฒˆ ๊ฒฐ๊ณผ๋กœ ํ™•์ธ ํ•ด๋ณด์ž.

์ด ๊ณ„์‚ฐ ๊ธˆ์•ก์„ 40.00์œผ๋กœ ๊ณ„์‚ฐํ•ด์•ผ ํ•  ์‚ฌ๋žŒ์€ 4๋ช…์œผ๋กœ ํŒ์€ 0์œผ๋กœ ์„ค์ • ํ•˜์—ฌ ์•„๋ž˜์ชฝ ์„น์…˜์„ ํ™•์ธ ํ•ด๋ณด๋ฉด ์ •์ƒ์ ์œผ๋กœ 10์ด๋ผ๋Š” ๊ฒฐ๊ณผ๊ฐ€ ๋‚˜์˜จ๋‹ค.

 


 

์ด์ œ ๋‹ค์™”๋‹ค. ๋งˆ์ง€๋ง‰์œผ๋กœ ์•„๊นŒ๋ถ€ํ„ฐ ๊ณ„์† ๊ฑฐ์Šฌ๋ฆฌ๊ฒŒ ํ–ˆ๋˜ ํ‚ค๋ณด๋“œ์— ๊ด€ํ•œ ๊ฒƒ์ธ๋ฐ, ์ด์ „์—๋Š” ์•ˆ๋– ์„œ ๋‚œ๋ฆฌ ์ณค์—ˆ๋Š”๋ฐ ์ด๋ฒˆ์—๋Š” ํ•œ๋ฒˆ ์˜ฌ๋ผ์˜จ ํ‚ค๋ณด๋“œ๋Š” ๋‹ค์‹œ ๋‚ด๋ ค๊ฐ€์ง€ ์•Š๋Š”๊ฒƒ์ด ๋ฌธ์ œ๊ฐ€ ๋˜์—ˆ๋‹ค. ์ด๊ฑด ๋‹ค๋ฅธ ํŽ˜์ด์ง€, ์˜ˆ๋ฅผ ๋“ค๋ฉด PickerํŽ˜์ด์ง€๋กœ ๋ณ€๊ฒฝ ๋˜์—ˆ๋‹ค๊ฐ€ ๋Œ์•„์™€๋„ ๋ณ€ํ•จ ์—†์ด ํ‚ค๋ณด๋“œ๋Š” ์‚ฌ๋ผ์ง€์ง€์•Š์•˜๋‹ค. ๊ทธ๋ž˜์„œ ์ด๋ฒˆ์—๋Š” ์ด ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•ด๋ณด์ž!

 

 

@FocusState private var amountIsFocused: Bool

ํ•ด๋‹น ์ƒˆ ์†์„ฑ์„ ContentView์— ์ถ”๊ฐ€ ํ•œ๋‹ค. ๊ทธ๋ฆฌ๊ณ  ํ…์ŠคํŠธ ํ•„๋“œ์— ํฌ์ปค์Šค๊ฐ€ ๋งž์ถฐ์ ธ ์žˆ์„๋•Œ๋Š” true, ์•„๋‹ˆ๋ฉด false๊ฐ€ ๋˜๋„๋ก ํ•  ์ˆ˜์žˆ๋‹ค. ๊ทธ๋ž˜์„œ ์•„๋ž˜ ์ฝ”๋“œ๋ฅผ TextField์— ์ถ”๊ฐ€ ํ•˜๋ฉด SwiftUI๋Š” ํ…์ŠคํŠธ ํ•„๋“œ์— ํ˜„์žฌ ํฌ์ปค์Šค๊ฐ€ ์žˆ์–ด์•ผ ํ•˜๋Š”์ง€์— ๋Œ€ํ•œ ์—ฌ๋ถ€๋ฅผ ์•Œ์•„์„œ ํŒ๋‹จํ•˜๊ณ  ๊ฒฐ์ • ํ•˜๊ฒŒ ๋œ๋‹ค. ์ด๊ฑธ SwiftUI๊ฐ€ ์•Œ๊ณ  ์ดํ›„ ์‚ฌ์šฉ์ž๊ฐ€ ์›ํ•  ๋•Œ ํฌ์ปค์Šค๋ฅผ ์ œ๊ฑฐ ํ•˜๊ธฐ ์œ„ํ•ด์„œ ์šฐ๋ฆฌ๋Š” ์ถ”๊ฐ€์ ์œผ๋กœ ๋ฒ„ํŠผ์„ ์ถ”๊ฐ€ ํ• ๊ฒƒ์ด๋‹ค. 

 

๊ทธ๋Ÿผ ๋ฐ”๋กœ ๋งŒ๋“ค์–ด ๋ณด์ž!

์ด์ „์—” WeSplit์ด๋ผ๋Š” navigationTitle์„ ์ถ”๊ฐ€ํ•œ์ ์ด ์žˆ๋‹ค. ์—ฌ๊ธฐ์—

.toolbar {
    ToolbarItemGroup(placement: .keyboard) {           
        Button("Done") {
            amountIsFocused = false
        }
    }
}

 

๋‹ค์Œ ์ฝ”๋“œ๋ฅผ ์ถ”๊ฐ€ ํ• ๊ฒƒ์ธ๋ฐ, ๊ฐ์ค„์˜ ์—ญํ• ์„ ํ•œ๋ฒˆ ์ฒœ์ฒœํžˆ ์‚ดํŽด ๋ณด์ž

  1. toolbar()๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ๋ณด๊ธฐ์— ๋Œ€ํ•œ ๋„๊ตฌ ๋ชจ์Œ ํ•ญ๋ชฉ์„ ์ง€์ • ํ•  ์ˆ˜์žˆ๊ฒŒ ๋œ๋‹ค. 
  2. ToolbarItemGroup์€ ํŠน์ • ์œ„์น˜์— ํ•˜๋‚˜ ์ด์ƒ์˜ ๋ฒ„ํŠผ์„ ๋ฐฐ์น˜ ํ•  ์ˆ˜์žˆ๋‹ค. ์—ฌ๊ธฐ์„œ ํ‚ค๋ณด๋“œ์— ๋Œ€ํ•œ ๋„๊ตฌ ๋ชจ์Œ์œผ๋กœ ์ง€์ •ํ•ด์•ผ๋งŒ ํ‚ค๋ณด๋“œ์— ๋ถ™์–ด์„œ ํ•จ๊ป˜ ๋‚˜ํƒ€๋‚ฌ๋‹ค๊ฐ€ ์—†์–ด์กŒ๋‹ค๊ฐ€ ํ•  ์ˆ˜์žˆ๊ฒŒ ๋œ๋‹ค.
  3. Done์ด๋ผ๋Š” ํ…์ŠคํŠธ์™€ ํ•จ๊ป˜ ๋ฒ„ํŠผ์„ ๋ˆŒ๋ €์„๋•Œ amountIsFocused๊ฐ€ ํ‚ค๋ณด๋“œ๊ฐ€ ๋‹ซํžˆ๋„๋ก false๋กœ ์„ค์ • ๋œ๋‹ค. ๊ทธ๋ž˜์•ผ ํฌ์ปค์Šค๊ฐ€ ํ’€๋ฆฌ๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค. 

 

๊ทธ๋ฆฌ๊ณ  ๋งˆ์ง€๋ง‰์œผ๋กœ  Spacer()๋ฅผ ToolbarItemGroup์™€ ๋ฒ„ํŠผ ์‚ฌ์ด์— ๋‘์–ด์„œ ์ด์ „ ๋ณด๋‹ค ์œ ์—ฐํ•œ ๊ณต๊ฐ„์„ ์ œ๊ณต ํ•˜์—ฌ ๋„๊ตฌ ๋ชจ์Œ์—์„œ ๋ฒ„ํŠผ์ด ์˜ค๋ฅธ์ชฝ์œผ๋กœ ๋ฐ€๋ ค๋‚˜๊ฒŒ ๋œ๋‹ค. ๊ทธ๋ ‡๊ฒŒ ํ•ด์„œ ๋งˆ์ง€๋ง‰ ๊ฒฐ๊ณผ๋ฌผ์„ ํ™•์ธ ํ•ด๋ณด๋ฉด???

 

์ €๊ธฐ ํ‚ค๋ณด๋“œ์— ๋ถ™์–ด์žˆ๋Š” Done๋ฒ„ํŠผ์„ ๋ˆ„๋ฅด๋ฉด ํ‚ค๋ณด๋“œ๊ฐ€ ์ž˜๋‚ด๋ ค๊ฐ€๋Š”๊ฒƒ์„ ํ™•์ธ ํ•  ์ˆ˜์žˆ์œผ๋ฉฐ, ๋‹ค์‹œ ๋ฐ์ดํ„ฐ๋ฅผ ์ž…๋ ฅํ•˜๊ธฐ ์œ„ํ•ด TextField๋ฅผ ๋ˆ„๋ฅด๋ฉด ํ‚ค๋ณด๋“œ๊ฐ€ ์˜ฌ๋ผ์˜ค๋Š”๊ฒƒ์„ ํ™•์ธ ํ•  ์ˆ˜์žˆ์„ ๊ฒƒ์ด๋‹ค.

 


์šฐ๋ฆฌ๋‚˜๋ผ๋Š” ํŒ์— ๋Œ€ํ•œ ๋ฌธํ™”๊ฐ€ ๋งŽ์ด ์ •์ฐฉ ๋˜์–ด ์žˆ์ง€ ์•Š๊ณ  ์•ฑ ๋‚ด ํ†ตํ™” ๊ธฐ์ค€๋„ ์šฐ๋ฆฌ๋‚˜๋ผ์ฒ˜๋Ÿผ "์›"์ด ์•„๋‹Œ "๋‹ฌ๋Ÿฌ"๋กœ ํ‘œ์‹œ ๋˜์–ด์žˆ์ง€๋งŒ, ์ด๋ฒˆ ํ”„๋กœ์ ํŠธ๋ฅผ ํ†ตํ•ด์„œ ๊ฐ„๋‹จํ•œ ๊ธฐ๋Šฅ์ด์ง€๋งŒ ์ƒ๊ฐ ๋ณด๋‹ค ์–ป์€ ์ •๋ณด๋“ค์ด ๋„ˆ๋ฌด ๋งŽ์•˜๋˜๊ฒƒ ๊ฐ™๋‹ค. ์ด ๋‹ค์Œ ์‹œ๊ฐ„์—๋„ ์ƒˆ๋กœ์šด ํ”„๋กœ์ ํŠธ๋ฅผ ์‹œ์ž‘ํ•˜๊ฒ ์ง€๋งŒ ํ•œ๋ฒˆ ๋” ๋ฆฌ๋ทฐํ•ด๋ณด๋Š” ์‹œ๊ฐ„์„ ๊ฐ€์ ธ ๋ณด๋Š”๊ฒƒ๋„ ์ข‹์„๊ฒƒ ๊ฐ™๋‹ค. ์ด๊ฒƒ์œผ๋กœ WeSplitํ”„๋กœ์ ํŠธ๋Š” ๋!

 

 

learning by repetition

๋ฐ˜์‘ํ˜•

'SwiftUI & UIKit > Tutorials' ์นดํ…Œ๊ณ ๋ฆฌ์˜ ๋‹ค๋ฅธ ๊ธ€

HACKING WITH SWIFT - Guess the Flag(3)  (0) 2022.09.03
HACKING WITH SWIFT - Guess the Flag(2)  (0) 2022.09.03
HACKING WITH SWIFT - Guess the Flag  (0) 2022.08.31
HACKING WITH SWIFT - WeSplit(2)  (0) 2022.08.18
HACKING WITH SWIFT - WeSplit  (0) 2022.08.17