[SwiftUI] CryptoApp: App Icon & Launch Animation

Junyoung Park·2022년 11월 5일
0

SwiftUI

목록 보기
93/136
post-thumbnail
post-custom-banner

App Icon, Launch Screen, and Launch Animation | SwiftUI Crypto App #24

CryptoApp: App Icon & Launch Animation

구현 목표

  • 앱 아이콘 및 런치 스크린 애니메이션 적용

구현 태스크

  • 런치 스크린 스토리보드 구현
  • 런치 스크린 커스텀 뷰 구현
  • 메인 연결 시 ZStack을 통한 준비 단계 구현

핵심 코드

var body: some Scene {
        WindowGroup {
            ZStack {
                NavigationView {
                    HomeView()
                        .toolbar(.hidden)
                }
                .environmentObject(viewModel)
                ZStack {
                    if showLaunchView {
                        LaunchView(showLaunchView: $showLaunchView)
                            .transition(.move(edge: .leading))
                    }
                }
                .zIndex(2.0)
            }
        }
    }
  • 윈도우 그룹의 HomeView가 해당 앱의 메인 뷰
  • 메인 뷰 진입 이전 ZStack을 통해 LaunchView를 상단에 띄우기
  • showLaunchView를 통해 현재 런치 뷰가 메인 뷰 위에 있을 경우를 체크

소스 코드

  • 기존의 스토리보드를 통해 런치 스크린을 구현하는 방법
import SwiftUI

@main
struct CryptoAppBootCampApp: App {
    @StateObject private var viewModel = HomeViewModel()
    @State private var showLaunchView: Bool = true
    init() {
        UINavigationBar.appearance().largeTitleTextAttributes = [.foregroundColor: UIColor(Color.theme.accent)]
        UINavigationBar.appearance().titleTextAttributes = [.foregroundColor: UIColor(Color.theme.accent)]
    }
    var body: some Scene {
        WindowGroup {
            ZStack {
                NavigationView {
                    HomeView()
                        .toolbar(.hidden)
                }
                .environmentObject(viewModel)
                ZStack {
                    if showLaunchView {
                        LaunchView(showLaunchView: $showLaunchView)
                            .transition(.move(edge: .leading))
                    }
                }
                .zIndex(2.0)
            }
        }
    }
}
  • 메인 뷰로 진입하는 최상단 코드
  • ZStack을 통해 홈 뷰로 들어가기 전 런치 스크린 뷰를 상단에 띄우기
  • zIndex를 통해 상단에 있음을 보장 가능
  • showLaunchView@State로 선언, 바인딩 프로퍼티로 넘겨줌으로써 런치 뷰 상의 핸들링을 현 시점의 뷰에서 확인 가능
import SwiftUI

struct LaunchView: View {
    @State private var loadingText: [String] = "Loading your portfolio...".map({String($0)})
    @State private var showLoadingText: Bool = false
    private let timer = Timer.publish(every: 0.1, on: .main, in: .common).autoconnect()
    @State private var counter: Int = 0
    @State private var loops: Int = 0
    @Binding var showLaunchView: Bool
    var body: some View {
        ZStack {
            Color.launch.background
                .ignoresSafeArea()
            Image("logo-transparent")
                .resizable()
                .frame(width: 100, height: 100)
            ZStack {
                if showLoadingText {
                    HStack(spacing: 0) {
                        ForEach(0..<loadingText.count) { index in
                            Text(loadingText[index])
                                .font(.headline)
                                .fontWeight(.heavy)
                                .foregroundColor(Color.launch.accent)
                                .offset(y: counter == index ? -5 : 0)
                        }
                    }
                    .transition(AnyTransition.scale.animation(.easeIn))
                }
            }
            .offset(y: 70)
        }
        .onAppear {
            showLoadingText.toggle()
        }
        .onReceive(timer) { _ in
            withAnimation(.spring()) {
                let lastIndex = loadingText.count - 1
                if counter == lastIndex {
                    counter = 0
                    loops += 1
                    if loops >= 2 {
                        showLaunchView = false
                    }
                } else {
                    counter += 1
                }
            }
        }
    }
}
  • showLoadingTextonAppear에서 값 변경함으로써 애니메이션 스케일 효과 적용
  • loadingText로 적용할 문자열 데이터를 배열로 관리, 전체적인 Hstack을 통해 각 텍스트 별 핸들링 가능
  • timercounter, loops를 통해 현재 주어진 loadingText의 어떤 문구를 offset 변경을 통해 애니메이션 효과를 줄지 확인 가능
  • loops가 특정 횟수가 될 때 바인딩으로 받고 있는 showLaunchView 변경, 메인 뷰 시점에서 현재 런치 뷰를 내리고 홈 뷰로 진입 가능

구현 화면

커스텀 런치 뷰를 통해 메인 뷰로 들어가기 전 런치 스크린과 같은 효과를 만들 수 있다! 즉 원하는 애니메이션 기법 등을 보다 유연하게 적용할 수 있다는 점이 장점이다.

profile
JUST DO IT
post-custom-banner

0개의 댓글