SwiftUI & UIKit/Tutorials

HACKING WITH SWIFT - WeSplit(2)

NelchuPapa 2022. 8. 18. 01:45
λ°˜μ‘ν˜•

πŸ§‘‍πŸ’»μ΄μ „ μ‹œκ°„μ— μ΄μ–΄μ„œ 이번 μ‹œκ°„μ—λ„ λ™μΌν•˜κ²Œ 계속 μ§„ν–‰ν•΄λ³΄κ² μŠ΅λ‹ˆλ‹€~!

 

 

 


1. μƒνƒœ μˆ˜μ •

 

κ²Œμž„μ„ ν•˜λ‹€λ³΄λ©΄ μΊλ¦­ν„°μ˜ λͺ©μˆ¨μ„ λͺ‡ 개 μžƒμ„ μˆ˜λ„ 있고 점수λ₯Ό μ–»λŠ”λ‹€λ˜μ§€ ν•˜λŠ” κ²½μš°κ°€ μžˆλ‹€. 이걸 μš°λ¦¬λŠ” ν”„λ‘œκ·Έλž˜λ°μ— μžˆμ–΄μ„œ "μƒνƒœ"라고 λΆ€λ₯΄λŠ”λ°

SwiftUI의 λ·°κ°€ μƒνƒœμ˜ ν•¨μˆ˜λΌκ³  λ§ν•˜λ©΄ μ‚¬μš©μž μΈν„°νŽ˜μ΄μŠ€μ˜ λͺ¨μ–‘, 즉 μ‚¬λžŒλ“€μ΄ λ³Ό μˆ˜μžˆλŠ” 것과 μƒν˜Έ μž‘μš©ν•  μˆ˜μžˆλŠ” 것이 ν”„λ‘œκ·Έλž¨μ˜ μƒνƒœμ— 따라 κ²°μ •λœλ‹€λŠ” 것을 μ˜λ―Έν•œλ‹€. 예λ₯Ό λ“€λ©΄, ν…μŠ€νŠΈ ν•„λ“œμ— 이름을 μž…λ ₯ν•  λ•ŒκΉŒμ§€ 계속을 λˆ„λ₯Ό 수 μ—†λ‹€.

 

μ΄λ²ˆμ—λŠ” κ·Έλž˜μ„œ SwiftUIμ—μ„œ λ¬Έμžμ—΄κ³Ό λ²„νŠΌμ„ νƒ­ν• λ•Œλ§ˆλ‹€ μ‹€ν–‰ λ˜λŠ” μž‘μ—… ν΄λ‘œμ €λ₯Ό 생성할 μˆ˜μžˆλŠ” λ²„νŠΌμ„ 개발 ν•΄λ³΄μž.
 
struct ContentView: View {
    var tapCount = 0

    var body: some View {
        Button("Tap Count: \(tapCount)") {
            tapCount += 1
        }
    }
}

μ½”λ“œλ₯Ό 보면 λ”±νžˆ λ¬Έμ œκ°€ μ—†μ–΄ 보인닀. 근데 이 μ½”λ“œλŠ” μ‹€μ œλ‘œλŠ” λΉŒλ“œ λ˜μ§€ μ•ŠλŠ”λ° μ΄μœ λŠ” ContentViewλŠ” μƒμˆ˜λ‘œ 생성될 수 μžˆλŠ” ꡬ쑰체이닀. μ•žμ„œ μš°λ¦¬κ°€ 배운 ꡬ쑰체 파트λ₯Ό 기얡해보면 그건 μ›λž˜ λ³€ν•˜μ§€ μ•ŠλŠ” κ²ƒμ΄μ—ˆλ‹€. 

 

μš°λ¦¬κ°€ νŠΉμ„±μ„ λ³€κ²½ν• λ €λŠ” ꡬ쑰체 λ©”μ„œλ“œλ₯Ό μž‘μ„±ν•  λ•Œ mutationg ν‚€μ›Œλ“œλ₯Ό μΆ”κ°€ν•΄μ•Ό ν•œλ‹€. 

