본문 바로가기
Xcode/IOS

iOS) SwiftUI 내 맘 정리#1 (feat: Animation , Circle & Capsule , DragGesture)

by 후르륵짭짭 2023. 3. 5.
728x90
반응형

안녕하세요. 후르륵짭짭입니다.

최근에 Udemy에서 SwiftUI Masterclass 2023 강의를 듣고 있습니다.

1만 5천원에 판매하고 있어서, 회사 돈 말고 그냥 제 돈으로 구매했습니다.

시간이 많았으면 SwiftUI를 천천히 공부하면서 알아 갔을 건데, 그럴 시간이 없어서 강의를 구매 했습니다. 

앞으로 강좌 섹션에서 배운 것을 두서 없이 정리하려고 합니다.

 

** Animation ** 

SwiftUI Masterclass는 SwiftUI의 장점인 Animation을 많이 사용하는 것 같은데요.

그래서 그 부분을 좀더 작성해보려고 합니다.

VStack(spacing:20) {
    // MARK: HEADER
    VStack(spacing: 0, content: {
        Text(textTitle)
            .font(.system(size: 60)) //폰트의 크기
            .fontWeight(.heavy) // 폰트의 굻기
            .foregroundColor(.white) // 전면색
            .transition(.opacity)//animation과 같은 효과
            .id(textTitle)//유니크한 id를 준다.

        Text("""
        It's not how much we give but
        how much love we put into giving
        """)
        .font(.title3)
        .fontWeight(.light)
        .foregroundColor(.white)
        .multilineTextAlignment(.center)//Text가 여러줄일 때 정렬 방법
        .padding(.horizontal,10)
    })
    .opacity(isAnimating ? 1 : 0)
    .offset(y: isAnimating ? 0 : -40)//animation false일 때 y의 -40에 있다가 true일 때 0으로 내려가는 에니메이션을 그린다.
    .animation(.easeOut(duration: 1), value: isAnimating) //1초 동안에 위에서 아래로 내려온다.

여기서 봐야할 것은 Animation 입니다.

위의 과정을 보면, VStack의 View를 모두 생성한 다음 

opacity와 offset을 isAnimating을 기준으로 정하고 animation을 실행합니다.

이 Animation에 다양한 기능들이 존재하는데, 이번 강의에서는 

.animation(.easeOut(duration: 1), value: isAnimating)

.animation(.spring(response: 10, dampingFraction: 0.1, blendDuration: blendDuration), value: change)

withAnimation(.linear(duration: 0.25), {
    indicatorOpacity = 1
    textTitle = "Share."
})

정도 등장하였습니다.

Animation method는 

 animation<V>(_ animation: Animation?, value: V)

이렇게 Animation과 value를 가지고 있는데, 

Animation은 어떤 Animation을 적용할 것이지이고 value는 언제 애니메이션을 작동할 건지 입니다.

처음에 이 value가 어떤 것인지 잘 이해가 안 됐는데,,, chatGPT가 너무 잘 설명해줬습니다 ㅠ ㅠ

 

EaseOut은 속도가 빨랐다가 느려지게 됩니다.

이렇게 x가 시간이고 y가 속도 일 때, y의 증가 속도가 줄어들게 됩니다.

그리고 duration이 존재하는데, 이는 애니메이션 종료까지 2초가 걸리는 것을 의미합니다.

EaseOut의 반대는 EaseIn 입니다.

 

다음은 spring animation 입니다

//Animation을 걸어두면
//spring - response : 변경되는데 총 걸리는 시간 , dampingFraction : 뜅기는 반동 , blendDuration : 물방울이 커지는 정도?
AsyncImage(url: URL(string: imageURL),
transaction: .init(animation: .spring(response: 1, dampingFraction: 0.2, blendDuration: 1)),
content: { phase in

  switch phase {
  case .success(let image ) :
      image.imageModifier()
          .transition(.scale(scale: 1.5)) //Transition과 같은 변경사항이 Animation과 엮여서 작동한다.
  case .failure(_) :
      Image(systemName: "ant.circle.fill")
          .iconModifier()
  case .empty :
      Image(systemName: "photo.circle.fill")
          .iconModifier()
  default:
      ProgressView()
  }

})
.padding(40)

위의 코드를 보면 transcation에 spring이 있습니다.

spring은 위의 이미지 처럼 왔다리 갔다리 하는 애니메이션 입니다.

reponse 같은 경우 animation의 총 걸리는 시간

dampingFraction은 스프링이 정지하는 속도 입니다. 따라서 해당 값이 높으면 높을 수록 정지하는 속도가 증가하고

0이라면 영원히 정지 하지 않게 됩니다.

blendDuration은 다른 애니메이션 간의 전환 길이를 제어하기 위한 기능 이라고 하는데 ,,,,

사실 정확한 차리를 못 느끼겠습니다 ㅠ ㅠ

 

이 외에도 수많은 animation이 존재합니다. 

하나씩 사용해 보면서 익숙 해질 필요가 있습니다.

https://minosaekki.tistory.com/37

 

SwiftUI- Chpater 14: Animations

좋은 앱과 훌륭한 앱의 차이는 디테일에서 옵니다. 적절한 자리에 적절한 애니메이션을 사용하는 것은 앱 스토어에서 인기를 얻게 만들어줍니다. 애미메이션은 앱을 더 재밌게 할 수 있으며 사

minosaekki.tistory.com

여기가 잘 정리되어 있더라구요.

 

** Circle  & Capsule ** 

 - Circle - 

var body: some View {
    ZStack(content: {
        Circle()//기본도형인 원
            .stroke(self.ShapeColor.opacity(self.ShapeOpacity), lineWidth: 40)//원의 테두리 굵기
            .frame(width: 260, height: 260, alignment: .center)
            // 도형의 전체 크기

        Circle()
            .stroke(self.ShapeColor.opacity(self.ShapeOpacity),lineWidth: 80)
            .frame(width: 260, height: 260, alignment: .center)
    })
    .blur(radius: isAnimating ? 0 : 10) //흐리게하는 블러처리
    .opacity(isAnimating ? 1 : 0 )
    .scaleEffect(isAnimating ? 1 : 0.5) //화면 확대
    .animation(.easeOut(duration: 1), value: isAnimating)
    .onAppear(perform: {
        isAnimating = true
    })
}

기본적인 원형의 View를 만들어주는 객체 입니다.

.stroke(self.ShapeColor.opacity(self.ShapeOpacity), lineWidth: 40)//원의 테두리 굵기

원의 테두리를 만들어 줄 수 있습니다.

 

 - Capsule - 

Capsule()//타원형의 도형
.fill(.white.opacity(0.2))

Capsule은 타원형의 도형입니다.

 

** DragGesture ** 

HStack {
    ZStack(content: {
        Capsule()
            .fill(Color("ColorRed"))
        Capsule()
            .fill(.black.opacity(0.15))
            .padding(8)
        Image(systemName: "chevron.right.2")
            .font(.system(size: 24, weight: .bold))
    })
    .foregroundColor(.white)
    .frame(width: 80, height: 80, alignment: .center)
    .offset(x:self.buttonOffset)
    .gesture( //제스처를 넣을 수 있다.
        DragGesture() //Drag가 필요한 에니메이션을 넣을 수 있다.
            .onChanged({ gesture in
                // 드래그를 오른쪽으로 할 때 반응할 수 있도록 함
                if gesture.translation.width > 0 && buttonOffset <= buttonWidth - 80 {
                    buttonOffset = gesture.translation.width
                    //새로운 value를 buttonOffsetdㅔ 넣어준다.
                    //offset은 중심에서 시작한다.
                }
            })
            .onEnded({ _ in //드래그를 놓았을 때 해야할 설정을 적는다.
                //Animation을 넣을 때 withAnimation을 사용한다.
                withAnimation(Animation.easeOut(duration: 0.4), {
                    if buttonOffset > buttonWidth / 2 {
                        buttonOffset = buttonWidth - 80
                        isOnboardingViewActive = false
                    }
                    else{
                        buttonOffset = 0
                    }
                })
            })
    )

    Spacer()
}

위와 같이 DragGesture 객체에 onChnaged와 onEnded 객체를 통해서 

View에 대한 Drag 여기와 끝을 알 수 있고 

해당 Closure에 원하는 내용을 적어 주면 된다.

 

** 후기 ** 

따라 만든 것

사실 SwiftUI를 직접 찾아서 공부해도 되지만 UI라는것이,,, 사실 만들고 싶은게 있어야 공부가 된다.

하지만 동기가 없어서,,, SwiftUI를 공부하기 쉽지 않았기 때문에 동영상 강의를 구매했다.

이번 1강은 처음 부터 굉장히 흥미로웠다. 

먼가 예전으로 돌아간 느낌??

let hapticFeedback = UINotificationFeedbackGenerator()
hapticFeedback.notificationOccurred(.success)

햅틱 피드백도 어떻게 하는지 직접 찾아보지 않아도 알려주고 ㅋㅋㅋㅋ

.preferredColorScheme(.dark)

다크모드에서 Status 변환도 알려주고 

이렇게 원하는 색깔을 Assets에서 등록해주는 것도 처음 알았다.

굉장히 다양한 기술을 많이 알려주기 때문에 

1만 5천원에 구매한 것 치고는 너무 갓성비가 좋은 강의가 아닌가 싶다.

 

** 참고 사이트 ** 

withAnimation : 

https://ios-development.tistory.com/1140

 

[iOS - SwiftUI] Animatable, Animation, GeometryReader, withAnimation (easeIn, easeInOut, easeOut, linear) 사용 방법

목차) SwiftUI의 기본 - 목차 링크 Animation SwiftUI에서는 withAnimation을 통하여 쉽게 애니메이션 효과 적용이 가능 버튼을 눌렀을때 widthAnimation()에 애니메이션 타입, duration, 애니메이션 적용할 클로저

