본문 바로가기

iOS

[iOS] iOS 14 SwiftUI Features

Introduce


본 포스트에서는 iOS14 SwiftUI의 주요 변경 Feature들을 간단한 예시 코드와 함께 소개합니다.

 

 

What’s New in SwiftUI 2.0(iOS 14.0)


 

 

RootView 설정


 

AppDelegate 혹은 SceneDelegate를 통하지 않고 아래와 같은 방법으로 RootView를 설정하게 되었습니다.

 

@main
struct DemoApp: App {
    var body: some Scene {
        WindowGroup {
            ContentView()
    }
}

@Main 특성을 적용하여 프로그램 흐름에 대한 최상위 진입점을 나타냅니다.

 

LazyVStack & LazyHStack


Apple Developer Documentation

Apple Developer Documentation

 

이전 버전까지 SwiftUI의 뷰는 즉시 로드되는 구조였습니다.

 

따라서 대량의 데이터를 뷰에 보여줄때 성능 및 메모리에 대한 우려가 있었는데요,

 

이에 따라 애플은 SwiftUI 2.0에서 lazy한 방식으로 컨텐츠를 로드하는 VStack과 HStack을 제공하였습니다. (ListVIew에도 당연히 적용됩니다 🙂)

 

struct ContentView: View {

    var body: some View {

        ScrollView(.horizontal) {

            **LazyHStack(spacing: 10) {**
                ForEach(0..<1000) { index in
                    Text("\(index)")
                            .frame(width: 100, height: 200)
                            .background(Color.blue)
                }
            }
            .padding(.leading, 10)
        }
    }
}

 

이와 같이 lazy한 성격을 띄는 스택뷰는 스크린에 렌더가 필요하기 이전까지는 아이템을 생성하지 않는 특성을 갖습니다.

 

ScrollViewReader를 통한 ScrollView 기능 강화


Apple Developer Documentation

Apple Developer Documentation

 

SwiftUI 첫 버전은 ScrollView 의 제한된 기능으로 인해 많은 어려움이 있었다고 합니다.

 

iOS 14에서는 ScrollViewReaderScrollViewProxy 를 통해 ScrollVIew의 포지션을 제어할 수 있게 되었습니다.

 

struct ContnetView: View {

    var body: some View {

        ScrollView(.horizontal) {

                **ScrollViewReader { scrollViewProxy in       // ScrollViewReader 를 생성하여 ScrollViewProxy를 전달받습니다.**

                    LazyHStack(spacing: 10) {
                        ForEach(0..<6) { index in
                            Text("\(index)")
                        }

                        Text("leadingAnchor로 스크롤!")
                            .onTapGesture {
                                    **scrollViewProxy.scrollTo(0, anchor: .leading)    // Proxy 객체를 통해 ScrollView의 스크롤 포지션을 제어합니다**
                            }
                    }
            }    
    }
}

 

ScrollView 내에 ScrollViewReader를 생성하면 ScrollViewProxy 인스턴스를 전달받게 되고 해당 Proxy 인스턴스를 통해 코드 기반의 스크롤링 제어가 가능합니다.

 

ProgressView


Apple Developer Documentation

 

이전 버전까지는 SwiftUI 자체적으로 ActivityIndicator 를 제공하지 않아 UIViewRepresentable 을 통해 UIActivityIndicator 를 표현하였습니다.

 

iOS 14부터는 이를 ProgressView 라는 이름으로 제공하며 두 가지의 스타일을 제공합니다.

  • CircularProgressViewStyle(tint:) - UIActivityIndicator와 동일한 생김새를 갖습니다.
  • LinearProgressViewStyle(tint:) - 선형의 막대바 생김새를 갖습니다.
struct ContentView: View {

    var body: some View {

        VStack {                                           
            ProgressView("다운로드중...", value: someBinding, total: 100) //총값: 100
                                **.progressViewStyle(LinearProgressViewStyle(tint: .red)    // 선형의 ProgressView**

                        ProgressView(value: someBinding)
                                **.progressViewStyle(CircularProgressViewStyle(tint: .red))  // ActivityIndicator 모양의 ProgressView**
        **}**

    }
}

 

 

Labels, Links, and ColorPickers


Apple Developer Documentation

Apple Developer Documentation

Apple Developer Documentation

 

 

Label에서는 생성시 systemImage 를 인자로 받아 해당 이미지를 텍스트 옆에 띄울수 있게 되었습니다.

Label("SwiftUI 2.0 New Feature", systemImage: "checkmark.icloud")

 

Link는 URL로의 네비게이션을 제공하는 구조체입니다.

Link("Nav to URL", destionation: URL(string: "your_url"))

 

Link를 통해 웹 브라우저로 이동하거나 유니버셜 링크의 경우 관련 어플로 이동합니다.

ColorPicker가 Native로 제공되었으며 @State 프로퍼티를 통해 사용자가 선택한 색상을 업데이트 할 수 있습니다.

ColorPicker("Sample Picker", selection: $selectedColor)

 

 

TextEditor, MapKit


Apple Developer Documentation

Apple Developer Documentation

 

멀티라인 스크롤이 가능한 UITextView가 SwiftUI에서는 TextEditor라는 이름으로 제공됩니다.

 

TextEditor(text: $stateProperty)

 

기존에 UIViewRepresentable 내부에 wrapping되어 제공되던 MapKit이 이제 기본으로 제공됩니다.

 

MKCoordinateRegion 을 통해 사용자의 위치를 보여주는 등 MapKit이 제공하던 기능들을 SwiftUI의 인터페이스로 제공할 수 있게 되었습니다.

 

onChange Modifier


Apple Developer Documentation

 

iOS14 부터 지원되는 새로운 ViewModifier로 상태 변화를 감지하다가 변화가 발생하면 액션을 수행합니다.

 

struct ContentView: View {
    @State var currentText: String = "안녕하세요 이안입니다 :)"
    @State var clearText: Bool = false

    var body: some View {
        VStack {
            TextEditor(text: $currentText)
                .onChange(of: clearText) { _ in
                    if clearText {
                        currentText = ""
                }
            }

            Button(action: { clearText = true }, label: {
                Text("Clear")
            })
        }
    }
}

 

버튼을 터치하면 TextEditor에 기재되어있는 Text를 클리어합니다.

 

'iOS' 카테고리의 다른 글

[iOS] Clean Architecture  (0) 2022.05.07
[iOS] iOS 15 SwiftUI Features  (0) 2022.02.07
[iOS] iOS 13 SwiftUI Features  (0) 2022.02.04
[iOS] Using AVAudioEngine to Record Audio on iOS  (0) 2021.12.11
[iOS] AVAudioEngine  (0) 2021.12.10