우리의 λͺ©μ μ€ λ²„νŠΌμ„ ν„°μΉ˜ ν• λ•Œλ§ˆλ‹€ 1μ”© μ¦κ°€ν•˜κ²Œ ν”„λ‘œκ·Έλž˜λ°ν•˜λŠ” 것이 λͺ©μ μ΄μ—ˆμ—ˆλŠ”λ° Viewκ°€ ꡬ쑰체이기 λ•Œλ¬Έμ— Swiftκ°€ κ·Έκ±Έ ν—ˆμš©ν•΄μ£Όμ§€ μ•Šμ•˜κΈ° λ•Œλ¬Έμ— μƒλ‹Ήνžˆ κ³€λž€ν•΄μ§„ 상황이닀.

 

 

 

이런 μƒν™©μ—μ„œ SwiftλŠ” 속성 래퍼(property wrapper)라고 ν•˜λŠ” νŠΉλ³„ν•œ 해닡을 μ œκ³΅ν•˜λŠ”λ° 속성에 효과적으둜 λŠ₯λ ₯을 λΆ€μ—¬ν•˜λŠ” 특수 속성이닀. κ·Έλž˜μ„œ ν˜„μž¬ μƒν™©μ—μ„œλŠ” @StateλΌλŠ” 속성 래퍼λ₯Ό μ‚¬μš©ν•˜κ²Œ λœλ‹€. 

struct ContentView: View {
    @State var tapCount = 0

    var body: some View {
        Button("Tap Count: \(tapCount)") {
            self.tapCount += 1
        }
    }
}

 

ꡬ쑰체가 κ³ μ •λ˜μ–΄μžˆκΈ° λ•Œλ¬Έμ— 속성을 λ³€κ²½ ν• μˆ˜ μ—†λ‹€λŠ” 것을 μ•Œκ³  μžˆμ§€λ§Œ @State을 μ΄μš©ν•˜λ©΄ ν•΄λ‹Ή 값을 μˆ˜μ • κ°€λŠ₯ν•œ μœ„μΉ˜μ— λ³„λ„λ‘œ μ €μž₯ν•  수 있게 λœλ‹€. λ”°λΌμ„œ @Stateλ₯Ό μ΄μš©ν•˜μ—¬ ꡬ쑰체의 ν•œκ³„λ₯Ό ν•΄κ²°ν•  수 μžˆλ‹€.

Tap Countλ₯Ό ν„°μΉ˜ν• λ•Œλ§ˆλ‹€ 카운트 μˆ«μžκ°€ μ»€μ§€κ²Œ λœλ‹€.

 

 


 

 

 

2. μ‚¬μš©μž μΈν„°νŽ˜μ΄μŠ€ μ»¨νŠΈλ‘€μ— μƒνƒœ 바인딩 ν•˜κΈ°

 

μ΄μ „μ—λŠ” @Stateλ₯Ό μ΄μš©ν•˜μ—¬ ꡬ쑰체의 ν•œκ³„λ₯Ό ν•΄κ²°ν•˜λŠ” 방법에 λŒ€ν•΄μ„œ μ•Œμ•„λ³΄μ•˜λŠ”λ° μ΄λ²ˆμ—λŠ” μ‚¬μš©μžκ°€ μž…λ ₯ν•  μˆ˜μžˆλŠ” νŽΈμ§‘ κ°€λŠ₯ν•œ ν…μŠ€νŠΈ ν•„λ“œλ₯Ό λ§Œλ“€μ–΄ 보자.

 

struct ContentView: View {
    var body: some View {
        Form {
            TextField("Enter your name")
            Text("Hello, world!")
        }
    }
}

자 μ΄λ ‡κ²Œ 해보면 또 κ³Όμ—° 잘될까? κ·ΈλŸ΄λ¦¬κ°€ μ—†λ‹€. SwiftUIλŠ” ν…μŠ€νŠΈ ν•„λ“œμ—μ„œ ν…μŠ€νŠΈλ₯Ό μ €μž₯ν•  μœ„μΉ˜λ₯Ό μ•Œκ³  μ‹Άμ–΄ ν•˜κΈ° λ•Œλ¬Έμ— ν•΄λ‹Ή μ½”λ“œλŠ” μ •μƒμ μœΌλ‘œ μ»΄νŒŒμΌλ˜μ§€ μ•ŠλŠ”λ‹€. 그럼 이것도 μ•„κΉŒμ™€ λΉ„μŠ·ν•˜κ²Œ μˆ˜μ •μ„ ν•΄λ³΄μž.

 

 