ios-development.tistory.com

 

transition : 

https://seons-dev.tistory.com/m/entry/SwiftUI-%EC%95%A0%EB%8B%88%EB%A9%94%EC%9D%B4%EC%85%98%EA%B3%BC-%EB%B9%84%EC%8A%B7%ED%95%9C-Transitions

 

SwiftUI : 애니메이션과 비슷한 Transitions

Transition 에 대해 알아보도록 합시다. Transitons Transitions은 Animation과 매우 유사한 기능입니다. 하지만 이것을 사용하기 위해서는 반드시 조건부가 필요합니다. 확실히 animation을 사용하는 것보다는

seons-dev.tistory.com

 

Blur : 

https://www.hackingwithswift.com/quick-start/swiftui/how-to-blur-a-view

 

How to blur a view - a free SwiftUI by Example tutorial

Was this page useful? Let us know! 1 2 3 4 5

www.hackingwithswift.com

 

Basic Animation : 

https://www.hackingwithswift.com/quick-start/swiftui/how-to-create-basic-animations

 

How to create basic animations - a free SwiftUI by Example tutorial

Was this page useful? Let us know! 1 2 3 4 5

www.hackingwithswift.com

 

App Storgate : 

https://declan.tistory.com/31

 

SwiftUI @AppStorage

swiftUI를 조금씩 공부하면서 키워드를 하나씩 정리해 나가고 있다. 오늘은 @AppStorage에 대해서 알아보겠다. (공식문서 내용) A property wrapper type that reflects a value from UserDefaults and invalidates a view on a ch

declan.tistory.com

 

728x90
반응형

댓글