[SwiftUI] CryptoApp: HomeView Header

Junyoung Park·2022년 11월 2일
0

SwiftUI

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

Creating HomeView and a navigation header | SwiftUI Crypto App #2

CryptoApp: HomeView Header

구현 목표

  • 홈 뷰의 커스텀 헤더 구현

구현 태스크

  • 홈 뷰 구현
  • 헤더 뷰 구현
  • 헤더 뷰 사용 버튼 애니메이션 구현

핵심 코드

struct CircleButtonAnimationView: View {
    @Binding var animated: Bool
    var body: some View {
        Circle()
            .stroke(lineWidth: 5.0)
            .scale(animated ? 1.0 : 0.0)
            .opacity(animated ? 0.0 : 1.0)
            .animation(animated ? .easeOut(duration: 1.0) : .none)
    }
}
  • Binding으로 특정 값의 변화를 감지 새롭게 뷰를 그려줄 수 있는 커스텀 컴포넌트 뷰
  • animation의 불리언 값에 따라 버튼 이펙트를 발생시키는 뷰
CircleButtonView(iconName: "chevron.right")
                .rotationEffect(Angle(degrees: showPortfolio ? 180 : 0))
                .onTapGesture {
                    withAnimation(.spring()) {
                        showPortfolio.toggle()
                    }
                }
  • 헤더 뷰의 특정 버튼 뷰
  • onTapGesuture를 통해 애니메이션 효과와 함께 State 변수 토글링
  • Binding으로 해당 변수를 묶어 놓았기 때문에 위의 버튼 이펙트 뷰에서 변수 값 변경을 감지 가능

소스 코드

import SwiftUI

struct HomeView: View {
    @State private var showPortfolio: Bool = false
    
    var body: some View {
        ZStack {
            // background layer
            Color.theme.background
                .ignoresSafeArea()
            
            // content layer
            VStack {
                homeHeader
                Spacer(minLength: 0)
            }
        }
    }
}

extension HomeView {
    private var homeHeader: some View {
        HStack {
            CircleButtonView(iconName: showPortfolio ? "plus" : "info")
                .animation(.none, value: showPortfolio)
                .background(
                    CircleButtonAnimationView(animated: $showPortfolio)
                )
            Spacer()
            Text(showPortfolio ? "Portfolio" : "Live Prices")
                .font(.headline)
                .fontWeight(.heavy)
                .foregroundColor(Color.theme.accent)
                .animation(.none)
            Spacer()
            CircleButtonView(iconName: "chevron.right")
                .rotationEffect(Angle(degrees: showPortfolio ? 180 : 0))
                .onTapGesture {
                    withAnimation(.spring()) {
                        showPortfolio.toggle()
                    }
                }
        }
        .padding(.horizontal)
    }
}
  • 익스텐션으로 별도로 긴 코드 분리
  • Animation 이펙트가 핵심인 코드
  • 화살표 버튼을 클릭할 경우 화살표 변경 이벤트, 헤더 문자 변경, 버튼 클릭 이벤트 등이 발생함
import SwiftUI

struct CircleButtonView: View {
    let iconName: String
    
    var body: some View {
        Image(systemName: iconName)
            .font(.headline)
            .foregroundColor(Color.theme.accent)
            .frame(width: 50, height: 50)
            .background(
                Circle()
                    .foregroundColor(Color.theme.background)
            )
            .shadow(
                color: Color.theme.accent.opacity(0.25),
                radius: 10, x: 0, y: 0)
            .padding()
    }
}
  • 재사용될 버튼을 뷰 자체로 커스텀
import SwiftUI

struct CircleButtonAnimationView: View {
    @Binding var animated: Bool
    var body: some View {
        Circle()
            .stroke(lineWidth: 5.0)
            .scale(animated ? 1.0 : 0.0)
            .opacity(animated ? 0.0 : 1.0)
            .animation(animated ? .easeOut(duration: 1.0) : .none)
    }
}
  • scale, opacity를 통해 불리언 상태에 따라 표햔할 두 가지 경우 표현 가능
  • aniamtion을 통해 두 가지 경우 사이의 변경을 상태에 따라 조정 가능

구현 화면

SwiftUI의 애니메이션은 정말로 간편하고 보기 좋다.

profile
JUST DO IT
post-custom-banner

0개의 댓글