lottie-ios 4.4.1 → 4.4.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.github/workflows/main.yml +5 -0
- package/Lottie.xcodeproj/project.pbxproj +40 -44
- package/Lottie.xcworkspace/xcuserdata/calstephens.xcuserdatad/UserInterfaceState.xcuserstate +0 -0
- package/Lottie.xcworkspace/xcuserdata/calstephens.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist +18 -0
- package/Package.swift +1 -1
- package/README.md +1 -1
- package/Rakefile +5 -12
- package/Sources/Private/EmbeddedLibraries/EpoxyCore/README.md +3 -4
- package/Sources/Private/EmbeddedLibraries/EpoxyCore/SwiftUI/EpoxySwiftUIIntrinsicContentSizeInvalidator.swift +0 -1
- package/Sources/Private/EmbeddedLibraries/EpoxyCore/SwiftUI/EpoxySwiftUILayoutMargins.swift +0 -4
- package/Sources/Private/EmbeddedLibraries/EpoxyCore/SwiftUI/EpoxyableView+SwiftUIView.swift +0 -4
- package/Sources/Private/EmbeddedLibraries/EpoxyCore/SwiftUI/LayoutUtilities/MeasuringViewRepresentable.swift +0 -4
- package/Sources/Private/EmbeddedLibraries/EpoxyCore/SwiftUI/LayoutUtilities/SwiftUIMeasurementContainer.swift +0 -1
- package/Sources/Private/EmbeddedLibraries/EpoxyCore/SwiftUI/SwiftUIView.swift +0 -4
- package/Sources/Private/EmbeddedLibraries/EpoxyCore/SwiftUI/UIView+SwiftUIView.swift +0 -1
- package/Sources/Private/EmbeddedLibraries/EpoxyCore/SwiftUI/UIViewConfiguringSwiftUIView.swift +0 -2
- package/Sources/Private/EmbeddedLibraries/EpoxyCore/Views/ViewType.swift +0 -4
- package/Sources/Private/MainThread/LayerContainers/Utility/CoreTextRenderLayer.swift +0 -1
- package/Sources/Private/Model/DotLottie/DotLottieUtils.swift +3 -5
- package/Sources/Private/Utility/Extensions/DataExtension.swift +5 -8
- package/Sources/Private/Utility/Extensions/MathKit.swift +2 -2
- package/Sources/Private/Utility/Helpers/Binding+Map.swift +0 -1
- package/Sources/Private/Utility/Helpers/View+ValueChanged.swift +15 -2
- package/Sources/Public/Animation/LottieAnimationHelpers.swift +0 -1
- package/Sources/Public/Animation/LottieView.swift +11 -8
- package/Sources/Public/Controls/LottieButton.swift +0 -1
- package/Sources/Public/Controls/LottieSwitch.swift +0 -1
- package/Sources/Public/Controls/LottieViewType.swift +1 -1
- package/Sources/Public/DotLottie/DotLottieFileHelpers.swift +0 -5
- package/Sources/Public/iOS/LottieAnimationViewBase.swift +1 -5
- package/Version.xcconfig +6 -0
- package/lottie-ios.podspec +5 -4
- package/package.json +1 -1
- package/Sources/Private/EmbeddedLibraries/EpoxyCore/SwiftUI/EpoxySwiftUIHostingController.swift +0 -46
- package/Sources/Private/EmbeddedLibraries/EpoxyCore/SwiftUI/EpoxySwiftUIHostingView.swift +0 -389
|
@@ -1,389 +0,0 @@
|
|
|
1
|
-
// Created by eric_horacek on 9/16/21.
|
|
2
|
-
// Copyright © 2021 Airbnb Inc. All rights reserved.
|
|
3
|
-
|
|
4
|
-
#if canImport(Combine) && canImport(SwiftUI) && !os(macOS)
|
|
5
|
-
import Combine
|
|
6
|
-
import SwiftUI
|
|
7
|
-
|
|
8
|
-
// MARK: - SwiftUIHostingViewReuseBehavior
|
|
9
|
-
|
|
10
|
-
/// The reuse behavior of an `EpoxySwiftUIHostingView`.
|
|
11
|
-
enum SwiftUIHostingViewReuseBehavior: Hashable {
|
|
12
|
-
/// Instances of a `EpoxySwiftUIHostingView` with `RootView`s of same type can be reused within
|
|
13
|
-
/// the Epoxy container.
|
|
14
|
-
///
|
|
15
|
-
/// This is the default reuse behavior.
|
|
16
|
-
case reusable
|
|
17
|
-
/// Instances of a `EpoxySwiftUIHostingView` with `RootView`s of same type can only reused within
|
|
18
|
-
/// the Epoxy container when they have identical `reuseID`s.
|
|
19
|
-
case unique(reuseID: AnyHashable)
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
// MARK: - CallbackContextEpoxyModeled
|
|
23
|
-
|
|
24
|
-
@available(iOS 13.0, tvOS 13.0, macOS 10.15, *)
|
|
25
|
-
extension CallbackContextEpoxyModeled
|
|
26
|
-
where
|
|
27
|
-
Self: WillDisplayProviding & DidEndDisplayingProviding,
|
|
28
|
-
CallbackContext: ViewProviding & AnimatedProviding
|
|
29
|
-
{
|
|
30
|
-
/// Updates the appearance state of a `EpoxySwiftUIHostingView` in coordination with the
|
|
31
|
-
/// `willDisplay` and `didEndDisplaying` callbacks of this `EpoxyableModel`.
|
|
32
|
-
///
|
|
33
|
-
/// - Note: You should only need to call then from the implementation of a concrete
|
|
34
|
-
/// `EpoxyableModel` convenience vendor method, e.g. `SwiftUI.View.itemModel(…)`.
|
|
35
|
-
func linkDisplayLifecycle<RootView: View>() -> Self
|
|
36
|
-
where
|
|
37
|
-
CallbackContext.View == EpoxySwiftUIHostingView<RootView>
|
|
38
|
-
{
|
|
39
|
-
willDisplay { context in
|
|
40
|
-
context.view.handleWillDisplay(animated: context.animated)
|
|
41
|
-
}
|
|
42
|
-
.didEndDisplaying { context in
|
|
43
|
-
context.view.handleDidEndDisplaying(animated: context.animated)
|
|
44
|
-
}
|
|
45
|
-
}
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
// MARK: - EpoxySwiftUIHostingView
|
|
49
|
-
|
|
50
|
-
/// A `UIView` that hosts a SwiftUI view within an Epoxy container, e.g. an Epoxy `CollectionView`.
|
|
51
|
-
///
|
|
52
|
-
/// Wraps an `EpoxySwiftUIHostingController` and adds it as a child view controller to the next
|
|
53
|
-
/// ancestor view controller in the hierarchy.
|
|
54
|
-
///
|
|
55
|
-
/// There's a private API that accomplishes this same behavior without needing a `UIViewController`:
|
|
56
|
-
/// `_UIHostingView`, but we can't safely use it as 1) the behavior may change out from under us, 2)
|
|
57
|
-
/// the API is private and 3) the `_UIHostingView` doesn't not accept setting a new `View` instance.
|
|
58
|
-
///
|
|
59
|
-
/// - SeeAlso: `EpoxySwiftUIHostingController`
|
|
60
|
-
@available(iOS 13.0, tvOS 13.0, *)
|
|
61
|
-
final class EpoxySwiftUIHostingView<RootView: View>: UIView, EpoxyableView {
|
|
62
|
-
|
|
63
|
-
// MARK: Lifecycle
|
|
64
|
-
|
|
65
|
-
init(style: Style) {
|
|
66
|
-
// Ignore the safe area to ensure the view isn't laid out incorrectly when being sized while
|
|
67
|
-
// overlapping the safe area.
|
|
68
|
-
epoxyContent = EpoxyHostingContent(rootView: style.initialContent.rootView)
|
|
69
|
-
viewController = EpoxySwiftUIHostingController(
|
|
70
|
-
rootView: .init(content: epoxyContent, environment: epoxyEnvironment),
|
|
71
|
-
ignoreSafeArea: true)
|
|
72
|
-
|
|
73
|
-
dataID = style.initialContent.dataID ?? DefaultDataID.noneProvided as AnyHashable
|
|
74
|
-
|
|
75
|
-
super.init(frame: .zero)
|
|
76
|
-
|
|
77
|
-
epoxyEnvironment.intrinsicContentSizeInvalidator = .init(invalidate: { [weak self] in
|
|
78
|
-
self?.viewController.view.invalidateIntrinsicContentSize()
|
|
79
|
-
|
|
80
|
-
// Inform the enclosing collection view that the size has changed, if we're contained in one,
|
|
81
|
-
// allowing the cell to resize.
|
|
82
|
-
//
|
|
83
|
-
// On iOS 16+, we could call `invalidateIntrinsicContentSize()` on the enclosing collection
|
|
84
|
-
// view cell instead, but that currently causes visual artifacts with `MagazineLayout`. The
|
|
85
|
-
// better long term fix is likely to switch to `UIHostingConfiguration` on iOS 16+ anyways.
|
|
86
|
-
if let enclosingCollectionView = self?.superview?.superview?.superview as? UICollectionView {
|
|
87
|
-
enclosingCollectionView.collectionViewLayout.invalidateLayout()
|
|
88
|
-
}
|
|
89
|
-
})
|
|
90
|
-
layoutMargins = .zero
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
@available(*, unavailable)
|
|
94
|
-
required init?(coder _: NSCoder) {
|
|
95
|
-
fatalError("init(coder:) has not been implemented")
|
|
96
|
-
}
|
|
97
|
-
|
|
98
|
-
// MARK: Internal
|
|
99
|
-
|
|
100
|
-
struct Style: Hashable {
|
|
101
|
-
init(reuseBehavior: SwiftUIHostingViewReuseBehavior, initialContent: Content) {
|
|
102
|
-
self.reuseBehavior = reuseBehavior
|
|
103
|
-
self.initialContent = initialContent
|
|
104
|
-
}
|
|
105
|
-
|
|
106
|
-
var reuseBehavior: SwiftUIHostingViewReuseBehavior
|
|
107
|
-
var initialContent: Content
|
|
108
|
-
|
|
109
|
-
static func == (lhs: Style, rhs: Style) -> Bool {
|
|
110
|
-
lhs.reuseBehavior == rhs.reuseBehavior
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
func hash(into hasher: inout Hasher) {
|
|
114
|
-
hasher.combine(reuseBehavior)
|
|
115
|
-
}
|
|
116
|
-
}
|
|
117
|
-
|
|
118
|
-
struct Content: Equatable {
|
|
119
|
-
init(rootView: RootView, dataID: AnyHashable?) {
|
|
120
|
-
self.rootView = rootView
|
|
121
|
-
self.dataID = dataID
|
|
122
|
-
}
|
|
123
|
-
|
|
124
|
-
var rootView: RootView
|
|
125
|
-
var dataID: AnyHashable?
|
|
126
|
-
|
|
127
|
-
static func == (_: Content, _: Content) -> Bool {
|
|
128
|
-
// The content should never be equal since we need the `rootView` to be updated on every
|
|
129
|
-
// content change.
|
|
130
|
-
false
|
|
131
|
-
}
|
|
132
|
-
}
|
|
133
|
-
|
|
134
|
-
override func didMoveToWindow() {
|
|
135
|
-
super.didMoveToWindow()
|
|
136
|
-
|
|
137
|
-
// We'll only be able to discover a valid parent `viewController` once we're added to a window,
|
|
138
|
-
// so we do so here in addition to the `handleWillDisplay(…)` method.
|
|
139
|
-
if window != nil {
|
|
140
|
-
addViewControllerIfNeeded()
|
|
141
|
-
}
|
|
142
|
-
}
|
|
143
|
-
|
|
144
|
-
func setContent(_ content: Content, animated _: Bool) {
|
|
145
|
-
// This triggers a change in the observed `EpoxyHostingContent` object and allows the
|
|
146
|
-
// propagation of the SwiftUI transaction, instead of just replacing the `rootView`.
|
|
147
|
-
epoxyContent.rootView = content.rootView
|
|
148
|
-
dataID = content.dataID ?? DefaultDataID.noneProvided as AnyHashable
|
|
149
|
-
|
|
150
|
-
// The view controller must be added to the view controller hierarchy to measure its content.
|
|
151
|
-
if window != nil {
|
|
152
|
-
addViewControllerIfNeeded()
|
|
153
|
-
}
|
|
154
|
-
|
|
155
|
-
// As of iOS 15.2, `UIHostingController` now renders updated content asynchronously, and as such
|
|
156
|
-
// this view will get sized incorrectly with the previous content when reused unless we invoke
|
|
157
|
-
// this semi-private API. We couldn't find any other method to get the view to resize
|
|
158
|
-
// synchronously after updating `rootView`, but hopefully this will become a internal API soon so
|
|
159
|
-
// we can remove this call.
|
|
160
|
-
viewController._render(seconds: 0)
|
|
161
|
-
|
|
162
|
-
// This is required to ensure that views with new content are properly resized.
|
|
163
|
-
viewController.view.invalidateIntrinsicContentSize()
|
|
164
|
-
}
|
|
165
|
-
|
|
166
|
-
override func layoutMarginsDidChange() {
|
|
167
|
-
super.layoutMarginsDidChange()
|
|
168
|
-
|
|
169
|
-
let margins = layoutMargins
|
|
170
|
-
switch effectiveUserInterfaceLayoutDirection {
|
|
171
|
-
case .rightToLeft:
|
|
172
|
-
epoxyEnvironment.layoutMargins = .init(
|
|
173
|
-
top: margins.top,
|
|
174
|
-
leading: margins.right,
|
|
175
|
-
bottom: margins.bottom,
|
|
176
|
-
trailing: margins.left)
|
|
177
|
-
case .leftToRight:
|
|
178
|
-
fallthrough
|
|
179
|
-
@unknown default:
|
|
180
|
-
epoxyEnvironment.layoutMargins = .init(
|
|
181
|
-
top: margins.top,
|
|
182
|
-
leading: margins.left,
|
|
183
|
-
bottom: margins.bottom,
|
|
184
|
-
trailing: margins.right)
|
|
185
|
-
}
|
|
186
|
-
|
|
187
|
-
// Allow the layout margins update to fully propagate through to the SwiftUI View before
|
|
188
|
-
// invalidating the layout.
|
|
189
|
-
DispatchQueue.main.async {
|
|
190
|
-
self.viewController.view.invalidateIntrinsicContentSize()
|
|
191
|
-
}
|
|
192
|
-
}
|
|
193
|
-
|
|
194
|
-
func handleWillDisplay(animated: Bool) {
|
|
195
|
-
guard state != .appeared, window != nil else { return }
|
|
196
|
-
transition(to: .appearing(animated: animated))
|
|
197
|
-
transition(to: .appeared)
|
|
198
|
-
}
|
|
199
|
-
|
|
200
|
-
func handleDidEndDisplaying(animated: Bool) {
|
|
201
|
-
guard state != .disappeared else { return }
|
|
202
|
-
transition(to: .disappearing(animated: animated))
|
|
203
|
-
transition(to: .disappeared)
|
|
204
|
-
}
|
|
205
|
-
|
|
206
|
-
// MARK: Private
|
|
207
|
-
|
|
208
|
-
private let viewController: EpoxySwiftUIHostingController<EpoxyHostingWrapper<RootView>>
|
|
209
|
-
private let epoxyContent: EpoxyHostingContent<RootView>
|
|
210
|
-
private let epoxyEnvironment = EpoxyHostingEnvironment()
|
|
211
|
-
private var dataID: AnyHashable
|
|
212
|
-
private var state: AppearanceState = .disappeared
|
|
213
|
-
|
|
214
|
-
/// Updates the appearance state of the `viewController`.
|
|
215
|
-
private func transition(to state: AppearanceState) {
|
|
216
|
-
guard state != self.state else { return }
|
|
217
|
-
|
|
218
|
-
// See "Handling View-Related Notifications" section for the state machine diagram.
|
|
219
|
-
// https://developer.apple.com/documentation/uikit/uiviewcontroller
|
|
220
|
-
switch (to: state, from: self.state) {
|
|
221
|
-
case (to: .appearing(let animated), from: .disappeared):
|
|
222
|
-
viewController.beginAppearanceTransition(true, animated: animated)
|
|
223
|
-
addViewControllerIfNeeded()
|
|
224
|
-
case (to: .disappearing(let animated), from: .appeared):
|
|
225
|
-
viewController.beginAppearanceTransition(false, animated: animated)
|
|
226
|
-
case (to: .disappeared, from: .disappearing):
|
|
227
|
-
removeViewControllerIfNeeded()
|
|
228
|
-
case (to: .appeared, from: .appearing):
|
|
229
|
-
viewController.endAppearanceTransition()
|
|
230
|
-
case (to: .disappeared, from: .appeared):
|
|
231
|
-
viewController.beginAppearanceTransition(false, animated: true)
|
|
232
|
-
removeViewControllerIfNeeded()
|
|
233
|
-
case (to: .appeared, from: .disappearing(let animated)):
|
|
234
|
-
viewController.beginAppearanceTransition(true, animated: animated)
|
|
235
|
-
viewController.endAppearanceTransition()
|
|
236
|
-
case (to: .disappeared, from: .appearing(let animated)):
|
|
237
|
-
viewController.beginAppearanceTransition(false, animated: animated)
|
|
238
|
-
removeViewControllerIfNeeded()
|
|
239
|
-
case (to: .appeared, from: .disappeared):
|
|
240
|
-
viewController.beginAppearanceTransition(true, animated: false)
|
|
241
|
-
addViewControllerIfNeeded()
|
|
242
|
-
viewController.endAppearanceTransition()
|
|
243
|
-
case (to: .appearing(let animated), from: .appeared):
|
|
244
|
-
viewController.beginAppearanceTransition(false, animated: animated)
|
|
245
|
-
viewController.beginAppearanceTransition(true, animated: animated)
|
|
246
|
-
case (to: .appearing(let animated), from: .disappearing):
|
|
247
|
-
viewController.beginAppearanceTransition(true, animated: animated)
|
|
248
|
-
case (to: .disappearing(let animated), from: .disappeared):
|
|
249
|
-
viewController.beginAppearanceTransition(true, animated: animated)
|
|
250
|
-
addViewControllerIfNeeded()
|
|
251
|
-
viewController.beginAppearanceTransition(false, animated: animated)
|
|
252
|
-
case (to: .disappearing(let animated), from: .appearing):
|
|
253
|
-
viewController.beginAppearanceTransition(false, animated: animated)
|
|
254
|
-
case (to: .appearing, from: .appearing),
|
|
255
|
-
(to: .appeared, from: .appeared),
|
|
256
|
-
(to: .disappearing, from: .disappearing),
|
|
257
|
-
(to: .disappeared, from: .disappeared):
|
|
258
|
-
// This should never happen since we guard on identical states.
|
|
259
|
-
EpoxyLogger.shared.assertionFailure("Impossible state change from \(self.state) to \(state)")
|
|
260
|
-
}
|
|
261
|
-
|
|
262
|
-
self.state = state
|
|
263
|
-
}
|
|
264
|
-
|
|
265
|
-
private func addViewControllerIfNeeded() {
|
|
266
|
-
// This isn't great, and means that we're going to add this view controller as a child view
|
|
267
|
-
// controller of a view controller somewhere else in the hierarchy, which the author of that
|
|
268
|
-
// view controller may not be expecting. However there's not really a better pathway forward
|
|
269
|
-
// here without requiring a view controller instance to be passed all the way through, which is
|
|
270
|
-
// both burdensome and error-prone.
|
|
271
|
-
guard let nextViewController = superview?.next(UIViewController.self) else {
|
|
272
|
-
EpoxyLogger.shared.assertionFailure(
|
|
273
|
-
"""
|
|
274
|
-
Unable to add a UIHostingController view, could not locate a UIViewController in the \
|
|
275
|
-
responder chain for view with ID \(dataID) of type \(RootView.self).
|
|
276
|
-
""")
|
|
277
|
-
return
|
|
278
|
-
}
|
|
279
|
-
|
|
280
|
-
guard viewController.parent !== nextViewController else { return }
|
|
281
|
-
|
|
282
|
-
// If in a different parent, we need to first remove from it before we add.
|
|
283
|
-
if viewController.parent != nil {
|
|
284
|
-
removeViewControllerIfNeeded()
|
|
285
|
-
}
|
|
286
|
-
|
|
287
|
-
addViewController(to: nextViewController)
|
|
288
|
-
|
|
289
|
-
state = .appeared
|
|
290
|
-
}
|
|
291
|
-
|
|
292
|
-
private func addViewController(to parent: UIViewController) {
|
|
293
|
-
viewController.willMove(toParent: parent)
|
|
294
|
-
|
|
295
|
-
parent.addChild(viewController)
|
|
296
|
-
|
|
297
|
-
addSubview(viewController.view)
|
|
298
|
-
|
|
299
|
-
// Get the view controller's view to be sized correctly so that we don't have to wait for
|
|
300
|
-
// autolayout to perform a pass to do so.
|
|
301
|
-
viewController.view.frame = bounds
|
|
302
|
-
|
|
303
|
-
viewController.view.translatesAutoresizingMaskIntoConstraints = false
|
|
304
|
-
NSLayoutConstraint.activate([
|
|
305
|
-
viewController.view.leadingAnchor.constraint(equalTo: leadingAnchor),
|
|
306
|
-
viewController.view.topAnchor.constraint(equalTo: topAnchor),
|
|
307
|
-
viewController.view.trailingAnchor.constraint(equalTo: trailingAnchor),
|
|
308
|
-
viewController.view.bottomAnchor.constraint(equalTo: bottomAnchor),
|
|
309
|
-
])
|
|
310
|
-
|
|
311
|
-
viewController.didMove(toParent: parent)
|
|
312
|
-
}
|
|
313
|
-
|
|
314
|
-
private func removeViewControllerIfNeeded() {
|
|
315
|
-
guard viewController.parent != nil else { return }
|
|
316
|
-
|
|
317
|
-
viewController.willMove(toParent: nil)
|
|
318
|
-
viewController.view.removeFromSuperview()
|
|
319
|
-
viewController.removeFromParent()
|
|
320
|
-
viewController.didMove(toParent: nil)
|
|
321
|
-
}
|
|
322
|
-
}
|
|
323
|
-
|
|
324
|
-
// MARK: - AppearanceState
|
|
325
|
-
|
|
326
|
-
/// The appearance state of a `EpoxySwiftUIHostingController` contained within a
|
|
327
|
-
/// `EpoxySwiftUIHostingView`.
|
|
328
|
-
private enum AppearanceState: Equatable {
|
|
329
|
-
case appearing(animated: Bool)
|
|
330
|
-
case appeared
|
|
331
|
-
case disappearing(animated: Bool)
|
|
332
|
-
case disappeared
|
|
333
|
-
}
|
|
334
|
-
|
|
335
|
-
// MARK: - UIResponder
|
|
336
|
-
|
|
337
|
-
extension UIResponder {
|
|
338
|
-
/// Recursively traverses the responder chain upwards from this responder to its next responder
|
|
339
|
-
/// until the a responder of the given type is located, else returns `nil`.
|
|
340
|
-
@nonobjc
|
|
341
|
-
fileprivate func next<ResponderType>(_ type: ResponderType.Type) -> ResponderType? {
|
|
342
|
-
self as? ResponderType ?? next?.next(type)
|
|
343
|
-
}
|
|
344
|
-
}
|
|
345
|
-
|
|
346
|
-
// MARK: - EpoxyHostingContent
|
|
347
|
-
|
|
348
|
-
/// The object that is used to communicate changes in the root view to the
|
|
349
|
-
/// `EpoxySwiftUIHostingController`.
|
|
350
|
-
@available(iOS 13.0, tvOS 13.0, *)
|
|
351
|
-
final class EpoxyHostingContent<RootView: View>: ObservableObject {
|
|
352
|
-
|
|
353
|
-
// MARK: Lifecycle
|
|
354
|
-
|
|
355
|
-
init(rootView: RootView) {
|
|
356
|
-
_rootView = .init(wrappedValue: rootView)
|
|
357
|
-
}
|
|
358
|
-
|
|
359
|
-
// MARK: Internal
|
|
360
|
-
|
|
361
|
-
@Published var rootView: RootView
|
|
362
|
-
}
|
|
363
|
-
|
|
364
|
-
// MARK: - EpoxyHostingEnvironment
|
|
365
|
-
|
|
366
|
-
/// The object that is used to communicate values to SwiftUI views within an
|
|
367
|
-
/// `EpoxySwiftUIHostingController`, e.g. layout margins.
|
|
368
|
-
@available(iOS 13.0, tvOS 13.0, *)
|
|
369
|
-
final class EpoxyHostingEnvironment: ObservableObject {
|
|
370
|
-
@Published var layoutMargins = EdgeInsets()
|
|
371
|
-
@Published var intrinsicContentSizeInvalidator = EpoxyIntrinsicContentSizeInvalidator(invalidate: { })
|
|
372
|
-
}
|
|
373
|
-
|
|
374
|
-
// MARK: - EpoxyHostingWrapper
|
|
375
|
-
|
|
376
|
-
/// The wrapper view that is used to communicate values to SwiftUI views within an
|
|
377
|
-
/// `EpoxySwiftUIHostingController`, e.g. layout margins.
|
|
378
|
-
@available(iOS 13.0, tvOS 13.0, *)
|
|
379
|
-
struct EpoxyHostingWrapper<Content: View>: View {
|
|
380
|
-
@ObservedObject var content: EpoxyHostingContent<Content>
|
|
381
|
-
@ObservedObject var environment: EpoxyHostingEnvironment
|
|
382
|
-
|
|
383
|
-
var body: some View {
|
|
384
|
-
content.rootView
|
|
385
|
-
.environment(\.epoxyLayoutMargins, environment.layoutMargins)
|
|
386
|
-
.environment(\.epoxyIntrinsicContentSizeInvalidator, environment.intrinsicContentSizeInvalidator)
|
|
387
|
-
}
|
|
388
|
-
}
|
|
389
|
-
#endif
|