Day 16 ~ 18 : project 1

sun·2021년 9월 20일
0

100 Days of SwiftUI

목록 보기
10/11

[Day 16]   [Day 17]   [Day 18]

# Views and UIwindows

  • view 는 state의 결과로 유저 인터페이스를 구성함
  • UI window 는 view들을 담는 컨테이너
  • 참고

# Form

  • 데이터 입력에 사용되는 컨트롤을 그룹화한 컨테이너
  • formmodifier 를 추가하면 form 의 새로운 카피가 생성됨

# @state

  • 구조체 내의 연산 프로퍼티가 구조체의 변수를 변경할 수 있도록 하는 프로퍼티 래퍼
    struct ContentView: View {
        @State var tapCount = 0
        
        var body: some View {
            Button("Tap Count: \(tapCont)" {
                self.tapCount += 1
            }
        }
    }

# Two-way binding

  • two-way binding 이 되는 경우 양자가 서로 영향을 받음
  • $ 를 붙여서 two-way binding 임을 나타낼 수 있음
    struct ContentView: View {
        @State private var name = ""

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

# Challenge

총 금액을 나타내는 섹션 만들기

  • 처음에는 grandTotal 변수만 따로 선언해서 totalPerPerson 변수 연산 과정 중에 값을 지정해줄 수 있지 않을까 했는데 이 방법은 불가능했다

    • 원인 : 렌더링 중 grandTotal 변수가 변경되어 다시 렌더링을 요청하게 되므로 SwiftUI가 혼란에 빠짐!

  • 다양한 방법을 고민하다가 그냥 아예 grandTotal 변수와 그와 관련된 일련의 연산 과정을 별도의 연산 프로퍼티로 정의해서 해결했다

    var grandTotal : Double {
        let tipSelection = Double(tipPercentages[tipPercentage])
        let orderAmount = Double(checkAmount) ?? 0
        
        let tipValue = orderAmount * tipSelection / 100
        let totalAmount = orderAmount + tipValue
        
        return totalAmount
    }
    
    var totalPerPerson : Double {
        let peopleCount = Double(numberOfPeople) ?? 0
        let amountPerPerson = grandTotal / peopleCount
        
        return amountPerPerson
    }

Number of people Picker를 text field로 바꾸기

  • 처음에는 그냥 Picker 부분 코드를 TextField 로 바꿔줬는데 다음과 같은 2가지 문제가 있었다
    TextField("Number of People", text: $numberOfPeople)
        .keyboardType(.numberPad)
  • TextField 는 기본적으로 입력을 문자열 형태로 받는데 numberOfPeople 을 Int로 초기화했다 : 이 부분은 초기화를 빈 문자열로 바꿔줘서 해결
    @State private var numberOfPeople = ""
  • totalPerPerson 을 구하기 위해 이제 numberOfPeople 을 형변환하면 옵셔널 더블 이 되므로 nil coalescing 이 필요했는데 별 생각없이 nil 일 때의 디폴트 값을 0으로 설정했더니 아마도 ZeroDivisionError 가 발생했는지 아무것도 입력하기 전 앱을 처음 킨 상태에서 NaN 이 떴다... : 디폴트 값을 1 로 바꿔서 해결!
    let peopleCount = Double(numberOfPeople) ?? 1

WeSplit 깃허브 링크


☀️ TIL

  • body 가 하나의 프로퍼티라니...다 작성하고 짚어줘서 알았다...프로퍼티에 대한 고정관념이 있었던 것 같다...결국 하나의 view를 리턴하므로 하나의 연산 프로퍼티라는 점이 아직 엄청 와닿지는 않지만 계속 해보다보면 익숙해지겠지 싶은 마음...!
  • TextField 는 항상 문자열을 받으므로 다른 타입으로 사용하고 싶다면 형 변환 이 필요하다
  • .navigationBarTitle() modifier 와 관련해서 NavigationView 가 끝나는 시점에 써야되는 게 아닌가 했는데, 그 내부의 Form 이 끝나는 시점에 attach 해야 navigation view 가 여러개의 view를 계속 보여줄때 제목을 자유롭게 변경할 수 있다고 한다...
  • 음 사실 100 days of SwiftUI를 선택한 가장 큰 이유 중 하나가 업데이트를 빠르게 반영한다는 이야기를 많이 봤기 때문이었는데 첫 플젝부터 xcode 구버전을 사용하고 있다는 점이 의아했고, 초보자를 위한 설명이 다소 불충분하다는 느낌을 좀 받았다...일단 첫 플젝은 마저 따라가보고 이후에 Apple Developer SwiftUI Tutorial이나 스탠포드 강의를 들어볼 지 다시 고민해봐야겠다...
profile
☀️

0개의 댓글