일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
Tags
- Swift
- 비동기
- Codable
- deadlock
- struct
- @state
- 앨런
- 알고리즘
- 100 days of SwiftUI
- 인프런
- 프로세스 스케줄링
- SwiftUI
- decode
- core data
- Algorithm
- 오브젝트
- UserDefaults
- scrollview
- IOS
- 동기화
- 데드락
- Linked List
- 상호배제
- 운영체제
- 가상 메모리
- forEach
- Apple Developer Academy
- async
- COLOR
- 동시성
Archives
- Today
- Total
기어가더라도 제대로
[SwiftUI-기초] 양방향 바인딩(two-way binding), ForEach 본문
UI에서 얻는 값을 저장 - 양방향 결합(two-way binding)
- 이 코드는 오류를 뱉음
- TextField 에서 얻을 값을 저장할 공간을 만들어 주지 않았기 때문
- struct 내부에 텍스트 필드에서 얻은 값을 저장할 property가 필요
- 다음과 같이 선언해주었는데 과연 될까?
struct ContentView: View {
@State private var name = ""
var body: some View {
Form {
TextField("Enter your name", text: name)
Text("Hello, world!")
}
}
}
- 이것도 오류를 냄
- 이는 Swift 가 property 의 기능을 다르게 두었음
- "property 의 값을 여기에 보여주세요"
- 저번 튜토리얼에서 button 의 text 가 변경되는 경우
- "property의 값을 여기에 보여는 주는데요, 만약 변경사항이 생기면 다시 property에 써주세요."
- 위의 예제의 경우
- "property 의 값을 여기에 보여주세요"
- 이를 two-way binding 이라고 함
- text field 에 name 속성을 보여주고
- text field 에서 일어나는 변경사항을 name property 에 업데이트함
- 이 특별한 binding 을 "$" 표시로 한다.
- "프로퍼티에서 값을 읽고요, 변경사항이 생기면 그 프로퍼티에 다시 써주세요" 라고 swift 에게 전하는 약속
struct ContentView: View {
@State private var name = ""
var body: some View {
Form {
TextField("Enter your name", text: $name)
Text("Your name is \(name)")
}
}
}
- name 과 $name의 차이점
- 양방향 바인딩을 여기서 하겠다 -> $name
- 양방향 바인딩을 여기서 하지 않겠다. -> name
- Text 는 변경될 일이 없기 때문
반복문 안에서 view 생성
여기서 주인공은 ForEach 입니다.
- 범위나 배열을 돌면서 뷰를 만드는 작업을 반복할 수 있다.
- 10 개 view 제한에도 걸리지 않는다. (직접 타이핑 하면 걸림, 10개 이상 생성할 수 있다는 뜻)
- 범위나 배열과 하나의 요소를 넘겨받았을 때 실행할 클로저도 같이 넘긴다.
Picker 뷰와 함께 사용되는 예시
- 이름의 배열이 있습니다.
- 현재 선택된 학생의 이름을 저장하는 @State 변수가 있습니다.(기본값은 "Harry")
- 사용자에게 가장 좋아하는 학생을 고르도록 Picker 뷰를 생성하고 양방향 바인딩으로 @State property 에게 연결합니다.
- ForEach 를 사용해 모든 학생의 이름이 반복해서 Text 뷰에 나타나도록 합니다.
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)
}
}
}
}
}
}
- selectedStudent 변수는 기본값이 "Herry" 이긴 하지만 변경 가능성이 있으므로 @State 프로퍼티 래퍼를 붙입니다.
- Picker 는 label 을 갖는데 사용자에게 무엇을 할지 알려주고, Screen reader 가 읽는 정보를 제공합니다.
- Picker 는 selectedStudent와 양방향 바인딩 되어있습니다.
- ForEach 내부에서 모든 학생의 이름을 반복합니다.
- 학생의 이름마다 Text 뷰를 생성해 학생의 이름을 보여줍니다.
여기까진 쉬우리라 생각합니다.
근데 id: \.self 가 낯설어 보입니다.
- SwiftUI 가 뷰가 변경되면 감지할 id
- 모든 뷰를 고유하게 인식하는데 도움을 줌
- "Ron" 을 이름 배열에서 가장 앞으로 가져다 놓으면, SwiftUI 도 그에 맞춰 뷰를 생성
- 각각의 항목을 구별할 수 있도록 지정해줘야합니다.
- ForEach(students, id: \.self) 의 해석
- students 속성을 쓸 건데
- 이 속성의 요소들의 고유한 요소가 그 자체야.
- 만약 student 가 단순한 문자열의 배열이 아니라 Student 같은 struct 였다면, 학번이 있을 수 있고, 이름이 있을 수 있는데,
- 그 구조체의 고유한 식별자를 선언하는 것이라고 보면 됨
- 여기서는 단순한 문자열이기 때문에 그 자체가 (\.self) 고유한 식별자라고 알려주는 상황
- SwiftUI 는 ForEach 를 하면 "어떤 식별자가 문자열 배열에서 각 항목 아이템을 유일하게 해주는가"를 묻는데
- 여기에 "string 그자체로 유일해요" 라고 답하는 모양새
- 만약 문자열 배열에 중복되는 값이 있으면 문제 가능성이 있음
'SwiftUI - 기초' 카테고리의 다른 글
[SwiftUI-기초] HStack, VStack, ZStack (0) | 2022.10.09 |
---|---|
[SwiftUI-기초] Picker, Segment Control, Keyboard 반응 (0) | 2022.10.08 |
[SwiftUI-기초] TextField (1) | 2022.10.07 |
[SwiftUI-기초] Form, Navigation bar, State (1) | 2022.10.05 |
[SwiftUI-기초] SwiftUI의 기본 구조 (0) | 2022.10.04 |
Comments