diff --git a/Examples/SkeletonUI-macOS-iOS/SkeletonUI-macOS-iOS/Views/CharacterView.swift b/Examples/SkeletonUI-macOS-iOS/SkeletonUI-macOS-iOS/Views/CharacterView.swift
index 9820dcb..fb0b9c7 100644
--- a/Examples/SkeletonUI-macOS-iOS/SkeletonUI-macOS-iOS/Views/CharacterView.swift
+++ b/Examples/SkeletonUI-macOS-iOS/SkeletonUI-macOS-iOS/Views/CharacterView.swift
@@ -25,7 +25,7 @@ struct CharacterView: View {
Text(character?.name)
.skeleton(with: loading)
.shape(type: .capsule)
- .multiline(lines: 3, scales: [1: 0.5, 2: 0.25])
+ .multiline(lines: 3, scales: [1: 0.5, 2: 0.25], padding: EdgeInsets(top: 16, leading: 0, bottom: 16, trailing: 0))
.appearance(type: .gradient())
.animation(type: .linear())
}
@@ -35,7 +35,7 @@ struct CharacterView: View {
#if DEBUG
struct CharacterView_Previews: PreviewProvider {
static var previews: some View {
- CharacterView(character: nil, loading: false)
+ CharacterView(character: nil, loading: true).previewLayout(.sizeThatFits).frame(width: 300, height: 100, alignment: .center)
}
}
#endif
diff --git a/Examples/SkeletonUI-watchOS/SkeletonUI-watchOS.xcodeproj/xcshareddata/xcschemes/SkeletonUI-watchOS.xcscheme b/Examples/SkeletonUI-watchOS/SkeletonUI-watchOS.xcodeproj/xcshareddata/xcschemes/SkeletonUI-watchOS.xcscheme
index 4a699fc..49ce619 100644
--- a/Examples/SkeletonUI-watchOS/SkeletonUI-watchOS.xcodeproj/xcshareddata/xcschemes/SkeletonUI-watchOS.xcscheme
+++ b/Examples/SkeletonUI-watchOS/SkeletonUI-watchOS.xcodeproj/xcshareddata/xcschemes/SkeletonUI-watchOS.xcscheme
@@ -54,10 +54,8 @@
debugDocumentVersioning = "YES"
debugServiceExtension = "internal"
allowLocationSimulation = "YES">
-
+
-
+
-
+
-
-
-
-
-
+
diff --git a/Package.resolved b/Package.resolved
index dc5a1db..f3cc78c 100644
--- a/Package.resolved
+++ b/Package.resolved
@@ -6,8 +6,8 @@
"repositoryURL": "https://github.com/pointfreeco/swift-snapshot-testing",
"state": {
"branch": null,
- "revision": "12c6a7ce9d67f39a23c6bab757bdb073bd997885",
- "version": "1.7.1"
+ "revision": "f8a9c997c3c1dab4e216a8ec9014e23144cbab37",
+ "version": "1.9.0"
}
}
]
diff --git a/SkeletonUI.podspec b/SkeletonUI.podspec
index 3c8f777..d23ac9c 100644
--- a/SkeletonUI.podspec
+++ b/SkeletonUI.podspec
@@ -1,6 +1,6 @@
Pod::Spec.new do |s|
s.name = 'SkeletonUI'
- s.version = '1.0.5'
+ s.version = '1.0.6'
s.summary = 'Elegant skeleton loading animation in SwiftUI and Combine'
s.description = <<-DESC
SkeletonUI aims to bring an elegant, declarative syntax to skeleton loading animations. Get rid of loading screens or spinners and start using skeletons to represent final content shapes
diff --git a/Sources/SkeletonUI/Extensions/ModifiedContent+SkeletonModifier.swift b/Sources/SkeletonUI/Extensions/ModifiedContent+SkeletonModifier.swift
index 7031a1e..76b8d7a 100644
--- a/Sources/SkeletonUI/Extensions/ModifiedContent+SkeletonModifier.swift
+++ b/Sources/SkeletonUI/Extensions/ModifiedContent+SkeletonModifier.swift
@@ -12,10 +12,11 @@ public extension ModifiedContent where Content: View, Modifier == SkeletonModifi
return self
}
- func multiline(lines: Int, scales: [Int: CGFloat]? = nil, spacing: CGFloat? = nil) -> ModifiedContent {
+ func multiline(lines: Int, scales: [Int: CGFloat]? = nil, spacing: CGFloat? = nil, padding: EdgeInsets? = nil) -> ModifiedContent {
modifier.skeleton.multiline.lines.send(lines)
modifier.skeleton.multiline.scales.send(scales)
modifier.skeleton.multiline.spacing.send(spacing)
+ modifier.skeleton.multiline.padding.send(padding)
return self
}
diff --git a/Sources/SkeletonUI/Extensions/View+SkeletonModifier.swift b/Sources/SkeletonUI/Extensions/View+SkeletonModifier.swift
index 222477e..c4c8ca2 100644
--- a/Sources/SkeletonUI/Extensions/View+SkeletonModifier.swift
+++ b/Sources/SkeletonUI/Extensions/View+SkeletonModifier.swift
@@ -2,7 +2,7 @@ import SwiftUI
@available(iOS 13.0, macOS 10.15, tvOS 13.0, watchOS 6.0, *)
public extension View {
- func skeleton(with loading: Bool, transition: AnyTransition? = nil, animated: Animation? = nil) -> ModifiedContent {
- modifier(SkeletonModifier(skeleton: SkeletonInteractor(loading, transition: transition, animated: animated)))
+ func skeleton(with loading: Bool, transition: AnyTransition? = nil, animated: Animation? = nil, width: CGFloat? = nil, height: CGFloat? = nil) -> ModifiedContent {
+ modifier(SkeletonModifier(skeleton: SkeletonInteractor(loading, transition: transition, animated: animated, width: width, height: height)))
}
}
diff --git a/Sources/SkeletonUI/Modifiers/SkeletonModifier.swift b/Sources/SkeletonUI/Modifiers/SkeletonModifier.swift
index 6c9ca47..a7af06d 100644
--- a/Sources/SkeletonUI/Modifiers/SkeletonModifier.swift
+++ b/Sources/SkeletonUI/Modifiers/SkeletonModifier.swift
@@ -31,6 +31,8 @@ public struct SkeletonModifier: ViewModifier {
}
}
}
+ .padding(skeleton.multiline.presenter.padding ?? EdgeInsets(top: 0, leading: 0, bottom: 0, trailing: 0))
+ .frame(width: skeleton.presenter.width, height: skeleton.presenter.height)
.transition(skeleton.presenter.transition)
} else {
content
diff --git a/Sources/SkeletonUI/Multiline/MultilineInteractor.swift b/Sources/SkeletonUI/Multiline/MultilineInteractor.swift
index 0a7377b..b22e406 100644
--- a/Sources/SkeletonUI/Multiline/MultilineInteractor.swift
+++ b/Sources/SkeletonUI/Multiline/MultilineInteractor.swift
@@ -9,6 +9,7 @@ protocol MultilineInteractable: AnyObject {
var scale: CurrentValueSubject { get }
var spacing: CurrentValueSubject { get }
var scales: CurrentValueSubject<[Int: CGFloat]?, Never> { get }
+ var padding: CurrentValueSubject { get }
}
final class MultilineInteractor: MultilineInteractable {
@@ -18,6 +19,7 @@ final class MultilineInteractor: MultilineInteractable {
let scale: CurrentValueSubject
let spacing: CurrentValueSubject
let scales: CurrentValueSubject<[Int: CGFloat]?, Never>
+ let padding: CurrentValueSubject
private var cancellables = Set()
@@ -27,6 +29,8 @@ final class MultilineInteractor: MultilineInteractable {
scale = CurrentValueSubject(presenter.scale)
spacing = CurrentValueSubject(presenter.spacing)
scales = CurrentValueSubject<[Int: CGFloat]?, Never>(presenter.scales)
+ padding = CurrentValueSubject(presenter.padding)
+
line.map { [weak self] line in
guard let self = self else { fatalError() }
if let scale = self.scales.value?[line] {
@@ -37,5 +41,6 @@ final class MultilineInteractor: MultilineInteractable {
lines.assign(to: \.lines, on: presenter).store(in: &cancellables)
scales.assign(to: \.scales, on: presenter).store(in: &cancellables)
spacing.assign(to: \.spacing, on: presenter).store(in: &cancellables)
+ padding.assign(to: \.padding, on: presenter).store(in: &cancellables)
}
}
diff --git a/Sources/SkeletonUI/Multiline/MultilinePresenter.swift b/Sources/SkeletonUI/Multiline/MultilinePresenter.swift
index 4ba0891..486ff81 100644
--- a/Sources/SkeletonUI/Multiline/MultilinePresenter.swift
+++ b/Sources/SkeletonUI/Multiline/MultilinePresenter.swift
@@ -6,4 +6,5 @@ final class MultilinePresenter: ObservableObject {
@Published var spacing: CGFloat?
@Published var scale: CGFloat = 1
@Published var scales: [Int: CGFloat]?
+ @Published var padding: EdgeInsets?
}
diff --git a/Sources/SkeletonUI/Skeleton/SkeletonInteractor.swift b/Sources/SkeletonUI/Skeleton/SkeletonInteractor.swift
index 3252f2c..ee46409 100644
--- a/Sources/SkeletonUI/Skeleton/SkeletonInteractor.swift
+++ b/Sources/SkeletonUI/Skeleton/SkeletonInteractor.swift
@@ -17,8 +17,8 @@ final class SkeletonInteractor: SkeletonInteractable {
let appearance: AppearanceInteractable
let animation: AnimationInteractable
- init(_ loading: Bool, transition: AnyTransition?, animated: Animation?, shape: ShapeInteractable = ShapeInteractor(), multiline: MultilineInteractable = MultilineInteractor(), appearance: AppearanceInteractable = AppearanceInteractor(), animation: AnimationInteractable = AnimationInteractor()) {
- presenter = SkeletonPresenter(loading, transition: transition, animated: animated)
+ init(_ loading: Bool, transition: AnyTransition?, animated: Animation?, width: CGFloat?, height: CGFloat?, shape: ShapeInteractable = ShapeInteractor(), multiline: MultilineInteractable = MultilineInteractor(), appearance: AppearanceInteractable = AppearanceInteractor(), animation: AnimationInteractable = AnimationInteractor()) {
+ presenter = SkeletonPresenter(loading, transition: transition, animated: animated, width: width, height: height)
self.shape = shape
self.multiline = multiline
self.appearance = appearance
diff --git a/Sources/SkeletonUI/Skeleton/SkeletonPresenter.swift b/Sources/SkeletonUI/Skeleton/SkeletonPresenter.swift
index 647fdb8..03f8b3d 100644
--- a/Sources/SkeletonUI/Skeleton/SkeletonPresenter.swift
+++ b/Sources/SkeletonUI/Skeleton/SkeletonPresenter.swift
@@ -4,10 +4,14 @@ final class SkeletonPresenter: ObservableObject {
@Published var loading: Bool
@Published var transition: AnyTransition
@Published var animated: Animation
+ @Published var width: CGFloat?
+ @Published var height: CGFloat?
- init(_ loading: Bool, transition: AnyTransition?, animated: Animation?) {
+ init(_ loading: Bool, transition: AnyTransition?, animated: Animation?, width: CGFloat?, height: CGFloat?) {
self.loading = loading
self.transition = transition ?? .opacity
self.animated = animated ?? .default
+ self.width = width
+ self.height = height
}
}
diff --git a/Tests/SkeletonUISnapshotTests/AutoMockable.generated.swift b/Tests/SkeletonUISnapshotTests/AutoMockable.generated.swift
index ddba87c..aed5bd6 100644
--- a/Tests/SkeletonUISnapshotTests/AutoMockable.generated.swift
+++ b/Tests/SkeletonUISnapshotTests/AutoMockable.generated.swift
@@ -93,6 +93,12 @@ class AppearanceInteractableMock: AppearanceInteractable {
}
class MultilineInteractableMock: MultilineInteractable {
+ var underlyingPadding: CurrentValueSubject!
+ var padding: CurrentValueSubject {
+ get { return underlyingPadding }
+ set(value) { underlyingPadding = value }
+ }
+
var presenter: MultilinePresenter {
get { return underlyingPresenter }
set(value) { underlyingPresenter = value }
diff --git a/Tests/SkeletonUISnapshotTests/SnapshotTests.swift b/Tests/SkeletonUISnapshotTests/SnapshotTests.swift
index 573cb50..c4627bd 100644
--- a/Tests/SkeletonUISnapshotTests/SnapshotTests.swift
+++ b/Tests/SkeletonUISnapshotTests/SnapshotTests.swift
@@ -22,6 +22,11 @@ final class SnapshotTests: XCTestCase {
let view = Text(nil).skeleton(with: true).appearance(type: .solid()).shape(type: .rectangle).multiline(lines: 2, scales: [1: 0.5]).animation(type: .pulse())
assertNamedSnapshot(matching: view, as: .image(size: CGSize(width: 100, height: 50)))
}
+
+ func testCustomTextWithPadding() {
+ let view = Text(nil).skeleton(with: true).appearance(type: .solid()).shape(type: .rectangle).multiline(lines: 2, scales: [1: 0.5], padding: EdgeInsets(top: 5, leading: 0, bottom: 5, trailing: 0)).animation(type: .pulse())
+ assertNamedSnapshot(matching: view, as: .image(size: CGSize(width: 100, height: 60)))
+ }
func testDefaultImage() {
#if os(macOS)