기어가더라도 제대로

[SwiftUI-기초] ScrollView, Stack, Lazy Stack 본문

SwiftUI - 기초

[SwiftUI-기초] ScrollView, Stack, Lazy Stack

Damagucci-juice 2022. 11. 8. 22:11
  • 사실 List, ForEach 를 쓰면 스크롤링이 되는 데이터들의 로우를 만들 수 있는데 좀 더 커스텀하게 무언가를 조절하고 싶다면...
  • ScorllView 를 만들어야합니다. 그래도 UIScrollView 를 만드는 것만큼 어렵지는 않습니다.
  • List의 경우엔, Table 형태로 된 데이터를 다루기 좋지만, ScrollView 를 사용하면, 독자적인 데이터를 다룰 수 있습니다. 
  • 예를 들면 웹툰의 뷰...? 
    • 네이버 웹툰의 경우 만화 이미지 초안이 800 * 20000 정도라고 하는데,
      이런 수직으로(혹은 수평으로) 긴 이미지를 다룰 때 효과적입니다. 
  • 거두절미하고 ScrollView를 어떻게 만드는지 알아보도록 하겠습니다. 

...?

  • scrollView indicater 도 숫자 바로 옆에 생깁니다 ...
  • 이를 해결하기 위해 VStack에 화면 너비만큼을 줘보죠
ScrollView {
    VStack(spacing: 10) {
        ForEach(0..<100) {
            Text("Item \($0)")
                .font(.title)
        }
    }
    .frame(maxWidth: .infinity)
}

  • 같아 보이지만 인디케이터가 오른쪽 가장자리에 생겼습니다. 

수평 이동 스크롤뷰

  • 위는 수직 스크롤 뷰 였다면, 수평 스크롤뷰도 간단하다.
  • ScrollView 생성할 때 .horizontal 를 넘기고
  • VStack에서 HStack으로 변화하면 끝이다.
ScrollView(.horizontal) {
    HStack(spacing: 10) {
        ForEach(0..<100) {
            CustomText("Item \($0)")
                .font(.title)
        }
    }
}

한꺼번에 생성 VS. 필요할 때마다 생성 

struct CustomText: View {
    let text: String

    var body: some View {
        Text(text)
    }

    init(_ text: String) {
        print("Creating a new CustomText:: \(text)")
        self.text = text
    }
}


struct ContentView: View {
    var body: some View {
        ScrollView {
            VStack(spacing: 10) {
                ForEach(0..<100) {
                    CustomText("Item \($0)")
                }
            }
            .frame(maxWidth: .infinity)
        }
    }
}
  • 이런 커스텀 Text 를 만들어주고, 생성될 때마다 프린트를 찍게했습니다. 
  • 앱을 실행시키면 어떤 결과가 일어날까요? 

  • 아직 item25 밖에 보지 못하는데 말이죠.. 100개의 Text 가 생긴것을 볼 수 있습니다. 
  • VStack에 등록된 모든 뷰를 즉시 생성한 모습입니다. 
  • 시스템적으로 낭비일 수도 있겠다는 생각입니다. 
  • 그때 그때 필요한 양의 뷰만을 생성하는 방법이 있습니다.

Lazy V(H)Stack

  • 아주 간단한 사용법입니다. 
  • VStack 을 LazyVStack으로 바꿔주기만 하면 됩니다. 
struct ContentView: View {
    var body: some View {
        ScrollView {
            LazyVStack(spacing: 10) {
                ForEach(0..<100) {
                    CustomText("Item \($0)")
                }
            }
            .frame(maxWidth: .infinity)
        }
    }
}

  • 26개(+ A)만 생성한 모습입니다. 
    • 똑같은 번호를 2번 생성하는 경우도 있긴한데 왜 그런지는 모르겠네요.

Regular Stack 과 Lazy Stack 비교

  • 이 둘은 똑같은데 비용적인 측면에서만 다릅니다.
  • Regular Stack 
    • 필요한 만큼 자원을 차지합니다.
  • Lazy Stack
    • 우리가 볼 수 있는 layout 안에서 여분의 공간만큼 자원을 차지합니다. 
  • 오호.. 그렇다면 항상 Lazy Stack 이 좋은거같은데... 왜 기본적으로 Apple 은 일반 Stack 을 사용하게 할까요? 
    • 그리기작업 외에 자원을 소모합니다.
      • 어떤뷰가 그려졌고, 어떤뷰가 아직 안그려졌는지에 대한 시간적, 메모리적 자원을 소모합니다. 
    • 사용자 반응성이 떨어집니다. 
      •  만약에 LazyVStack 안에 Horizontal ScrollView가 있다고 가정을 해볼게요.
      • 이미지의 썸네일들이 수평으로 스크롤되는데 이 이미지들은 미리 준비가 안되어있고 필요할 때마다 그려질 것입니다.
      • 두둑두둑 끊기는 사용자 경험을 낼 것으로 예상이 되죠. 
      • Scroll하는 주체가 이미지와 같이 큰 데이터라면 스크롤할 때 미처 이미지가 마련이 안될 가능성이 있습니다.
      • 이런 경우엔 한번에 만들어놓고 기다리는 것이 좋지요. 
  • 그래서 기본적으로 ! VStack, HStack을 사용을 해보고요.
  • instrument profiling 을 통해서 메모리 등에 문제가 있다면
    추가적으로 LazyVStack, LazyHStack 등을 사용하는 것이 좋다고 합니다. 
    • 예를들어 ScollView 안에 VStack, HStack 등을 담는 것이 추천됨...
Comments