개발

SwiftUI) @State 변수를 id(_)에 적용하여 화면 갱신하기!

소소ing 2022. 5. 10. 15:43
반응형

@State 변수의 상태 변경되면 @State 변수가 가지고 있는 컴포넌트를 갱신 시킬 수 있다고 알고 있다. 

여기서는 해당 변수값을 SwiftUI View의 id에 대입하여 화면을 갱신 할 수 있는 방법이 있다는 것을 보려고 한다. 

 

먼저 id(_)는 SwiftUI Views들을 식별하는 고유 값으로 보면 될듯 하다. 

즉 View의 id(_) 값을 변경한다는 건 새로운 뷰를 보이는 것과 같다고 볼 수 있다. 

 

예를 들어, 이름, 이메일, 웹 사이트를 사용자로 부터 입력 받는다고 가정할때, ContentView에서 ExampleView를 호출하는 구조이며, ExampleView의 id를 @State 변수 값으로 지정하여 Reset 버튼으로 해당 값을 수정한다면... 

사용자로 부터 입력을 모두 받더라도 Reset 버튼 클릭 시 초기 상태로 변경이 되어 버린다. 

이는 theId = 0 인 ExampleView()와 theId = 1인 ExampleView()는 다른 뷰로 간주되기 때문이다. 

즉, 0인 View가 1인 View로 대체가 되었다고 보는게 맞을듯 하다.

struct ContentView: View {
    @State private var theId = 0
    
    var body: some View {
        VStack {
            ExampleView().id(theId)
            
            Button("Reset") { self.theId += 1 }
        }
    }
}

struct ExampleView: View {
    @State private var firstname = ""
    @State private var lastname = ""
    @State private var email = ""
    @State private var website = ""

    var body: some View {
        Form {
            TextField("Enter firstname", text: self.$firstname)
            TextField("Enter lastname", text: self.$lastname)
            TextField("Enter email address", text: self.$email)
            TextField("Enter website address", text: self.$website)
        }
    }
}

 

하여 theId 값을 다시 0으로 한다고 해서 이전 입력받아 출력했던 화면이 다시 나오는것이 아니라 새로운 id값이 0 인 View로 대체가 되어버린다. 

 

그럼 그냥 @State 변수만 사용하면 되지 View id를 사용하는 방법은 무엇일까?

List 정렬, 랜덤 순서 등을 사용할때 그 개수가 많을 경우 View id를 사용하게 되면 빠르게 정렬 및 랜덤 순서 출력을 마칠 수 있는 장점이 있다. 

// View id를 사용하지 않을 경우 
extension String {
    static func random(length: Int = 20) -> String {
        String((0..<length).map { _ in "ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890".randomElement()! })
    }
}

struct ContentView: View {
    @State private var array = (0..<500).map { _ in String.random() }
    
    var body: some View {
        VStack {
            List(array, id: \.self) { item in
                Text("\(item)")
            }

            Button("Shuffle") {
                self.array.shuffle()
            }
        }
    }
}

// View id를 사용할 경우
extension String {
    static func random(length: Int = 20) -> String {
        String((0..<length).map { _ in "ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890".randomElement()! })
    }
}

struct ContentView: View {
    @State private var theId = 0
    @State private var array = (0..<500).map { _ in String.random() }
    
    var body: some View {
        VStack {
            List(array, id: \.self) { item in
                Text("\(item)")
            }.id(theId)

            Button("Shuffle") {
                self.array.shuffle()
                self.theId += 1
            }
        }
    }
}

아래 영상을 보면 속도 차이를 체감할 수 있다. 

 

[출처]

https://swiftui-lab.com/swiftui-id/

반응형