-
-
Notifications
You must be signed in to change notification settings - Fork 3.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add cross-platform SwiftUI wrapper for AnimatedSwitch #2138
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,61 @@ | ||
// Created by Cal Stephens on 8/11/23. | ||
// Copyright © 2023 Airbnb Inc. All rights reserved. | ||
|
||
import Lottie | ||
import SwiftUI | ||
|
||
// MARK: - ControlsDemoView | ||
|
||
struct ControlsDemoView: View { | ||
|
||
var body: some View { | ||
List { | ||
LottieSwitchRow( | ||
animationName: "Samples/Switch", | ||
title: "Switch", | ||
onTimeRange: 0.5...1.0, | ||
offTimeRange: 0.0...0.5) | ||
|
||
LottieSwitchRow( | ||
animationName: "Samples/Switch", | ||
title: "Switch (Custom Colors)", | ||
onTimeRange: 0.5...1.0, | ||
offTimeRange: 0.0...0.5, | ||
colorValueProviders: [ | ||
"Checkmark Outlines.Group 1.Stroke 1.Color": [Keyframe(.black)], | ||
"Checkmark Outlines 2.Group 1.Stroke 1.Color": [Keyframe(.black)], | ||
"X Outlines.Group 1.Stroke 1.Color": [Keyframe(.black)], | ||
"Switch Outline Outlines.Fill 1.Color": [ | ||
Keyframe(value: LottieColor.black, time: 0), | ||
Keyframe(value: LottieColor(r: 0.76, g: 0.76, b: 0.76, a: 1), time: 75), | ||
Keyframe(value: LottieColor.black, time: 150), | ||
], | ||
]) | ||
|
||
// TODO: Add SwiftUI support for AnimatedButton | ||
// AnimatedButtonRow( | ||
// animationName: "Samples/TwitterHeartButton", | ||
// title: "Twitter Heart Button", | ||
// playRanges: [ | ||
// .init(fromMarker: "touchDownStart", toMarker: "touchDownEnd", event: .touchDown), | ||
// .init(fromMarker: "touchDownEnd", toMarker: "touchUpCancel", event: .touchUpOutside), | ||
// .init(fromMarker: "touchDownEnd", toMarker: "touchUpEnd", event: .touchUpInside), | ||
// ])) | ||
Comment on lines
+36
to
+43
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Should we remove the comments until we have the demo working? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Nah I'll uncomment this out in the next PR |
||
|
||
LottieSwitchRow( | ||
animationName: "Samples/Issues/issue_1877", | ||
title: "Issue #1877", | ||
onTimeRange: nil, // use the default (0...1) | ||
offTimeRange: nil, // use the default (1...0) | ||
colorValueProviders: ["**.Color": [Keyframe(.black)]]) | ||
} | ||
.navigationTitle("Controls Demo") | ||
} | ||
|
||
} | ||
|
||
extension LottieColor { | ||
static var black: LottieColor { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Do we have a way to create a There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Not at the moment. Would probably be a good idea though. |
||
.init(r: 0, g: 0, b: 0, a: 1) | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,53 @@ | ||
// Created by Cal Stephens on 8/11/23. | ||
// Copyright © 2023 Airbnb Inc. All rights reserved. | ||
|
||
import Lottie | ||
import SwiftUI | ||
|
||
// MARK: - LottieSwitchRow | ||
|
||
struct LottieSwitchRow: View { | ||
|
||
// MARK: Internal | ||
|
||
var animationName: String | ||
var title: String | ||
var onTimeRange: ClosedRange<AnimationProgressTime>? | ||
var offTimeRange: ClosedRange<AnimationProgressTime>? | ||
var colorValueProviders: [String: [Keyframe<LottieColor>]] = [:] | ||
|
||
var body: some View { | ||
HStack { | ||
LottieSwitch(animation: .named(animationName)) | ||
.isOn($isOn) | ||
.onAnimation( | ||
fromProgress: onTimeRange?.lowerBound ?? 0, | ||
toProgress: onTimeRange?.upperBound ?? 1) | ||
.offAnimation( | ||
fromProgress: offTimeRange?.lowerBound ?? 1, | ||
toProgress: offTimeRange?.upperBound ?? 0) | ||
.colorValueProviders(colorValueProviders) | ||
.frame(width: 80, height: 80) | ||
|
||
Text(verbatim: "\(title) (isOn=\(isOn))") | ||
} | ||
} | ||
|
||
// MARK: Private | ||
|
||
@State private var isOn = false | ||
} | ||
|
||
extension LottieSwitch { | ||
func colorValueProviders(_ colorValueProviders: [String: [Keyframe<LottieColor>]]) -> Self { | ||
var copy = self | ||
|
||
for (keypath, keyframes) in colorValueProviders { | ||
copy = copy.valueProvider( | ||
ColorValueProvider(keyframes), | ||
for: AnimationKeypath(keypath: keypath)) | ||
} | ||
|
||
return copy | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These demo cases are copied exactly from the iOS example app