ν…μŠ€νŠΈ ν•„λ“œμ˜ κ²½μš°μ— ν…μŠ€νŠΈμ— μžˆλŠ” λͺ¨λ“  λ‚΄μš©μ΄ name 속성에도 포함 λ˜μ–΄μžˆλŠ”μ§€ 확인을 ν•΄μ•Ό ν•œλ‹€. 즉, μ‚¬μš©μžκ°€ λ³Ό 수 μžˆλŠ” λͺ¨λ“  것은 μ½”λ“œμ—μ„œ ꡬ쑰체와 μ†μ„±μ˜ κ°€μ‹œμ  ν‘œν˜„!! 이것을 μš°λ¦¬λŠ” μ–‘λ°©ν–₯ 바인딩이라고 ν•œλ‹€.

 

ν…μŠ€νŠΈ ν•„λ“œλ₯Ό 바인딩 ν•˜μ—¬ 속성 값을 ν‘œμ‹œ ν•˜μ§€λ§Œ ν…μŠ€νŠΈ ν•„λ“œλ₯Ό μˆ˜μ •ν•˜λ©΄ 속성도 μ—…λ°μ΄νŠΈν•˜λ„λ‘ λ°”μΈλ”©ν•œλ‹€λŠ” 것이닀. 

κ·Έλž˜μ„œ μ–‘λ°©ν–₯ 바인딩을 ν• λ•Œ 특수 기호인 $λ₯Ό μ‚¬μš©ν•˜μ—¬ 속성값을 읽고 λ³€κ²½ 사항이 λ°œμƒν•˜λ©΄ λ‹€μ‹œ 써야 ν•œλ‹€κ³  Swiftμ—κ²Œ μ•Œλ €μ£ΌλŠ” 역할을 ν•œλ‹€. 이제 λͺ¨λ“  μ •λ¦¬λŠ” λλ‚¬μœΌλ‹ˆ μ½”λ“œλ‘œ ν•œλ²ˆ μ •λ¦¬ν•΄λ³΄μž.

 

struct ContentView: View {
    @State private var name = ""

    var body: some View {
        Form {
            TextField("Enter your name", text: $name)
            Text("Your name is \(name)")
        }
    }
}

 

 

 


 

 

3. Viewμ—μ„œ λ°˜λ³΅μ‚¬μš©

 

 

View λ‚΄μ—μ„œ λ°˜λ³΅λ¬Έμ„ μ‚¬μš©ν•˜λŠ” κ²½μš°λŠ” 생각보닀 λ§Žλ‹€. 예λ₯Ό λ“€λ©΄ 이름 배열을 반볡적으둜 λ³΄μ—¬μ£Όκ±°λ‚˜ 메뉴 ν•­λͺ© 배열을 생성할 λ•Œκ°€ κ·Έλ ‡λ‹€. SwiftUIλŠ” μ΄λŸ¬ν•œ λͺ©μ μ„ μœ„ν•΄ ForEachλ₯Ό μ‚¬μš©ν•˜κ²Œ λ˜λŠ”λ° 이건 λ°°μ—΄κ³Ό λ²”μœ„λ₯Ό λ°˜λ³΅ν•΄μ„œ ν•„μš”ν•œ 만큼 Viewλ₯Ό 생성할 수 μžˆλ‹€. 

 

λ˜ν•œ ForEachλ₯Ό μ‚¬μš©ν•˜λ©΄ 10개의 λ·° μ œν•œ λ˜ν•œ μ—†λ‹€. 

λ°”λ‘œ μ‚¬μš©ν•΄λ³΄μžλ©΄

Form {
    ForEach(0..<100) { number in
        Text("Row \(number)")
    }
}

 

 

 

ForEachλŠ” λ˜ν•œ SwiftUI둜 μž‘μ—…ν•  λ•Œ 특히 μœ μš©ν•œλ°, Picker와 ν•¨κ»˜ μ‚¬μš©ν•˜λ©΄ μ‚¬μš©μžκ°€ 선택할 수 μžˆλŠ” λ‹€μ–‘ν•œ μ˜΅μ…˜μ„ ν‘œμ‹œν•  수 μžˆλ‹€. 

 

