Dog foot print

[SWIFT UI]들어가기 앞서 정리 본문

IOS/SwiftUI

[SWIFT UI]들어가기 앞서 정리

개 발자국 2021. 9. 25. 17:38

XCODE 13변화

XCODE 13이 배포되고 IOS15가 배포 되며 Swift UI 에서는 더이상 App delegate Life cycle을 사용 할 수 없게 되었다. Xcode 12버전에서는 Swift UI를에서 App Delegate와 Scene Delegate를 사용하며, 앱의 상태변화를 체크 하였지만 이제는 SwiftUI life Cycle만 사용 가능하며, 이로 인하여 지금 현재 인터넷에 존재하는 대다수 강의들과 차이가 존재하기에 처음 배우는 사람들의 난황이 예상된다.

링크 모음

  1. : Swift 프로젝트 생성에서 Life Cycle 선택하기

View Protocol

기존 UIKIt 에서는 UIView Class 를 상속하여 이를 인스턴스화 하는 형식이었다. 그러나, Swift에서 View를 그리기 위해서는 구조체에 View 프로토콜을 준수하는 형태이며, 내부에 View 를 리턴하는 body라는 변수를 선언해야 한다.

import SwiftUI

struct ContentView: View {  
    var body: some View {
            Text("Hello world")
    }
}

Some Keyword

위의 View Protocol Section 에 보면 body 는 Computed Property 임과 동시에 some View 타입인 것을 볼 수 있다.

Some keyword 는 swift 5.1의 새로운 기능이며, 이를 요약하면 프로토콜 X를 준수하는 것이다.

view를 준수하는 다양한 Text, Rectangle 과 같은 구조체가 많고, 이 변수는 수시로 어떤 View protocol을 준수하는 구조체가 사라질 수도 있고 생성 될 수 도 있다. 이런 경우, 이 body가 무슨 타입인지 계속해서 명시해주어야 하고 이는 코드의 복잡성을 높이는 요인이 된다. 그래서 some이라는 키워드로 body 변수가 무엇인지는 모르지만 이 변수는 view protocol을 준수하는 무언가를 return 한다 라고 명시하는 것이다.

링크 모음

  1. : Swift - some 키워드란 무엇일까?
  2. SwiftUI - some 키워드에 대한 정리
  3. What’s this “some” in SwiftUI?. An Intuitive Explanation of The New… | by Mischa Hildebrand | Medium

@state

import SwiftUI

struct ContentView: View {

    var buttonTitle = "default State"

    var body: some View {
        Button(buttonTitle) {
            self.buttonTitle = "changed State"
        }
    }
}

위의 코드는 button을 터치 한 경우 button의 title을 변경하도록 한 예시 코드이다.

이 코드를 실행하려고 하면 Cannot assign to property: 'self' is immutable 라며 변경 할 수 없다고 오류가 발생하는데, 이는 구조체에서 mutating 으로 선언된 함수에서만 값을 변경 시킬 수 있기 때문이다.

struct ContentView: View {

    var buttonTitle = "default State"

    var body: some View {
        Button(buttonTitle) {
            self.changed()
        }
    }

    mutating func changed(){
        buttonTitle = "changed State"
    }
}

그래서 위와 같이 값을 변경 하도록 꼼수를 사용하면, 이 또한 사용 할 수 없다고 에러를 발생 시킨다.

어떤 값의 상태를 body내부에서 변경 시키도록 하고, 이에 반응하여 body가 새롭게 갱신되려면 다음과 같이 @state private 를 사용하여야 한다.

struct ContentView: View {

    @State private var buttonTitle = "default State"

    var body: some View {
        Button(buttonTitle, action: {
            buttonTitle = "changed State"
        })
    }
}

@binding

어떤 하위 뷰에서 상위 뷰의 상태를 변경하여야 할 때가 존재한다. 이런 경우, 상위 뷰에서는 하위 뷰에게 해당 상태 주소를 전달해야 하며, 하위 뷰는 해당 상태가 상위로 부터 온 것임을 명시해야할 필요가 있다.

struct ContentView: View {

    @State private var buttonTitle = "default State"
    @State private var isToggleOn = false
    var body: some View {
        VStack{
            Text("is toggle on ? : \(isToggleOn.description)")
            ButtonView(isToggleOn: $isToggleOn, buttonName: $buttonTitle)
        }
    }
}

struct ButtonView : View {

    @Binding var isToggleOn : Bool
    @Binding var buttonName : String

    var body : some View {
        Button(buttonName) {
            isToggleOn = !isToggleOn
            if isToggleOn {
                buttonName = "changedState"
            }else{
                buttonName = "defaultState"
            }
        }
    }
}

링크 모음

  1. SwiftUI 튜토리얼 5편 — @State, @Binding, @ObservedObject | by Harry The Great | 해리의 유목코딩 | Medium

#swift #swiftui

반응형
Comments