본문 바로가기

Swift/SwiftUI

SwiftUI_Tutorial 간단 정리(2/3) - Drawing and animation

이전 글: https://dev-doogie.tistory.com/23

다음 글: https://dev-doogie.tistory.com/26

Drawing paths and shapes 

GeometryReader

  • 상위 뷰의 크기에 맞춰 하위 뷰를 조정하는 기능

예를들어 여러 화면에 서 쓰이는 A뷰가 있다고 가정해보겠다
그런데 A뷰를 구성하는 뷰들을 고정값들로 배치하게 된다고면 부모뷰의 크기와는 상관 없이 오로지 고정된 값으로만 구성이 되며
다른 뷰 혹은 기기가 바뀌거나 회전 되었을 때, 너무 작음 혹은 크거나, 좌표가 벗어나버리는 일이 발생할 것이다

그래서

 

GeometryReader { geometry in
                .
                .
                .
}

이 `GeometryReader` 코드 블럭 안에서 geometry를 이용해 부모뷰의 크기의 몇퍼센트, 부모뷰 기준 어디 좌표 이런 식으로 자식 뷰를 구성할 수 있다

 

Path & Gradient

  • 솔직히 튜토리얼에서 설명하는 육각형을 만들고 막 곂쳐서 뱃지 만드는건 나중에 이해하기로 하고 하단 문제에 나온 아래 코드를 통해 Path와 Gradient 사용법을 익혔다
Path { path in
   path.move(to: CGPoint(x: 20, y: 0))
   path.addLine(to: CGPoint(x: 20, y: 200))
   path.addLine(to: CGPoint(x: 220, y: 200))
   path.addLine(to: CGPoint(x: 220, y: 0))
}
.fill(
   .linearGradient(
       Gradient(colors: [.green, .blue]),
       startPoint: .init(x: 0.5, y: 0),
       endPoint: .init(x: 0.5, y: 0.5)
   )
)

Path도 뭘 따로 선언하고 어쩌고 할 필요 없이 간단하게 그려낼 수 있고 특히 Gradient는 사용하기에 훨씬 편해진 것 같다

 

ZStack

  • 기존 UIKit에서는 addsubView하는 순서에 따라 위아래가 바뀌고 하나하나 위치를 지정해줬어야 했던 반면 ZStack을 이용해 Z축으로 뷰를 쉽게 쌓을 수 있다
ZStack {
   Circle().fill(.green)
   Circle().fill(.yellow).scaleEffect(0.8)
   Circle().fill(.orange).scaleEffect(0.6)
   Circle().fill(.red).scaleEffect(0.4)
}

Animating views and transitions

Animation

뷰에 직접적으로 animation적용은 물론,

@state 변수가 변하는 코드를 withAnimation으로 감싸면 withAnimation의 영향을 받는 뷰들에 애니메이션이 자동으로 적용됨
즉, 뷰마다 개별 애니메이션을 적용할 필요가 없고 duration도 바로 적용 가능

withAnimation(.easeInOut(duration: 4)) {
     showDetail.toggle()
}

그냥 전체적으로 뷰에 할당되는 애니메이션 위치에 따라 알아서(?) 적용이 된다
UIKit에서도 물론 기본 프리셋 같은게 있었지만 그 종류가 훨씬 다양하기도 하고 만약 원하는 애니메이션이 없다면 UIKit 처럼 Custom하게 만드는 것도 가능하지 않을까??

 

Transition

HikeDetail(hike: hike)
        .transition(.scale)

위코드로 바로 트랜지션을 줄 수 있음

extension AnyTransition {
    static var moveAndFade: AnyTransition {
        .asymmetric(insertion: .move(edge: .trailing),
                    removal: .scale.combined(with: .opacity))
    }
}

이런 방식으로 트랜지션을 만들어 사용할 수 있고 나타날 때 트랜지션, 없어질 때 트랜지션 둘 다 적용 가능
(그런데 없어진 이후로 잠깐 동안의 유예기간이 있는 듯 하다 .opacity로 사라지고 바로 다시 키면 .opacity효과로 켜진다)