κ·Έλž˜μ„œ 이걸 λ°”λ‘œ μ˜ˆμ‹œλ‘œ 보기 μœ„ν•΄ μ•„λž˜μ™€ 같은 Viewλ₯Ό μ •μ˜ν•΄λ³΄μž

  1. 학생 이름에 λŒ€ν•œ 배열이 μžˆλ‹€.
  2. ν˜„μž¬ μ„ νƒν•œ 학생을 μ €μž₯ν•˜λŠ” 속성인 @Stateλ₯Ό μ΄μš©ν•œλ‹€. 
  3. μ‚¬μš©μžμ— λŒ€ν•œ μ–‘λ°©ν–₯ 바인딩을 μ‚¬μš©ν•˜μ—¬ 즐겨찾기λ₯Ό μ„ νƒν•˜λ„λ‘ Picker viewλ₯Ό μƒμ„±ν•œλ‹€. 
  4. ForEachλ₯Ό μ‚¬μš©ν•˜μ—¬ κ°€λŠ₯ν•œ λͺ¨λ“  학생 이름을 λ°˜λ³΅ν•˜μ—¬ Text View둜 λ°”κΎΌλ‹€. 

 

 

struct ContentView: View {
    let students = ["Harry", "Hermione", "Ron"]
    @State private var selectedStudent = "Harry"

    var body: some View {
        NavigationView {
            Form {
                Picker("Select your student", selection: $selectedStudent) {
                    ForEach(students, id: \.self) {
                        Text($0)
                    }
                }
            }
        }
    }
}

 

 

μ—¬κΈ°μ„œ 짚고 λ„˜μ–΄κ°€μ•Ό ν•˜λŠ” 것 λͺ‡ κ°€μ§€λ§Œ 더 μ‚΄νŽ΄λ³΄μž.

  1. selectedStudent 속성은 Harryκ°’μœΌλ‘œ μ‹œμž‘ν•˜μ§€λ§Œ 이후 μ‚¬μš©μžμ— μ˜ν•΄ 변경될 수 있기 λ•Œλ¬Έμ— @Stateλ₯Ό μ‚¬μš©ν•œλ‹€.
  2. Pickerλ ˆμ΄λΈ”μ„ 톡해 학생 선택할 수 μžˆλ‹€.
  3. Picker와 selectedStudent 사이에 μ–‘λ°©ν–₯ 바인딩이 μžˆλ‹€. μ•žμ„œ λ§ν–ˆλ“― μ‚¬μš©μžμ— μ˜ν•΄ 값이 변경될 수 있기 λ•Œλ¬Έμ΄λ‹€. 

 

μ—¬κΈ°μ„œ 쑰금 μ–΄λ €μ› λ˜ 뢀뢄은 ForEach(students, id: \. self)둜 SwiftUIκ°€ ν™”λ©΄μ˜ λͺ¨λ“  viewλ₯Ό κ³ μœ ν•˜κ²Œ 식별할 수 μžˆμ–΄μ•Ό ν•˜λ―€λ‘œ 상황이 변경될 λ•Œ 감지할 수 있게 ν•˜κΈ° μœ„ν•΄ μ‘΄μž¬ν•˜λŠ”λ° \. selfκ°€ μ˜λ―Έν•˜λŠ” λ°”λŠ” λ¬Έμžμ—΄ μžμ²΄κ°€ κ³ μœ ν•˜λ‹€λŠ” 것을 μ˜λ―Έν•œλ‹€.

 

 


κΈ΄κ°€λ―Όκ°€ν•˜κ²Œ λ°°μ›Œ μ• λ§€ν–ˆμ§€λ§Œ 이후 μžμ„Έν•œ λ‚΄μš©μ€ 이후 ν”„λ‘œμ νŠΈλ₯Ό μ§„ν–‰ν•΄λ³΄λ©΄μ„œ μ°¨κ·Όμ°¨κ·Ό λ‹€μ‹œ ν•΄λ³΄μž!!

learning by repetition

 

 

λ°˜μ‘ν˜•