Dev.YoungKyu
YoungKyu's Devlog
전체 방문자
오늘
어제
  • 분류 전체보기
    • 부스트캠프
    • visionOS
    • iOS
    • 알고리즘
    • CS
    • Git
    • Python
    • 끄적끄적

블로그 메뉴

  • 홈
  • 🌝 티스토리 홈
  • ⭐️ 깃허브
  • 태그

공지사항

인기 글

최근 댓글

최근 글

태그

  • boj
  • 소프트웨어공학
  • guard
  • 소프트웨어 공학
  • ImageResource
  • ios
  • Concurrency
  • CS
  • swift
  • MVC
  • jekyll
  • if let
  • Swift5.7
  • 오블완
  • Animation
  • 백준
  • avaudiosessionportdescription
  • 알고리즘
  • Git
  • AVAudioSession
  • 모듈화
  • 부스트캠프
  • AutoLayout
  • 소프트웨어 테스트
  • SwiftUI
  • Optional
  • constraint
  • image
  • Python
  • 티스토리챌린지

티스토리

hELLO · Designed By 정상우.
Dev.YoungKyu
[Gradient Animation] AngularGradient Border 애니메이션 넣기
iOS

[Gradient Animation] AngularGradient Border 애니메이션 넣기

2022. 9. 25. 19:12

1. 이미지 리사이징

struct ContentView: View {
    var body: some View {
        Image("IU")
            .resizable()
            .scaledToFit()
            .frame(width: 300)
            .mask { RoundedRectangle(cornerRadius: 12) }
    }
}

이미지에 코너곡선만 줬을때

 

2. 그림자 추가

struct ContentView: View {
    var body: some View {
        Image("IU")
            .resizable()
            .scaledToFit()
            .frame(width: 300)
            .mask { RoundedRectangle(cornerRadius: 12) }
            .shadow(radius: 8)
    }
}

그림자 효과 추가

 

3. AngularGradient Border 추가

struct ContentView: View {
    private let gradientColors: [Color] = [.red, .yellow, .green, .blue, .purple, .red]
    var body: some View {
        Image("IU")
            .resizable()
            .scaledToFit()
            .frame(width: 300)
            .mask { RoundedRectangle(cornerRadius: 12) }
            .shadow(radius: 8)
            .overlay {
                gradientBorderView
            }
    }
    var gradientBorderView: some View {
        RoundedRectangle(cornerRadius: 12)
            .strokeBorder(
                AngularGradient(gradient: Gradient(colors: gradientColors), center: .center))
    }
}

테두리가 알록달록

 

4. AngularGradient에 Animation 추가

struct ContentView: View {
	// Color를 너무 적게 넣거나하면 동작을 안할때가 있더라구요ㅠ 아직은 원인불명..
    private let gradientColors: [Color] = [.red, .yellow, .green, .blue, .purple, .red]
    @State  var gradientAngle: Double = 0 
    var body: some View {
        Image("IU")
            .resizable()
            .scaledToFit()
            .frame(width: 300)
            .mask { RoundedRectangle(cornerRadius: 12) }
            .shadow(radius: 8)
            .overlay {
                gradientBorderView
            }
    }
    var gradientBorderView: some View {
        RoundedRectangle(cornerRadius: 12)
            .strokeBorder(
            	// gradientAngle이 WithAnimaion으로 변경되면서 변화에 따라 AngularGradient를 회전
                AngularGradient(gradient: Gradient(colors: gradientColors), 
                				center: .center, 
                				angle: .degrees(gradientAngle)))
            .onAppear {
            	// duration을 너무 짧거나 길게 바꾸면 동작을 안할때가 있더라구요ㅠ 
                // 성능관련 문제같은데 정확한 원인은 모르겠네요!
                withAnimation(.linear(duration: 3).repeatForever(autoreverses: false)) {
                    self.gradientAngle = 360
                }
            }
    }
}

 

빙글빙글 돌아가니 예쁘네요

 

확대샷




gradientAngle 까지는 잘 접근했는데 컬러 설정과 애니메이션 길이 설정(duration)에 따라서 애니메이션이 동작 안할 때가 많아 애먹었습니다ㅜㅜ 확실하게 언제 되고 언제 안되는지 정리하고 싶었는데 아쉽네요 이유에 대해서 아시는 분은 댓글로 알려주시면 감사하겠습니다!

 

애니메이션 미동작 원인 및 해결방법

some View 로 구현했던게 원인이었던 것 같습니다!

rootView의@State 변수 하나로 다수의 some View의 애니메이션을 컨트롤하려고 해 문제가 된 것 같습니다.

 

struct ContentView: View {
    var body: some View {
        Image("IU")
            .resizable()
            .scaledToFit()
            .frame(width: 300)
            .mask { RoundedRectangle(cornerRadius: 12) }
            .shadow(radius: 8)
            .overlay {
                GradientBorderView()
            }
    }
}

struct GradientBorderView: View {
    private var colors: [Color] = [.red, .yellow, .green, .blue, .purple, .red]
    @State var gradientAngle: Double = 0
    var body: some View {
        RoundedRectangle(cornerRadius: 8)
            .strokeBorder(
                AngularGradient(gradient: Gradient(colors: colors), center: .center, angle: .degrees(gradientAngle)))
            .onAppear {
                withAnimation(.linear(duration: 3).repeatForever(autoreverses: false)) {
                    gradientAngle = 360
                }
            }
    }
}

UI는 메인스레드에서 동작하는데 애니메이션도 UI니까 메인스레드에서 애니메이션을 동작하게 하는 과정에서 문제가 있지 않았을까 싶습니다. 더 자세한 원인이나 틀린 부분이 있다면 댓글로 알려주시면 감사하겠습니다!

저작자표시

'iOS' 카테고리의 다른 글

앱스토어 첫 심사와 리젝 대응 : Guideline 2.1  (0) 2022.10.24
협업 시 팀원과 Provisioning Profile 및 Certificate 공유하기  (9) 2022.10.22
[EventKit] 캘린더에 이벤트 추가하기(with. Async/await)  (0) 2022.09.23
Swift 5.7 - if let 문 간략화  (0) 2022.09.13
Swift 5.7 릴리즈 - 언어 및 표준라이브러리, 개발자 경험  (0) 2022.09.13
    'iOS' 카테고리의 다른 글
    • 앱스토어 첫 심사와 리젝 대응 : Guideline 2.1
    • 협업 시 팀원과 Provisioning Profile 및 Certificate 공유하기
    • [EventKit] 캘린더에 이벤트 추가하기(with. Async/await)
    • Swift 5.7 - if let 문 간략화
    Dev.YoungKyu
    Dev.YoungKyu
    iOS를 공부하고 있습니다

    티스토리툴바