스트리밍은 대부분의 브라우저와
Developer 앱에서 사용할 수 있습니다.
-
앱의 기호에 애니메이션 적용하기
애니메이션이 적용된 기호로 앱에 활기를 더하세요. 새로운 Symbols 프레임워크를 탐구하여 통합된 API를 통해 기호 효과를 생성하고 설정하세요. SwiftUI, AppKit, UIKit를 통해 UI 기호에 애니메이션을 적용하는 쉬운 방법을 배워 보세요. 다른 앱 콘텐츠에 새로운 애니메이션을 매끄럽게 통합하는 비법을 알아보세요. 이 세션의 내용을 최대한 이해하려면 'SF Symbols 5의 새로운 사항'을 먼저 시청하시기 바랍니다.
리소스
관련 비디오
WWDC23
-
다운로드
♪ ♪
안녕하세요 '앱의 기호에 애니메이션 적용하기'예요 제 이름은 Anant이고 UIKit의 엔지니어죠 SF Symbols는 Apple 인터페이스의 상징적인 요소예요
메뉴, 툴바, 사이드바 등에서 멋진 모습으로 사용되죠 사람들이 기호에 익숙하기 때문에 앱 사용의 직관성을 높여 줘요 iOS 17과 macOS Sonoma에서 애니메이션으로 기호를 보강하여 그 어느 때보다 여러분 앱에 생동감을 불어넣죠 먼저 새로운 기호 애니메이션을 소개할 건데 '기호 효과'로도 불러요 이후에는 SwiftUI, UIkit과 AppKit의 새로운 API를 통해 기호 효과를 앱에 추가하는 법을 알려드리죠 끝으로 기호 효과를 활용하는 비법을 소개할게요
그럼 시작하죠
iOS 17과 macOS Sonoma에 도입된 범용적인 애니메이션은 모든 기호 이미지와 맞춤형 기호에 적용할 수 있어요 애니메이션의 이름은 Bounce, Pulse, Variable Color Scale, Appear, Disappear 그리고 Replace죠
'SF Symbols 5의 새로운 사항' 세션을 확인하여 애니메이션들을 깊이 알아보고 인터페이스를 디자인하는 모범 사례를 살펴보세요
API에서 이런 애니메이션을 '기호 효과'라고 부르죠 새로운 Symbols 프레임워크에 모든 기호 효과가 있어요 SwiftUI, AppKit 또는 UIKit을 사용하여 앱을 빌드한다면 무료로 사용할 수 있죠 Symbols 프레임워크의 멋진 기능은 각 효과의 이름을 간단하게 마침표로 구분한다는 거예요 튕기는 효과를 만들 때 코드에 '.bounce'라고 작성하면 되죠
마침표로 이름을 구분하면 효과를 확장하여 구성할 수 있는데 예를 들어 어떤 기호가 위 또는 아래로 튀도록 지정할 수 있지만 대개는 아무것도 지정하지 않아도 돼요 프레임워크가 자동으로 적절한 방향을 선택하죠 일부 효과는 구성할 수 있는 방식이 많아요 예를 들어 가변 색상은 세 가지 설정이 있죠 설정을 함께 사용하면 쉽게 구체적인 효과를 설정할 수 있어요 효과의 이름이 실제 Swift 코드죠 스트링을 쓸 필요가 없습니다 Xcode가 이름의 일부를 자동 완성하며 만약 효과가 잘못 구성되면 컴파일 타임 때 오류가 나타나죠 새로운 애니메이션을 전부 살펴보는 최고의 방법은 SF Symbols 앱을 활용하는 거예요 새로운 애니메이션 탭에서 각 효과에 대한 설정 가능 선택지를 알아볼 수 있죠 마침표로 구분된 효과 이름을 복사하여 여러분 코드에 바로 사용할 수도 있어요 모든 효과의 종류와 설정 항목을 이용하면 사용할 수 있는 애니메이션이 엄청나게 많아지죠 하지만 이러한 효과들은 더 작은 집합의 행동을 포함해요
예를 들어 Bounce는 애니메이션을 일회성으로 재생하죠 이는 독립 행동으로 간주해요 반면 Scale 효과를 추가하면 기호의 스케일을 바꿔 무기한으로 바뀐 크기를 유지하죠 Scale은 무기한 행동을 지원한다고 해요 독립 효과와는 달리 무기한 효과는 명시적으로 제거했을 때 끝나죠
Appear와 Disappear는 전환 행동을 지원해요 기호가 뷰에 나타났다가 사라지는 걸 전환할 수 있죠
끝으로 Replace는 콘텐츠 전환이에요 하나의 기호에서 다른 기호로 움직이죠
이렇게 네 가지 행동이 있어요 독립, 무기한 행동과 전환, 콘텐츠 전환이죠 Symbols 프레임워크에서는 각 행동에 대한 프로토콜이 있는데 각 프로토콜에 컨폼하여 효과가 지원 행동을 선언해요
사용할 수 있는 모든 효과와 지원 행동을 표로 정리했죠 이 내용은 나중에 더 자세히 다룰게요 효과의 행동이 어떤 UI 프레임워크 API와 작동할 수 있는지 결정하죠 UI 프레임워크 API 얘기가 나왔으니 멋진 효과들을 SwiftUI, UIkit과 AppKit 앱에 추가하는 법을 얘기해 볼게요
SwiftUI에는 새로운 뷰 모디파이어 symbolEffect가 있어요
이 모디파이어를 추가하고 원하는 효과를 통과시키세요 여기서 variableColor를 통과하면 기호가 기본적인 가변 색상 애니메이션을 재생하죠
Appkit과 UIKit에서도 쉽게 할 수 있어요 이미지 뷰에서 addSymbolEffect 메서드를 사용하여 가변 색상 효과를 추가하세요 마침표 구문을 이용하여 가변 색상 효과를 설정할 수 있죠 여기서 효과를 variableColor.iterative .reversing으로 바꿔서 다른 가변 색상 애니메이션을 만들었어요 제 앱이 네트워크에 연결됐음을 보여 주는 좋은 방식이죠 서로 다른 효과를 혼합할 수도 있어요 여기에 scale.up 효과를 추가하죠 이제 기호가 가변 색상을 보여 주면서 크기가 커졌어요
이러한 API들을 통해 간단한 방법으로 기호 이미지에 무기한 효과를 추가할 수 있죠 무기한 효과는 없어질 때까지 기호의 일부 특성을 무기한으로 바꿔요
따라서 symbolEffect 모디파이어를 이용하여 가변 색상 효과를 적용하면 애니메이션이 계속 재생되죠 하지만 언제 효과를 활성화할지 제어할 방법이 필요해요 앱이 네트워크에 성공적으로 연결된 후에도 이 애니메이션이 재생되길 원하지 않죠
이럴 땐 isActive 불리언 매개변수를 추가하세요 인터넷에 연결할 때만 효과가 적용되죠 앱이 연결을 마치면 기호 애니메이션이 종료돼요
Appkit과 UIKit에서는 removeSymbolEffect 메서드로 무기한 효과를 종료하세요 일회성 애니메이션을 재생하는 독립 효과는 어떨까요? 앞에서 Bounce를 예로 들었죠 여러분의 앱이 특정 이벤트에 의해 Bounce 효과를 발동할 수 있어요
SwiftUI에서도 symbolEffect 모디파이어로 독립 효과를 추가할 수 있죠 대신 SwiftUI에 값을 제공해야 해요 값이 바뀔 때마다 SwiftUI가 독립 효과를 발동하죠
누를 때마다 기호가 튕기는 버튼을 추가할게요 Button의 핸들러는 bounceValue를 증가시키죠 SwiftUI가 bounceValue의 변화를 보고 튕기는 동작을 발동해요 Appkit과 UIKit에서는 이미지 뷰에 Bounce 효과를 추가하면 되죠 Bounce는 독립 효과만 지원하므로 효과를 추가하면 한 번만 튕겨요 이후에 효과를 제거하지 않아도 되죠
이제 기호가 한 번만 튕기는 걸 원치 않는다고 가정할게요 두 번 튕기는 건 어떨까요? SwiftUI, Appkit과 UIKit가 지원하는 옵션 매개변수에서 원하는 반복 횟수를 지정할 수 있죠 이제 효과를 발동했을 때 기호가 두 번 튕겨요 Bounce만 독립 행동을 보이는 효과가 아니죠 앞에서 다뤘던 Pulse와 Variable Color는 무기한 행동뿐만 아니라 독립 행동도 지원해요 달리 말하자면 Bounce 같은 일회성 애니메이션을 재생할 수 있죠 그 말은 앞에서 언급했던 Bounce 예시를 variableColor로 바꿀 수 있다는 거예요 Variable Color가 바뀌어 독립 행동을 하게 되는데 반복적이지 않게 적용했기 때문이죠
이제 버튼을 누르면 Variable Color가 2회 재생돼요
이제 콘텐츠 전환 효과를 얘기해 보죠 2개의 기호 이미지를 왕복하며 움직이는 Replace 효과가 콘텐츠 전환의 주요 예시죠 여기에 일시 정지와 재생 기호를 전환하는 이미지가 있어요
SwiftUI에 contentTransition 타입인 symbolEffect가 있는데 Replace에 사용할 수 있죠 어떤 기호를 표시할지 토글하는 Button 안에 Image를 넣으면 변화가 애니메이션으로 나타나요 Appkit과 UIKit에서는 setSymbolImage 메서드로 기호 콘텐츠 전환을 이용하여 이미지를 바꿀 수 있죠
마지막으로 Appear와 Disappear가 있는데 독특한 애니메이션으로 기호를 보여 주거나 숨길 수 있죠 이런 효과는 전환 효과로 분류돼요 이를 다루기 전에 평행 우주에 관해 얘기해야 해요 걱정하지 마세요 생각보다 복잡하지 않죠 한 우주에서는 이미지가 사라지지만 이미지 뷰가 계층 구조 안에 있어요 레이아웃에 변화가 없다는 뜻이죠 정사각형과 원은 여전히 같은 거리를 유지해요 평행 우주에서는 이미지 뷰가 계층 구조에 추가됐다가 제거되죠 그 결과 주변 뷰의 레이아웃이 바뀔 수 있어요
다행히 Appear와 Disappear가 두 행동을 모두 지원하죠
첫 번째 행동이 가능한 건 Appear와 Disappear가 무기한 효과이기 때문이에요
무기한 효과를 사용하는 방법은 이미 알고 있죠 SwiftUI에서는 .symbolEffect 모디파이어를 사용하고 .disappear를 통과시키세요 isMoonHidden의 값이 업데이트되면 Disappear 효과가 적용돼요
Appkit과 UIKit에서는 addSymbolEffect를 사용하고 .disappear 또는 .appear를 통과시키세요
여기서 알 수 있는 건 무기한 효과가 레이아웃을 전혀 바꾸지 않는다는 거예요 이미지 뷰 안에서 기호의 렌더링만 바꾸죠
이제 첫 번째 행동을 다뤘어요 주변의 레이아웃이 바뀌는 평행 우주로 어떻게 넘어갈까요?
이런 때 전환 행동이 필요하죠 전환 효과를 사용하려면 SwiftUI에 내장된 전환 모디파이어를 통해 뷰 계층 구조에서 뷰의 삽입과 제거를 연출하세요
이전 코드를 바꿔서 전환 효과를 사용해 보죠 Disappear 효과를 조건부로 적용하는 대신 뷰 계층 구조에 기호를 조건부로 추가할게요
그리고 전환 모디파이어를 추가할게요 SwiftUI에는 새로운 전환 타입이 있는데 맞습니다, symbolEffect죠 .disappear를 통과시키면 기호가 애니메이션을 통해 추가됐다가 제거돼요
Automatic이라는 독특한 전환 효과도 사용할 수 있죠 이 효과는 기호에 가장 적합한 전환 애니메이션을 자동으로 수행해요
만약 SwiftUI를 사용하지 않는다면 계층 구조에서 이미지 뷰를 수동으로 제거해야 하죠 UIkit은 효과를 위한 완료 핸들러를 사용하면 돼요 Disappear 효과를 추가하고 효과가 끝나면 계층 구조에서 이미지 뷰를 제거하세요 이제 됐어요 SwiftUI, Appkit과 UIKit의 기호 효과를 알아봤죠 이제 기초를 알았으니 기호 효과를 더 활용할 수 있는 비결을 알려드릴게요 먼저 UIImageView의 새로운 UIKit 메서드들은 UIBarButtonItem에서도 이용할 수 있죠 이를 통해 기호 애니메이션으로 툴바의 생동감을 높일 수 있어요 일부 UIKit 컨트롤은 iOS 17에 내장된 기호 애니메이션이 있죠
예를 들어 UISlider는 엄지가 트랙 끝에 갔을 때 이미지를 튕기죠 이런 애니메이션을 재생할지 제어하려면 isSymbolAnimationEnabled 프로퍼티를 이용하면 돼요 UIControl과 UIBarButtonItem에 있죠
SwiftUI에서는 기호 효과를 비활성화하기 위한 독특한 고려 사항이 있어요
SwiftUI의 다른 모디파이어처럼 symbolEffect 모디파이어가 뷰 계층 구조를 통해 전파하죠 이 의미는 부모 뷰에 모디파이어를 추가하여 여러 이미지에 효과를 적용할 수 있다는 거예요 symbolEffectsRemoved 모디파이어를 사용하여 뷰가 기호 효과를 상속받는 걸 방지하세요 일부 기호 효과인 Appear, Disappear와 Scale은 애니메이션으로 기호의 모습을 바꾸죠 기호가 애니메이션 없이 일단 커지거나 일단 사라지는 걸 연출하고 싶을 수도 있어요 SwiftUI에서는 애니메이션을 비활성화하고 트랜잭션을 사용하면 되죠 여기서 사용하면 애니메이션 없이 scale.up 효과를 적용해요
Appkit과 UIKit에서 애니메이션 없는 효과를 원하면 addSymbolEffect의 animated 매개변수를 사용하세요 끝으로 가변 값에 관해 얘기해 보죠
iOS 16과 macOS Ventura에서 기호의 새로운 차원으로 가변 값을 도입하여 볼륨의 크기나 신호의 강도 같은 개념을 표현했죠
iOS 17과 macOS Sonoma에서는 임의의 가변 값 사이의 크로스페이드를 아주 쉽게 할 수 있어요
SwiftUI에서는 아무것도 안 해도 되죠 여기 Wi-Fi 기호가 있는데 상태를 기반으로 가변 값이 달라지죠 이 경우의 상태는 현재 신호 강도예요 신호 강도가 바뀔 때마다 Wi-Fi 기호가 자동으로 바뀌며 가변 값에 따라 애니메이션이 나타나죠 Appkit과 UIKit에서는 자동 기호 콘텐츠 전환을 사용하세요 새로운 기호 이미지의 가변 값이 바뀌었는지 감지하며 바뀌었으면 새로운 값으로 크로스페이드 하세요
오늘 참여해 주셔서 감사해요 기호를 동작하게 하는 방법이 많으니까 SF Symbols 앱을 보고 어떤 연출이 가능한지 살펴보세요 Symbols 프레임워크를 탐색하고 SwiftUI, AppKit과 UIKit의 새로운 기호 효과 API를 이용해 보세요 끝으로 애니메이션을 채택하여 여러분 앱의 인터페이스를 어느 때보다 즐겁게 만드세요
기호를 다루는 다른 세션과 Human Interface Guidelines의 기호 애니메이션을 확인하고 맞춤형 기호를 업데이트하여 모든 효과를 지원하세요 감사합니다 즐거운 코딩 작업하세요
-
-
6:02 - Symbol effects in SwiftUI
// Symbol effects in SwiftUI Image(systemName: "wifi.router") .symbolEffect(.variableColor.iterative.reversing) .symbolEffect(.scale.up)
-
6:02 - Symbol effects in AppKit and UIKit
let imageView: NSImageView = ... imageView.addSymbolEffect(.variableColor.iterative.reversing) imageView.addSymbolEffect(.scale.up)
-
6:49 - Indefinite symbol effects in SwiftUI
struct ContentView: View { @State var isConnectingToInternet: Bool = true var body: some View { Image(systemName: "wifi.router") .symbolEffect( .variableColor.iterative.reversing, isActive: isConnectingToInternet ) } }
-
7:09 - Indefinite symbol effects in AppKit and UIKit
let imageView: NSImageView = ... imageView.addSymbolEffect(.variableColor.iterative.reversing) // Later, remove the effect imageView.removeSymbolEffect(ofType: .variableColor)
-
8:26 - Discrete symbol effects in SwiftUI
struct ContentView: View { @State var bounceValue: Int = 0 var body: some View { VStack { Image(systemName: "antenna.radiowaves.left.and.right") .symbolEffect( .bounce, options: .repeat(2), value: bounceValue ) Button("Animate") { bounceValue += 1 } } } }
-
8:26 - Discrete symbol effects in AppKit and UIKit
let imageView: NSImageView = ... // Bounce imageView.addSymbolEffect(.bounce, options: .repeat(2))
-
9:40 - Content transition symbol effects in SwiftUI
struct ContentView: View { @State var isPaused: Bool = false var body: some View { Button { isPaused.toggle() } label: { Image(systemName: isPaused ? "pause.fill" : "play.fill") .contentTransition(.symbolEffect(.replace.offUp)) } } }
-
9:57 - Content transition symbol effects in AppKit and UIKit
let imageView: UIImageView = ... imageView.image = UIImage(systemName: "play.fill") // Change the image with a Replace effect let pauseImage = UIImage(systemName: "pause.fill")! imageView.setSymbolImage(pauseImage, contentTransition: .replace.offUp)
-
11:14 - Indefinite Appear and Disappear symbol effects in SwiftUI
struct ContentView: View { @State var isMoonHidden: Bool = false var body: some View { HStack { RoundedRectangle(cornerRadius: 5) Image(systemName: "moon.stars") .symbolEffect(.disappear, isActive: isMoonHidden) Circle() } } }
-
11:30 - Indefinite Appear and Disappear symbol effects in AppKit and UIKit
let imageView: UIImageView = ... imageView.image = UIImage(systemName: "moon.stars") imageView.addSymbolEffect(.disappear) // Re-appear the symbol imageView.addSymbolEffect(.appear)
-
12:38 - Transition symbol effects in SwiftUI
struct ContentView: View { @State var isMoonHidden: Bool = false var body: some View { HStack { RoundedRectangle(cornerRadius: 5) if !isMoonHidden { Image(systemName: "moon.stars") .transition(.symbolEffect(.disappear.down)) } Circle() } } }
-
12:59 - Appear and Disappear symbol effects in UIKit with completion handler
let imageView: UIImageView = ... imageView.image = UIImage(systemName: "moon.stars") imageView.addSymbolEffect(.disappear) { context in if let imageView = context.sender as? UIImageView, context.isFinished { imageView.removeFromSuperview() } }
-
14:19 - Symbol effect propagation in SwiftUI
VStack { Image(systemName: "figure.walk") .symbolEffectsRemoved() Image(systemName: "car") Image(systemName: "tram") } .symbolEffect(.pulse)
-
14:55 - Effects without animation in SwiftUI
struct ContentView: View { @State var isScaledUp: Bool = false var body: some View { Image(systemName: "iphone.radiowaves.left.and.right") .symbolEffect(.scale.up, isActive: isScaledUp) .onAppear { var transaction = Transaction() transaction.disablesAnimations = true withTransaction(transaction) { isScaledUp = true } } } }
-
15:06 - Effects without animation in AppKit and UIKit
// Effects without animation in AppKit and UIKit let imageView: UIImageView = ... imageView.image = UIImage(systemName: "iphone.radiowaves.left.and.right") imageView.addSymbolEffect(.disappear, animated: false)
-
15:44 - Variable value animations in SwiftUI
struct ContentView: View { @State var signalLevel: Double = 0.5 var body: some View { Image(systemName: "wifi", variableValue: signalLevel) } }
-
16:07 - Variable value animations in AppKit and UIKit
let imageView: UIImageView = ... imageView.image = UIImage(systemName: "wifi", variableValue: 1.0) // Animate to a different Wi-Fi level let currentSignalImage = UIImage( systemName: "wifi", variableValue: signalLevel )! imageView.setSymbolImage(currentSignalImage, contentTransition: .automatic)
-
-
찾고 계신 콘텐츠가 있나요? 위에 주제를 입력하고 원하는 내용을 바로 검색해 보세요.
쿼리를 제출하는 중에 오류가 발생했습니다. 인터넷 연결을 확인하고 다시 시도해 주세요.