diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml
index af3ca64c..4c33c6ef 100644
--- a/.github/workflows/main.yml
+++ b/.github/workflows/main.yml
@@ -10,10 +10,12 @@ jobs:
strategy:
matrix:
build-config:
- - { target: 'SkeletonView-iOS', destination: 'platform=iOS Simulator,name=iPhone 8', sdk: 'iphonesimulator' }
- - { target: 'SkeletonView-tvOS', destination: 'platform=tvOS Simulator,name=Apple TV', sdk: 'appletvsimulator' }
- - { target: 'SkeletonViewExample', destination: 'platform=iOS Simulator,name=iPhone 8', sdk: 'iphonesimulator' }
+ - { scheme: 'SkeletonView iOS', destination: 'platform=iOS Simulator,name=iPhone 8', sdk: 'iphonesimulator' }
+ - { scheme: 'SkeletonView tvOS', destination: 'platform=tvOS Simulator,name=Apple TV', sdk: 'appletvsimulator' }
+ - { scheme: 'iOS Example', destination: 'platform=iOS Simulator,name=iPhone 8', sdk: 'iphonesimulator' }
+ - { scheme: 'tvOS Example', destination: 'platform=tvOS Simulator,name=Apple TV', sdk: 'appletvsimulator' }
steps:
- uses: actions/checkout@v2
- name: Build
- run: xcodebuild clean build -target '${{ matrix.build-config['target'] }}' -sdk '${{ matrix.build-config['sdk'] }}' -destination '${{ matrix.build-config['destination'] }}'
+ run: xcodebuild clean build -workspace 'SkeletonView.xcworkspace' -scheme '${{ matrix.build-config['scheme'] }}' -sdk '${{ matrix.build-config['sdk'] }}' -destination '${{ matrix.build-config['destination'] }}'
+
diff --git a/.swiftlint.yml b/.swiftlint.yml
index 0681011f..fec8885a 100755
--- a/.swiftlint.yml
+++ b/.swiftlint.yml
@@ -1,5 +1,5 @@
included:
- - Sources
+ - SkeletonViewCore/Sources
disabled_rules:
- trailing_whitespace
- line_length
@@ -20,6 +20,8 @@ disabled_rules:
- function_default_parameter_at_end
- unowned_variable_capture
- legacy_constructor
+ - redundant_type_annotation
+ - vertical_whitespace_opening_braces
opt_in_rules:
- multiline_arguments
- multiline_parameters
@@ -49,18 +51,21 @@ opt_in_rules:
- private_outlet
- redundant_optional_initialization
- redundant_set_access_control
- - redundant_type_annotation
- sorted_first_last
- switch_case_on_newline
- unneeded_parentheses_in_closure_argument
- unused_declaration
- unused_import
- - vertical_whitespace_opening_braces
- discouraged_optional_collection
- - enum_case_associated_values_counts
+ - enum_case_associated_values_count
- legacy_multiple
- legacy_random
indentation: 2
+type_name:
+ min_length: 2
+ max_length:
+ warning: 50
+ error: 60
file_length:
- 2500
- 3000
diff --git a/.swiftpm/xcode/package.xcworkspace/contents.xcworkspacedata b/.swiftpm/xcode/package.xcworkspace/contents.xcworkspacedata
new file mode 100644
index 00000000..919434a6
--- /dev/null
+++ b/.swiftpm/xcode/package.xcworkspace/contents.xcworkspacedata
@@ -0,0 +1,7 @@
+
+
+
+
+
diff --git a/Configs/SkeletonView-iOS.plist b/Configs/SkeletonView-iOS.plist
deleted file mode 100644
index f1971090..00000000
--- a/Configs/SkeletonView-iOS.plist
+++ /dev/null
@@ -1,24 +0,0 @@
-
-
-
-
- CFBundleDevelopmentRegion
- en
- CFBundleExecutable
- $(EXECUTABLE_NAME)
- CFBundleIdentifier
- $(PRODUCT_BUNDLE_IDENTIFIER)
- CFBundleInfoDictionaryVersion
- 6.0
- CFBundleName
- $(PRODUCT_NAME)
- CFBundlePackageType
- FMWK
- CFBundleShortVersionString
- 1.3
- CFBundleSignature
- ????
- CFBundleVersion
- $(CURRENT_PROJECT_VERSION)
-
-
diff --git a/Example/TableView/Assets.xcassets/Contents.json b/Example/TableView/Assets.xcassets/Contents.json
deleted file mode 100644
index da4a164c..00000000
--- a/Example/TableView/Assets.xcassets/Contents.json
+++ /dev/null
@@ -1,6 +0,0 @@
-{
- "info" : {
- "version" : 1,
- "author" : "xcode"
- }
-}
\ No newline at end of file
diff --git a/Example/CollectionView/AppDelegate.swift b/Examples/CollectionView/AppDelegate.swift
similarity index 100%
rename from Example/CollectionView/AppDelegate.swift
rename to Examples/CollectionView/AppDelegate.swift
diff --git a/Example/CollectionView/Assets.xcassets/AppIcon.appiconset/Contents.json b/Examples/CollectionView/Assets.xcassets/AppIcon.appiconset/Contents.json
similarity index 100%
rename from Example/CollectionView/Assets.xcassets/AppIcon.appiconset/Contents.json
rename to Examples/CollectionView/Assets.xcassets/AppIcon.appiconset/Contents.json
diff --git a/Example/CollectionView/Assets.xcassets/Contents.json b/Examples/CollectionView/Assets.xcassets/Contents.json
similarity index 100%
rename from Example/CollectionView/Assets.xcassets/Contents.json
rename to Examples/CollectionView/Assets.xcassets/Contents.json
diff --git a/Example/CollectionView/Assets.xcassets/avatar.imageset/Contents.json b/Examples/CollectionView/Assets.xcassets/avatar.imageset/Contents.json
similarity index 100%
rename from Example/CollectionView/Assets.xcassets/avatar.imageset/Contents.json
rename to Examples/CollectionView/Assets.xcassets/avatar.imageset/Contents.json
diff --git a/Example/CollectionView/Assets.xcassets/avatar.imageset/avatar.png b/Examples/CollectionView/Assets.xcassets/avatar.imageset/avatar.png
similarity index 100%
rename from Example/CollectionView/Assets.xcassets/avatar.imageset/avatar.png
rename to Examples/CollectionView/Assets.xcassets/avatar.imageset/avatar.png
diff --git a/Example/CollectionView/Assets.xcassets/picture.imageset/Contents.json b/Examples/CollectionView/Assets.xcassets/picture.imageset/Contents.json
similarity index 100%
rename from Example/CollectionView/Assets.xcassets/picture.imageset/Contents.json
rename to Examples/CollectionView/Assets.xcassets/picture.imageset/Contents.json
diff --git a/Example/CollectionView/Assets.xcassets/picture.imageset/picture.png b/Examples/CollectionView/Assets.xcassets/picture.imageset/picture.png
similarity index 100%
rename from Example/CollectionView/Assets.xcassets/picture.imageset/picture.png
rename to Examples/CollectionView/Assets.xcassets/picture.imageset/picture.png
diff --git a/Example/CollectionView/Base.lproj/LaunchScreen.storyboard b/Examples/CollectionView/Base.lproj/LaunchScreen.storyboard
similarity index 100%
rename from Example/CollectionView/Base.lproj/LaunchScreen.storyboard
rename to Examples/CollectionView/Base.lproj/LaunchScreen.storyboard
diff --git a/Example/CollectionView/CollectionViewCell.swift b/Examples/CollectionView/CollectionViewCell.swift
similarity index 100%
rename from Example/CollectionView/CollectionViewCell.swift
rename to Examples/CollectionView/CollectionViewCell.swift
diff --git a/Example/CollectionView/Main.storyboard b/Examples/CollectionView/Main.storyboard
similarity index 100%
rename from Example/CollectionView/Main.storyboard
rename to Examples/CollectionView/Main.storyboard
diff --git a/Configs/SkeletonViewExampleCollectionview-Info.plist b/Examples/CollectionView/SkeletonViewExampleCollectionview-Info.plist
similarity index 100%
rename from Configs/SkeletonViewExampleCollectionview-Info.plist
rename to Examples/CollectionView/SkeletonViewExampleCollectionview-Info.plist
diff --git a/Example/CollectionView/ViewController.swift b/Examples/CollectionView/ViewController.swift
similarity index 100%
rename from Example/CollectionView/ViewController.swift
rename to Examples/CollectionView/ViewController.swift
diff --git a/Example/TableView/AppDelegate.swift b/Examples/iOS Example/Sources/AppDelegate.swift
similarity index 100%
rename from Example/TableView/AppDelegate.swift
rename to Examples/iOS Example/Sources/AppDelegate.swift
diff --git a/Examples/iOS Example/Sources/Assets.xcassets/AccentColor.colorset/Contents.json b/Examples/iOS Example/Sources/Assets.xcassets/AccentColor.colorset/Contents.json
new file mode 100644
index 00000000..22c4bb0a
--- /dev/null
+++ b/Examples/iOS Example/Sources/Assets.xcassets/AccentColor.colorset/Contents.json
@@ -0,0 +1,38 @@
+{
+ "colors" : [
+ {
+ "color" : {
+ "color-space" : "srgb",
+ "components" : {
+ "alpha" : "1.000",
+ "blue" : "1.000",
+ "green" : "1.000",
+ "red" : "1.000"
+ }
+ },
+ "idiom" : "universal"
+ },
+ {
+ "appearances" : [
+ {
+ "appearance" : "luminosity",
+ "value" : "dark"
+ }
+ ],
+ "color" : {
+ "color-space" : "srgb",
+ "components" : {
+ "alpha" : "1.000",
+ "blue" : "1.000",
+ "green" : "1.000",
+ "red" : "1.000"
+ }
+ },
+ "idiom" : "universal"
+ }
+ ],
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ }
+}
diff --git a/Example/TableView/Assets.xcassets/AppIcon.appiconset/Contents.json b/Examples/iOS Example/Sources/Assets.xcassets/AppIcon.appiconset/Contents.json
similarity index 100%
rename from Example/TableView/Assets.xcassets/AppIcon.appiconset/Contents.json
rename to Examples/iOS Example/Sources/Assets.xcassets/AppIcon.appiconset/Contents.json
diff --git a/Examples/iOS Example/Sources/Assets.xcassets/Contents.json b/Examples/iOS Example/Sources/Assets.xcassets/Contents.json
new file mode 100644
index 00000000..73c00596
--- /dev/null
+++ b/Examples/iOS Example/Sources/Assets.xcassets/Contents.json
@@ -0,0 +1,6 @@
+{
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ }
+}
diff --git a/Example/TableView/Assets.xcassets/avatar.imageset/Contents.json b/Examples/iOS Example/Sources/Assets.xcassets/avatar.imageset/Contents.json
similarity index 100%
rename from Example/TableView/Assets.xcassets/avatar.imageset/Contents.json
rename to Examples/iOS Example/Sources/Assets.xcassets/avatar.imageset/Contents.json
diff --git a/Example/TableView/Assets.xcassets/avatar.imageset/avatar.png b/Examples/iOS Example/Sources/Assets.xcassets/avatar.imageset/avatar.png
similarity index 100%
rename from Example/TableView/Assets.xcassets/avatar.imageset/avatar.png
rename to Examples/iOS Example/Sources/Assets.xcassets/avatar.imageset/avatar.png
diff --git a/Example/TableView/Base.lproj/LaunchScreen.storyboard b/Examples/iOS Example/Sources/Base.lproj/LaunchScreen.storyboard
similarity index 100%
rename from Example/TableView/Base.lproj/LaunchScreen.storyboard
rename to Examples/iOS Example/Sources/Base.lproj/LaunchScreen.storyboard
diff --git a/Example/TableView/Base.lproj/Main.storyboard b/Examples/iOS Example/Sources/Base.lproj/Main.storyboard
similarity index 100%
rename from Example/TableView/Base.lproj/Main.storyboard
rename to Examples/iOS Example/Sources/Base.lproj/Main.storyboard
diff --git a/Example/TableView/Cell.swift b/Examples/iOS Example/Sources/Cell.swift
similarity index 100%
rename from Example/TableView/Cell.swift
rename to Examples/iOS Example/Sources/Cell.swift
diff --git a/Example/TableView/Constants.swift b/Examples/iOS Example/Sources/Constants.swift
similarity index 100%
rename from Example/TableView/Constants.swift
rename to Examples/iOS Example/Sources/Constants.swift
diff --git a/Example/TableView/HeaderFooterSection.swift b/Examples/iOS Example/Sources/HeaderFooterSection.swift
similarity index 100%
rename from Example/TableView/HeaderFooterSection.swift
rename to Examples/iOS Example/Sources/HeaderFooterSection.swift
diff --git a/Configs/SkeletonViewExampleInfo.plist b/Examples/iOS Example/Sources/Info.plist
similarity index 91%
rename from Configs/SkeletonViewExampleInfo.plist
rename to Examples/iOS Example/Sources/Info.plist
index 9751b3b3..1993c7fa 100644
--- a/Configs/SkeletonViewExampleInfo.plist
+++ b/Examples/iOS Example/Sources/Info.plist
@@ -13,13 +13,15 @@
CFBundleName
$(PRODUCT_NAME)
CFBundlePackageType
- APPL
+ $(PRODUCT_BUNDLE_PACKAGE_TYPE)
CFBundleShortVersionString
- 1.3
+ 1.0
CFBundleVersion
1
LSRequiresIPhoneOS
+ UIApplicationSupportsIndirectInputEvents
+
UILaunchStoryboardName
LaunchScreen
UIMainStoryboardFile
diff --git a/Example/TableView/ViewController.swift b/Examples/iOS Example/Sources/ViewController.swift
similarity index 100%
rename from Example/TableView/ViewController.swift
rename to Examples/iOS Example/Sources/ViewController.swift
diff --git a/Examples/iOS Example/iOS Example.xcodeproj/project.pbxproj b/Examples/iOS Example/iOS Example.xcodeproj/project.pbxproj
new file mode 100644
index 00000000..41425b0c
--- /dev/null
+++ b/Examples/iOS Example/iOS Example.xcodeproj/project.pbxproj
@@ -0,0 +1,453 @@
+// !$*UTF8*$!
+{
+ archiveVersion = 1;
+ classes = {
+ };
+ objectVersion = 50;
+ objects = {
+
+/* Begin PBXBuildFile section */
+ F556F5C026CD20A300A80B83 /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = F556F5B726CD20A300A80B83 /* ViewController.swift */; };
+ F556F5C126CD20A300A80B83 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = F556F5B826CD20A300A80B83 /* Assets.xcassets */; };
+ F556F5C226CD20A300A80B83 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = F556F5B926CD20A300A80B83 /* LaunchScreen.storyboard */; };
+ F556F5C326CD20A300A80B83 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = F556F5BB26CD20A300A80B83 /* Main.storyboard */; };
+ F556F5C426CD20A300A80B83 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = F556F5BD26CD20A300A80B83 /* AppDelegate.swift */; };
+ F556F5E626CD21D300A80B83 /* SkeletonView.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F556F5E026CD21CB00A80B83 /* SkeletonView.framework */; };
+ F556F6EE26CE813F00A80B83 /* Cell.swift in Sources */ = {isa = PBXBuildFile; fileRef = F556F6E626CE813F00A80B83 /* Cell.swift */; };
+ F556F6EF26CE813F00A80B83 /* Constants.swift in Sources */ = {isa = PBXBuildFile; fileRef = F556F6EC26CE813F00A80B83 /* Constants.swift */; };
+ F556F6F026CE813F00A80B83 /* HeaderFooterSection.swift in Sources */ = {isa = PBXBuildFile; fileRef = F556F6ED26CE813F00A80B83 /* HeaderFooterSection.swift */; };
+/* End PBXBuildFile section */
+
+/* Begin PBXContainerItemProxy section */
+ F556F5DF26CD21CB00A80B83 /* PBXContainerItemProxy */ = {
+ isa = PBXContainerItemProxy;
+ containerPortal = F556F5D926CD21CB00A80B83 /* SkeletonView.xcodeproj */;
+ proxyType = 2;
+ remoteGlobalIDString = "SkeletonView::SkeletonView::Product";
+ remoteInfo = "SkeletonView iOS";
+ };
+ F556F5E126CD21CB00A80B83 /* PBXContainerItemProxy */ = {
+ isa = PBXContainerItemProxy;
+ containerPortal = F556F5D926CD21CB00A80B83 /* SkeletonView.xcodeproj */;
+ proxyType = 2;
+ remoteGlobalIDString = "SkeletonView::SkeletonViewTests::Product";
+ remoteInfo = SkeletonViewTests;
+ };
+ F556F5E326CD21CB00A80B83 /* PBXContainerItemProxy */ = {
+ isa = PBXContainerItemProxy;
+ containerPortal = F556F5D926CD21CB00A80B83 /* SkeletonView.xcodeproj */;
+ proxyType = 2;
+ remoteGlobalIDString = F556F59426CD1F3900A80B83;
+ remoteInfo = "SkeletonView tvOS";
+ };
+ F556F5E926CD21DA00A80B83 /* PBXContainerItemProxy */ = {
+ isa = PBXContainerItemProxy;
+ containerPortal = F556F5D926CD21CB00A80B83 /* SkeletonView.xcodeproj */;
+ proxyType = 1;
+ remoteGlobalIDString = "SkeletonView::SkeletonView";
+ remoteInfo = "SkeletonView iOS";
+ };
+ F556F6EA26CE813F00A80B83 /* PBXContainerItemProxy */ = {
+ isa = PBXContainerItemProxy;
+ containerPortal = F556F5D926CD21CB00A80B83 /* SkeletonView.xcodeproj */;
+ proxyType = 2;
+ remoteGlobalIDString = F556F67126CD458500A80B83;
+ remoteInfo = "SkeletonView tvOS Tests";
+ };
+/* End PBXContainerItemProxy section */
+
+/* Begin PBXFileReference section */
+ F556F59F26CD201B00A80B83 /* iOS Example.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "iOS Example.app"; sourceTree = BUILT_PRODUCTS_DIR; };
+ F556F5B726CD20A300A80B83 /* ViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ViewController.swift; sourceTree = ""; };
+ F556F5B826CD20A300A80B83 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; };
+ F556F5BA26CD20A300A80B83 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; };
+ F556F5BC26CD20A300A80B83 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; };
+ F556F5BD26CD20A300A80B83 /* AppDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; };
+ F556F5BE26CD20A300A80B83 /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; };
+ F556F5D926CD21CB00A80B83 /* SkeletonView.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = SkeletonView.xcodeproj; path = ../../SkeletonView.xcodeproj; sourceTree = ""; };
+ F556F6E626CE813F00A80B83 /* Cell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Cell.swift; sourceTree = ""; };
+ F556F6EC26CE813F00A80B83 /* Constants.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Constants.swift; sourceTree = ""; };
+ F556F6ED26CE813F00A80B83 /* HeaderFooterSection.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = HeaderFooterSection.swift; sourceTree = ""; };
+/* End PBXFileReference section */
+
+/* Begin PBXFrameworksBuildPhase section */
+ F556F59C26CD201B00A80B83 /* Frameworks */ = {
+ isa = PBXFrameworksBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ F556F5E626CD21D300A80B83 /* SkeletonView.framework in Frameworks */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+/* End PBXFrameworksBuildPhase section */
+
+/* Begin PBXGroup section */
+ F556F59626CD201B00A80B83 = {
+ isa = PBXGroup;
+ children = (
+ F556F5B626CD20A300A80B83 /* Sources */,
+ F556F5A026CD201B00A80B83 /* Products */,
+ F556F5D926CD21CB00A80B83 /* SkeletonView.xcodeproj */,
+ );
+ sourceTree = "";
+ };
+ F556F5A026CD201B00A80B83 /* Products */ = {
+ isa = PBXGroup;
+ children = (
+ F556F59F26CD201B00A80B83 /* iOS Example.app */,
+ );
+ name = Products;
+ sourceTree = "";
+ };
+ F556F5B626CD20A300A80B83 /* Sources */ = {
+ isa = PBXGroup;
+ children = (
+ F556F6E626CE813F00A80B83 /* Cell.swift */,
+ F556F6EC26CE813F00A80B83 /* Constants.swift */,
+ F556F6ED26CE813F00A80B83 /* HeaderFooterSection.swift */,
+ F556F5B726CD20A300A80B83 /* ViewController.swift */,
+ F556F5B826CD20A300A80B83 /* Assets.xcassets */,
+ F556F5B926CD20A300A80B83 /* LaunchScreen.storyboard */,
+ F556F5BB26CD20A300A80B83 /* Main.storyboard */,
+ F556F5BD26CD20A300A80B83 /* AppDelegate.swift */,
+ F556F5BE26CD20A300A80B83 /* Info.plist */,
+ );
+ path = Sources;
+ sourceTree = "";
+ };
+ F556F5DA26CD21CB00A80B83 /* Products */ = {
+ isa = PBXGroup;
+ children = (
+ F556F5E026CD21CB00A80B83 /* SkeletonView.framework */,
+ F556F5E226CD21CB00A80B83 /* SkeletonViewTests.xctest */,
+ F556F5E426CD21CB00A80B83 /* SkeletonView.framework */,
+ F556F6EB26CE813F00A80B83 /* SkeletonView tvOS Tests.xctest */,
+ );
+ name = Products;
+ sourceTree = "";
+ };
+/* End PBXGroup section */
+
+/* Begin PBXNativeTarget section */
+ F556F59E26CD201B00A80B83 /* iOS Example */ = {
+ isa = PBXNativeTarget;
+ buildConfigurationList = F556F5B326CD201C00A80B83 /* Build configuration list for PBXNativeTarget "iOS Example" */;
+ buildPhases = (
+ F556F59B26CD201B00A80B83 /* Sources */,
+ F556F59C26CD201B00A80B83 /* Frameworks */,
+ F556F59D26CD201B00A80B83 /* Resources */,
+ );
+ buildRules = (
+ );
+ dependencies = (
+ F556F5EA26CD21DA00A80B83 /* PBXTargetDependency */,
+ );
+ name = "iOS Example";
+ productName = "iOS Example";
+ productReference = F556F59F26CD201B00A80B83 /* iOS Example.app */;
+ productType = "com.apple.product-type.application";
+ };
+/* End PBXNativeTarget section */
+
+/* Begin PBXProject section */
+ F556F59726CD201B00A80B83 /* Project object */ = {
+ isa = PBXProject;
+ attributes = {
+ LastSwiftUpdateCheck = 1250;
+ LastUpgradeCheck = 1250;
+ TargetAttributes = {
+ F556F59E26CD201B00A80B83 = {
+ CreatedOnToolsVersion = 12.5.1;
+ };
+ };
+ };
+ buildConfigurationList = F556F59A26CD201B00A80B83 /* Build configuration list for PBXProject "iOS Example" */;
+ compatibilityVersion = "Xcode 9.3";
+ developmentRegion = en;
+ hasScannedForEncodings = 0;
+ knownRegions = (
+ en,
+ Base,
+ );
+ mainGroup = F556F59626CD201B00A80B83;
+ productRefGroup = F556F5A026CD201B00A80B83 /* Products */;
+ projectDirPath = "";
+ projectReferences = (
+ {
+ ProductGroup = F556F5DA26CD21CB00A80B83 /* Products */;
+ ProjectRef = F556F5D926CD21CB00A80B83 /* SkeletonView.xcodeproj */;
+ },
+ );
+ projectRoot = "";
+ targets = (
+ F556F59E26CD201B00A80B83 /* iOS Example */,
+ );
+ };
+/* End PBXProject section */
+
+/* Begin PBXReferenceProxy section */
+ F556F5E026CD21CB00A80B83 /* SkeletonView.framework */ = {
+ isa = PBXReferenceProxy;
+ fileType = wrapper.framework;
+ path = SkeletonView.framework;
+ remoteRef = F556F5DF26CD21CB00A80B83 /* PBXContainerItemProxy */;
+ sourceTree = BUILT_PRODUCTS_DIR;
+ };
+ F556F5E226CD21CB00A80B83 /* SkeletonViewTests.xctest */ = {
+ isa = PBXReferenceProxy;
+ fileType = wrapper.cfbundle;
+ path = SkeletonViewTests.xctest;
+ remoteRef = F556F5E126CD21CB00A80B83 /* PBXContainerItemProxy */;
+ sourceTree = BUILT_PRODUCTS_DIR;
+ };
+ F556F5E426CD21CB00A80B83 /* SkeletonView.framework */ = {
+ isa = PBXReferenceProxy;
+ fileType = wrapper.framework;
+ path = SkeletonView.framework;
+ remoteRef = F556F5E326CD21CB00A80B83 /* PBXContainerItemProxy */;
+ sourceTree = BUILT_PRODUCTS_DIR;
+ };
+ F556F6EB26CE813F00A80B83 /* SkeletonView tvOS Tests.xctest */ = {
+ isa = PBXReferenceProxy;
+ fileType = wrapper.cfbundle;
+ path = "SkeletonView tvOS Tests.xctest";
+ remoteRef = F556F6EA26CE813F00A80B83 /* PBXContainerItemProxy */;
+ sourceTree = BUILT_PRODUCTS_DIR;
+ };
+/* End PBXReferenceProxy section */
+
+/* Begin PBXResourcesBuildPhase section */
+ F556F59D26CD201B00A80B83 /* Resources */ = {
+ isa = PBXResourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ F556F5C326CD20A300A80B83 /* Main.storyboard in Resources */,
+ F556F5C126CD20A300A80B83 /* Assets.xcassets in Resources */,
+ F556F5C226CD20A300A80B83 /* LaunchScreen.storyboard in Resources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+/* End PBXResourcesBuildPhase section */
+
+/* Begin PBXSourcesBuildPhase section */
+ F556F59B26CD201B00A80B83 /* Sources */ = {
+ isa = PBXSourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ F556F6EF26CE813F00A80B83 /* Constants.swift in Sources */,
+ F556F5C426CD20A300A80B83 /* AppDelegate.swift in Sources */,
+ F556F6EE26CE813F00A80B83 /* Cell.swift in Sources */,
+ F556F5C026CD20A300A80B83 /* ViewController.swift in Sources */,
+ F556F6F026CE813F00A80B83 /* HeaderFooterSection.swift in Sources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+/* End PBXSourcesBuildPhase section */
+
+/* Begin PBXTargetDependency section */
+ F556F5EA26CD21DA00A80B83 /* PBXTargetDependency */ = {
+ isa = PBXTargetDependency;
+ name = "SkeletonView iOS";
+ targetProxy = F556F5E926CD21DA00A80B83 /* PBXContainerItemProxy */;
+ };
+/* End PBXTargetDependency section */
+
+/* Begin PBXVariantGroup section */
+ F556F5B926CD20A300A80B83 /* LaunchScreen.storyboard */ = {
+ isa = PBXVariantGroup;
+ children = (
+ F556F5BA26CD20A300A80B83 /* Base */,
+ );
+ name = LaunchScreen.storyboard;
+ sourceTree = "";
+ };
+ F556F5BB26CD20A300A80B83 /* Main.storyboard */ = {
+ isa = PBXVariantGroup;
+ children = (
+ F556F5BC26CD20A300A80B83 /* Base */,
+ );
+ name = Main.storyboard;
+ sourceTree = "";
+ };
+/* End PBXVariantGroup section */
+
+/* Begin XCBuildConfiguration section */
+ F556F5B126CD201C00A80B83 /* Debug */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ ALWAYS_SEARCH_USER_PATHS = NO;
+ CLANG_ANALYZER_NONNULL = YES;
+ CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
+ CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
+ CLANG_CXX_LIBRARY = "libc++";
+ CLANG_ENABLE_MODULES = YES;
+ CLANG_ENABLE_OBJC_ARC = YES;
+ CLANG_ENABLE_OBJC_WEAK = YES;
+ CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
+ CLANG_WARN_BOOL_CONVERSION = YES;
+ CLANG_WARN_COMMA = YES;
+ CLANG_WARN_CONSTANT_CONVERSION = YES;
+ CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
+ CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
+ CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
+ CLANG_WARN_EMPTY_BODY = YES;
+ CLANG_WARN_ENUM_CONVERSION = YES;
+ CLANG_WARN_INFINITE_RECURSION = YES;
+ CLANG_WARN_INT_CONVERSION = YES;
+ CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
+ CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
+ CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
+ CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
+ CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
+ CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
+ CLANG_WARN_STRICT_PROTOTYPES = YES;
+ CLANG_WARN_SUSPICIOUS_MOVE = YES;
+ CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
+ CLANG_WARN_UNREACHABLE_CODE = YES;
+ CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
+ COPY_PHASE_STRIP = NO;
+ DEBUG_INFORMATION_FORMAT = dwarf;
+ ENABLE_STRICT_OBJC_MSGSEND = YES;
+ ENABLE_TESTABILITY = YES;
+ GCC_C_LANGUAGE_STANDARD = gnu11;
+ GCC_DYNAMIC_NO_PIC = NO;
+ GCC_NO_COMMON_BLOCKS = YES;
+ GCC_OPTIMIZATION_LEVEL = 0;
+ GCC_PREPROCESSOR_DEFINITIONS = (
+ "DEBUG=1",
+ "$(inherited)",
+ );
+ GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
+ GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
+ GCC_WARN_UNDECLARED_SELECTOR = YES;
+ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
+ GCC_WARN_UNUSED_FUNCTION = YES;
+ GCC_WARN_UNUSED_VARIABLE = YES;
+ IPHONEOS_DEPLOYMENT_TARGET = 14.5;
+ MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
+ MTL_FAST_MATH = YES;
+ ONLY_ACTIVE_ARCH = YES;
+ SDKROOT = iphoneos;
+ SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG;
+ SWIFT_OPTIMIZATION_LEVEL = "-Onone";
+ };
+ name = Debug;
+ };
+ F556F5B226CD201C00A80B83 /* Release */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ ALWAYS_SEARCH_USER_PATHS = NO;
+ CLANG_ANALYZER_NONNULL = YES;
+ CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
+ CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
+ CLANG_CXX_LIBRARY = "libc++";
+ CLANG_ENABLE_MODULES = YES;
+ CLANG_ENABLE_OBJC_ARC = YES;
+ CLANG_ENABLE_OBJC_WEAK = YES;
+ CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
+ CLANG_WARN_BOOL_CONVERSION = YES;
+ CLANG_WARN_COMMA = YES;
+ CLANG_WARN_CONSTANT_CONVERSION = YES;
+ CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
+ CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
+ CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
+ CLANG_WARN_EMPTY_BODY = YES;
+ CLANG_WARN_ENUM_CONVERSION = YES;
+ CLANG_WARN_INFINITE_RECURSION = YES;
+ CLANG_WARN_INT_CONVERSION = YES;
+ CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
+ CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
+ CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
+ CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
+ CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
+ CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
+ CLANG_WARN_STRICT_PROTOTYPES = YES;
+ CLANG_WARN_SUSPICIOUS_MOVE = YES;
+ CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
+ CLANG_WARN_UNREACHABLE_CODE = YES;
+ CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
+ COPY_PHASE_STRIP = NO;
+ DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
+ ENABLE_NS_ASSERTIONS = NO;
+ ENABLE_STRICT_OBJC_MSGSEND = YES;
+ GCC_C_LANGUAGE_STANDARD = gnu11;
+ GCC_NO_COMMON_BLOCKS = YES;
+ GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
+ GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
+ GCC_WARN_UNDECLARED_SELECTOR = YES;
+ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
+ GCC_WARN_UNUSED_FUNCTION = YES;
+ GCC_WARN_UNUSED_VARIABLE = YES;
+ IPHONEOS_DEPLOYMENT_TARGET = 14.5;
+ MTL_ENABLE_DEBUG_INFO = NO;
+ MTL_FAST_MATH = YES;
+ SDKROOT = iphoneos;
+ SWIFT_COMPILATION_MODE = wholemodule;
+ SWIFT_OPTIMIZATION_LEVEL = "-O";
+ VALIDATE_PRODUCT = YES;
+ };
+ name = Release;
+ };
+ F556F5B426CD201C00A80B83 /* Debug */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
+ ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
+ CODE_SIGN_STYLE = Automatic;
+ INFOPLIST_FILE = "$(SRCROOT)/Sources/Info.plist";
+ IPHONEOS_DEPLOYMENT_TARGET = 9.0;
+ LD_RUNPATH_SEARCH_PATHS = (
+ "$(inherited)",
+ "@executable_path/Frameworks",
+ );
+ PRODUCT_BUNDLE_IDENTIFIER = "com.skeletonview.iOS-Example";
+ PRODUCT_NAME = "$(TARGET_NAME)";
+ SWIFT_VERSION = 5.0;
+ TARGETED_DEVICE_FAMILY = "1,2";
+ };
+ name = Debug;
+ };
+ F556F5B526CD201C00A80B83 /* Release */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
+ ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
+ CODE_SIGN_STYLE = Automatic;
+ INFOPLIST_FILE = "$(SRCROOT)/Sources/Info.plist";
+ IPHONEOS_DEPLOYMENT_TARGET = 9.0;
+ LD_RUNPATH_SEARCH_PATHS = (
+ "$(inherited)",
+ "@executable_path/Frameworks",
+ );
+ PRODUCT_BUNDLE_IDENTIFIER = "com.skeletonview.iOS-Example";
+ PRODUCT_NAME = "$(TARGET_NAME)";
+ SWIFT_VERSION = 5.0;
+ TARGETED_DEVICE_FAMILY = "1,2";
+ };
+ name = Release;
+ };
+/* End XCBuildConfiguration section */
+
+/* Begin XCConfigurationList section */
+ F556F59A26CD201B00A80B83 /* Build configuration list for PBXProject "iOS Example" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ F556F5B126CD201C00A80B83 /* Debug */,
+ F556F5B226CD201C00A80B83 /* Release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
+ F556F5B326CD201C00A80B83 /* Build configuration list for PBXNativeTarget "iOS Example" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ F556F5B426CD201C00A80B83 /* Debug */,
+ F556F5B526CD201C00A80B83 /* Release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
+/* End XCConfigurationList section */
+ };
+ rootObject = F556F59726CD201B00A80B83 /* Project object */;
+}
diff --git a/Examples/iOS Example/iOS Example.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/Examples/iOS Example/iOS Example.xcodeproj/project.xcworkspace/contents.xcworkspacedata
new file mode 100644
index 00000000..919434a6
--- /dev/null
+++ b/Examples/iOS Example/iOS Example.xcodeproj/project.xcworkspace/contents.xcworkspacedata
@@ -0,0 +1,7 @@
+
+
+
+
+
diff --git a/Examples/iOS Example/iOS Example.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/Examples/iOS Example/iOS Example.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist
new file mode 100644
index 00000000..18d98100
--- /dev/null
+++ b/Examples/iOS Example/iOS Example.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist
@@ -0,0 +1,8 @@
+
+
+
+
+ IDEDidComputeMac32BitWarning
+
+
+
diff --git a/Examples/tvOS Example/Sources/AppDelegate.swift b/Examples/tvOS Example/Sources/AppDelegate.swift
new file mode 100644
index 00000000..0d3fa508
--- /dev/null
+++ b/Examples/tvOS Example/Sources/AppDelegate.swift
@@ -0,0 +1,40 @@
+//
+// AppDelegate.swift
+// tvOS Example
+//
+// Created by Juanpe Catalán on 18/8/21.
+//
+
+import UIKit
+
+@main
+class AppDelegate: UIResponder, UIApplicationDelegate {
+
+ var window: UIWindow?
+
+
+ func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
+ // Override point for customization after application launch.
+ return true
+ }
+
+ func applicationWillResignActive(_ application: UIApplication) {
+ // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
+ // Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game.
+ }
+
+ func applicationDidEnterBackground(_ application: UIApplication) {
+ // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.
+ }
+
+ func applicationWillEnterForeground(_ application: UIApplication) {
+ // Called as part of the transition from the background to the active state; here you can undo many of the changes made on entering the background.
+ }
+
+ func applicationDidBecomeActive(_ application: UIApplication) {
+ // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
+ }
+
+
+}
+
diff --git a/Examples/tvOS Example/Sources/Assets.xcassets/AccentColor.colorset/Contents.json b/Examples/tvOS Example/Sources/Assets.xcassets/AccentColor.colorset/Contents.json
new file mode 100644
index 00000000..eb878970
--- /dev/null
+++ b/Examples/tvOS Example/Sources/Assets.xcassets/AccentColor.colorset/Contents.json
@@ -0,0 +1,11 @@
+{
+ "colors" : [
+ {
+ "idiom" : "universal"
+ }
+ ],
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ }
+}
diff --git a/Examples/tvOS Example/Sources/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - App Store.imagestack/Back.imagestacklayer/Content.imageset/Contents.json b/Examples/tvOS Example/Sources/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - App Store.imagestack/Back.imagestacklayer/Content.imageset/Contents.json
new file mode 100644
index 00000000..2e003356
--- /dev/null
+++ b/Examples/tvOS Example/Sources/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - App Store.imagestack/Back.imagestacklayer/Content.imageset/Contents.json
@@ -0,0 +1,11 @@
+{
+ "images" : [
+ {
+ "idiom" : "tv"
+ }
+ ],
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ }
+}
diff --git a/Examples/tvOS Example/Sources/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - App Store.imagestack/Back.imagestacklayer/Contents.json b/Examples/tvOS Example/Sources/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - App Store.imagestack/Back.imagestacklayer/Contents.json
new file mode 100644
index 00000000..73c00596
--- /dev/null
+++ b/Examples/tvOS Example/Sources/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - App Store.imagestack/Back.imagestacklayer/Contents.json
@@ -0,0 +1,6 @@
+{
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ }
+}
diff --git a/Examples/tvOS Example/Sources/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - App Store.imagestack/Contents.json b/Examples/tvOS Example/Sources/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - App Store.imagestack/Contents.json
new file mode 100644
index 00000000..de59d885
--- /dev/null
+++ b/Examples/tvOS Example/Sources/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - App Store.imagestack/Contents.json
@@ -0,0 +1,17 @@
+{
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ },
+ "layers" : [
+ {
+ "filename" : "Front.imagestacklayer"
+ },
+ {
+ "filename" : "Middle.imagestacklayer"
+ },
+ {
+ "filename" : "Back.imagestacklayer"
+ }
+ ]
+}
diff --git a/Examples/tvOS Example/Sources/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - App Store.imagestack/Front.imagestacklayer/Content.imageset/Contents.json b/Examples/tvOS Example/Sources/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - App Store.imagestack/Front.imagestacklayer/Content.imageset/Contents.json
new file mode 100644
index 00000000..2e003356
--- /dev/null
+++ b/Examples/tvOS Example/Sources/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - App Store.imagestack/Front.imagestacklayer/Content.imageset/Contents.json
@@ -0,0 +1,11 @@
+{
+ "images" : [
+ {
+ "idiom" : "tv"
+ }
+ ],
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ }
+}
diff --git a/Examples/tvOS Example/Sources/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - App Store.imagestack/Front.imagestacklayer/Contents.json b/Examples/tvOS Example/Sources/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - App Store.imagestack/Front.imagestacklayer/Contents.json
new file mode 100644
index 00000000..73c00596
--- /dev/null
+++ b/Examples/tvOS Example/Sources/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - App Store.imagestack/Front.imagestacklayer/Contents.json
@@ -0,0 +1,6 @@
+{
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ }
+}
diff --git a/Examples/tvOS Example/Sources/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - App Store.imagestack/Middle.imagestacklayer/Content.imageset/Contents.json b/Examples/tvOS Example/Sources/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - App Store.imagestack/Middle.imagestacklayer/Content.imageset/Contents.json
new file mode 100644
index 00000000..2e003356
--- /dev/null
+++ b/Examples/tvOS Example/Sources/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - App Store.imagestack/Middle.imagestacklayer/Content.imageset/Contents.json
@@ -0,0 +1,11 @@
+{
+ "images" : [
+ {
+ "idiom" : "tv"
+ }
+ ],
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ }
+}
diff --git a/Examples/tvOS Example/Sources/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - App Store.imagestack/Middle.imagestacklayer/Contents.json b/Examples/tvOS Example/Sources/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - App Store.imagestack/Middle.imagestacklayer/Contents.json
new file mode 100644
index 00000000..73c00596
--- /dev/null
+++ b/Examples/tvOS Example/Sources/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - App Store.imagestack/Middle.imagestacklayer/Contents.json
@@ -0,0 +1,6 @@
+{
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ }
+}
diff --git a/Examples/tvOS Example/Sources/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon.imagestack/Back.imagestacklayer/Content.imageset/Contents.json b/Examples/tvOS Example/Sources/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon.imagestack/Back.imagestacklayer/Content.imageset/Contents.json
new file mode 100644
index 00000000..795cce17
--- /dev/null
+++ b/Examples/tvOS Example/Sources/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon.imagestack/Back.imagestacklayer/Content.imageset/Contents.json
@@ -0,0 +1,16 @@
+{
+ "images" : [
+ {
+ "idiom" : "tv",
+ "scale" : "1x"
+ },
+ {
+ "idiom" : "tv",
+ "scale" : "2x"
+ }
+ ],
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ }
+}
diff --git a/Examples/tvOS Example/Sources/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon.imagestack/Back.imagestacklayer/Contents.json b/Examples/tvOS Example/Sources/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon.imagestack/Back.imagestacklayer/Contents.json
new file mode 100644
index 00000000..73c00596
--- /dev/null
+++ b/Examples/tvOS Example/Sources/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon.imagestack/Back.imagestacklayer/Contents.json
@@ -0,0 +1,6 @@
+{
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ }
+}
diff --git a/Examples/tvOS Example/Sources/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon.imagestack/Contents.json b/Examples/tvOS Example/Sources/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon.imagestack/Contents.json
new file mode 100644
index 00000000..de59d885
--- /dev/null
+++ b/Examples/tvOS Example/Sources/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon.imagestack/Contents.json
@@ -0,0 +1,17 @@
+{
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ },
+ "layers" : [
+ {
+ "filename" : "Front.imagestacklayer"
+ },
+ {
+ "filename" : "Middle.imagestacklayer"
+ },
+ {
+ "filename" : "Back.imagestacklayer"
+ }
+ ]
+}
diff --git a/Examples/tvOS Example/Sources/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon.imagestack/Front.imagestacklayer/Content.imageset/Contents.json b/Examples/tvOS Example/Sources/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon.imagestack/Front.imagestacklayer/Content.imageset/Contents.json
new file mode 100644
index 00000000..795cce17
--- /dev/null
+++ b/Examples/tvOS Example/Sources/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon.imagestack/Front.imagestacklayer/Content.imageset/Contents.json
@@ -0,0 +1,16 @@
+{
+ "images" : [
+ {
+ "idiom" : "tv",
+ "scale" : "1x"
+ },
+ {
+ "idiom" : "tv",
+ "scale" : "2x"
+ }
+ ],
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ }
+}
diff --git a/Examples/tvOS Example/Sources/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon.imagestack/Front.imagestacklayer/Contents.json b/Examples/tvOS Example/Sources/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon.imagestack/Front.imagestacklayer/Contents.json
new file mode 100644
index 00000000..73c00596
--- /dev/null
+++ b/Examples/tvOS Example/Sources/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon.imagestack/Front.imagestacklayer/Contents.json
@@ -0,0 +1,6 @@
+{
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ }
+}
diff --git a/Examples/tvOS Example/Sources/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon.imagestack/Middle.imagestacklayer/Content.imageset/Contents.json b/Examples/tvOS Example/Sources/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon.imagestack/Middle.imagestacklayer/Content.imageset/Contents.json
new file mode 100644
index 00000000..795cce17
--- /dev/null
+++ b/Examples/tvOS Example/Sources/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon.imagestack/Middle.imagestacklayer/Content.imageset/Contents.json
@@ -0,0 +1,16 @@
+{
+ "images" : [
+ {
+ "idiom" : "tv",
+ "scale" : "1x"
+ },
+ {
+ "idiom" : "tv",
+ "scale" : "2x"
+ }
+ ],
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ }
+}
diff --git a/Examples/tvOS Example/Sources/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon.imagestack/Middle.imagestacklayer/Contents.json b/Examples/tvOS Example/Sources/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon.imagestack/Middle.imagestacklayer/Contents.json
new file mode 100644
index 00000000..73c00596
--- /dev/null
+++ b/Examples/tvOS Example/Sources/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon.imagestack/Middle.imagestacklayer/Contents.json
@@ -0,0 +1,6 @@
+{
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ }
+}
diff --git a/Examples/tvOS Example/Sources/Assets.xcassets/App Icon & Top Shelf Image.brandassets/Contents.json b/Examples/tvOS Example/Sources/Assets.xcassets/App Icon & Top Shelf Image.brandassets/Contents.json
new file mode 100644
index 00000000..f47ba43d
--- /dev/null
+++ b/Examples/tvOS Example/Sources/Assets.xcassets/App Icon & Top Shelf Image.brandassets/Contents.json
@@ -0,0 +1,32 @@
+{
+ "assets" : [
+ {
+ "filename" : "App Icon - App Store.imagestack",
+ "idiom" : "tv",
+ "role" : "primary-app-icon",
+ "size" : "1280x768"
+ },
+ {
+ "filename" : "App Icon.imagestack",
+ "idiom" : "tv",
+ "role" : "primary-app-icon",
+ "size" : "400x240"
+ },
+ {
+ "filename" : "Top Shelf Image Wide.imageset",
+ "idiom" : "tv",
+ "role" : "top-shelf-image-wide",
+ "size" : "2320x720"
+ },
+ {
+ "filename" : "Top Shelf Image.imageset",
+ "idiom" : "tv",
+ "role" : "top-shelf-image",
+ "size" : "1920x720"
+ }
+ ],
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ }
+}
diff --git a/Examples/tvOS Example/Sources/Assets.xcassets/App Icon & Top Shelf Image.brandassets/Top Shelf Image Wide.imageset/Contents.json b/Examples/tvOS Example/Sources/Assets.xcassets/App Icon & Top Shelf Image.brandassets/Top Shelf Image Wide.imageset/Contents.json
new file mode 100644
index 00000000..b65f0cdd
--- /dev/null
+++ b/Examples/tvOS Example/Sources/Assets.xcassets/App Icon & Top Shelf Image.brandassets/Top Shelf Image Wide.imageset/Contents.json
@@ -0,0 +1,24 @@
+{
+ "images" : [
+ {
+ "idiom" : "tv",
+ "scale" : "1x"
+ },
+ {
+ "idiom" : "tv",
+ "scale" : "2x"
+ },
+ {
+ "idiom" : "tv-marketing",
+ "scale" : "1x"
+ },
+ {
+ "idiom" : "tv-marketing",
+ "scale" : "2x"
+ }
+ ],
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ }
+}
diff --git a/Examples/tvOS Example/Sources/Assets.xcassets/App Icon & Top Shelf Image.brandassets/Top Shelf Image.imageset/Contents.json b/Examples/tvOS Example/Sources/Assets.xcassets/App Icon & Top Shelf Image.brandassets/Top Shelf Image.imageset/Contents.json
new file mode 100644
index 00000000..b65f0cdd
--- /dev/null
+++ b/Examples/tvOS Example/Sources/Assets.xcassets/App Icon & Top Shelf Image.brandassets/Top Shelf Image.imageset/Contents.json
@@ -0,0 +1,24 @@
+{
+ "images" : [
+ {
+ "idiom" : "tv",
+ "scale" : "1x"
+ },
+ {
+ "idiom" : "tv",
+ "scale" : "2x"
+ },
+ {
+ "idiom" : "tv-marketing",
+ "scale" : "1x"
+ },
+ {
+ "idiom" : "tv-marketing",
+ "scale" : "2x"
+ }
+ ],
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ }
+}
diff --git a/Examples/tvOS Example/Sources/Assets.xcassets/Contents.json b/Examples/tvOS Example/Sources/Assets.xcassets/Contents.json
new file mode 100644
index 00000000..73c00596
--- /dev/null
+++ b/Examples/tvOS Example/Sources/Assets.xcassets/Contents.json
@@ -0,0 +1,6 @@
+{
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ }
+}
diff --git a/Examples/tvOS Example/Sources/Base.lproj/LaunchScreen.storyboard b/Examples/tvOS Example/Sources/Base.lproj/LaunchScreen.storyboard
new file mode 100644
index 00000000..660ba53d
--- /dev/null
+++ b/Examples/tvOS Example/Sources/Base.lproj/LaunchScreen.storyboard
@@ -0,0 +1,24 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Examples/tvOS Example/Sources/Base.lproj/Main.storyboard b/Examples/tvOS Example/Sources/Base.lproj/Main.storyboard
new file mode 100644
index 00000000..c277013f
--- /dev/null
+++ b/Examples/tvOS Example/Sources/Base.lproj/Main.storyboard
@@ -0,0 +1,28 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Configs/SkeletonView-tvOS.plist b/Examples/tvOS Example/Sources/Info.plist
similarity index 63%
rename from Configs/SkeletonView-tvOS.plist
rename to Examples/tvOS Example/Sources/Info.plist
index 1007fd9d..25869efc 100644
--- a/Configs/SkeletonView-tvOS.plist
+++ b/Examples/tvOS Example/Sources/Info.plist
@@ -13,12 +13,22 @@
CFBundleName
$(PRODUCT_NAME)
CFBundlePackageType
- FMWK
+ $(PRODUCT_BUNDLE_PACKAGE_TYPE)
CFBundleShortVersionString
1.0
CFBundleVersion
- $(CURRENT_PROJECT_VERSION)
- NSPrincipalClass
-
+ 1
+ LSRequiresIPhoneOS
+
+ UILaunchStoryboardName
+ LaunchScreen
+ UIMainStoryboardFile
+ Main
+ UIRequiredDeviceCapabilities
+
+ arm64
+
+ UIUserInterfaceStyle
+ Automatic
diff --git a/Examples/tvOS Example/Sources/ViewController.swift b/Examples/tvOS Example/Sources/ViewController.swift
new file mode 100644
index 00000000..841a8a38
--- /dev/null
+++ b/Examples/tvOS Example/Sources/ViewController.swift
@@ -0,0 +1,19 @@
+//
+// ViewController.swift
+// tvOS Example
+//
+// Created by Juanpe Catalán on 18/8/21.
+//
+
+import UIKit
+
+class ViewController: UIViewController {
+
+ override func viewDidLoad() {
+ super.viewDidLoad()
+ // Do any additional setup after loading the view.
+ }
+
+
+}
+
diff --git a/Examples/tvOS Example/tvOS Example.xcodeproj/project.pbxproj b/Examples/tvOS Example/tvOS Example.xcodeproj/project.pbxproj
new file mode 100644
index 00000000..b6fde7fe
--- /dev/null
+++ b/Examples/tvOS Example/tvOS Example.xcodeproj/project.pbxproj
@@ -0,0 +1,441 @@
+// !$*UTF8*$!
+{
+ archiveVersion = 1;
+ classes = {
+ };
+ objectVersion = 50;
+ objects = {
+
+/* Begin PBXBuildFile section */
+ F556F61226CD224900A80B83 /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = F556F60A26CD224900A80B83 /* ViewController.swift */; };
+ F556F61326CD224900A80B83 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = F556F60B26CD224900A80B83 /* Assets.xcassets */; };
+ F556F61426CD224900A80B83 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = F556F60C26CD224900A80B83 /* LaunchScreen.storyboard */; };
+ F556F61526CD224900A80B83 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = F556F60E26CD224900A80B83 /* Main.storyboard */; };
+ F556F61626CD224900A80B83 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = F556F61026CD224900A80B83 /* AppDelegate.swift */; };
+ F556F62526CD225C00A80B83 /* SkeletonView.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F556F62326CD224F00A80B83 /* SkeletonView.framework */; };
+/* End PBXBuildFile section */
+
+/* Begin PBXContainerItemProxy section */
+ F556F61E26CD224F00A80B83 /* PBXContainerItemProxy */ = {
+ isa = PBXContainerItemProxy;
+ containerPortal = F556F61826CD224F00A80B83 /* SkeletonView.xcodeproj */;
+ proxyType = 2;
+ remoteGlobalIDString = "SkeletonView::SkeletonView::Product";
+ remoteInfo = "SkeletonView iOS";
+ };
+ F556F62026CD224F00A80B83 /* PBXContainerItemProxy */ = {
+ isa = PBXContainerItemProxy;
+ containerPortal = F556F61826CD224F00A80B83 /* SkeletonView.xcodeproj */;
+ proxyType = 2;
+ remoteGlobalIDString = "SkeletonView::SkeletonViewTests::Product";
+ remoteInfo = SkeletonViewTests;
+ };
+ F556F62226CD224F00A80B83 /* PBXContainerItemProxy */ = {
+ isa = PBXContainerItemProxy;
+ containerPortal = F556F61826CD224F00A80B83 /* SkeletonView.xcodeproj */;
+ proxyType = 2;
+ remoteGlobalIDString = F556F59426CD1F3900A80B83;
+ remoteInfo = "SkeletonView tvOS";
+ };
+ F556F62826CD226600A80B83 /* PBXContainerItemProxy */ = {
+ isa = PBXContainerItemProxy;
+ containerPortal = F556F61826CD224F00A80B83 /* SkeletonView.xcodeproj */;
+ proxyType = 1;
+ remoteGlobalIDString = F556F56426CD1F3900A80B83;
+ remoteInfo = "SkeletonView tvOS";
+ };
+ F556F6FE26CE88DC00A80B83 /* PBXContainerItemProxy */ = {
+ isa = PBXContainerItemProxy;
+ containerPortal = F556F61826CD224F00A80B83 /* SkeletonView.xcodeproj */;
+ proxyType = 2;
+ remoteGlobalIDString = F556F67126CD458500A80B83;
+ remoteInfo = "SkeletonView tvOS Tests";
+ };
+/* End PBXContainerItemProxy section */
+
+/* Begin PBXFileReference section */
+ F556F5F426CD221300A80B83 /* tvOS Example.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "tvOS Example.app"; sourceTree = BUILT_PRODUCTS_DIR; };
+ F556F60A26CD224900A80B83 /* ViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ViewController.swift; sourceTree = ""; };
+ F556F60B26CD224900A80B83 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; };
+ F556F60D26CD224900A80B83 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; };
+ F556F60F26CD224900A80B83 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; };
+ F556F61026CD224900A80B83 /* AppDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; };
+ F556F61126CD224900A80B83 /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; };
+ F556F61826CD224F00A80B83 /* SkeletonView.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = SkeletonView.xcodeproj; path = ../../SkeletonView.xcodeproj; sourceTree = ""; };
+/* End PBXFileReference section */
+
+/* Begin PBXFrameworksBuildPhase section */
+ F556F5F126CD221300A80B83 /* Frameworks */ = {
+ isa = PBXFrameworksBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ F556F62526CD225C00A80B83 /* SkeletonView.framework in Frameworks */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+/* End PBXFrameworksBuildPhase section */
+
+/* Begin PBXGroup section */
+ F556F5EB26CD221300A80B83 = {
+ isa = PBXGroup;
+ children = (
+ F556F60926CD224900A80B83 /* Sources */,
+ F556F5F526CD221300A80B83 /* Products */,
+ F556F61826CD224F00A80B83 /* SkeletonView.xcodeproj */,
+ );
+ sourceTree = "";
+ };
+ F556F5F526CD221300A80B83 /* Products */ = {
+ isa = PBXGroup;
+ children = (
+ F556F5F426CD221300A80B83 /* tvOS Example.app */,
+ );
+ name = Products;
+ sourceTree = "";
+ };
+ F556F60926CD224900A80B83 /* Sources */ = {
+ isa = PBXGroup;
+ children = (
+ F556F60A26CD224900A80B83 /* ViewController.swift */,
+ F556F60B26CD224900A80B83 /* Assets.xcassets */,
+ F556F60C26CD224900A80B83 /* LaunchScreen.storyboard */,
+ F556F60E26CD224900A80B83 /* Main.storyboard */,
+ F556F61026CD224900A80B83 /* AppDelegate.swift */,
+ F556F61126CD224900A80B83 /* Info.plist */,
+ );
+ path = Sources;
+ sourceTree = "";
+ };
+ F556F61926CD224F00A80B83 /* Products */ = {
+ isa = PBXGroup;
+ children = (
+ F556F61F26CD224F00A80B83 /* SkeletonView.framework */,
+ F556F62126CD224F00A80B83 /* SkeletonViewTests.xctest */,
+ F556F62326CD224F00A80B83 /* SkeletonView.framework */,
+ F556F6FF26CE88DC00A80B83 /* SkeletonView tvOS Tests.xctest */,
+ );
+ name = Products;
+ sourceTree = "";
+ };
+/* End PBXGroup section */
+
+/* Begin PBXNativeTarget section */
+ F556F5F326CD221300A80B83 /* tvOS Example */ = {
+ isa = PBXNativeTarget;
+ buildConfigurationList = F556F60626CD221400A80B83 /* Build configuration list for PBXNativeTarget "tvOS Example" */;
+ buildPhases = (
+ F556F5F026CD221300A80B83 /* Sources */,
+ F556F5F126CD221300A80B83 /* Frameworks */,
+ F556F5F226CD221300A80B83 /* Resources */,
+ );
+ buildRules = (
+ );
+ dependencies = (
+ F556F62926CD226600A80B83 /* PBXTargetDependency */,
+ );
+ name = "tvOS Example";
+ productName = "tvOS Example";
+ productReference = F556F5F426CD221300A80B83 /* tvOS Example.app */;
+ productType = "com.apple.product-type.application";
+ };
+/* End PBXNativeTarget section */
+
+/* Begin PBXProject section */
+ F556F5EC26CD221300A80B83 /* Project object */ = {
+ isa = PBXProject;
+ attributes = {
+ LastSwiftUpdateCheck = 1250;
+ LastUpgradeCheck = 1250;
+ TargetAttributes = {
+ F556F5F326CD221300A80B83 = {
+ CreatedOnToolsVersion = 12.5.1;
+ };
+ };
+ };
+ buildConfigurationList = F556F5EF26CD221300A80B83 /* Build configuration list for PBXProject "tvOS Example" */;
+ compatibilityVersion = "Xcode 9.3";
+ developmentRegion = en;
+ hasScannedForEncodings = 0;
+ knownRegions = (
+ en,
+ Base,
+ );
+ mainGroup = F556F5EB26CD221300A80B83;
+ productRefGroup = F556F5F526CD221300A80B83 /* Products */;
+ projectDirPath = "";
+ projectReferences = (
+ {
+ ProductGroup = F556F61926CD224F00A80B83 /* Products */;
+ ProjectRef = F556F61826CD224F00A80B83 /* SkeletonView.xcodeproj */;
+ },
+ );
+ projectRoot = "";
+ targets = (
+ F556F5F326CD221300A80B83 /* tvOS Example */,
+ );
+ };
+/* End PBXProject section */
+
+/* Begin PBXReferenceProxy section */
+ F556F61F26CD224F00A80B83 /* SkeletonView.framework */ = {
+ isa = PBXReferenceProxy;
+ fileType = wrapper.framework;
+ path = SkeletonView.framework;
+ remoteRef = F556F61E26CD224F00A80B83 /* PBXContainerItemProxy */;
+ sourceTree = BUILT_PRODUCTS_DIR;
+ };
+ F556F62126CD224F00A80B83 /* SkeletonViewTests.xctest */ = {
+ isa = PBXReferenceProxy;
+ fileType = wrapper.cfbundle;
+ path = SkeletonViewTests.xctest;
+ remoteRef = F556F62026CD224F00A80B83 /* PBXContainerItemProxy */;
+ sourceTree = BUILT_PRODUCTS_DIR;
+ };
+ F556F62326CD224F00A80B83 /* SkeletonView.framework */ = {
+ isa = PBXReferenceProxy;
+ fileType = wrapper.framework;
+ path = SkeletonView.framework;
+ remoteRef = F556F62226CD224F00A80B83 /* PBXContainerItemProxy */;
+ sourceTree = BUILT_PRODUCTS_DIR;
+ };
+ F556F6FF26CE88DC00A80B83 /* SkeletonView tvOS Tests.xctest */ = {
+ isa = PBXReferenceProxy;
+ fileType = wrapper.cfbundle;
+ path = "SkeletonView tvOS Tests.xctest";
+ remoteRef = F556F6FE26CE88DC00A80B83 /* PBXContainerItemProxy */;
+ sourceTree = BUILT_PRODUCTS_DIR;
+ };
+/* End PBXReferenceProxy section */
+
+/* Begin PBXResourcesBuildPhase section */
+ F556F5F226CD221300A80B83 /* Resources */ = {
+ isa = PBXResourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ F556F61526CD224900A80B83 /* Main.storyboard in Resources */,
+ F556F61326CD224900A80B83 /* Assets.xcassets in Resources */,
+ F556F61426CD224900A80B83 /* LaunchScreen.storyboard in Resources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+/* End PBXResourcesBuildPhase section */
+
+/* Begin PBXSourcesBuildPhase section */
+ F556F5F026CD221300A80B83 /* Sources */ = {
+ isa = PBXSourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ F556F61626CD224900A80B83 /* AppDelegate.swift in Sources */,
+ F556F61226CD224900A80B83 /* ViewController.swift in Sources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+/* End PBXSourcesBuildPhase section */
+
+/* Begin PBXTargetDependency section */
+ F556F62926CD226600A80B83 /* PBXTargetDependency */ = {
+ isa = PBXTargetDependency;
+ name = "SkeletonView tvOS";
+ targetProxy = F556F62826CD226600A80B83 /* PBXContainerItemProxy */;
+ };
+/* End PBXTargetDependency section */
+
+/* Begin PBXVariantGroup section */
+ F556F60C26CD224900A80B83 /* LaunchScreen.storyboard */ = {
+ isa = PBXVariantGroup;
+ children = (
+ F556F60D26CD224900A80B83 /* Base */,
+ );
+ name = LaunchScreen.storyboard;
+ sourceTree = "";
+ };
+ F556F60E26CD224900A80B83 /* Main.storyboard */ = {
+ isa = PBXVariantGroup;
+ children = (
+ F556F60F26CD224900A80B83 /* Base */,
+ );
+ name = Main.storyboard;
+ sourceTree = "";
+ };
+/* End PBXVariantGroup section */
+
+/* Begin XCBuildConfiguration section */
+ F556F60426CD221400A80B83 /* Debug */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ ALWAYS_SEARCH_USER_PATHS = NO;
+ CLANG_ANALYZER_NONNULL = YES;
+ CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
+ CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
+ CLANG_CXX_LIBRARY = "libc++";
+ CLANG_ENABLE_MODULES = YES;
+ CLANG_ENABLE_OBJC_ARC = YES;
+ CLANG_ENABLE_OBJC_WEAK = YES;
+ CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
+ CLANG_WARN_BOOL_CONVERSION = YES;
+ CLANG_WARN_COMMA = YES;
+ CLANG_WARN_CONSTANT_CONVERSION = YES;
+ CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
+ CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
+ CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
+ CLANG_WARN_EMPTY_BODY = YES;
+ CLANG_WARN_ENUM_CONVERSION = YES;
+ CLANG_WARN_INFINITE_RECURSION = YES;
+ CLANG_WARN_INT_CONVERSION = YES;
+ CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
+ CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
+ CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
+ CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
+ CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
+ CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
+ CLANG_WARN_STRICT_PROTOTYPES = YES;
+ CLANG_WARN_SUSPICIOUS_MOVE = YES;
+ CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
+ CLANG_WARN_UNREACHABLE_CODE = YES;
+ CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
+ COPY_PHASE_STRIP = NO;
+ DEBUG_INFORMATION_FORMAT = dwarf;
+ ENABLE_STRICT_OBJC_MSGSEND = YES;
+ ENABLE_TESTABILITY = YES;
+ GCC_C_LANGUAGE_STANDARD = gnu11;
+ GCC_DYNAMIC_NO_PIC = NO;
+ GCC_NO_COMMON_BLOCKS = YES;
+ GCC_OPTIMIZATION_LEVEL = 0;
+ GCC_PREPROCESSOR_DEFINITIONS = (
+ "DEBUG=1",
+ "$(inherited)",
+ );
+ GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
+ GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
+ GCC_WARN_UNDECLARED_SELECTOR = YES;
+ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
+ GCC_WARN_UNUSED_FUNCTION = YES;
+ GCC_WARN_UNUSED_VARIABLE = YES;
+ MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
+ MTL_FAST_MATH = YES;
+ ONLY_ACTIVE_ARCH = YES;
+ SDKROOT = appletvos;
+ SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG;
+ SWIFT_OPTIMIZATION_LEVEL = "-Onone";
+ TVOS_DEPLOYMENT_TARGET = 9.0;
+ };
+ name = Debug;
+ };
+ F556F60526CD221400A80B83 /* Release */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ ALWAYS_SEARCH_USER_PATHS = NO;
+ CLANG_ANALYZER_NONNULL = YES;
+ CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
+ CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
+ CLANG_CXX_LIBRARY = "libc++";
+ CLANG_ENABLE_MODULES = YES;
+ CLANG_ENABLE_OBJC_ARC = YES;
+ CLANG_ENABLE_OBJC_WEAK = YES;
+ CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
+ CLANG_WARN_BOOL_CONVERSION = YES;
+ CLANG_WARN_COMMA = YES;
+ CLANG_WARN_CONSTANT_CONVERSION = YES;
+ CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
+ CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
+ CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
+ CLANG_WARN_EMPTY_BODY = YES;
+ CLANG_WARN_ENUM_CONVERSION = YES;
+ CLANG_WARN_INFINITE_RECURSION = YES;
+ CLANG_WARN_INT_CONVERSION = YES;
+ CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
+ CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
+ CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
+ CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
+ CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
+ CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
+ CLANG_WARN_STRICT_PROTOTYPES = YES;
+ CLANG_WARN_SUSPICIOUS_MOVE = YES;
+ CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
+ CLANG_WARN_UNREACHABLE_CODE = YES;
+ CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
+ COPY_PHASE_STRIP = NO;
+ DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
+ ENABLE_NS_ASSERTIONS = NO;
+ ENABLE_STRICT_OBJC_MSGSEND = YES;
+ GCC_C_LANGUAGE_STANDARD = gnu11;
+ GCC_NO_COMMON_BLOCKS = YES;
+ GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
+ GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
+ GCC_WARN_UNDECLARED_SELECTOR = YES;
+ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
+ GCC_WARN_UNUSED_FUNCTION = YES;
+ GCC_WARN_UNUSED_VARIABLE = YES;
+ MTL_ENABLE_DEBUG_INFO = NO;
+ MTL_FAST_MATH = YES;
+ SDKROOT = appletvos;
+ SWIFT_COMPILATION_MODE = wholemodule;
+ SWIFT_OPTIMIZATION_LEVEL = "-O";
+ TVOS_DEPLOYMENT_TARGET = 9.0;
+ VALIDATE_PRODUCT = YES;
+ };
+ name = Release;
+ };
+ F556F60726CD221400A80B83 /* Debug */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ ASSETCATALOG_COMPILER_APPICON_NAME = "App Icon & Top Shelf Image";
+ ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
+ CODE_SIGN_STYLE = Automatic;
+ INFOPLIST_FILE = Sources/Info.plist;
+ LD_RUNPATH_SEARCH_PATHS = (
+ "$(inherited)",
+ "@executable_path/Frameworks",
+ );
+ PRODUCT_BUNDLE_IDENTIFIER = "com.skeletonview.tvOS-Example";
+ PRODUCT_NAME = "$(TARGET_NAME)";
+ SWIFT_VERSION = 5.0;
+ TARGETED_DEVICE_FAMILY = 3;
+ TVOS_DEPLOYMENT_TARGET = 9.0;
+ };
+ name = Debug;
+ };
+ F556F60826CD221400A80B83 /* Release */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ ASSETCATALOG_COMPILER_APPICON_NAME = "App Icon & Top Shelf Image";
+ ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
+ CODE_SIGN_STYLE = Automatic;
+ INFOPLIST_FILE = Sources/Info.plist;
+ LD_RUNPATH_SEARCH_PATHS = (
+ "$(inherited)",
+ "@executable_path/Frameworks",
+ );
+ PRODUCT_BUNDLE_IDENTIFIER = "com.skeletonview.tvOS-Example";
+ PRODUCT_NAME = "$(TARGET_NAME)";
+ SWIFT_VERSION = 5.0;
+ TARGETED_DEVICE_FAMILY = 3;
+ TVOS_DEPLOYMENT_TARGET = 9.0;
+ };
+ name = Release;
+ };
+/* End XCBuildConfiguration section */
+
+/* Begin XCConfigurationList section */
+ F556F5EF26CD221300A80B83 /* Build configuration list for PBXProject "tvOS Example" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ F556F60426CD221400A80B83 /* Debug */,
+ F556F60526CD221400A80B83 /* Release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
+ F556F60626CD221400A80B83 /* Build configuration list for PBXNativeTarget "tvOS Example" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ F556F60726CD221400A80B83 /* Debug */,
+ F556F60826CD221400A80B83 /* Release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
+/* End XCConfigurationList section */
+ };
+ rootObject = F556F5EC26CD221300A80B83 /* Project object */;
+}
diff --git a/Examples/tvOS Example/tvOS Example.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/Examples/tvOS Example/tvOS Example.xcodeproj/project.xcworkspace/contents.xcworkspacedata
new file mode 100644
index 00000000..919434a6
--- /dev/null
+++ b/Examples/tvOS Example/tvOS Example.xcodeproj/project.xcworkspace/contents.xcworkspacedata
@@ -0,0 +1,7 @@
+
+
+
+
+
diff --git a/Examples/tvOS Example/tvOS Example.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/Examples/tvOS Example/tvOS Example.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist
new file mode 100644
index 00000000..18d98100
--- /dev/null
+++ b/Examples/tvOS Example/tvOS Example.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist
@@ -0,0 +1,8 @@
+
+
+
+
+ IDEDidComputeMac32BitWarning
+
+
+
diff --git a/Package.swift b/Package.swift
index 4aafdbd6..cbe059a3 100644
--- a/Package.swift
+++ b/Package.swift
@@ -4,20 +4,26 @@ import PackageDescription
let package = Package(
name: "SkeletonView",
- platforms: [
- .iOS(.v9),
- .tvOS(.v9)
- ],
+ platforms: [
+ .iOS(.v9),
+ .tvOS(.v9)
+ ],
products: [
.library(
name: "SkeletonView",
- targets: ["SkeletonView"])
- ],
- targets: [
- .target(
- name: "SkeletonView",
- dependencies: [],
- path: "Sources")
- ],
- swiftLanguageVersions: [.v5]
+ targets: ["SkeletonView"]
+ )
+ ],
+ targets: [
+ .target(
+ name: "SkeletonView",
+ path: "SkeletonViewCore/Sources"
+ ),
+ .testTarget(
+ name: "SkeletonViewTests",
+ dependencies: ["SkeletonView"],
+ path: "SkeletonViewCore/Tests"
+ )
+ ],
+ swiftLanguageVersions: [.v5]
)
diff --git a/README.md b/README.md
index be997804..7d6f275e 100755
--- a/README.md
+++ b/README.md
@@ -21,7 +21,7 @@
• Contributing
-**🌎 README is available in other languages: [🇪🇸](https://github.com/Juanpe/SkeletonView/blob/main/README_es.md) . [🇨🇳](https://github.com/Juanpe/SkeletonView/blob/master/README_zh.md) . [🇧🇷](https://github.com/Juanpe/SkeletonView/blob/master/README_pt-br.md) . [🇰🇷](https://github.com/Juanpe/SkeletonView/blob/master/README_ko.md) . [🇫🇷](https://github.com/Juanpe/SkeletonView/blob/master/README_fr.md)**
+**🌎 README is available in other languages: [🇪🇸](Translations/README_es.md) . [🇨🇳](Translations/README_zh.md) . [🇧🇷](Translations/README_pt-br.md) . [🇰🇷](Translations/README_ko.md) . [🇫🇷](Translations/README_fr.md)**
Today almost all apps have async processes, such as API requests, long running processes, etc. While the processes are working, usually developers place a loading view to show users that something is going on.
diff --git a/SkeletonVIew.xcworkspace/contents.xcworkspacedata b/SkeletonVIew.xcworkspace/contents.xcworkspacedata
new file mode 100644
index 00000000..ef729c26
--- /dev/null
+++ b/SkeletonVIew.xcworkspace/contents.xcworkspacedata
@@ -0,0 +1,13 @@
+
+
+
+
+
+
+
+
+
diff --git a/SkeletonVIew.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/SkeletonVIew.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist
new file mode 100644
index 00000000..18d98100
--- /dev/null
+++ b/SkeletonVIew.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist
@@ -0,0 +1,8 @@
+
+
+
+
+ IDEDidComputeMac32BitWarning
+
+
+
diff --git a/SkeletonView.podspec b/SkeletonView.podspec
index 99ebefb6..f4fae540 100644
--- a/SkeletonView.podspec
+++ b/SkeletonView.podspec
@@ -14,5 +14,5 @@ Pod::Spec.new do |s|
s.tvos.deployment_target = "9.0"
s.swift_version = "5.0"
s.source = { :git => "https://github.com/Juanpe/SkeletonView.git", :tag => s.version.to_s }
- s.source_files = "Sources/**/*"
+ s.source_files = "SkeletonViewCore/Sources/**/*.{swift,h}"
end
diff --git a/SkeletonView.xcodeproj/project.pbxproj b/SkeletonView.xcodeproj/project.pbxproj
index 40ebda76..3ab80ac1 100644
--- a/SkeletonView.xcodeproj/project.pbxproj
+++ b/SkeletonView.xcodeproj/project.pbxproj
@@ -3,691 +3,725 @@
archiveVersion = 1;
classes = {
};
- objectVersion = 47;
+ objectVersion = 52;
objects = {
/* Begin PBXBuildFile section */
- 17DD0E08207FB28900C56334 /* CollectionSkeletonProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = F5F899EC1FAB9F04002E8FDA /* CollectionSkeletonProtocol.swift */; };
- 17DD0E09207FB28900C56334 /* SkeletonCollectionDataSource.swift in Sources */ = {isa = PBXBuildFile; fileRef = F5F899EA1FAB9DA3002E8FDA /* SkeletonCollectionDataSource.swift */; };
- 17DD0E0A207FB28900C56334 /* SkeletonCollectionViewProtocols.swift in Sources */ = {isa = PBXBuildFile; fileRef = F5307E381FB1078E00EE67C5 /* SkeletonCollectionViewProtocols.swift */; };
- 17DD0E0B207FB28900C56334 /* SkeletonTableViewProtocols.swift in Sources */ = {isa = PBXBuildFile; fileRef = F5307E361FB1076E00EE67C5 /* SkeletonTableViewProtocols.swift */; };
- 17DD0E0C207FB28900C56334 /* UICollectionView+CollectionSkeleton.swift in Sources */ = {isa = PBXBuildFile; fileRef = F54CF5E32024CEB000330B0D /* UICollectionView+CollectionSkeleton.swift */; };
- 17DD0E0D207FB28900C56334 /* UITableView+CollectionSkeleton.swift in Sources */ = {isa = PBXBuildFile; fileRef = F54CF5E22024CEAF00330B0D /* UITableView+CollectionSkeleton.swift */; };
- 17DD0E0E207FB28900C56334 /* UIView+CollectionSkeleton.swift in Sources */ = {isa = PBXBuildFile; fileRef = F54CF5E12024CEAF00330B0D /* UIView+CollectionSkeleton.swift */; };
- 17DD0E0F207FB28C00C56334 /* CALayer+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = F5F622421FAC81FD007C062A /* CALayer+Extensions.swift */; };
- 17DD0E10207FB28C00C56334 /* UIColor+Skeleton.swift in Sources */ = {isa = PBXBuildFile; fileRef = F5F622401FAC6E31007C062A /* UIColor+Skeleton.swift */; };
- 17DD0E11207FB28C00C56334 /* UIView+Frame.swift in Sources */ = {isa = PBXBuildFile; fileRef = F5307E2D1FB0E5E400EE67C5 /* UIView+Frame.swift */; };
- 17DD0E13207FB28C00C56334 /* UIView+UIApplicationDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = F587FB85202CEC95002DB5FE /* UIView+UIApplicationDelegate.swift */; };
- 17DD0E14207FB28F00C56334 /* SkeletonAnimationBuilder.swift in Sources */ = {isa = PBXBuildFile; fileRef = F51DE1081FBF70A70037919A /* SkeletonAnimationBuilder.swift */; };
- 17DD0E15207FB28F00C56334 /* SkeletonAppearance.swift in Sources */ = {isa = PBXBuildFile; fileRef = F5307E2F1FB0EC9D00EE67C5 /* SkeletonAppearance.swift */; };
- 17DD0E16207FB28F00C56334 /* SkeletonGradient.swift in Sources */ = {isa = PBXBuildFile; fileRef = F5307E2B1FAF6BC900EE67C5 /* SkeletonGradient.swift */; };
- 17DD0E17207FB28F00C56334 /* SkeletonLayer.swift in Sources */ = {isa = PBXBuildFile; fileRef = F5F899E81FAB9D2B002E8FDA /* SkeletonLayer.swift */; };
- 17DD0E18207FB28F00C56334 /* SkeletonView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8933C7841EB5B820000D00A4 /* SkeletonView.swift */; };
- 17DD0E19207FB28F00C56334 /* SkeletonFlow.swift in Sources */ = {isa = PBXBuildFile; fileRef = F587FB83202CBFC8002DB5FE /* SkeletonFlow.swift */; };
- 17DD0E1C207FB32100C56334 /* AssociationPolicy.swift in Sources */ = {isa = PBXBuildFile; fileRef = F5F899D11FAB9630002E8FDA /* AssociationPolicy.swift */; };
- 17DD0E1D207FB32100C56334 /* ContainsMultilineText.swift in Sources */ = {isa = PBXBuildFile; fileRef = F5307E3A1FB123C100EE67C5 /* ContainsMultilineText.swift */; };
- 17DD0E1E207FB32100C56334 /* PrepareForSkeletonProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = F56B94451FAE20AF0095662F /* PrepareForSkeletonProtocol.swift */; };
- 17DD0E1F207FB32100C56334 /* RecursiveProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = F5307E311FB0F42F00EE67C5 /* RecursiveProtocol.swift */; };
- 1E291F3E2540655D0018D602 /* UIView+Autolayout.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1E291F3D2540655D0018D602 /* UIView+Autolayout.swift */; };
- 1E291F3F2540655D0018D602 /* UIView+Autolayout.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1E291F3D2540655D0018D602 /* UIView+Autolayout.swift */; };
- 1E6C67A2230E76CC0019D87B /* SkeletonTransitionStyle.swift in Sources */ = {isa = PBXBuildFile; fileRef = E4CE587C22EEE65200333067 /* SkeletonTransitionStyle.swift */; };
- 1E6C67A3230E76CE0019D87B /* UIView+Transitions.swift in Sources */ = {isa = PBXBuildFile; fileRef = E4CE587B22EEE63100333067 /* UIView+Transitions.swift */; };
- 1EE42E1F23FF25CC00BF665A /* ProcessInfo+XCTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1EE42E1E23FF25CC00BF665A /* ProcessInfo+XCTest.swift */; };
- 1EE42E2023FF25CC00BF665A /* ProcessInfo+XCTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1EE42E1E23FF25CC00BF665A /* ProcessInfo+XCTest.swift */; };
- 3467F55F2473601F0086C027 /* UITextView+Multiline.swift in Headers */ = {isa = PBXBuildFile; fileRef = 872D5A5E21C24F8E0037D763 /* UITextView+Multiline.swift */; settings = {ATTRIBUTES = (Public, ); }; };
- 3467F560247360270086C027 /* UIView+IBInspectable.swift in Headers */ = {isa = PBXBuildFile; fileRef = F5804771230ECD0000066D02 /* UIView+IBInspectable.swift */; settings = {ATTRIBUTES = (Public, ); }; };
- 3467F5612473602D0086C027 /* UILabel+Multiline.swift in Headers */ = {isa = PBXBuildFile; fileRef = 872D5A5B21C24EDD0037D763 /* UILabel+Multiline.swift */; settings = {ATTRIBUTES = (Public, ); }; };
- 42ABD063210B548200BEEFF4 /* SkeletonView.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 52D6D97C1BEFF229002C0205 /* SkeletonView.framework */; };
- 42ABD069210B548200BEEFF4 /* SkeletonView.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 52D6D97C1BEFF229002C0205 /* SkeletonView.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
- 42ABD078210B54E200BEEFF4 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 42ABD070210B54E100BEEFF4 /* AppDelegate.swift */; };
- 42ABD079210B54E200BEEFF4 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 42ABD071210B54E100BEEFF4 /* Main.storyboard */; };
- 42ABD07A210B54E200BEEFF4 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 42ABD072210B54E100BEEFF4 /* Assets.xcassets */; };
- 42ABD07B210B54E200BEEFF4 /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 42ABD073210B54E100BEEFF4 /* ViewController.swift */; };
- 42ABD07C210B54E200BEEFF4 /* Base.lproj in Resources */ = {isa = PBXBuildFile; fileRef = 42ABD074210B54E100BEEFF4 /* Base.lproj */; };
- 42ABD07F210B54E200BEEFF4 /* CollectionViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 42ABD077210B54E200BEEFF4 /* CollectionViewCell.swift */; };
- 5600784423FD293D00669AD6 /* UITableView+VisibleSections.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5600784323FD293D00669AD6 /* UITableView+VisibleSections.swift */; };
- 5600784523FD293D00669AD6 /* UITableView+VisibleSections.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5600784323FD293D00669AD6 /* UITableView+VisibleSections.swift */; };
- 5600784923FD33AD00669AD6 /* HeaderFooterSection.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5600784623FD2BC300669AD6 /* HeaderFooterSection.swift */; };
- 5600784A23FD33AE00669AD6 /* HeaderFooterSection.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5600784623FD2BC300669AD6 /* HeaderFooterSection.swift */; };
- 870F4E4321CAC07300B9233B /* SkeletonConfig.swift in Sources */ = {isa = PBXBuildFile; fileRef = 870F4E4221CAC07300B9233B /* SkeletonConfig.swift */; };
- 870F4E4421CAC07300B9233B /* SkeletonConfig.swift in Sources */ = {isa = PBXBuildFile; fileRef = 870F4E4221CAC07300B9233B /* SkeletonConfig.swift */; };
- 872D5A5621C177E20037D763 /* UIView+Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 872D5A5521C177E20037D763 /* UIView+Extension.swift */; };
- 872D5A5721C177E20037D763 /* UIView+Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 872D5A5521C177E20037D763 /* UIView+Extension.swift */; };
- 872D5A5C21C24EDD0037D763 /* UILabel+Multiline.swift in Sources */ = {isa = PBXBuildFile; fileRef = 872D5A5B21C24EDD0037D763 /* UILabel+Multiline.swift */; };
- 872D5A5D21C24EDD0037D763 /* UILabel+Multiline.swift in Sources */ = {isa = PBXBuildFile; fileRef = 872D5A5B21C24EDD0037D763 /* UILabel+Multiline.swift */; };
- 872D5A5F21C24F8E0037D763 /* UITextView+Multiline.swift in Sources */ = {isa = PBXBuildFile; fileRef = 872D5A5E21C24F8E0037D763 /* UITextView+Multiline.swift */; };
- 872D5A6021C24F8E0037D763 /* UITextView+Multiline.swift in Sources */ = {isa = PBXBuildFile; fileRef = 872D5A5E21C24F8E0037D763 /* UITextView+Multiline.swift */; };
- 8748240E20C6A88E00E92179 /* ContainsMultilineText.swift in Headers */ = {isa = PBXBuildFile; fileRef = F5307E3A1FB123C100EE67C5 /* ContainsMultilineText.swift */; settings = {ATTRIBUTES = (Public, ); }; };
- 877EFA4521BEE9D80031FC00 /* SkeletonLayerBuilder.swift in Sources */ = {isa = PBXBuildFile; fileRef = 877EFA4421BEE9D80031FC00 /* SkeletonLayerBuilder.swift */; };
- 877EFA4621BEE9D80031FC00 /* SkeletonLayerBuilder.swift in Sources */ = {isa = PBXBuildFile; fileRef = 877EFA4421BEE9D80031FC00 /* SkeletonLayerBuilder.swift */; };
- 877EFA4821BEED760031FC00 /* SkeletonMultilineLayerBuilder.swift in Sources */ = {isa = PBXBuildFile; fileRef = 877EFA4721BEED760031FC00 /* SkeletonMultilineLayerBuilder.swift */; };
- 877EFA4921BEED760031FC00 /* SkeletonMultilineLayerBuilder.swift in Sources */ = {isa = PBXBuildFile; fileRef = 877EFA4721BEED760031FC00 /* SkeletonMultilineLayerBuilder.swift */; };
- 8785E3A1211C9C9800CC9DFD /* SkeletonDebug.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8785E3A0211C9C9800CC9DFD /* SkeletonDebug.swift */; };
- 8785E3A2211C9CA500CC9DFD /* SkeletonDebug.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8785E3A0211C9C9800CC9DFD /* SkeletonDebug.swift */; };
- 8785E3A3211C9CE800CC9DFD /* Constants.swift in Sources */ = {isa = PBXBuildFile; fileRef = 88DEA97D1FCDBD1F006C80EF /* Constants.swift */; };
- 88DEA97F1FCDBD78006C80EF /* Constants.swift in Sources */ = {isa = PBXBuildFile; fileRef = 88DEA97D1FCDBD1F006C80EF /* Constants.swift */; };
- 8933C7851EB5B820000D00A4 /* SkeletonView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8933C7841EB5B820000D00A4 /* SkeletonView.swift */; };
- E4CE587D22EEE65200333067 /* SkeletonTransitionStyle.swift in Sources */ = {isa = PBXBuildFile; fileRef = E4CE587C22EEE65200333067 /* SkeletonTransitionStyle.swift */; };
- E4CE588B22EEF70D00333067 /* UIView+Transitions.swift in Sources */ = {isa = PBXBuildFile; fileRef = E4CE587B22EEE63100333067 /* UIView+Transitions.swift */; };
- F51DE1091FBF70A70037919A /* SkeletonAnimationBuilder.swift in Sources */ = {isa = PBXBuildFile; fileRef = F51DE1081FBF70A70037919A /* SkeletonAnimationBuilder.swift */; };
- F51DF871206E91B300D23301 /* SkeletonReusableCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = F51DF870206E91B300D23301 /* SkeletonReusableCell.swift */; };
- F51DF873206E91FB00D23301 /* GenericCollectionView.swift in Sources */ = {isa = PBXBuildFile; fileRef = F51DF872206E91FB00D23301 /* GenericCollectionView.swift */; };
- F51DF879206E9F5500D23301 /* SkeletonCollectionDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = F51DF878206E9F5500D23301 /* SkeletonCollectionDelegate.swift */; };
- F51ED28320973CBB008B2434 /* SkeletonCollectionDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = F51DF878206E9F5500D23301 /* SkeletonCollectionDelegate.swift */; };
- F51ED28420973CC6008B2434 /* GenericCollectionView.swift in Sources */ = {isa = PBXBuildFile; fileRef = F51DF872206E91FB00D23301 /* GenericCollectionView.swift */; };
- F51ED28520973CC9008B2434 /* SkeletonReusableCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = F51DF870206E91B300D23301 /* SkeletonReusableCell.swift */; };
- F5307E2C1FAF6BC900EE67C5 /* SkeletonGradient.swift in Sources */ = {isa = PBXBuildFile; fileRef = F5307E2B1FAF6BC900EE67C5 /* SkeletonGradient.swift */; };
- F5307E2E1FB0E5E400EE67C5 /* UIView+Frame.swift in Sources */ = {isa = PBXBuildFile; fileRef = F5307E2D1FB0E5E400EE67C5 /* UIView+Frame.swift */; };
- F5307E301FB0EC9D00EE67C5 /* SkeletonAppearance.swift in Sources */ = {isa = PBXBuildFile; fileRef = F5307E2F1FB0EC9D00EE67C5 /* SkeletonAppearance.swift */; };
- F5307E321FB0F42F00EE67C5 /* RecursiveProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = F5307E311FB0F42F00EE67C5 /* RecursiveProtocol.swift */; };
- F5307E371FB1076E00EE67C5 /* SkeletonTableViewProtocols.swift in Sources */ = {isa = PBXBuildFile; fileRef = F5307E361FB1076E00EE67C5 /* SkeletonTableViewProtocols.swift */; };
- F5307E391FB1078E00EE67C5 /* SkeletonCollectionViewProtocols.swift in Sources */ = {isa = PBXBuildFile; fileRef = F5307E381FB1078E00EE67C5 /* SkeletonCollectionViewProtocols.swift */; };
- F5307E3B1FB123C100EE67C5 /* ContainsMultilineText.swift in Sources */ = {isa = PBXBuildFile; fileRef = F5307E3A1FB123C100EE67C5 /* ContainsMultilineText.swift */; };
- F5307E411FB3B84500EE67C5 /* SkeletonView.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 52D6D97C1BEFF229002C0205 /* SkeletonView.framework */; };
- F5307E421FB3B84500EE67C5 /* SkeletonView.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 52D6D97C1BEFF229002C0205 /* SkeletonView.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
- F54CF5E42024CEB000330B0D /* UIView+CollectionSkeleton.swift in Sources */ = {isa = PBXBuildFile; fileRef = F54CF5E12024CEAF00330B0D /* UIView+CollectionSkeleton.swift */; };
- F54CF5E52024CEB000330B0D /* UITableView+CollectionSkeleton.swift in Sources */ = {isa = PBXBuildFile; fileRef = F54CF5E22024CEAF00330B0D /* UITableView+CollectionSkeleton.swift */; };
- F54CF5E62024CEB000330B0D /* UICollectionView+CollectionSkeleton.swift in Sources */ = {isa = PBXBuildFile; fileRef = F54CF5E32024CEB000330B0D /* UICollectionView+CollectionSkeleton.swift */; };
- F56B94461FAE20AF0095662F /* PrepareForSkeletonProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = F56B94451FAE20AF0095662F /* PrepareForSkeletonProtocol.swift */; };
- F570ABF42314629700390248 /* Swizzling.swift in Sources */ = {isa = PBXBuildFile; fileRef = F570ABF32314629700390248 /* Swizzling.swift */; };
- F570ABF52314629700390248 /* Swizzling.swift in Sources */ = {isa = PBXBuildFile; fileRef = F570ABF32314629700390248 /* Swizzling.swift */; };
- F5804772230ECD0000066D02 /* UIView+IBInspectable.swift in Sources */ = {isa = PBXBuildFile; fileRef = F5804771230ECD0000066D02 /* UIView+IBInspectable.swift */; };
- F5804773230ECD0000066D02 /* UIView+IBInspectable.swift in Sources */ = {isa = PBXBuildFile; fileRef = F5804771230ECD0000066D02 /* UIView+IBInspectable.swift */; };
- F587FB84202CBFC8002DB5FE /* SkeletonFlow.swift in Sources */ = {isa = PBXBuildFile; fileRef = F587FB83202CBFC8002DB5FE /* SkeletonFlow.swift */; };
- F587FB86202CEC95002DB5FE /* UIView+UIApplicationDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = F587FB85202CEC95002DB5FE /* UIView+UIApplicationDelegate.swift */; };
- F58A6E6B20A8C54100612494 /* RecoverableViewState.swift in Sources */ = {isa = PBXBuildFile; fileRef = F58A6E6A20A8C54100612494 /* RecoverableViewState.swift */; };
- F58A6E6C20A8C54100612494 /* RecoverableViewState.swift in Sources */ = {isa = PBXBuildFile; fileRef = F58A6E6A20A8C54100612494 /* RecoverableViewState.swift */; };
- F58A6E6E20A8C66300612494 /* Recoverable.swift in Sources */ = {isa = PBXBuildFile; fileRef = F58A6E6D20A8C66300612494 /* Recoverable.swift */; };
- F58A6E6F20A8C66300612494 /* Recoverable.swift in Sources */ = {isa = PBXBuildFile; fileRef = F58A6E6D20A8C66300612494 /* Recoverable.swift */; };
- F5A5E8B4211DCE7000FD20D0 /* Int+Whitespaces.swift in Sources */ = {isa = PBXBuildFile; fileRef = F5A5E8B3211DCE7000FD20D0 /* Int+Whitespaces.swift */; };
- F5A5E8B5211DCE7000FD20D0 /* Int+Whitespaces.swift in Sources */ = {isa = PBXBuildFile; fileRef = F5A5E8B3211DCE7000FD20D0 /* Int+Whitespaces.swift */; };
- F5D3FB0B209DCAA300003FCF /* SubviewsSkeletonables.swift in Sources */ = {isa = PBXBuildFile; fileRef = F5D3FB0A209DCAA300003FCF /* SubviewsSkeletonables.swift */; };
- F5D3FB0C209DCAA300003FCF /* SubviewsSkeletonables.swift in Sources */ = {isa = PBXBuildFile; fileRef = F5D3FB0A209DCAA300003FCF /* SubviewsSkeletonables.swift */; };
- F5F622411FAC6E31007C062A /* UIColor+Skeleton.swift in Sources */ = {isa = PBXBuildFile; fileRef = F5F622401FAC6E31007C062A /* UIColor+Skeleton.swift */; };
- F5F622431FAC81FD007C062A /* CALayer+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = F5F622421FAC81FD007C062A /* CALayer+Extensions.swift */; };
- F5F622451FACA338007C062A /* Cell.swift in Sources */ = {isa = PBXBuildFile; fileRef = F5F622441FACA338007C062A /* Cell.swift */; };
- F5F899D21FAB9630002E8FDA /* AssociationPolicy.swift in Sources */ = {isa = PBXBuildFile; fileRef = F5F899D11FAB9630002E8FDA /* AssociationPolicy.swift */; };
- F5F899E91FAB9D2B002E8FDA /* SkeletonLayer.swift in Sources */ = {isa = PBXBuildFile; fileRef = F5F899E81FAB9D2B002E8FDA /* SkeletonLayer.swift */; };
- F5F899EB1FAB9DA3002E8FDA /* SkeletonCollectionDataSource.swift in Sources */ = {isa = PBXBuildFile; fileRef = F5F899EA1FAB9DA3002E8FDA /* SkeletonCollectionDataSource.swift */; };
- F5F899ED1FAB9F04002E8FDA /* CollectionSkeletonProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = F5F899EC1FAB9F04002E8FDA /* CollectionSkeletonProtocol.swift */; };
- F5F899F51FABA607002E8FDA /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = F5F899F41FABA607002E8FDA /* AppDelegate.swift */; };
- F5F899F71FABA607002E8FDA /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = F5F899F61FABA607002E8FDA /* ViewController.swift */; };
- F5F899FA1FABA607002E8FDA /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = F5F899F81FABA607002E8FDA /* Main.storyboard */; };
- F5F899FC1FABA607002E8FDA /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = F5F899FB1FABA607002E8FDA /* Assets.xcassets */; };
- F5F899FF1FABA607002E8FDA /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = F5F899FD1FABA607002E8FDA /* LaunchScreen.storyboard */; };
+ F556F56626CD1F3900A80B83 /* SkeletonAppearance.swift in Sources */ = {isa = PBXBuildFile; fileRef = OBJ_9 /* SkeletonAppearance.swift */; };
+ F556F56726CD1F3900A80B83 /* SkeletonLayerBuilder.swift in Sources */ = {isa = PBXBuildFile; fileRef = OBJ_11 /* SkeletonLayerBuilder.swift */; };
+ F556F56826CD1F3900A80B83 /* SkeletonMultilineLayerBuilder.swift in Sources */ = {isa = PBXBuildFile; fileRef = OBJ_12 /* SkeletonMultilineLayerBuilder.swift */; };
+ F556F56926CD1F3900A80B83 /* CollectionSkeleton.swift in Sources */ = {isa = PBXBuildFile; fileRef = OBJ_14 /* CollectionSkeleton.swift */; };
+ F556F56A26CD1F3900A80B83 /* SkeletonCollectionViewProtocols.swift in Sources */ = {isa = PBXBuildFile; fileRef = OBJ_16 /* SkeletonCollectionViewProtocols.swift */; };
+ F556F56B26CD1F3900A80B83 /* UICollectionView+CollectionSkeleton.swift in Sources */ = {isa = PBXBuildFile; fileRef = OBJ_17 /* UICollectionView+CollectionSkeleton.swift */; };
+ F556F56D26CD1F3900A80B83 /* SkeletonReusableCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = OBJ_20 /* SkeletonReusableCell.swift */; };
+ F556F56E26CD1F3900A80B83 /* SkeletonCollectionDataSource.swift in Sources */ = {isa = PBXBuildFile; fileRef = OBJ_21 /* SkeletonCollectionDataSource.swift */; };
+ F556F56F26CD1F3900A80B83 /* SkeletonCollectionDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = OBJ_22 /* SkeletonCollectionDelegate.swift */; };
+ F556F57026CD1F3900A80B83 /* SkeletonTableViewProtocols.swift in Sources */ = {isa = PBXBuildFile; fileRef = OBJ_24 /* SkeletonTableViewProtocols.swift */; };
+ F556F57126CD1F3900A80B83 /* UITableView+CollectionSkeleton.swift in Sources */ = {isa = PBXBuildFile; fileRef = OBJ_25 /* UITableView+CollectionSkeleton.swift */; };
+ F556F57226CD1F3900A80B83 /* UIView+CollectionSkeleton.swift in Sources */ = {isa = PBXBuildFile; fileRef = OBJ_26 /* UIView+CollectionSkeleton.swift */; };
+ F556F57526CD1F3900A80B83 /* Int+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = OBJ_31 /* Int+Extensions.swift */; };
+ F556F57726CD1F3900A80B83 /* UIColor+Skeleton.swift in Sources */ = {isa = PBXBuildFile; fileRef = OBJ_33 /* UIColor+Skeleton.swift */; };
+ F556F57826CD1F3900A80B83 /* UITableView+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = OBJ_34 /* UITableView+Extensions.swift */; };
+ F556F57D26CD1F3900A80B83 /* UIView+AppLifecycleNotifications.swift in Sources */ = {isa = PBXBuildFile; fileRef = OBJ_39 /* UIView+AppLifecycleNotifications.swift */; };
+ F556F57E26CD1F3900A80B83 /* AssociationPolicy.swift in Sources */ = {isa = PBXBuildFile; fileRef = OBJ_41 /* AssociationPolicy.swift */; };
+ F556F58026CD1F3900A80B83 /* Recursive.swift in Sources */ = {isa = PBXBuildFile; fileRef = OBJ_43 /* Recursive.swift */; };
+ F556F58126CD1F3900A80B83 /* Swizzling.swift in Sources */ = {isa = PBXBuildFile; fileRef = OBJ_44 /* Swizzling.swift */; };
+ F556F58526CD1F3900A80B83 /* Recoverable.swift in Sources */ = {isa = PBXBuildFile; fileRef = OBJ_50 /* Recoverable.swift */; };
+ F556F58626CD1F3900A80B83 /* RecoverableViewState.swift in Sources */ = {isa = PBXBuildFile; fileRef = OBJ_51 /* RecoverableViewState.swift */; };
+ F556F58726CD1F3900A80B83 /* SkeletonAnimationBuilder.swift in Sources */ = {isa = PBXBuildFile; fileRef = OBJ_52 /* SkeletonAnimationBuilder.swift */; };
+ F556F58826CD1F3900A80B83 /* SkeletonConfig.swift in Sources */ = {isa = PBXBuildFile; fileRef = OBJ_53 /* SkeletonConfig.swift */; };
+ F556F58926CD1F3900A80B83 /* SkeletonFlowHandler.swift in Sources */ = {isa = PBXBuildFile; fileRef = OBJ_54 /* SkeletonFlowHandler.swift */; };
+ F556F58A26CD1F3900A80B83 /* SkeletonGradient.swift in Sources */ = {isa = PBXBuildFile; fileRef = OBJ_55 /* SkeletonGradient.swift */; };
+ F556F58B26CD1F3900A80B83 /* SkeletonLayer.swift in Sources */ = {isa = PBXBuildFile; fileRef = OBJ_56 /* SkeletonLayer.swift */; };
+ F556F58D26CD1F3900A80B83 /* SubviewsSkeletonables.swift in Sources */ = {isa = PBXBuildFile; fileRef = OBJ_58 /* SubviewsSkeletonables.swift */; };
+ F556F58E26CD1F3900A80B83 /* SkeletonTransitionStyle.swift in Sources */ = {isa = PBXBuildFile; fileRef = OBJ_60 /* SkeletonTransitionStyle.swift */; };
+ F556F58F26CD1F3900A80B83 /* UIView+Transitions.swift in Sources */ = {isa = PBXBuildFile; fileRef = OBJ_61 /* UIView+Transitions.swift */; };
+ F556F64D26CD2CF800A80B83 /* SkeletonDebug.swift in Sources */ = {isa = PBXBuildFile; fileRef = F556F64C26CD2CF700A80B83 /* SkeletonDebug.swift */; };
+ F556F64E26CD2D3D00A80B83 /* SkeletonDebug.swift in Sources */ = {isa = PBXBuildFile; fileRef = F556F64C26CD2CF700A80B83 /* SkeletonDebug.swift */; };
+ F556F65026CD2DFD00A80B83 /* SkeletonView.swift in Sources */ = {isa = PBXBuildFile; fileRef = F556F64F26CD2DFD00A80B83 /* SkeletonView.swift */; };
+ F556F65126CD2DFD00A80B83 /* SkeletonView.swift in Sources */ = {isa = PBXBuildFile; fileRef = F556F64F26CD2DFD00A80B83 /* SkeletonView.swift */; };
+ F556F65D26CD3E3600A80B83 /* SkeletonDebugTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = F556F65C26CD3E3600A80B83 /* SkeletonDebugTests.swift */; };
+ F556F67626CD458500A80B83 /* SkeletonView.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F556F59426CD1F3900A80B83 /* SkeletonView.framework */; platformFilter = maccatalyst; };
+ F556F67C26CD45A300A80B83 /* SkeletonDebugTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = F556F65C26CD3E3600A80B83 /* SkeletonDebugTests.swift */; };
+ F556F68026CD47CF00A80B83 /* ProcessInfo+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = F556F67F26CD47CF00A80B83 /* ProcessInfo+Extensions.swift */; };
+ F556F68126CD47CF00A80B83 /* ProcessInfo+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = F556F67F26CD47CF00A80B83 /* ProcessInfo+Extensions.swift */; };
+ F556F68326CD48F700A80B83 /* UIView+AssociatedObjects.swift in Sources */ = {isa = PBXBuildFile; fileRef = F556F68226CD48F700A80B83 /* UIView+AssociatedObjects.swift */; };
+ F556F68426CD48F700A80B83 /* UIView+AssociatedObjects.swift in Sources */ = {isa = PBXBuildFile; fileRef = F556F68226CD48F700A80B83 /* UIView+AssociatedObjects.swift */; };
+ F556F68726CD49F900A80B83 /* UIView+IBInspectable.swift in Sources */ = {isa = PBXBuildFile; fileRef = F556F68626CD49F900A80B83 /* UIView+IBInspectable.swift */; };
+ F556F68826CD49F900A80B83 /* UIView+IBInspectable.swift in Sources */ = {isa = PBXBuildFile; fileRef = F556F68626CD49F900A80B83 /* UIView+IBInspectable.swift */; };
+ F556F68A26CD4D6100A80B83 /* Notification+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = F556F68926CD4D6100A80B83 /* Notification+Extensions.swift */; };
+ F556F68B26CD4D6100A80B83 /* Notification+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = F556F68926CD4D6100A80B83 /* Notification+Extensions.swift */; };
+ F556F69226CD506C00A80B83 /* Deprecated.swift in Sources */ = {isa = PBXBuildFile; fileRef = F556F69126CD506C00A80B83 /* Deprecated.swift */; };
+ F556F69326CD506C00A80B83 /* Deprecated.swift in Sources */ = {isa = PBXBuildFile; fileRef = F556F69126CD506C00A80B83 /* Deprecated.swift */; };
+ F556F69526CD509E00A80B83 /* Notification+SkeletonFlow.swift in Sources */ = {isa = PBXBuildFile; fileRef = F556F69426CD509E00A80B83 /* Notification+SkeletonFlow.swift */; };
+ F556F69626CD509E00A80B83 /* Notification+SkeletonFlow.swift in Sources */ = {isa = PBXBuildFile; fileRef = F556F69426CD509E00A80B83 /* Notification+SkeletonFlow.swift */; };
+ F556F69E26CD553B00A80B83 /* UIView+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = F556F69D26CD553B00A80B83 /* UIView+Extensions.swift */; };
+ F556F69F26CD553B00A80B83 /* UIView+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = F556F69D26CD553B00A80B83 /* UIView+Extensions.swift */; };
+ F556F6A126CD566C00A80B83 /* UIView+Debug.swift in Sources */ = {isa = PBXBuildFile; fileRef = F556F6A026CD566C00A80B83 /* UIView+Debug.swift */; };
+ F556F6A226CD566C00A80B83 /* UIView+Debug.swift in Sources */ = {isa = PBXBuildFile; fileRef = F556F6A026CD566C00A80B83 /* UIView+Debug.swift */; };
+ F556F6A426CD5A9000A80B83 /* CALayer+Animations.swift in Sources */ = {isa = PBXBuildFile; fileRef = F556F6A326CD5A9000A80B83 /* CALayer+Animations.swift */; };
+ F556F6A526CD5A9000A80B83 /* CALayer+Animations.swift in Sources */ = {isa = PBXBuildFile; fileRef = F556F6A326CD5A9000A80B83 /* CALayer+Animations.swift */; };
+ F556F6A726CD5B0400A80B83 /* CALayer+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = F556F6A626CD5B0400A80B83 /* CALayer+Extensions.swift */; };
+ F556F6A826CD5B0400A80B83 /* CALayer+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = F556F6A626CD5B0400A80B83 /* CALayer+Extensions.swift */; };
+ F556F6AB26CD5C4900A80B83 /* SkeletonMultilinesLayerConfig.swift in Sources */ = {isa = PBXBuildFile; fileRef = F556F6AA26CD5C4900A80B83 /* SkeletonMultilinesLayerConfig.swift */; };
+ F556F6AC26CD5C4900A80B83 /* SkeletonMultilinesLayerConfig.swift in Sources */ = {isa = PBXBuildFile; fileRef = F556F6AA26CD5C4900A80B83 /* SkeletonMultilinesLayerConfig.swift */; };
+ F556F6AF26CE244100A80B83 /* DispatchQueue+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = F556F6AE26CE244100A80B83 /* DispatchQueue+Extensions.swift */; };
+ F556F6B026CE244100A80B83 /* DispatchQueue+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = F556F6AE26CE244100A80B83 /* DispatchQueue+Extensions.swift */; };
+ F556F6B526CE258300A80B83 /* GradientDirection+Animations.swift in Sources */ = {isa = PBXBuildFile; fileRef = F556F6B426CE258300A80B83 /* GradientDirection+Animations.swift */; };
+ F556F6B626CE258300A80B83 /* GradientDirection+Animations.swift in Sources */ = {isa = PBXBuildFile; fileRef = F556F6B426CE258300A80B83 /* GradientDirection+Animations.swift */; };
+ F556F6B926CE262700A80B83 /* GradientDirection.swift in Sources */ = {isa = PBXBuildFile; fileRef = F556F6B826CE262700A80B83 /* GradientDirection.swift */; };
+ F556F6BA26CE262700A80B83 /* GradientDirection.swift in Sources */ = {isa = PBXBuildFile; fileRef = F556F6B826CE262700A80B83 /* GradientDirection.swift */; };
+ F556F6BC26CE272600A80B83 /* UILabel+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = F556F6BB26CE272600A80B83 /* UILabel+Extensions.swift */; };
+ F556F6BD26CE272600A80B83 /* UILabel+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = F556F6BB26CE272600A80B83 /* UILabel+Extensions.swift */; };
+ F556F6BF26CE277F00A80B83 /* PrepareViewForSkeleton.swift in Sources */ = {isa = PBXBuildFile; fileRef = F556F6BE26CE277F00A80B83 /* PrepareViewForSkeleton.swift */; };
+ F556F6C026CE277F00A80B83 /* PrepareViewForSkeleton.swift in Sources */ = {isa = PBXBuildFile; fileRef = F556F6BE26CE277F00A80B83 /* PrepareViewForSkeleton.swift */; };
+ F556F6C226CE27FD00A80B83 /* SkeletonType.swift in Sources */ = {isa = PBXBuildFile; fileRef = F556F6C126CE27FD00A80B83 /* SkeletonType.swift */; };
+ F556F6C326CE27FD00A80B83 /* SkeletonType.swift in Sources */ = {isa = PBXBuildFile; fileRef = F556F6C126CE27FD00A80B83 /* SkeletonType.swift */; };
+ F556F6C626CE2A2100A80B83 /* UILabel+IBInspectable.swift in Sources */ = {isa = PBXBuildFile; fileRef = F556F6C526CE2A2100A80B83 /* UILabel+IBInspectable.swift */; };
+ F556F6C726CE2A2100A80B83 /* UILabel+IBInspectable.swift in Sources */ = {isa = PBXBuildFile; fileRef = F556F6C526CE2A2100A80B83 /* UILabel+IBInspectable.swift */; };
+ F556F6C926CE2A4A00A80B83 /* UITextView+IBInspectable.swift in Sources */ = {isa = PBXBuildFile; fileRef = F556F6C826CE2A4A00A80B83 /* UITextView+IBInspectable.swift */; };
+ F556F6CA26CE2A4A00A80B83 /* UITextView+IBInspectable.swift in Sources */ = {isa = PBXBuildFile; fileRef = F556F6C826CE2A4A00A80B83 /* UITextView+IBInspectable.swift */; };
+ F556F6CC26CE2A7400A80B83 /* UITextView+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = F556F6CB26CE2A7400A80B83 /* UITextView+Extensions.swift */; };
+ F556F6CD26CE2A7400A80B83 /* UITextView+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = F556F6CB26CE2A7400A80B83 /* UITextView+Extensions.swift */; };
+ F556F6CF26CE2AB800A80B83 /* SkeletonTextNode.swift in Sources */ = {isa = PBXBuildFile; fileRef = F556F6CE26CE2AB800A80B83 /* SkeletonTextNode.swift */; };
+ F556F6D026CE2AB800A80B83 /* SkeletonTextNode.swift in Sources */ = {isa = PBXBuildFile; fileRef = F556F6CE26CE2AB800A80B83 /* SkeletonTextNode.swift */; };
+ F556F6D926CE315A00A80B83 /* UICollectionView+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = F556F6D826CE315A00A80B83 /* UICollectionView+Extensions.swift */; };
+ F556F6DA26CE315A00A80B83 /* UICollectionView+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = F556F6D826CE315A00A80B83 /* UICollectionView+Extensions.swift */; };
+ F556F6DD26CE33CE00A80B83 /* UIView+Swizzling.swift in Sources */ = {isa = PBXBuildFile; fileRef = F556F6DC26CE33CE00A80B83 /* UIView+Swizzling.swift */; };
+ F556F6E026CE367600A80B83 /* UIView+SkeletonView.swift in Sources */ = {isa = PBXBuildFile; fileRef = F556F6DF26CE367600A80B83 /* UIView+SkeletonView.swift */; };
+ F556F6E126CE367600A80B83 /* UIView+SkeletonView.swift in Sources */ = {isa = PBXBuildFile; fileRef = F556F6DF26CE367600A80B83 /* UIView+SkeletonView.swift */; };
+ F556F6F226CE818B00A80B83 /* UIView+Flags.swift in Sources */ = {isa = PBXBuildFile; fileRef = F556F6F126CE818B00A80B83 /* UIView+Flags.swift */; };
+ F556F6F326CE818B00A80B83 /* UIView+Flags.swift in Sources */ = {isa = PBXBuildFile; fileRef = F556F6F126CE818B00A80B83 /* UIView+Flags.swift */; };
+ F556F6F626CE876300A80B83 /* UIView+Swizzling.swift in Sources */ = {isa = PBXBuildFile; fileRef = F556F6DC26CE33CE00A80B83 /* UIView+Swizzling.swift */; };
+ OBJ_101 /* Int+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = OBJ_31 /* Int+Extensions.swift */; };
+ OBJ_103 /* UIColor+Skeleton.swift in Sources */ = {isa = PBXBuildFile; fileRef = OBJ_33 /* UIColor+Skeleton.swift */; };
+ OBJ_104 /* UITableView+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = OBJ_34 /* UITableView+Extensions.swift */; };
+ OBJ_109 /* UIView+AppLifecycleNotifications.swift in Sources */ = {isa = PBXBuildFile; fileRef = OBJ_39 /* UIView+AppLifecycleNotifications.swift */; };
+ OBJ_110 /* AssociationPolicy.swift in Sources */ = {isa = PBXBuildFile; fileRef = OBJ_41 /* AssociationPolicy.swift */; };
+ OBJ_112 /* Recursive.swift in Sources */ = {isa = PBXBuildFile; fileRef = OBJ_43 /* Recursive.swift */; };
+ OBJ_113 /* Swizzling.swift in Sources */ = {isa = PBXBuildFile; fileRef = OBJ_44 /* Swizzling.swift */; };
+ OBJ_117 /* Recoverable.swift in Sources */ = {isa = PBXBuildFile; fileRef = OBJ_50 /* Recoverable.swift */; };
+ OBJ_118 /* RecoverableViewState.swift in Sources */ = {isa = PBXBuildFile; fileRef = OBJ_51 /* RecoverableViewState.swift */; };
+ OBJ_119 /* SkeletonAnimationBuilder.swift in Sources */ = {isa = PBXBuildFile; fileRef = OBJ_52 /* SkeletonAnimationBuilder.swift */; };
+ OBJ_120 /* SkeletonConfig.swift in Sources */ = {isa = PBXBuildFile; fileRef = OBJ_53 /* SkeletonConfig.swift */; };
+ OBJ_121 /* SkeletonFlowHandler.swift in Sources */ = {isa = PBXBuildFile; fileRef = OBJ_54 /* SkeletonFlowHandler.swift */; };
+ OBJ_122 /* SkeletonGradient.swift in Sources */ = {isa = PBXBuildFile; fileRef = OBJ_55 /* SkeletonGradient.swift */; };
+ OBJ_123 /* SkeletonLayer.swift in Sources */ = {isa = PBXBuildFile; fileRef = OBJ_56 /* SkeletonLayer.swift */; };
+ OBJ_125 /* SubviewsSkeletonables.swift in Sources */ = {isa = PBXBuildFile; fileRef = OBJ_58 /* SubviewsSkeletonables.swift */; };
+ OBJ_126 /* SkeletonTransitionStyle.swift in Sources */ = {isa = PBXBuildFile; fileRef = OBJ_60 /* SkeletonTransitionStyle.swift */; };
+ OBJ_127 /* UIView+Transitions.swift in Sources */ = {isa = PBXBuildFile; fileRef = OBJ_61 /* UIView+Transitions.swift */; };
+ OBJ_147 /* SkeletonView.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = "SkeletonView::SkeletonView::Product" /* SkeletonView.framework */; };
+ OBJ_86 /* SkeletonAppearance.swift in Sources */ = {isa = PBXBuildFile; fileRef = OBJ_9 /* SkeletonAppearance.swift */; };
+ OBJ_87 /* SkeletonLayerBuilder.swift in Sources */ = {isa = PBXBuildFile; fileRef = OBJ_11 /* SkeletonLayerBuilder.swift */; };
+ OBJ_88 /* SkeletonMultilineLayerBuilder.swift in Sources */ = {isa = PBXBuildFile; fileRef = OBJ_12 /* SkeletonMultilineLayerBuilder.swift */; };
+ OBJ_89 /* CollectionSkeleton.swift in Sources */ = {isa = PBXBuildFile; fileRef = OBJ_14 /* CollectionSkeleton.swift */; };
+ OBJ_90 /* SkeletonCollectionViewProtocols.swift in Sources */ = {isa = PBXBuildFile; fileRef = OBJ_16 /* SkeletonCollectionViewProtocols.swift */; };
+ OBJ_91 /* UICollectionView+CollectionSkeleton.swift in Sources */ = {isa = PBXBuildFile; fileRef = OBJ_17 /* UICollectionView+CollectionSkeleton.swift */; };
+ OBJ_93 /* SkeletonReusableCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = OBJ_20 /* SkeletonReusableCell.swift */; };
+ OBJ_94 /* SkeletonCollectionDataSource.swift in Sources */ = {isa = PBXBuildFile; fileRef = OBJ_21 /* SkeletonCollectionDataSource.swift */; };
+ OBJ_95 /* SkeletonCollectionDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = OBJ_22 /* SkeletonCollectionDelegate.swift */; };
+ OBJ_96 /* SkeletonTableViewProtocols.swift in Sources */ = {isa = PBXBuildFile; fileRef = OBJ_24 /* SkeletonTableViewProtocols.swift */; };
+ OBJ_97 /* UITableView+CollectionSkeleton.swift in Sources */ = {isa = PBXBuildFile; fileRef = OBJ_25 /* UITableView+CollectionSkeleton.swift */; };
+ OBJ_98 /* UIView+CollectionSkeleton.swift in Sources */ = {isa = PBXBuildFile; fileRef = OBJ_26 /* UIView+CollectionSkeleton.swift */; };
/* End PBXBuildFile section */
/* Begin PBXContainerItemProxy section */
- 42ABD05C210B548200BEEFF4 /* PBXContainerItemProxy */ = {
+ F556F50C26CD1B1500A80B83 /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
- containerPortal = 52D6D9731BEFF229002C0205 /* Project object */;
+ containerPortal = OBJ_1 /* Project object */;
proxyType = 1;
- remoteGlobalIDString = 52D6D97B1BEFF229002C0205;
- remoteInfo = "SkeletonView-iOS";
+ remoteGlobalIDString = "SkeletonView::SkeletonView";
+ remoteInfo = SkeletonView;
};
- F5307E431FB3B84500EE67C5 /* PBXContainerItemProxy */ = {
+ F556F67726CD458500A80B83 /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
- containerPortal = 52D6D9731BEFF229002C0205 /* Project object */;
+ containerPortal = OBJ_1 /* Project object */;
proxyType = 1;
- remoteGlobalIDString = 52D6D97B1BEFF229002C0205;
- remoteInfo = "SkeletonView-iOS";
+ remoteGlobalIDString = F556F56426CD1F3900A80B83;
+ remoteInfo = "SkeletonView tvOS";
};
/* End PBXContainerItemProxy section */
-/* Begin PBXCopyFilesBuildPhase section */
- 42ABD068210B548200BEEFF4 /* Embed Frameworks */ = {
- isa = PBXCopyFilesBuildPhase;
- buildActionMask = 2147483647;
- dstPath = "";
- dstSubfolderSpec = 10;
- files = (
- 42ABD069210B548200BEEFF4 /* SkeletonView.framework in Embed Frameworks */,
- );
- name = "Embed Frameworks";
- runOnlyForDeploymentPostprocessing = 0;
- };
- F5307E451FB3B84600EE67C5 /* Embed Frameworks */ = {
- isa = PBXCopyFilesBuildPhase;
- buildActionMask = 2147483647;
- dstPath = "";
- dstSubfolderSpec = 10;
- files = (
- F5307E421FB3B84500EE67C5 /* SkeletonView.framework in Embed Frameworks */,
- );
- name = "Embed Frameworks";
- runOnlyForDeploymentPostprocessing = 0;
- };
-/* End PBXCopyFilesBuildPhase section */
-
/* Begin PBXFileReference section */
- 17DD0E00207FB27400C56334 /* SkeletonView.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = SkeletonView.framework; sourceTree = BUILT_PRODUCTS_DIR; };
- 17DD0E1A207FB2C200C56334 /* SkeletonView-tvOS.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "SkeletonView-tvOS.plist"; sourceTree = ""; };
- 17DD0E1B207FB2C200C56334 /* SkeletonView-iOS.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "SkeletonView-iOS.plist"; sourceTree = ""; };
- 1E291F3D2540655D0018D602 /* UIView+Autolayout.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UIView+Autolayout.swift"; sourceTree = ""; };
- 1EE42E1E23FF25CC00BF665A /* ProcessInfo+XCTest.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "ProcessInfo+XCTest.swift"; sourceTree = ""; };
- 42ABD06D210B548200BEEFF4 /* SkeletonViewExampleUICollectionView.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = SkeletonViewExampleUICollectionView.app; sourceTree = BUILT_PRODUCTS_DIR; };
- 42ABD070210B54E100BEEFF4 /* AppDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; };
- 42ABD071210B54E100BEEFF4 /* Main.storyboard */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.storyboard; path = Main.storyboard; sourceTree = ""; };
- 42ABD072210B54E100BEEFF4 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; };
- 42ABD073210B54E100BEEFF4 /* ViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ViewController.swift; sourceTree = ""; };
- 42ABD074210B54E100BEEFF4 /* Base.lproj */ = {isa = PBXFileReference; lastKnownFileType = folder; path = Base.lproj; sourceTree = ""; };
- 42ABD076210B54E200BEEFF4 /* SkeletonViewExampleCollectionview-Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = "SkeletonViewExampleCollectionview-Info.plist"; sourceTree = ""; };
- 42ABD077210B54E200BEEFF4 /* CollectionViewCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CollectionViewCell.swift; sourceTree = ""; };
- 52D6D97C1BEFF229002C0205 /* SkeletonView.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = SkeletonView.framework; sourceTree = BUILT_PRODUCTS_DIR; };
- 5600784323FD293D00669AD6 /* UITableView+VisibleSections.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UITableView+VisibleSections.swift"; sourceTree = ""; };
- 5600784623FD2BC300669AD6 /* HeaderFooterSection.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HeaderFooterSection.swift; sourceTree = ""; };
- 870F4E4221CAC07300B9233B /* SkeletonConfig.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SkeletonConfig.swift; sourceTree = ""; };
- 872D5A5521C177E20037D763 /* UIView+Extension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UIView+Extension.swift"; sourceTree = ""; };
- 872D5A5B21C24EDD0037D763 /* UILabel+Multiline.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UILabel+Multiline.swift"; sourceTree = ""; };
- 872D5A5E21C24F8E0037D763 /* UITextView+Multiline.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UITextView+Multiline.swift"; sourceTree = ""; };
- 877EFA4421BEE9D80031FC00 /* SkeletonLayerBuilder.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SkeletonLayerBuilder.swift; sourceTree = ""; };
- 877EFA4721BEED760031FC00 /* SkeletonMultilineLayerBuilder.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SkeletonMultilineLayerBuilder.swift; sourceTree = ""; };
- 8785E3A0211C9C9800CC9DFD /* SkeletonDebug.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SkeletonDebug.swift; sourceTree = ""; };
- 88DEA97D1FCDBD1F006C80EF /* Constants.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Constants.swift; sourceTree = ""; };
- 8933C7841EB5B820000D00A4 /* SkeletonView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SkeletonView.swift; sourceTree = ""; };
- E4CE587B22EEE63100333067 /* UIView+Transitions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UIView+Transitions.swift"; sourceTree = ""; };
- E4CE587C22EEE65200333067 /* SkeletonTransitionStyle.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SkeletonTransitionStyle.swift; sourceTree = ""; };
- F51DE1081FBF70A70037919A /* SkeletonAnimationBuilder.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SkeletonAnimationBuilder.swift; sourceTree = ""; };
- F51DF870206E91B300D23301 /* SkeletonReusableCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SkeletonReusableCell.swift; sourceTree = ""; };
- F51DF872206E91FB00D23301 /* GenericCollectionView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GenericCollectionView.swift; sourceTree = ""; };
- F51DF878206E9F5500D23301 /* SkeletonCollectionDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SkeletonCollectionDelegate.swift; sourceTree = ""; };
- F5307E2B1FAF6BC900EE67C5 /* SkeletonGradient.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SkeletonGradient.swift; sourceTree = ""; };
- F5307E2D1FB0E5E400EE67C5 /* UIView+Frame.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UIView+Frame.swift"; sourceTree = ""; };
- F5307E2F1FB0EC9D00EE67C5 /* SkeletonAppearance.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SkeletonAppearance.swift; sourceTree = ""; };
- F5307E311FB0F42F00EE67C5 /* RecursiveProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RecursiveProtocol.swift; sourceTree = ""; };
- F5307E361FB1076E00EE67C5 /* SkeletonTableViewProtocols.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SkeletonTableViewProtocols.swift; sourceTree = ""; };
- F5307E381FB1078E00EE67C5 /* SkeletonCollectionViewProtocols.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SkeletonCollectionViewProtocols.swift; sourceTree = ""; };
- F5307E3A1FB123C100EE67C5 /* ContainsMultilineText.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContainsMultilineText.swift; sourceTree = ""; };
- F54CF5E12024CEAF00330B0D /* UIView+CollectionSkeleton.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "UIView+CollectionSkeleton.swift"; sourceTree = ""; };
- F54CF5E22024CEAF00330B0D /* UITableView+CollectionSkeleton.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "UITableView+CollectionSkeleton.swift"; sourceTree = ""; };
- F54CF5E32024CEB000330B0D /* UICollectionView+CollectionSkeleton.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "UICollectionView+CollectionSkeleton.swift"; sourceTree = ""; };
- F56B94451FAE20AF0095662F /* PrepareForSkeletonProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PrepareForSkeletonProtocol.swift; sourceTree = ""; };
- F570ABF32314629700390248 /* Swizzling.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Swizzling.swift; sourceTree = ""; };
- F5804771230ECD0000066D02 /* UIView+IBInspectable.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "UIView+IBInspectable.swift"; sourceTree = ""; };
- F587FB83202CBFC8002DB5FE /* SkeletonFlow.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SkeletonFlow.swift; sourceTree = ""; };
- F587FB85202CEC95002DB5FE /* UIView+UIApplicationDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UIView+UIApplicationDelegate.swift"; sourceTree = ""; };
- F58A6E6A20A8C54100612494 /* RecoverableViewState.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RecoverableViewState.swift; sourceTree = ""; };
- F58A6E6D20A8C66300612494 /* Recoverable.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Recoverable.swift; sourceTree = ""; };
- F5A5E8B3211DCE7000FD20D0 /* Int+Whitespaces.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Int+Whitespaces.swift"; sourceTree = ""; };
- F5D3FB0A209DCAA300003FCF /* SubviewsSkeletonables.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SubviewsSkeletonables.swift; sourceTree = ""; };
- F5F622401FAC6E31007C062A /* UIColor+Skeleton.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UIColor+Skeleton.swift"; sourceTree = ""; };
- F5F622421FAC81FD007C062A /* CALayer+Extensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "CALayer+Extensions.swift"; sourceTree = ""; };
- F5F622441FACA338007C062A /* Cell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Cell.swift; sourceTree = ""; };
- F5F899D11FAB9630002E8FDA /* AssociationPolicy.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AssociationPolicy.swift; sourceTree = ""; };
- F5F899E81FAB9D2B002E8FDA /* SkeletonLayer.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SkeletonLayer.swift; sourceTree = ""; };
- F5F899EA1FAB9DA3002E8FDA /* SkeletonCollectionDataSource.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SkeletonCollectionDataSource.swift; sourceTree = ""; };
- F5F899EC1FAB9F04002E8FDA /* CollectionSkeletonProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CollectionSkeletonProtocol.swift; sourceTree = ""; };
- F5F899F21FABA607002E8FDA /* SkeletonViewExample.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = SkeletonViewExample.app; sourceTree = BUILT_PRODUCTS_DIR; };
- F5F899F41FABA607002E8FDA /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; };
- F5F899F61FABA607002E8FDA /* ViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewController.swift; sourceTree = ""; };
- F5F899F91FABA607002E8FDA /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; };
- F5F899FB1FABA607002E8FDA /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; };
- F5F899FE1FABA607002E8FDA /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; };
- F5F89A001FABA607002E8FDA /* SkeletonViewExampleInfo.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = SkeletonViewExampleInfo.plist; sourceTree = ""; };
+ F556F51026CD1B7900A80B83 /* SkeletonView.podspec */ = {isa = PBXFileReference; lastKnownFileType = text; path = SkeletonView.podspec; sourceTree = ""; };
+ F556F51126CD1B8000A80B83 /* LICENSE */ = {isa = PBXFileReference; lastKnownFileType = text; path = LICENSE; sourceTree = ""; };
+ F556F51426CD1BFF00A80B83 /* README_zh.md */ = {isa = PBXFileReference; lastKnownFileType = net.daringfireball.markdown; name = README_zh.md; path = Translations/README_zh.md; sourceTree = ""; };
+ F556F51526CD1BFF00A80B83 /* README.md */ = {isa = PBXFileReference; lastKnownFileType = net.daringfireball.markdown; path = README.md; sourceTree = ""; };
+ F556F51626CD1BFF00A80B83 /* README_ko.md */ = {isa = PBXFileReference; lastKnownFileType = net.daringfireball.markdown; name = README_ko.md; path = Translations/README_ko.md; sourceTree = ""; };
+ F556F51726CD1BFF00A80B83 /* README_fr.md */ = {isa = PBXFileReference; lastKnownFileType = net.daringfireball.markdown; name = README_fr.md; path = Translations/README_fr.md; sourceTree = ""; };
+ F556F51826CD1BFF00A80B83 /* README_es.md */ = {isa = PBXFileReference; lastKnownFileType = net.daringfireball.markdown; name = README_es.md; path = Translations/README_es.md; sourceTree = ""; };
+ F556F51926CD1BFF00A80B83 /* README_pt-br.md */ = {isa = PBXFileReference; lastKnownFileType = net.daringfireball.markdown; name = "README_pt-br.md"; path = "Translations/README_pt-br.md"; sourceTree = ""; };
+ F556F51A26CD1C1200A80B83 /* CHANGELOG.md */ = {isa = PBXFileReference; lastKnownFileType = net.daringfireball.markdown; path = CHANGELOG.md; sourceTree = ""; };
+ F556F51B26CD1C1200A80B83 /* CODE_OF_CONDUCT.md */ = {isa = PBXFileReference; lastKnownFileType = net.daringfireball.markdown; path = CODE_OF_CONDUCT.md; sourceTree = ""; };
+ F556F51C26CD1C1200A80B83 /* CONTRIBUTING.md */ = {isa = PBXFileReference; lastKnownFileType = net.daringfireball.markdown; path = CONTRIBUTING.md; sourceTree = ""; };
+ F556F51E26CD1C1C00A80B83 /* FUNDING.yml */ = {isa = PBXFileReference; lastKnownFileType = text.yaml; path = FUNDING.yml; sourceTree = ""; };
+ F556F52026CD1C1C00A80B83 /* release.yml */ = {isa = PBXFileReference; lastKnownFileType = text.yaml; path = release.yml; sourceTree = ""; };
+ F556F52126CD1C1C00A80B83 /* CD.yml */ = {isa = PBXFileReference; lastKnownFileType = text.yaml; path = CD.yml; sourceTree = ""; };
+ F556F52226CD1C1C00A80B83 /* validations.yml */ = {isa = PBXFileReference; lastKnownFileType = text.yaml; path = validations.yml; sourceTree = ""; };
+ F556F52326CD1C1C00A80B83 /* pod_lib_lint.yml */ = {isa = PBXFileReference; lastKnownFileType = text.yaml; path = pod_lib_lint.yml; sourceTree = ""; };
+ F556F52426CD1C1C00A80B83 /* main.yml */ = {isa = PBXFileReference; lastKnownFileType = text.yaml; path = main.yml; sourceTree = ""; };
+ F556F52526CD1C1C00A80B83 /* release_notes.yml */ = {isa = PBXFileReference; lastKnownFileType = text.yaml; path = release_notes.yml; sourceTree = ""; };
+ F556F52626CD1C1C00A80B83 /* stale.yml */ = {isa = PBXFileReference; lastKnownFileType = text.yaml; path = stale.yml; sourceTree = ""; };
+ F556F52726CD1C1C00A80B83 /* pull_request_template.md */ = {isa = PBXFileReference; lastKnownFileType = net.daringfireball.markdown; path = pull_request_template.md; sourceTree = ""; };
+ F556F52826CD1C1C00A80B83 /* release-drafter.yml */ = {isa = PBXFileReference; lastKnownFileType = text.yaml; path = "release-drafter.yml"; sourceTree = ""; };
+ F556F52A26CD1C1C00A80B83 /* submit-a-request.md */ = {isa = PBXFileReference; lastKnownFileType = net.daringfireball.markdown; path = "submit-a-request.md"; sourceTree = ""; };
+ F556F52B26CD1C1C00A80B83 /* bug_report.md */ = {isa = PBXFileReference; lastKnownFileType = net.daringfireball.markdown; path = bug_report.md; sourceTree = ""; };
+ F556F52C26CD1C1C00A80B83 /* feedback.md */ = {isa = PBXFileReference; lastKnownFileType = net.daringfireball.markdown; path = feedback.md; sourceTree = ""; };
+ F556F56226CD1D8500A80B83 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; };
+ F556F56326CD1D8B00A80B83 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; };
+ F556F59426CD1F3900A80B83 /* SkeletonView.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = SkeletonView.framework; sourceTree = BUILT_PRODUCTS_DIR; };
+ F556F64C26CD2CF700A80B83 /* SkeletonDebug.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SkeletonDebug.swift; sourceTree = ""; };
+ F556F64F26CD2DFD00A80B83 /* SkeletonView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SkeletonView.swift; sourceTree = ""; };
+ F556F65C26CD3E3600A80B83 /* SkeletonDebugTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SkeletonDebugTests.swift; sourceTree = ""; };
+ F556F67126CD458500A80B83 /* SkeletonView tvOS Tests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = "SkeletonView tvOS Tests.xctest"; sourceTree = BUILT_PRODUCTS_DIR; };
+ F556F67F26CD47CF00A80B83 /* ProcessInfo+Extensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "ProcessInfo+Extensions.swift"; sourceTree = ""; };
+ F556F68226CD48F700A80B83 /* UIView+AssociatedObjects.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UIView+AssociatedObjects.swift"; sourceTree = ""; };
+ F556F68626CD49F900A80B83 /* UIView+IBInspectable.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UIView+IBInspectable.swift"; sourceTree = ""; };
+ F556F68926CD4D6100A80B83 /* Notification+Extensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Notification+Extensions.swift"; sourceTree = ""; };
+ F556F69126CD506C00A80B83 /* Deprecated.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Deprecated.swift; sourceTree = ""; };
+ F556F69426CD509E00A80B83 /* Notification+SkeletonFlow.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Notification+SkeletonFlow.swift"; sourceTree = ""; };
+ F556F69D26CD553B00A80B83 /* UIView+Extensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UIView+Extensions.swift"; sourceTree = ""; };
+ F556F6A026CD566C00A80B83 /* UIView+Debug.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UIView+Debug.swift"; sourceTree = ""; };
+ F556F6A326CD5A9000A80B83 /* CALayer+Animations.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "CALayer+Animations.swift"; sourceTree = ""; };
+ F556F6A626CD5B0400A80B83 /* CALayer+Extensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "CALayer+Extensions.swift"; sourceTree = ""; };
+ F556F6AA26CD5C4900A80B83 /* SkeletonMultilinesLayerConfig.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SkeletonMultilinesLayerConfig.swift; sourceTree = ""; };
+ F556F6AE26CE244100A80B83 /* DispatchQueue+Extensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "DispatchQueue+Extensions.swift"; sourceTree = ""; };
+ F556F6B426CE258300A80B83 /* GradientDirection+Animations.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "GradientDirection+Animations.swift"; sourceTree = ""; };
+ F556F6B826CE262700A80B83 /* GradientDirection.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GradientDirection.swift; sourceTree = ""; };
+ F556F6BB26CE272600A80B83 /* UILabel+Extensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UILabel+Extensions.swift"; sourceTree = ""; };
+ F556F6BE26CE277F00A80B83 /* PrepareViewForSkeleton.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PrepareViewForSkeleton.swift; sourceTree = ""; };
+ F556F6C126CE27FD00A80B83 /* SkeletonType.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SkeletonType.swift; sourceTree = ""; };
+ F556F6C526CE2A2100A80B83 /* UILabel+IBInspectable.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UILabel+IBInspectable.swift"; sourceTree = ""; };
+ F556F6C826CE2A4A00A80B83 /* UITextView+IBInspectable.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UITextView+IBInspectable.swift"; sourceTree = ""; };
+ F556F6CB26CE2A7400A80B83 /* UITextView+Extensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UITextView+Extensions.swift"; sourceTree = ""; };
+ F556F6CE26CE2AB800A80B83 /* SkeletonTextNode.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SkeletonTextNode.swift; sourceTree = ""; };
+ F556F6D826CE315A00A80B83 /* UICollectionView+Extensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UICollectionView+Extensions.swift"; sourceTree = ""; };
+ F556F6DC26CE33CE00A80B83 /* UIView+Swizzling.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UIView+Swizzling.swift"; sourceTree = ""; };
+ F556F6DF26CE367600A80B83 /* UIView+SkeletonView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UIView+SkeletonView.swift"; sourceTree = ""; };
+ F556F6F126CE818B00A80B83 /* UIView+Flags.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UIView+Flags.swift"; sourceTree = ""; };
+ OBJ_11 /* SkeletonLayerBuilder.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SkeletonLayerBuilder.swift; sourceTree = ""; };
+ OBJ_12 /* SkeletonMultilineLayerBuilder.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SkeletonMultilineLayerBuilder.swift; sourceTree = ""; };
+ OBJ_14 /* CollectionSkeleton.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CollectionSkeleton.swift; sourceTree = ""; };
+ OBJ_16 /* SkeletonCollectionViewProtocols.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SkeletonCollectionViewProtocols.swift; sourceTree = ""; };
+ OBJ_17 /* UICollectionView+CollectionSkeleton.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UICollectionView+CollectionSkeleton.swift"; sourceTree = ""; };
+ OBJ_20 /* SkeletonReusableCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SkeletonReusableCell.swift; sourceTree = ""; };
+ OBJ_21 /* SkeletonCollectionDataSource.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SkeletonCollectionDataSource.swift; sourceTree = ""; };
+ OBJ_22 /* SkeletonCollectionDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SkeletonCollectionDelegate.swift; sourceTree = ""; };
+ OBJ_24 /* SkeletonTableViewProtocols.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SkeletonTableViewProtocols.swift; sourceTree = ""; };
+ OBJ_25 /* UITableView+CollectionSkeleton.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UITableView+CollectionSkeleton.swift"; sourceTree = ""; };
+ OBJ_26 /* UIView+CollectionSkeleton.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UIView+CollectionSkeleton.swift"; sourceTree = ""; };
+ OBJ_31 /* Int+Extensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Int+Extensions.swift"; sourceTree = ""; };
+ OBJ_33 /* UIColor+Skeleton.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UIColor+Skeleton.swift"; sourceTree = ""; };
+ OBJ_34 /* UITableView+Extensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UITableView+Extensions.swift"; sourceTree = ""; };
+ OBJ_39 /* UIView+AppLifecycleNotifications.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UIView+AppLifecycleNotifications.swift"; sourceTree = ""; };
+ OBJ_41 /* AssociationPolicy.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AssociationPolicy.swift; sourceTree = ""; };
+ OBJ_43 /* Recursive.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Recursive.swift; sourceTree = ""; };
+ OBJ_44 /* Swizzling.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Swizzling.swift; sourceTree = ""; };
+ OBJ_50 /* Recoverable.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Recoverable.swift; sourceTree = ""; };
+ OBJ_51 /* RecoverableViewState.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RecoverableViewState.swift; sourceTree = ""; };
+ OBJ_52 /* SkeletonAnimationBuilder.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SkeletonAnimationBuilder.swift; sourceTree = ""; };
+ OBJ_53 /* SkeletonConfig.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SkeletonConfig.swift; sourceTree = ""; };
+ OBJ_54 /* SkeletonFlowHandler.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SkeletonFlowHandler.swift; sourceTree = ""; };
+ OBJ_55 /* SkeletonGradient.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SkeletonGradient.swift; sourceTree = ""; };
+ OBJ_56 /* SkeletonLayer.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SkeletonLayer.swift; sourceTree = ""; };
+ OBJ_58 /* SubviewsSkeletonables.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SubviewsSkeletonables.swift; sourceTree = ""; };
+ OBJ_6 /* Package.swift */ = {isa = PBXFileReference; explicitFileType = sourcecode.swift; path = Package.swift; sourceTree = ""; };
+ OBJ_60 /* SkeletonTransitionStyle.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SkeletonTransitionStyle.swift; sourceTree = ""; };
+ OBJ_61 /* UIView+Transitions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UIView+Transitions.swift"; sourceTree = ""; };
+ OBJ_9 /* SkeletonAppearance.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SkeletonAppearance.swift; sourceTree = ""; };
+ "SkeletonView::SkeletonView::Product" /* SkeletonView.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; path = SkeletonView.framework; sourceTree = BUILT_PRODUCTS_DIR; };
+ "SkeletonView::SkeletonViewTests::Product" /* SkeletonViewTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; path = SkeletonViewTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
- 17DD0DFC207FB27400C56334 /* Frameworks */ = {
+ F556F59026CD1F3900A80B83 /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
- buildActionMask = 2147483647;
+ buildActionMask = 0;
files = (
);
runOnlyForDeploymentPostprocessing = 0;
};
- 42ABD062210B548200BEEFF4 /* Frameworks */ = {
+ F556F66E26CD458500A80B83 /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
- 42ABD063210B548200BEEFF4 /* SkeletonView.framework in Frameworks */,
+ F556F67626CD458500A80B83 /* SkeletonView.framework in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
- 52D6D9781BEFF229002C0205 /* Frameworks */ = {
+ OBJ_128 /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
- buildActionMask = 2147483647;
+ buildActionMask = 0;
files = (
);
runOnlyForDeploymentPostprocessing = 0;
};
- F5F899EF1FABA607002E8FDA /* Frameworks */ = {
+ OBJ_146 /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
- buildActionMask = 2147483647;
+ buildActionMask = 0;
files = (
- F5307E411FB3B84500EE67C5 /* SkeletonView.framework in Frameworks */,
+ OBJ_147 /* SkeletonView.framework in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXFrameworksBuildPhase section */
/* Begin PBXGroup section */
- 52D6D9721BEFF229002C0205 = {
+ F556F50F26CD1B6200A80B83 /* Deployment */ = {
isa = PBXGroup;
children = (
- F5F899F31FABA607002E8FDA /* Example */,
- 8933C7811EB5B7E0000D00A4 /* Sources */,
- 52D6D99C1BEFF38C002C0205 /* Configs */,
- 52D6D97D1BEFF229002C0205 /* Products */,
- F5F89A041FABA614002E8FDA /* Frameworks */,
+ F556F51126CD1B8000A80B83 /* LICENSE */,
+ F556F51026CD1B7900A80B83 /* SkeletonView.podspec */,
+ OBJ_6 /* Package.swift */,
);
+ name = Deployment;
+ sourceTree = "";
+ };
+ F556F51326CD1BED00A80B83 /* Documentation */ = {
+ isa = PBXGroup;
+ children = (
+ F556F51D26CD1C1C00A80B83 /* .github */,
+ F556F51A26CD1C1200A80B83 /* CHANGELOG.md */,
+ F556F51B26CD1C1200A80B83 /* CODE_OF_CONDUCT.md */,
+ F556F51C26CD1C1200A80B83 /* CONTRIBUTING.md */,
+ F556F51826CD1BFF00A80B83 /* README_es.md */,
+ F556F51726CD1BFF00A80B83 /* README_fr.md */,
+ F556F51626CD1BFF00A80B83 /* README_ko.md */,
+ F556F51926CD1BFF00A80B83 /* README_pt-br.md */,
+ F556F51426CD1BFF00A80B83 /* README_zh.md */,
+ F556F51526CD1BFF00A80B83 /* README.md */,
+ );
+ name = Documentation;
sourceTree = "";
};
- 52D6D97D1BEFF229002C0205 /* Products */ = {
+ F556F51D26CD1C1C00A80B83 /* .github */ = {
isa = PBXGroup;
children = (
- 52D6D97C1BEFF229002C0205 /* SkeletonView.framework */,
- F5F899F21FABA607002E8FDA /* SkeletonViewExample.app */,
- 17DD0E00207FB27400C56334 /* SkeletonView.framework */,
- 42ABD06D210B548200BEEFF4 /* SkeletonViewExampleUICollectionView.app */,
+ F556F51E26CD1C1C00A80B83 /* FUNDING.yml */,
+ F556F51F26CD1C1C00A80B83 /* workflows */,
+ F556F52626CD1C1C00A80B83 /* stale.yml */,
+ F556F52726CD1C1C00A80B83 /* pull_request_template.md */,
+ F556F52826CD1C1C00A80B83 /* release-drafter.yml */,
+ F556F52926CD1C1C00A80B83 /* ISSUE_TEMPLATE */,
+ );
+ path = .github;
+ sourceTree = "";
+ };
+ F556F51F26CD1C1C00A80B83 /* workflows */ = {
+ isa = PBXGroup;
+ children = (
+ F556F52026CD1C1C00A80B83 /* release.yml */,
+ F556F52126CD1C1C00A80B83 /* CD.yml */,
+ F556F52226CD1C1C00A80B83 /* validations.yml */,
+ F556F52326CD1C1C00A80B83 /* pod_lib_lint.yml */,
+ F556F52426CD1C1C00A80B83 /* main.yml */,
+ F556F52526CD1C1C00A80B83 /* release_notes.yml */,
+ );
+ path = workflows;
+ sourceTree = "";
+ };
+ F556F52926CD1C1C00A80B83 /* ISSUE_TEMPLATE */ = {
+ isa = PBXGroup;
+ children = (
+ F556F52A26CD1C1C00A80B83 /* submit-a-request.md */,
+ F556F52B26CD1C1C00A80B83 /* bug_report.md */,
+ F556F52C26CD1C1C00A80B83 /* feedback.md */,
);
- name = Products;
+ path = ISSUE_TEMPLATE;
sourceTree = "";
};
- 52D6D99C1BEFF38C002C0205 /* Configs */ = {
+ F556F55F26CD1D4400A80B83 /* Supporting Files */ = {
isa = PBXGroup;
children = (
- F5F89A061FABA725002E8FDA /* Example */,
- DD7502721C68FC1B006590AF /* Frameworks */,
+ F556F56226CD1D8500A80B83 /* Info.plist */,
);
- path = Configs;
+ path = "Supporting Files";
sourceTree = "";
};
- 872D5A5821C17D850037D763 /* CollectionView */ = {
+ F556F56026CD1D5300A80B83 /* Supporting Files */ = {
isa = PBXGroup;
children = (
- 42ABD070210B54E100BEEFF4 /* AppDelegate.swift */,
- 42ABD072210B54E100BEEFF4 /* Assets.xcassets */,
- 42ABD074210B54E100BEEFF4 /* Base.lproj */,
- 42ABD077210B54E200BEEFF4 /* CollectionViewCell.swift */,
- 42ABD071210B54E100BEEFF4 /* Main.storyboard */,
- 42ABD073210B54E100BEEFF4 /* ViewController.swift */,
- );
- path = CollectionView;
+ F556F56326CD1D8B00A80B83 /* Info.plist */,
+ );
+ path = "Supporting Files";
sourceTree = "";
};
- 872D5A5921C17D980037D763 /* TableView */ = {
+ F556F64A26CD2CD100A80B83 /* API */ = {
isa = PBXGroup;
children = (
- F5F899F41FABA607002E8FDA /* AppDelegate.swift */,
- 88DEA97D1FCDBD1F006C80EF /* Constants.swift */,
- F5F899F61FABA607002E8FDA /* ViewController.swift */,
- 5600784623FD2BC300669AD6 /* HeaderFooterSection.swift */,
- F5F622441FACA338007C062A /* Cell.swift */,
- F5F899F81FABA607002E8FDA /* Main.storyboard */,
- F5F899FB1FABA607002E8FDA /* Assets.xcassets */,
- F5F899FD1FABA607002E8FDA /* LaunchScreen.storyboard */,
- );
- path = TableView;
+ F556F6B226CE24DA00A80B83 /* AnimationBuilder */,
+ F556F6DB26CE32DA00A80B83 /* Appearance */,
+ F556F6D726CE30EE00A80B83 /* Collections */,
+ F556F69126CD506C00A80B83 /* Deprecated.swift */,
+ F556F68C26CD4EB400A80B83 /* FoundationExtensions */,
+ F556F6B726CE25B100A80B83 /* Models */,
+ F556F64F26CD2DFD00A80B83 /* SkeletonView.swift */,
+ F556F68526CD49E900A80B83 /* UIKitExtensions */,
+ );
+ path = API;
sourceTree = "";
};
- 872D5A5A21C24E7C0037D763 /* Multilines */ = {
+ F556F64B26CD2CD600A80B83 /* Internal */ = {
isa = PBXGroup;
children = (
- F5307E3A1FB123C100EE67C5 /* ContainsMultilineText.swift */,
- 872D5A5B21C24EDD0037D763 /* UILabel+Multiline.swift */,
- 872D5A5E21C24F8E0037D763 /* UITextView+Multiline.swift */,
+ F556F6D326CE2F3700A80B83 /* Collections */,
+ F556F65226CD2E0A00A80B83 /* Debug */,
+ F556F67E26CD476300A80B83 /* FoundationExtensions */,
+ F556F6AD26CE241D00A80B83 /* Helpers */,
+ F556F6C426CE284300A80B83 /* Models */,
+ F556F6A926CD5C3E00A80B83 /* SkeletonConfigs */,
+ F556F6B326CE256D00A80B83 /* SkeletonExtensions */,
+ OBJ_54 /* SkeletonFlowHandler.swift */,
+ F556F6B126CE246E00A80B83 /* SkeletonLayerBuilders */,
+ F556F67D26CD475800A80B83 /* UIKitExtensions */,
+ );
+ path = Internal;
+ sourceTree = "";
+ };
+ F556F65226CD2E0A00A80B83 /* Debug */ = {
+ isa = PBXGroup;
+ children = (
+ F556F64C26CD2CF700A80B83 /* SkeletonDebug.swift */,
);
- path = Multilines;
+ path = Debug;
sourceTree = "";
};
- 877EFA4321BEE9C40031FC00 /* Builders */ = {
+ F556F65B26CD3E1400A80B83 /* Debug */ = {
isa = PBXGroup;
children = (
- 877EFA4421BEE9D80031FC00 /* SkeletonLayerBuilder.swift */,
- 877EFA4721BEED760031FC00 /* SkeletonMultilineLayerBuilder.swift */,
+ F556F65C26CD3E3600A80B83 /* SkeletonDebugTests.swift */,
);
- path = Builders;
+ path = Debug;
sourceTree = "";
};
- 8785E39E211C9C6D00CC9DFD /* Appearance */ = {
+ F556F67D26CD475800A80B83 /* UIKitExtensions */ = {
isa = PBXGroup;
children = (
- F5307E2F1FB0EC9D00EE67C5 /* SkeletonAppearance.swift */,
+ F556F6A626CD5B0400A80B83 /* CALayer+Extensions.swift */,
+ OBJ_17 /* UICollectionView+CollectionSkeleton.swift */,
+ OBJ_33 /* UIColor+Skeleton.swift */,
+ F556F6BB26CE272600A80B83 /* UILabel+Extensions.swift */,
+ OBJ_25 /* UITableView+CollectionSkeleton.swift */,
+ OBJ_34 /* UITableView+Extensions.swift */,
+ F556F6CB26CE2A7400A80B83 /* UITextView+Extensions.swift */,
+ OBJ_39 /* UIView+AppLifecycleNotifications.swift */,
+ F556F68226CD48F700A80B83 /* UIView+AssociatedObjects.swift */,
+ OBJ_26 /* UIView+CollectionSkeleton.swift */,
+ F556F69D26CD553B00A80B83 /* UIView+Extensions.swift */,
+ F556F6DF26CE367600A80B83 /* UIView+SkeletonView.swift */,
+ F556F6DC26CE33CE00A80B83 /* UIView+Swizzling.swift */,
+ OBJ_61 /* UIView+Transitions.swift */,
+ );
+ path = UIKitExtensions;
+ sourceTree = "";
+ };
+ F556F67E26CD476300A80B83 /* FoundationExtensions */ = {
+ isa = PBXGroup;
+ children = (
+ OBJ_31 /* Int+Extensions.swift */,
+ F556F67F26CD47CF00A80B83 /* ProcessInfo+Extensions.swift */,
+ F556F68926CD4D6100A80B83 /* Notification+Extensions.swift */,
+ F556F6AE26CE244100A80B83 /* DispatchQueue+Extensions.swift */,
);
- path = Appearance;
+ path = FoundationExtensions;
sourceTree = "";
};
- 8785E39F211C9C7C00CC9DFD /* Debug */ = {
+ F556F68526CD49E900A80B83 /* UIKitExtensions */ = {
isa = PBXGroup;
children = (
- 8785E3A0211C9C9800CC9DFD /* SkeletonDebug.swift */,
+ F556F6A326CD5A9000A80B83 /* CALayer+Animations.swift */,
+ F556F68626CD49F900A80B83 /* UIView+IBInspectable.swift */,
+ F556F6A026CD566C00A80B83 /* UIView+Debug.swift */,
+ F556F6C526CE2A2100A80B83 /* UILabel+IBInspectable.swift */,
+ F556F6C826CE2A4A00A80B83 /* UITextView+IBInspectable.swift */,
+ F556F6D826CE315A00A80B83 /* UICollectionView+Extensions.swift */,
+ F556F6F126CE818B00A80B83 /* UIView+Flags.swift */,
+ );
+ path = UIKitExtensions;
+ sourceTree = "";
+ };
+ F556F68C26CD4EB400A80B83 /* FoundationExtensions */ = {
+ isa = PBXGroup;
+ children = (
+ F556F69426CD509E00A80B83 /* Notification+SkeletonFlow.swift */,
);
- path = Debug;
+ path = FoundationExtensions;
sourceTree = "";
};
- 8933C7811EB5B7E0000D00A4 /* Sources */ = {
+ F556F6A926CD5C3E00A80B83 /* SkeletonConfigs */ = {
isa = PBXGroup;
children = (
- E4CE587A22EEE62300333067 /* Transitions */,
- 872D5A5A21C24E7C0037D763 /* Multilines */,
- 877EFA4321BEE9C40031FC00 /* Builders */,
- 8785E39F211C9C7C00CC9DFD /* Debug */,
- 8785E39E211C9C6D00CC9DFD /* Appearance */,
- F58A6E7020A8C87100612494 /* Recoverable */,
- F5307E331FB1068500EE67C5 /* Collections */,
- F5307E341FB106A500EE67C5 /* Extensions */,
- F5307E351FB106BF00EE67C5 /* Helpers */,
- F51DE1081FBF70A70037919A /* SkeletonAnimationBuilder.swift */,
- F587FB83202CBFC8002DB5FE /* SkeletonFlow.swift */,
- F5307E2B1FAF6BC900EE67C5 /* SkeletonGradient.swift */,
- F5F899E81FAB9D2B002E8FDA /* SkeletonLayer.swift */,
- 8933C7841EB5B820000D00A4 /* SkeletonView.swift */,
- F5D3FB0A209DCAA300003FCF /* SubviewsSkeletonables.swift */,
- 870F4E4221CAC07300B9233B /* SkeletonConfig.swift */,
- );
- path = Sources;
+ OBJ_53 /* SkeletonConfig.swift */,
+ F556F6AA26CD5C4900A80B83 /* SkeletonMultilinesLayerConfig.swift */,
+ );
+ path = SkeletonConfigs;
sourceTree = "";
};
- DD7502721C68FC1B006590AF /* Frameworks */ = {
+ F556F6AD26CE241D00A80B83 /* Helpers */ = {
isa = PBXGroup;
children = (
- 17DD0E1B207FB2C200C56334 /* SkeletonView-iOS.plist */,
- 17DD0E1A207FB2C200C56334 /* SkeletonView-tvOS.plist */,
+ OBJ_43 /* Recursive.swift */,
+ OBJ_41 /* AssociationPolicy.swift */,
+ OBJ_44 /* Swizzling.swift */,
);
- name = Frameworks;
+ path = Helpers;
sourceTree = "";
};
- E4CE587A22EEE62300333067 /* Transitions */ = {
+ F556F6B126CE246E00A80B83 /* SkeletonLayerBuilders */ = {
isa = PBXGroup;
children = (
- E4CE587B22EEE63100333067 /* UIView+Transitions.swift */,
- E4CE587C22EEE65200333067 /* SkeletonTransitionStyle.swift */,
+ OBJ_12 /* SkeletonMultilineLayerBuilder.swift */,
+ OBJ_11 /* SkeletonLayerBuilder.swift */,
);
- path = Transitions;
+ path = SkeletonLayerBuilders;
sourceTree = "";
};
- F51DF874206E94D300D23301 /* CollectionViews */ = {
+ F556F6B226CE24DA00A80B83 /* AnimationBuilder */ = {
isa = PBXGroup;
children = (
- F54CF5E32024CEB000330B0D /* UICollectionView+CollectionSkeleton.swift */,
- F5307E381FB1078E00EE67C5 /* SkeletonCollectionViewProtocols.swift */,
+ OBJ_52 /* SkeletonAnimationBuilder.swift */,
);
- path = CollectionViews;
+ path = AnimationBuilder;
sourceTree = "";
};
- F51DF875206E94DA00D23301 /* TableViews */ = {
+ F556F6B326CE256D00A80B83 /* SkeletonExtensions */ = {
isa = PBXGroup;
children = (
- F54CF5E22024CEAF00330B0D /* UITableView+CollectionSkeleton.swift */,
- F5307E361FB1076E00EE67C5 /* SkeletonTableViewProtocols.swift */,
+ OBJ_58 /* SubviewsSkeletonables.swift */,
+ F556F6BE26CE277F00A80B83 /* PrepareViewForSkeleton.swift */,
+ F556F6CE26CE2AB800A80B83 /* SkeletonTextNode.swift */,
+ OBJ_50 /* Recoverable.swift */,
+ F556F6B426CE258300A80B83 /* GradientDirection+Animations.swift */,
);
- path = TableViews;
+ path = SkeletonExtensions;
sourceTree = "";
};
- F51DF877206E950000D23301 /* Generics */ = {
+ F556F6B726CE25B100A80B83 /* Models */ = {
isa = PBXGroup;
children = (
- F51DF872206E91FB00D23301 /* GenericCollectionView.swift */,
- F51DF870206E91B300D23301 /* SkeletonReusableCell.swift */,
+ OBJ_60 /* SkeletonTransitionStyle.swift */,
+ OBJ_55 /* SkeletonGradient.swift */,
+ F556F6B826CE262700A80B83 /* GradientDirection.swift */,
+ F556F6C126CE27FD00A80B83 /* SkeletonType.swift */,
);
- path = Generics;
+ path = Models;
sourceTree = "";
};
- F5307E331FB1068500EE67C5 /* Collections */ = {
+ F556F6C426CE284300A80B83 /* Models */ = {
isa = PBXGroup;
children = (
- F51DF877206E950000D23301 /* Generics */,
- F51DF875206E94DA00D23301 /* TableViews */,
- F51DF874206E94D300D23301 /* CollectionViews */,
- F5F899EC1FAB9F04002E8FDA /* CollectionSkeletonProtocol.swift */,
- F5F899EA1FAB9DA3002E8FDA /* SkeletonCollectionDataSource.swift */,
- F51DF878206E9F5500D23301 /* SkeletonCollectionDelegate.swift */,
- F54CF5E12024CEAF00330B0D /* UIView+CollectionSkeleton.swift */,
+ OBJ_56 /* SkeletonLayer.swift */,
+ OBJ_51 /* RecoverableViewState.swift */,
);
- path = Collections;
+ path = Models;
sourceTree = "";
};
- F5307E341FB106A500EE67C5 /* Extensions */ = {
+ F556F6D326CE2F3700A80B83 /* Collections */ = {
isa = PBXGroup;
children = (
- F5F622421FAC81FD007C062A /* CALayer+Extensions.swift */,
- F5A5E8B3211DCE7000FD20D0 /* Int+Whitespaces.swift */,
- F5F622401FAC6E31007C062A /* UIColor+Skeleton.swift */,
- 872D5A5521C177E20037D763 /* UIView+Extension.swift */,
- F5307E2D1FB0E5E400EE67C5 /* UIView+Frame.swift */,
- F5804771230ECD0000066D02 /* UIView+IBInspectable.swift */,
- F587FB85202CEC95002DB5FE /* UIView+UIApplicationDelegate.swift */,
- 1E291F3D2540655D0018D602 /* UIView+Autolayout.swift */,
- 5600784323FD293D00669AD6 /* UITableView+VisibleSections.swift */,
- 1EE42E1E23FF25CC00BF665A /* ProcessInfo+XCTest.swift */,
- );
- path = Extensions;
+ OBJ_21 /* SkeletonCollectionDataSource.swift */,
+ OBJ_22 /* SkeletonCollectionDelegate.swift */,
+ OBJ_20 /* SkeletonReusableCell.swift */,
+ OBJ_14 /* CollectionSkeleton.swift */,
+ );
+ path = Collections;
sourceTree = "";
};
- F5307E351FB106BF00EE67C5 /* Helpers */ = {
+ F556F6D726CE30EE00A80B83 /* Collections */ = {
isa = PBXGroup;
children = (
- F5F899D11FAB9630002E8FDA /* AssociationPolicy.swift */,
- F56B94451FAE20AF0095662F /* PrepareForSkeletonProtocol.swift */,
- F5307E311FB0F42F00EE67C5 /* RecursiveProtocol.swift */,
- F570ABF32314629700390248 /* Swizzling.swift */,
+ OBJ_23 /* TableViews */,
+ OBJ_15 /* CollectionViews */,
);
- path = Helpers;
+ path = Collections;
sourceTree = "";
};
- F58A6E7020A8C87100612494 /* Recoverable */ = {
+ F556F6DB26CE32DA00A80B83 /* Appearance */ = {
isa = PBXGroup;
children = (
- F58A6E6A20A8C54100612494 /* RecoverableViewState.swift */,
- F58A6E6D20A8C66300612494 /* Recoverable.swift */,
+ OBJ_9 /* SkeletonAppearance.swift */,
);
- path = Recoverable;
+ path = Appearance;
sourceTree = "";
};
- F5F899F31FABA607002E8FDA /* Example */ = {
+ OBJ_15 /* CollectionViews */ = {
isa = PBXGroup;
children = (
- 872D5A5921C17D980037D763 /* TableView */,
- 872D5A5821C17D850037D763 /* CollectionView */,
+ OBJ_16 /* SkeletonCollectionViewProtocols.swift */,
);
- path = Example;
+ path = CollectionViews;
sourceTree = "";
};
- F5F89A041FABA614002E8FDA /* Frameworks */ = {
+ OBJ_23 /* TableViews */ = {
isa = PBXGroup;
children = (
+ OBJ_24 /* SkeletonTableViewProtocols.swift */,
);
- name = Frameworks;
+ path = TableViews;
sourceTree = "";
};
- F5F89A061FABA725002E8FDA /* Example */ = {
+ OBJ_5 = {
isa = PBXGroup;
children = (
- 42ABD076210B54E200BEEFF4 /* SkeletonViewExampleCollectionview-Info.plist */,
- F5F89A001FABA607002E8FDA /* SkeletonViewExampleInfo.plist */,
+ F556F51326CD1BED00A80B83 /* Documentation */,
+ F556F50F26CD1B6200A80B83 /* Deployment */,
+ OBJ_7 /* Sources */,
+ OBJ_62 /* Tests */,
+ OBJ_64 /* Products */,
);
- name = Example;
sourceTree = "";
};
-/* End PBXGroup section */
-
-/* Begin PBXHeadersBuildPhase section */
- 17DD0DFD207FB27400C56334 /* Headers */ = {
- isa = PBXHeadersBuildPhase;
- buildActionMask = 2147483647;
- files = (
- 8748240E20C6A88E00E92179 /* ContainsMultilineText.swift in Headers */,
+ OBJ_62 /* Tests */ = {
+ isa = PBXGroup;
+ children = (
+ F556F65B26CD3E1400A80B83 /* Debug */,
+ F556F56026CD1D5300A80B83 /* Supporting Files */,
);
- runOnlyForDeploymentPostprocessing = 0;
+ name = Tests;
+ path = SkeletonViewCore/Tests;
+ sourceTree = SOURCE_ROOT;
};
- 52D6D9791BEFF229002C0205 /* Headers */ = {
- isa = PBXHeadersBuildPhase;
- buildActionMask = 2147483647;
- files = (
- 3467F5612473602D0086C027 /* UILabel+Multiline.swift in Headers */,
- 3467F55F2473601F0086C027 /* UITextView+Multiline.swift in Headers */,
- 3467F560247360270086C027 /* UIView+IBInspectable.swift in Headers */,
+ OBJ_64 /* Products */ = {
+ isa = PBXGroup;
+ children = (
+ "SkeletonView::SkeletonView::Product" /* SkeletonView.framework */,
+ "SkeletonView::SkeletonViewTests::Product" /* SkeletonViewTests.xctest */,
+ F556F59426CD1F3900A80B83 /* SkeletonView.framework */,
+ F556F67126CD458500A80B83 /* SkeletonView tvOS Tests.xctest */,
);
- runOnlyForDeploymentPostprocessing = 0;
+ name = Products;
+ sourceTree = BUILT_PRODUCTS_DIR;
};
-/* End PBXHeadersBuildPhase section */
+ OBJ_7 /* Sources */ = {
+ isa = PBXGroup;
+ children = (
+ F556F64A26CD2CD100A80B83 /* API */,
+ F556F64B26CD2CD600A80B83 /* Internal */,
+ F556F55F26CD1D4400A80B83 /* Supporting Files */,
+ );
+ name = Sources;
+ path = SkeletonViewCore/Sources;
+ sourceTree = SOURCE_ROOT;
+ };
+/* End PBXGroup section */
/* Begin PBXNativeTarget section */
- 17DD0DFF207FB27400C56334 /* SkeletonView-tvOS */ = {
+ F556F56426CD1F3900A80B83 /* SkeletonView tvOS */ = {
isa = PBXNativeTarget;
- buildConfigurationList = 17DD0E07207FB27400C56334 /* Build configuration list for PBXNativeTarget "SkeletonView-tvOS" */;
+ buildConfigurationList = F556F59126CD1F3900A80B83 /* Build configuration list for PBXNativeTarget "SkeletonView tvOS" */;
buildPhases = (
- 17DD0DFB207FB27400C56334 /* Sources */,
- 17DD0DFC207FB27400C56334 /* Frameworks */,
- 17DD0DFD207FB27400C56334 /* Headers */,
- 17DD0DFE207FB27400C56334 /* Resources */,
- 1E3CFFD5250AD9A400DDB852 /* SwiftLint */,
+ F556F65626CD312100A80B83 /* Swiftlint */,
+ F556F56526CD1F3900A80B83 /* Sources */,
+ F556F59026CD1F3900A80B83 /* Frameworks */,
);
buildRules = (
);
dependencies = (
);
- name = "SkeletonView-tvOS";
- productName = "SkeletonView-tvOS";
- productReference = 17DD0E00207FB27400C56334 /* SkeletonView.framework */;
+ name = "SkeletonView tvOS";
+ productName = SkeletonView;
+ productReference = F556F59426CD1F3900A80B83 /* SkeletonView.framework */;
productType = "com.apple.product-type.framework";
};
- 42ABD05A210B548200BEEFF4 /* SkeletonViewExampleUICollectionView */ = {
+ F556F67026CD458500A80B83 /* SkeletonView tvOS Tests */ = {
isa = PBXNativeTarget;
- buildConfigurationList = 42ABD06A210B548200BEEFF4 /* Build configuration list for PBXNativeTarget "SkeletonViewExampleUICollectionView" */;
+ buildConfigurationList = F556F67926CD458500A80B83 /* Build configuration list for PBXNativeTarget "SkeletonView tvOS Tests" */;
buildPhases = (
- 42ABD05D210B548200BEEFF4 /* Sources */,
- 42ABD062210B548200BEEFF4 /* Frameworks */,
- 42ABD064210B548200BEEFF4 /* Resources */,
- 42ABD068210B548200BEEFF4 /* Embed Frameworks */,
+ F556F66D26CD458500A80B83 /* Sources */,
+ F556F66E26CD458500A80B83 /* Frameworks */,
+ F556F66F26CD458500A80B83 /* Resources */,
);
buildRules = (
);
dependencies = (
- 42ABD05B210B548200BEEFF4 /* PBXTargetDependency */,
+ F556F67826CD458500A80B83 /* PBXTargetDependency */,
);
- name = SkeletonViewExampleUICollectionView;
- productName = SkeletonViewExample;
- productReference = 42ABD06D210B548200BEEFF4 /* SkeletonViewExampleUICollectionView.app */;
- productType = "com.apple.product-type.application";
+ name = "SkeletonView tvOS Tests";
+ productName = "SkeletonView tvOS Tests";
+ productReference = F556F67126CD458500A80B83 /* SkeletonView tvOS Tests.xctest */;
+ productType = "com.apple.product-type.bundle.unit-test";
};
- 52D6D97B1BEFF229002C0205 /* SkeletonView-iOS */ = {
+ "SkeletonView::SkeletonView" /* SkeletonView iOS */ = {
isa = PBXNativeTarget;
- buildConfigurationList = 52D6D9901BEFF229002C0205 /* Build configuration list for PBXNativeTarget "SkeletonView-iOS" */;
+ buildConfigurationList = OBJ_82 /* Build configuration list for PBXNativeTarget "SkeletonView iOS" */;
buildPhases = (
- 52D6D9771BEFF229002C0205 /* Sources */,
- 52D6D9781BEFF229002C0205 /* Frameworks */,
- 52D6D9791BEFF229002C0205 /* Headers */,
- 52D6D97A1BEFF229002C0205 /* Resources */,
- 1E3CFFD3250AD95300DDB852 /* SwiftLint */,
+ F556F65526CD311200A80B83 /* Swiftlint */,
+ OBJ_85 /* Sources */,
+ OBJ_128 /* Frameworks */,
);
buildRules = (
);
dependencies = (
);
- name = "SkeletonView-iOS";
+ name = "SkeletonView iOS";
productName = SkeletonView;
- productReference = 52D6D97C1BEFF229002C0205 /* SkeletonView.framework */;
+ productReference = "SkeletonView::SkeletonView::Product" /* SkeletonView.framework */;
productType = "com.apple.product-type.framework";
};
- F5F899F11FABA607002E8FDA /* SkeletonViewExample */ = {
+ "SkeletonView::SkeletonViewTests" /* SkeletonView iOS Tests */ = {
isa = PBXNativeTarget;
- buildConfigurationList = F5F89A011FABA607002E8FDA /* Build configuration list for PBXNativeTarget "SkeletonViewExample" */;
+ buildConfigurationList = OBJ_141 /* Build configuration list for PBXNativeTarget "SkeletonView iOS Tests" */;
buildPhases = (
- F5F899EE1FABA607002E8FDA /* Sources */,
- F5F899EF1FABA607002E8FDA /* Frameworks */,
- F5F899F01FABA607002E8FDA /* Resources */,
- F5307E451FB3B84600EE67C5 /* Embed Frameworks */,
+ OBJ_144 /* Sources */,
+ OBJ_146 /* Frameworks */,
);
buildRules = (
);
dependencies = (
- F5307E441FB3B84500EE67C5 /* PBXTargetDependency */,
+ OBJ_148 /* PBXTargetDependency */,
);
- name = SkeletonViewExample;
- productName = SkeletonViewExample;
- productReference = F5F899F21FABA607002E8FDA /* SkeletonViewExample.app */;
- productType = "com.apple.product-type.application";
+ name = "SkeletonView iOS Tests";
+ productName = SkeletonViewTests;
+ productReference = "SkeletonView::SkeletonViewTests::Product" /* SkeletonViewTests.xctest */;
+ productType = "com.apple.product-type.bundle.unit-test";
};
/* End PBXNativeTarget section */
/* Begin PBXProject section */
- 52D6D9731BEFF229002C0205 /* Project object */ = {
+ OBJ_1 /* Project object */ = {
isa = PBXProject;
attributes = {
- LastSwiftUpdateCheck = 0910;
- LastUpgradeCheck = 1020;
- ORGANIZATIONNAME = SkeletonView;
+ LastSwiftMigration = 9999;
+ LastSwiftUpdateCheck = 1250;
+ LastUpgradeCheck = 9999;
TargetAttributes = {
- 17DD0DFF207FB27400C56334 = {
- CreatedOnToolsVersion = 9.3;
- ProvisioningStyle = Automatic;
- };
- 42ABD05A210B548200BEEFF4 = {
- LastSwiftMigration = 0940;
- ProvisioningStyle = Automatic;
- };
- 52D6D97B1BEFF229002C0205 = {
- CreatedOnToolsVersion = 7.1;
- LastSwiftMigration = 1000;
- ProvisioningStyle = Automatic;
- };
- F5F899F11FABA607002E8FDA = {
- CreatedOnToolsVersion = 9.1;
- LastSwiftMigration = 1000;
- ProvisioningStyle = Automatic;
+ F556F67026CD458500A80B83 = {
+ CreatedOnToolsVersion = 12.5.1;
};
};
};
- buildConfigurationList = 52D6D9761BEFF229002C0205 /* Build configuration list for PBXProject "SkeletonView" */;
- compatibilityVersion = "Xcode 6.3";
+ buildConfigurationList = OBJ_2 /* Build configuration list for PBXProject "SkeletonView" */;
+ compatibilityVersion = "Xcode 3.2";
developmentRegion = en;
hasScannedForEncodings = 0;
knownRegions = (
en,
- Base,
);
- mainGroup = 52D6D9721BEFF229002C0205;
- productRefGroup = 52D6D97D1BEFF229002C0205 /* Products */;
+ mainGroup = OBJ_5;
+ productRefGroup = OBJ_64 /* Products */;
projectDirPath = "";
projectRoot = "";
targets = (
- 52D6D97B1BEFF229002C0205 /* SkeletonView-iOS */,
- 17DD0DFF207FB27400C56334 /* SkeletonView-tvOS */,
- F5F899F11FABA607002E8FDA /* SkeletonViewExample */,
- 42ABD05A210B548200BEEFF4 /* SkeletonViewExampleUICollectionView */,
+ "SkeletonView::SkeletonView" /* SkeletonView iOS */,
+ "SkeletonView::SkeletonViewTests" /* SkeletonView iOS Tests */,
+ F556F56426CD1F3900A80B83 /* SkeletonView tvOS */,
+ F556F67026CD458500A80B83 /* SkeletonView tvOS Tests */,
);
};
/* End PBXProject section */
/* Begin PBXResourcesBuildPhase section */
- 17DD0DFE207FB27400C56334 /* Resources */ = {
+ F556F66F26CD458500A80B83 /* Resources */ = {
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
files = (
);
runOnlyForDeploymentPostprocessing = 0;
};
- 42ABD064210B548200BEEFF4 /* Resources */ = {
- isa = PBXResourcesBuildPhase;
- buildActionMask = 2147483647;
- files = (
- 42ABD07A210B54E200BEEFF4 /* Assets.xcassets in Resources */,
- 42ABD07C210B54E200BEEFF4 /* Base.lproj in Resources */,
- 42ABD079210B54E200BEEFF4 /* Main.storyboard in Resources */,
- );
- runOnlyForDeploymentPostprocessing = 0;
- };
- 52D6D97A1BEFF229002C0205 /* Resources */ = {
- isa = PBXResourcesBuildPhase;
- buildActionMask = 2147483647;
- files = (
- );
- runOnlyForDeploymentPostprocessing = 0;
- };
- F5F899F01FABA607002E8FDA /* Resources */ = {
- isa = PBXResourcesBuildPhase;
- buildActionMask = 2147483647;
- files = (
- F5F899FF1FABA607002E8FDA /* LaunchScreen.storyboard in Resources */,
- F5F899FC1FABA607002E8FDA /* Assets.xcassets in Resources */,
- F5F899FA1FABA607002E8FDA /* Main.storyboard in Resources */,
- );
- runOnlyForDeploymentPostprocessing = 0;
- };
/* End PBXResourcesBuildPhase section */
/* Begin PBXShellScriptBuildPhase section */
- 1E3CFFD3250AD95300DDB852 /* SwiftLint */ = {
+ F556F65526CD311200A80B83 /* Swiftlint */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
@@ -696,16 +730,16 @@
);
inputPaths = (
);
- name = SwiftLint;
+ name = Swiftlint;
outputFileListPaths = (
);
outputPaths = (
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
- shellScript = "if which swiftlint >/dev/null; then\n swiftlint\nelse\n echo \"warning: SwiftLint not installed, download from https://github.com/realm/SwiftLint\"\nfi\n";
+ shellScript = "if test -d \"/opt/homebrew/bin/\"; then\n PATH=\"/opt/homebrew/bin/:${PATH}\"\nfi\n\nexport PATH\n\nif which swiftlint >/dev/null; then\n swiftlint\nelse\n echo \"warning: SwiftLint not installed, download from https://github.com/realm/SwiftLint\"\nfi\n";
};
- 1E3CFFD5250AD9A400DDB852 /* SwiftLint */ = {
+ F556F65626CD312100A80B83 /* Swiftlint */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
@@ -714,307 +748,264 @@
);
inputPaths = (
);
- name = SwiftLint;
+ name = Swiftlint;
outputFileListPaths = (
);
outputPaths = (
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
- shellScript = "if which swiftlint >/dev/null; then\n swiftlint\nelse\n echo \"warning: SwiftLint not installed, download from https://github.com/realm/SwiftLint\"\nfi\n\n";
+ shellScript = "if test -d \"/opt/homebrew/bin/\"; then\n PATH=\"/opt/homebrew/bin/:${PATH}\"\nfi\n\nexport PATH\n\nif which swiftlint >/dev/null; then\n swiftlint\nelse\n echo \"warning: SwiftLint not installed, download from https://github.com/realm/SwiftLint\"\nfi\n";
};
/* End PBXShellScriptBuildPhase section */
/* Begin PBXSourcesBuildPhase section */
- 17DD0DFB207FB27400C56334 /* Sources */ = {
+ F556F56526CD1F3900A80B83 /* Sources */ = {
isa = PBXSourcesBuildPhase;
- buildActionMask = 2147483647;
+ buildActionMask = 0;
files = (
- 872D5A5721C177E20037D763 /* UIView+Extension.swift in Sources */,
- 1E291F3F2540655D0018D602 /* UIView+Autolayout.swift in Sources */,
- 17DD0E1F207FB32100C56334 /* RecursiveProtocol.swift in Sources */,
- 872D5A5D21C24EDD0037D763 /* UILabel+Multiline.swift in Sources */,
- 17DD0E1E207FB32100C56334 /* PrepareForSkeletonProtocol.swift in Sources */,
- F51ED28520973CC9008B2434 /* SkeletonReusableCell.swift in Sources */,
- 17DD0E17207FB28F00C56334 /* SkeletonLayer.swift in Sources */,
- 8785E3A2211C9CA500CC9DFD /* SkeletonDebug.swift in Sources */,
- 17DD0E08207FB28900C56334 /* CollectionSkeletonProtocol.swift in Sources */,
- F58A6E6C20A8C54100612494 /* RecoverableViewState.swift in Sources */,
- 17DD0E0B207FB28900C56334 /* SkeletonTableViewProtocols.swift in Sources */,
- 1E6C67A2230E76CC0019D87B /* SkeletonTransitionStyle.swift in Sources */,
- 17DD0E0D207FB28900C56334 /* UITableView+CollectionSkeleton.swift in Sources */,
- 17DD0E0E207FB28900C56334 /* UIView+CollectionSkeleton.swift in Sources */,
- 877EFA4921BEED760031FC00 /* SkeletonMultilineLayerBuilder.swift in Sources */,
- F51ED28320973CBB008B2434 /* SkeletonCollectionDelegate.swift in Sources */,
- F58A6E6F20A8C66300612494 /* Recoverable.swift in Sources */,
- 17DD0E18207FB28F00C56334 /* SkeletonView.swift in Sources */,
- 1EE42E2023FF25CC00BF665A /* ProcessInfo+XCTest.swift in Sources */,
- 17DD0E19207FB28F00C56334 /* SkeletonFlow.swift in Sources */,
- 17DD0E09207FB28900C56334 /* SkeletonCollectionDataSource.swift in Sources */,
- 17DD0E0C207FB28900C56334 /* UICollectionView+CollectionSkeleton.swift in Sources */,
- F5804773230ECD0000066D02 /* UIView+IBInspectable.swift in Sources */,
- 17DD0E13207FB28C00C56334 /* UIView+UIApplicationDelegate.swift in Sources */,
- F570ABF52314629700390248 /* Swizzling.swift in Sources */,
- F5D3FB0C209DCAA300003FCF /* SubviewsSkeletonables.swift in Sources */,
- 17DD0E14207FB28F00C56334 /* SkeletonAnimationBuilder.swift in Sources */,
- 17DD0E11207FB28C00C56334 /* UIView+Frame.swift in Sources */,
- 5600784523FD293D00669AD6 /* UITableView+VisibleSections.swift in Sources */,
- 17DD0E15207FB28F00C56334 /* SkeletonAppearance.swift in Sources */,
- 872D5A6021C24F8E0037D763 /* UITextView+Multiline.swift in Sources */,
- 17DD0E10207FB28C00C56334 /* UIColor+Skeleton.swift in Sources */,
- F51ED28420973CC6008B2434 /* GenericCollectionView.swift in Sources */,
- 17DD0E0A207FB28900C56334 /* SkeletonCollectionViewProtocols.swift in Sources */,
- 17DD0E1C207FB32100C56334 /* AssociationPolicy.swift in Sources */,
- 877EFA4621BEE9D80031FC00 /* SkeletonLayerBuilder.swift in Sources */,
- F5A5E8B5211DCE7000FD20D0 /* Int+Whitespaces.swift in Sources */,
- 870F4E4421CAC07300B9233B /* SkeletonConfig.swift in Sources */,
- 17DD0E1D207FB32100C56334 /* ContainsMultilineText.swift in Sources */,
- 17DD0E0F207FB28C00C56334 /* CALayer+Extensions.swift in Sources */,
- 17DD0E16207FB28F00C56334 /* SkeletonGradient.swift in Sources */,
- 1E6C67A3230E76CE0019D87B /* UIView+Transitions.swift in Sources */,
+ F556F56626CD1F3900A80B83 /* SkeletonAppearance.swift in Sources */,
+ F556F6CA26CE2A4A00A80B83 /* UITextView+IBInspectable.swift in Sources */,
+ F556F6E126CE367600A80B83 /* UIView+SkeletonView.swift in Sources */,
+ F556F56726CD1F3900A80B83 /* SkeletonLayerBuilder.swift in Sources */,
+ F556F6D026CE2AB800A80B83 /* SkeletonTextNode.swift in Sources */,
+ F556F65126CD2DFD00A80B83 /* SkeletonView.swift in Sources */,
+ F556F56826CD1F3900A80B83 /* SkeletonMultilineLayerBuilder.swift in Sources */,
+ F556F56926CD1F3900A80B83 /* CollectionSkeleton.swift in Sources */,
+ F556F56A26CD1F3900A80B83 /* SkeletonCollectionViewProtocols.swift in Sources */,
+ F556F6C026CE277F00A80B83 /* PrepareViewForSkeleton.swift in Sources */,
+ F556F6A826CD5B0400A80B83 /* CALayer+Extensions.swift in Sources */,
+ F556F56B26CD1F3900A80B83 /* UICollectionView+CollectionSkeleton.swift in Sources */,
+ F556F56D26CD1F3900A80B83 /* SkeletonReusableCell.swift in Sources */,
+ F556F56E26CD1F3900A80B83 /* SkeletonCollectionDataSource.swift in Sources */,
+ F556F56F26CD1F3900A80B83 /* SkeletonCollectionDelegate.swift in Sources */,
+ F556F68426CD48F700A80B83 /* UIView+AssociatedObjects.swift in Sources */,
+ F556F6CD26CE2A7400A80B83 /* UITextView+Extensions.swift in Sources */,
+ F556F57026CD1F3900A80B83 /* SkeletonTableViewProtocols.swift in Sources */,
+ F556F57126CD1F3900A80B83 /* UITableView+CollectionSkeleton.swift in Sources */,
+ F556F57226CD1F3900A80B83 /* UIView+CollectionSkeleton.swift in Sources */,
+ F556F6BD26CE272600A80B83 /* UILabel+Extensions.swift in Sources */,
+ F556F68B26CD4D6100A80B83 /* Notification+Extensions.swift in Sources */,
+ F556F57526CD1F3900A80B83 /* Int+Extensions.swift in Sources */,
+ F556F57726CD1F3900A80B83 /* UIColor+Skeleton.swift in Sources */,
+ F556F69626CD509E00A80B83 /* Notification+SkeletonFlow.swift in Sources */,
+ F556F57826CD1F3900A80B83 /* UITableView+Extensions.swift in Sources */,
+ F556F57D26CD1F3900A80B83 /* UIView+AppLifecycleNotifications.swift in Sources */,
+ F556F57E26CD1F3900A80B83 /* AssociationPolicy.swift in Sources */,
+ F556F6B026CE244100A80B83 /* DispatchQueue+Extensions.swift in Sources */,
+ F556F58026CD1F3900A80B83 /* Recursive.swift in Sources */,
+ F556F6F626CE876300A80B83 /* UIView+Swizzling.swift in Sources */,
+ F556F58126CD1F3900A80B83 /* Swizzling.swift in Sources */,
+ F556F6B626CE258300A80B83 /* GradientDirection+Animations.swift in Sources */,
+ F556F69F26CD553B00A80B83 /* UIView+Extensions.swift in Sources */,
+ F556F58526CD1F3900A80B83 /* Recoverable.swift in Sources */,
+ F556F58626CD1F3900A80B83 /* RecoverableViewState.swift in Sources */,
+ F556F58726CD1F3900A80B83 /* SkeletonAnimationBuilder.swift in Sources */,
+ F556F58826CD1F3900A80B83 /* SkeletonConfig.swift in Sources */,
+ F556F58926CD1F3900A80B83 /* SkeletonFlowHandler.swift in Sources */,
+ F556F58A26CD1F3900A80B83 /* SkeletonGradient.swift in Sources */,
+ F556F6C326CE27FD00A80B83 /* SkeletonType.swift in Sources */,
+ F556F6F326CE818B00A80B83 /* UIView+Flags.swift in Sources */,
+ F556F58B26CD1F3900A80B83 /* SkeletonLayer.swift in Sources */,
+ F556F6A226CD566C00A80B83 /* UIView+Debug.swift in Sources */,
+ F556F69326CD506C00A80B83 /* Deprecated.swift in Sources */,
+ F556F6BA26CE262700A80B83 /* GradientDirection.swift in Sources */,
+ F556F58D26CD1F3900A80B83 /* SubviewsSkeletonables.swift in Sources */,
+ F556F58E26CD1F3900A80B83 /* SkeletonTransitionStyle.swift in Sources */,
+ F556F6AC26CD5C4900A80B83 /* SkeletonMultilinesLayerConfig.swift in Sources */,
+ F556F68126CD47CF00A80B83 /* ProcessInfo+Extensions.swift in Sources */,
+ F556F68826CD49F900A80B83 /* UIView+IBInspectable.swift in Sources */,
+ F556F6C726CE2A2100A80B83 /* UILabel+IBInspectable.swift in Sources */,
+ F556F6DA26CE315A00A80B83 /* UICollectionView+Extensions.swift in Sources */,
+ F556F64E26CD2D3D00A80B83 /* SkeletonDebug.swift in Sources */,
+ F556F6A526CD5A9000A80B83 /* CALayer+Animations.swift in Sources */,
+ F556F58F26CD1F3900A80B83 /* UIView+Transitions.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
- 42ABD05D210B548200BEEFF4 /* Sources */ = {
+ F556F66D26CD458500A80B83 /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
- 42ABD07B210B54E200BEEFF4 /* ViewController.swift in Sources */,
- 5600784A23FD33AE00669AD6 /* HeaderFooterSection.swift in Sources */,
- 42ABD078210B54E200BEEFF4 /* AppDelegate.swift in Sources */,
- 42ABD07F210B54E200BEEFF4 /* CollectionViewCell.swift in Sources */,
- 8785E3A3211C9CE800CC9DFD /* Constants.swift in Sources */,
+ F556F67C26CD45A300A80B83 /* SkeletonDebugTests.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
- 52D6D9771BEFF229002C0205 /* Sources */ = {
+ OBJ_144 /* Sources */ = {
isa = PBXSourcesBuildPhase;
- buildActionMask = 2147483647;
+ buildActionMask = 0;
files = (
- E4CE588B22EEF70D00333067 /* UIView+Transitions.swift in Sources */,
- 1E291F3E2540655D0018D602 /* UIView+Autolayout.swift in Sources */,
- 872D5A5621C177E20037D763 /* UIView+Extension.swift in Sources */,
- 872D5A5C21C24EDD0037D763 /* UILabel+Multiline.swift in Sources */,
- F54CF5E42024CEB000330B0D /* UIView+CollectionSkeleton.swift in Sources */,
- F5307E371FB1076E00EE67C5 /* SkeletonTableViewProtocols.swift in Sources */,
- 8933C7851EB5B820000D00A4 /* SkeletonView.swift in Sources */,
- 8785E3A1211C9C9800CC9DFD /* SkeletonDebug.swift in Sources */,
- F5307E301FB0EC9D00EE67C5 /* SkeletonAppearance.swift in Sources */,
- F58A6E6B20A8C54100612494 /* RecoverableViewState.swift in Sources */,
- F54CF5E52024CEB000330B0D /* UITableView+CollectionSkeleton.swift in Sources */,
- F5307E321FB0F42F00EE67C5 /* RecursiveProtocol.swift in Sources */,
- F5F622431FAC81FD007C062A /* CALayer+Extensions.swift in Sources */,
- 877EFA4821BEED760031FC00 /* SkeletonMultilineLayerBuilder.swift in Sources */,
- E4CE587D22EEE65200333067 /* SkeletonTransitionStyle.swift in Sources */,
- F5F899ED1FAB9F04002E8FDA /* CollectionSkeletonProtocol.swift in Sources */,
- F58A6E6E20A8C66300612494 /* Recoverable.swift in Sources */,
- F5307E2C1FAF6BC900EE67C5 /* SkeletonGradient.swift in Sources */,
- 1EE42E1F23FF25CC00BF665A /* ProcessInfo+XCTest.swift in Sources */,
- F587FB86202CEC95002DB5FE /* UIView+UIApplicationDelegate.swift in Sources */,
- F5F899EB1FAB9DA3002E8FDA /* SkeletonCollectionDataSource.swift in Sources */,
- F5F622411FAC6E31007C062A /* UIColor+Skeleton.swift in Sources */,
- F5804772230ECD0000066D02 /* UIView+IBInspectable.swift in Sources */,
- F587FB84202CBFC8002DB5FE /* SkeletonFlow.swift in Sources */,
- F570ABF42314629700390248 /* Swizzling.swift in Sources */,
- F5D3FB0B209DCAA300003FCF /* SubviewsSkeletonables.swift in Sources */,
- F5F899D21FAB9630002E8FDA /* AssociationPolicy.swift in Sources */,
- F54CF5E62024CEB000330B0D /* UICollectionView+CollectionSkeleton.swift in Sources */,
- 5600784423FD293D00669AD6 /* UITableView+VisibleSections.swift in Sources */,
- F56B94461FAE20AF0095662F /* PrepareForSkeletonProtocol.swift in Sources */,
- F5307E391FB1078E00EE67C5 /* SkeletonCollectionViewProtocols.swift in Sources */,
- 872D5A5F21C24F8E0037D763 /* UITextView+Multiline.swift in Sources */,
- F51DF873206E91FB00D23301 /* GenericCollectionView.swift in Sources */,
- F5307E3B1FB123C100EE67C5 /* ContainsMultilineText.swift in Sources */,
- F5F899E91FAB9D2B002E8FDA /* SkeletonLayer.swift in Sources */,
- F5307E2E1FB0E5E400EE67C5 /* UIView+Frame.swift in Sources */,
- 877EFA4521BEE9D80031FC00 /* SkeletonLayerBuilder.swift in Sources */,
- F5A5E8B4211DCE7000FD20D0 /* Int+Whitespaces.swift in Sources */,
- 870F4E4321CAC07300B9233B /* SkeletonConfig.swift in Sources */,
- F51DF871206E91B300D23301 /* SkeletonReusableCell.swift in Sources */,
- F51DF879206E9F5500D23301 /* SkeletonCollectionDelegate.swift in Sources */,
- F51DE1091FBF70A70037919A /* SkeletonAnimationBuilder.swift in Sources */,
+ F556F65D26CD3E3600A80B83 /* SkeletonDebugTests.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
- F5F899EE1FABA607002E8FDA /* Sources */ = {
+ OBJ_85 /* Sources */ = {
isa = PBXSourcesBuildPhase;
- buildActionMask = 2147483647;
+ buildActionMask = 0;
files = (
- F5F899F71FABA607002E8FDA /* ViewController.swift in Sources */,
- 5600784923FD33AD00669AD6 /* HeaderFooterSection.swift in Sources */,
- F5F899F51FABA607002E8FDA /* AppDelegate.swift in Sources */,
- F5F622451FACA338007C062A /* Cell.swift in Sources */,
- 88DEA97F1FCDBD78006C80EF /* Constants.swift in Sources */,
+ OBJ_86 /* SkeletonAppearance.swift in Sources */,
+ F556F6C926CE2A4A00A80B83 /* UITextView+IBInspectable.swift in Sources */,
+ OBJ_87 /* SkeletonLayerBuilder.swift in Sources */,
+ F556F6CF26CE2AB800A80B83 /* SkeletonTextNode.swift in Sources */,
+ F556F65026CD2DFD00A80B83 /* SkeletonView.swift in Sources */,
+ OBJ_88 /* SkeletonMultilineLayerBuilder.swift in Sources */,
+ F556F6F226CE818B00A80B83 /* UIView+Flags.swift in Sources */,
+ OBJ_89 /* CollectionSkeleton.swift in Sources */,
+ OBJ_90 /* SkeletonCollectionViewProtocols.swift in Sources */,
+ F556F6BF26CE277F00A80B83 /* PrepareViewForSkeleton.swift in Sources */,
+ F556F6A726CD5B0400A80B83 /* CALayer+Extensions.swift in Sources */,
+ OBJ_91 /* UICollectionView+CollectionSkeleton.swift in Sources */,
+ OBJ_93 /* SkeletonReusableCell.swift in Sources */,
+ OBJ_94 /* SkeletonCollectionDataSource.swift in Sources */,
+ OBJ_95 /* SkeletonCollectionDelegate.swift in Sources */,
+ F556F68326CD48F700A80B83 /* UIView+AssociatedObjects.swift in Sources */,
+ F556F6CC26CE2A7400A80B83 /* UITextView+Extensions.swift in Sources */,
+ OBJ_96 /* SkeletonTableViewProtocols.swift in Sources */,
+ OBJ_97 /* UITableView+CollectionSkeleton.swift in Sources */,
+ OBJ_98 /* UIView+CollectionSkeleton.swift in Sources */,
+ F556F6BC26CE272600A80B83 /* UILabel+Extensions.swift in Sources */,
+ F556F68A26CD4D6100A80B83 /* Notification+Extensions.swift in Sources */,
+ OBJ_101 /* Int+Extensions.swift in Sources */,
+ OBJ_103 /* UIColor+Skeleton.swift in Sources */,
+ F556F69526CD509E00A80B83 /* Notification+SkeletonFlow.swift in Sources */,
+ OBJ_104 /* UITableView+Extensions.swift in Sources */,
+ OBJ_109 /* UIView+AppLifecycleNotifications.swift in Sources */,
+ OBJ_110 /* AssociationPolicy.swift in Sources */,
+ F556F6AF26CE244100A80B83 /* DispatchQueue+Extensions.swift in Sources */,
+ OBJ_112 /* Recursive.swift in Sources */,
+ OBJ_113 /* Swizzling.swift in Sources */,
+ F556F6B526CE258300A80B83 /* GradientDirection+Animations.swift in Sources */,
+ F556F69E26CD553B00A80B83 /* UIView+Extensions.swift in Sources */,
+ OBJ_117 /* Recoverable.swift in Sources */,
+ OBJ_118 /* RecoverableViewState.swift in Sources */,
+ OBJ_119 /* SkeletonAnimationBuilder.swift in Sources */,
+ OBJ_120 /* SkeletonConfig.swift in Sources */,
+ OBJ_121 /* SkeletonFlowHandler.swift in Sources */,
+ OBJ_122 /* SkeletonGradient.swift in Sources */,
+ F556F6C226CE27FD00A80B83 /* SkeletonType.swift in Sources */,
+ OBJ_123 /* SkeletonLayer.swift in Sources */,
+ F556F6E026CE367600A80B83 /* UIView+SkeletonView.swift in Sources */,
+ F556F6A126CD566C00A80B83 /* UIView+Debug.swift in Sources */,
+ F556F69226CD506C00A80B83 /* Deprecated.swift in Sources */,
+ F556F6B926CE262700A80B83 /* GradientDirection.swift in Sources */,
+ OBJ_125 /* SubviewsSkeletonables.swift in Sources */,
+ OBJ_126 /* SkeletonTransitionStyle.swift in Sources */,
+ F556F6AB26CD5C4900A80B83 /* SkeletonMultilinesLayerConfig.swift in Sources */,
+ F556F68026CD47CF00A80B83 /* ProcessInfo+Extensions.swift in Sources */,
+ F556F68726CD49F900A80B83 /* UIView+IBInspectable.swift in Sources */,
+ F556F6C626CE2A2100A80B83 /* UILabel+IBInspectable.swift in Sources */,
+ F556F6D926CE315A00A80B83 /* UICollectionView+Extensions.swift in Sources */,
+ F556F6DD26CE33CE00A80B83 /* UIView+Swizzling.swift in Sources */,
+ F556F64D26CD2CF800A80B83 /* SkeletonDebug.swift in Sources */,
+ F556F6A426CD5A9000A80B83 /* CALayer+Animations.swift in Sources */,
+ OBJ_127 /* UIView+Transitions.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXSourcesBuildPhase section */
/* Begin PBXTargetDependency section */
- 42ABD05B210B548200BEEFF4 /* PBXTargetDependency */ = {
+ F556F67826CD458500A80B83 /* PBXTargetDependency */ = {
isa = PBXTargetDependency;
- target = 52D6D97B1BEFF229002C0205 /* SkeletonView-iOS */;
- targetProxy = 42ABD05C210B548200BEEFF4 /* PBXContainerItemProxy */;
+ platformFilter = maccatalyst;
+ target = F556F56426CD1F3900A80B83 /* SkeletonView tvOS */;
+ targetProxy = F556F67726CD458500A80B83 /* PBXContainerItemProxy */;
};
- F5307E441FB3B84500EE67C5 /* PBXTargetDependency */ = {
+ OBJ_148 /* PBXTargetDependency */ = {
isa = PBXTargetDependency;
- target = 52D6D97B1BEFF229002C0205 /* SkeletonView-iOS */;
- targetProxy = F5307E431FB3B84500EE67C5 /* PBXContainerItemProxy */;
+ target = "SkeletonView::SkeletonView" /* SkeletonView iOS */;
+ targetProxy = F556F50C26CD1B1500A80B83 /* PBXContainerItemProxy */;
};
/* End PBXTargetDependency section */
-/* Begin PBXVariantGroup section */
- F5F899F81FABA607002E8FDA /* Main.storyboard */ = {
- isa = PBXVariantGroup;
- children = (
- F5F899F91FABA607002E8FDA /* Base */,
- );
- name = Main.storyboard;
- sourceTree = "";
- };
- F5F899FD1FABA607002E8FDA /* LaunchScreen.storyboard */ = {
- isa = PBXVariantGroup;
- children = (
- F5F899FE1FABA607002E8FDA /* Base */,
- );
- name = LaunchScreen.storyboard;
- sourceTree = "";
- };
-/* End PBXVariantGroup section */
-
/* Begin XCBuildConfiguration section */
- 17DD0E05207FB27400C56334 /* Debug */ = {
+ F556F59226CD1F3900A80B83 /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
- CLANG_ANALYZER_NONNULL = YES;
- CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
- CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
- CLANG_ENABLE_OBJC_WEAK = YES;
- CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
- CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
- CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
- CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
- CODE_SIGN_IDENTITY = "";
- CODE_SIGN_STYLE = Automatic;
- DEFINES_MODULE = YES;
- DYLIB_COMPATIBILITY_VERSION = 1;
- DYLIB_CURRENT_VERSION = 1;
- DYLIB_INSTALL_NAME_BASE = "@rpath";
- GCC_C_LANGUAGE_STANDARD = gnu11;
- INFOPLIST_FILE = "Configs/SkeletonView-tvOS.plist";
- INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
- LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
- PRODUCT_BUNDLE_IDENTIFIER = "com.SkeletonView.SkeletonView-tvOS";
- PRODUCT_NAME = SkeletonView;
+ CURRENT_PROJECT_VERSION = 1;
+ ENABLE_TESTABILITY = YES;
+ FRAMEWORK_SEARCH_PATHS = (
+ "$(inherited)",
+ "$(PLATFORM_DIR)/Developer/Library/Frameworks",
+ );
+ HEADER_SEARCH_PATHS = "$(inherited)";
+ INFOPLIST_FILE = "SkeletonViewCore/Sources/Supporting Files/Info.plist";
+ IPHONEOS_DEPLOYMENT_TARGET = 9.0;
+ LD_RUNPATH_SEARCH_PATHS = (
+ "$(inherited)",
+ "$(TOOLCHAIN_DIR)/usr/lib/swift/macosx",
+ );
+ MACOSX_DEPLOYMENT_TARGET = 10.10;
+ OTHER_CFLAGS = "$(inherited)";
+ OTHER_LDFLAGS = "$(inherited)";
+ OTHER_SWIFT_FLAGS = "$(inherited)";
+ PRODUCT_BUNDLE_IDENTIFIER = SkeletonView;
+ PRODUCT_MODULE_NAME = "$(TARGET_NAME:c99extidentifier)";
+ PRODUCT_NAME = "$(TARGET_NAME)";
SDKROOT = appletvos;
SKIP_INSTALL = YES;
- SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG;
+ SUPPORTED_PLATFORMS = "appletvsimulator appletvos";
+ SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited)";
SWIFT_VERSION = 5.0;
TARGETED_DEVICE_FAMILY = 3;
+ TARGET_NAME = SkeletonView;
TVOS_DEPLOYMENT_TARGET = 9.0;
+ WATCHOS_DEPLOYMENT_TARGET = 2.0;
};
name = Debug;
};
- 17DD0E06207FB27400C56334 /* Release */ = {
+ F556F59326CD1F3900A80B83 /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
- CLANG_ANALYZER_NONNULL = YES;
- CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
- CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
- CLANG_ENABLE_OBJC_WEAK = YES;
- CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
- CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
- CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
- CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
- CODE_SIGN_IDENTITY = "";
- CODE_SIGN_STYLE = Automatic;
- DEFINES_MODULE = YES;
- DYLIB_COMPATIBILITY_VERSION = 1;
- DYLIB_CURRENT_VERSION = 1;
- DYLIB_INSTALL_NAME_BASE = "@rpath";
- GCC_C_LANGUAGE_STANDARD = gnu11;
- INFOPLIST_FILE = "Configs/SkeletonView-tvOS.plist";
- INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
- LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
- PRODUCT_BUNDLE_IDENTIFIER = "com.SkeletonView.SkeletonView-tvOS";
- PRODUCT_NAME = SkeletonView;
+ CURRENT_PROJECT_VERSION = 1;
+ ENABLE_TESTABILITY = YES;
+ FRAMEWORK_SEARCH_PATHS = (
+ "$(inherited)",
+ "$(PLATFORM_DIR)/Developer/Library/Frameworks",
+ );
+ HEADER_SEARCH_PATHS = "$(inherited)";
+ INFOPLIST_FILE = "SkeletonViewCore/Sources/Supporting Files/Info.plist";
+ IPHONEOS_DEPLOYMENT_TARGET = 9.0;
+ LD_RUNPATH_SEARCH_PATHS = (
+ "$(inherited)",
+ "$(TOOLCHAIN_DIR)/usr/lib/swift/macosx",
+ );
+ MACOSX_DEPLOYMENT_TARGET = 10.10;
+ OTHER_CFLAGS = "$(inherited)";
+ OTHER_LDFLAGS = "$(inherited)";
+ OTHER_SWIFT_FLAGS = "$(inherited)";
+ PRODUCT_BUNDLE_IDENTIFIER = SkeletonView;
+ PRODUCT_MODULE_NAME = "$(TARGET_NAME:c99extidentifier)";
+ PRODUCT_NAME = "$(TARGET_NAME)";
SDKROOT = appletvos;
SKIP_INSTALL = YES;
- SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule";
+ SUPPORTED_PLATFORMS = "appletvsimulator appletvos";
+ SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited)";
SWIFT_VERSION = 5.0;
TARGETED_DEVICE_FAMILY = 3;
+ TARGET_NAME = SkeletonView;
TVOS_DEPLOYMENT_TARGET = 9.0;
+ WATCHOS_DEPLOYMENT_TARGET = 2.0;
};
name = Release;
};
- 42ABD06B210B548200BEEFF4 /* Debug */ = {
+ F556F67A26CD458500A80B83 /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
- ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
- ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
- CLANG_ANALYZER_NONNULL = YES;
- CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
- CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
- CLANG_ENABLE_MODULES = YES;
- CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
- CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
- CODE_SIGN_IDENTITY = "iPhone Developer";
- CODE_SIGN_STYLE = Automatic;
- DEVELOPMENT_TEAM = "";
- GCC_C_LANGUAGE_STANDARD = gnu11;
- INFOPLIST_FILE = "Configs/SkeletonViewExampleCollectionview-Info.plist";
- IPHONEOS_DEPLOYMENT_TARGET = 9.0;
- LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
- PRODUCT_BUNDLE_IDENTIFIER = com.juanpecatalan.SkeletonViewExample;
- PRODUCT_NAME = "$(TARGET_NAME)";
- SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG;
- SWIFT_OPTIMIZATION_LEVEL = "-Onone";
- SWIFT_VERSION = 5.0;
- TARGETED_DEVICE_FAMILY = "1,2";
- };
- name = Debug;
- };
- 42ABD06C210B548200BEEFF4 /* Release */ = {
- isa = XCBuildConfiguration;
- buildSettings = {
- ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
- ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
+ ALWAYS_SEARCH_USER_PATHS = NO;
CLANG_ANALYZER_NONNULL = YES;
CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
- CLANG_ENABLE_MODULES = YES;
- CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
- CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
- CODE_SIGN_IDENTITY = "iPhone Developer";
- CODE_SIGN_STYLE = Automatic;
- DEVELOPMENT_TEAM = "";
- GCC_C_LANGUAGE_STANDARD = gnu11;
- INFOPLIST_FILE = "Configs/SkeletonViewExampleCollectionview-Info.plist";
- IPHONEOS_DEPLOYMENT_TARGET = 9.0;
- LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
- PRODUCT_BUNDLE_IDENTIFIER = com.juanpecatalan.SkeletonViewExample;
- PRODUCT_NAME = "$(TARGET_NAME)";
- SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule";
- SWIFT_VERSION = 5.0;
- TARGETED_DEVICE_FAMILY = "1,2";
- };
- name = Release;
- };
- 52D6D98E1BEFF229002C0205 /* Debug */ = {
- isa = XCBuildConfiguration;
- buildSettings = {
- ALWAYS_SEARCH_USER_PATHS = NO;
- CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES;
- CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
CLANG_CXX_LIBRARY = "libc++";
CLANG_ENABLE_MODULES = YES;
- CLANG_ENABLE_OBJC_ARC = YES;
+ CLANG_ENABLE_OBJC_WEAK = YES;
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
CLANG_WARN_BOOL_CONVERSION = YES;
CLANG_WARN_COMMA = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
+ CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INFINITE_RECURSION = YES;
@@ -1023,21 +1014,19 @@
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
+ CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
CLANG_WARN_STRICT_PROTOTYPES = YES;
CLANG_WARN_SUSPICIOUS_MOVE = YES;
+ CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
- "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
- COPY_PHASE_STRIP = NO;
- CURRENT_PROJECT_VERSION = 1;
- DEBUG_INFORMATION_FORMAT = dwarf;
+ CODE_SIGN_STYLE = Automatic;
ENABLE_STRICT_OBJC_MSGSEND = YES;
ENABLE_TESTABILITY = YES;
- GCC_C_LANGUAGE_STANDARD = gnu99;
+ GCC_C_LANGUAGE_STANDARD = gnu11;
GCC_DYNAMIC_NO_PIC = NO;
GCC_NO_COMMON_BLOCKS = YES;
- GCC_OPTIMIZATION_LEVEL = 0;
GCC_PREPROCESSOR_DEFINITIONS = (
"DEBUG=1",
"$(inherited)",
@@ -1048,33 +1037,42 @@
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
- IPHONEOS_DEPLOYMENT_TARGET = 9.0;
- MTL_ENABLE_DEBUG_INFO = YES;
- ONLY_ACTIVE_ARCH = YES;
- SDKROOT = iphoneos;
- SWIFT_OPTIMIZATION_LEVEL = "-Onone";
+ INFOPLIST_FILE = "SkeletonViewCore/Tests/Supporting Files/Info.plist";
+ LD_RUNPATH_SEARCH_PATHS = (
+ "$(inherited)",
+ "@executable_path/Frameworks",
+ "@loader_path/Frameworks",
+ );
+ MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
+ MTL_FAST_MATH = YES;
+ PRODUCT_BUNDLE_IDENTIFIER = "com.skeletonview.SkeletonView-tvOS-Tests";
+ PRODUCT_NAME = "$(TARGET_NAME)";
+ SDKROOT = appletvos;
+ SUPPORTED_PLATFORMS = "appletvsimulator appletvos";
+ SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG;
SWIFT_VERSION = 5.0;
- TARGETED_DEVICE_FAMILY = "1,2";
- VERSIONING_SYSTEM = "apple-generic";
- VERSION_INFO_PREFIX = "";
+ TARGETED_DEVICE_FAMILY = 3;
+ TVOS_DEPLOYMENT_TARGET = 9.0;
};
name = Debug;
};
- 52D6D98F1BEFF229002C0205 /* Release */ = {
+ F556F67B26CD458500A80B83 /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
- CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES;
- CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
+ CLANG_ANALYZER_NONNULL = YES;
+ CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
+ CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
CLANG_CXX_LIBRARY = "libc++";
CLANG_ENABLE_MODULES = YES;
- CLANG_ENABLE_OBJC_ARC = YES;
+ CLANG_ENABLE_OBJC_WEAK = YES;
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
CLANG_WARN_BOOL_CONVERSION = YES;
CLANG_WARN_COMMA = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
+ CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INFINITE_RECURSION = YES;
@@ -1083,18 +1081,18 @@
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
+ CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
CLANG_WARN_STRICT_PROTOTYPES = YES;
CLANG_WARN_SUSPICIOUS_MOVE = YES;
+ CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
- "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
+ CODE_SIGN_STYLE = Automatic;
COPY_PHASE_STRIP = NO;
- CURRENT_PROJECT_VERSION = 1;
- DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
ENABLE_NS_ASSERTIONS = NO;
ENABLE_STRICT_OBJC_MSGSEND = YES;
- GCC_C_LANGUAGE_STANDARD = gnu99;
+ GCC_C_LANGUAGE_STANDARD = gnu11;
GCC_NO_COMMON_BLOCKS = YES;
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
@@ -1102,175 +1100,266 @@
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
- IPHONEOS_DEPLOYMENT_TARGET = 9.0;
+ INFOPLIST_FILE = "SkeletonViewCore/Tests/Supporting Files/Info.plist";
+ LD_RUNPATH_SEARCH_PATHS = (
+ "$(inherited)",
+ "@executable_path/Frameworks",
+ "@loader_path/Frameworks",
+ );
MTL_ENABLE_DEBUG_INFO = NO;
- SDKROOT = iphoneos;
+ MTL_FAST_MATH = YES;
+ PRODUCT_BUNDLE_IDENTIFIER = "com.skeletonview.SkeletonView-tvOS-Tests";
+ PRODUCT_NAME = "$(TARGET_NAME)";
+ SDKROOT = appletvos;
+ SUPPORTED_PLATFORMS = "appletvsimulator appletvos";
SWIFT_VERSION = 5.0;
- TARGETED_DEVICE_FAMILY = "1,2";
+ TARGETED_DEVICE_FAMILY = 3;
+ TVOS_DEPLOYMENT_TARGET = 9.0;
VALIDATE_PRODUCT = YES;
- VERSIONING_SYSTEM = "apple-generic";
- VERSION_INFO_PREFIX = "";
};
name = Release;
};
- 52D6D9911BEFF229002C0205 /* Debug */ = {
+ OBJ_142 /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
- APPLICATION_EXTENSION_API_ONLY = NO;
CLANG_ENABLE_MODULES = YES;
- CODE_SIGN_IDENTITY = "Apple Development";
- "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "";
- "CODE_SIGN_IDENTITY[sdk=macosx*]" = "Apple Development";
- CODE_SIGN_STYLE = Automatic;
- DEFINES_MODULE = YES;
- DEVELOPMENT_TEAM = "";
- DYLIB_COMPATIBILITY_VERSION = 1;
- DYLIB_CURRENT_VERSION = 1;
+ CURRENT_PROJECT_VERSION = 1;
+ EMBEDDED_CONTENT_CONTAINS_SWIFT = YES;
+ FRAMEWORK_SEARCH_PATHS = (
+ "$(inherited)",
+ "$(PLATFORM_DIR)/Developer/Library/Frameworks",
+ );
+ HEADER_SEARCH_PATHS = "$(inherited)";
+ INFOPLIST_FILE = "SkeletonViewCore/Tests/Supporting Files/Info.plist";
+ IPHONEOS_DEPLOYMENT_TARGET = 14.0;
+ LD_RUNPATH_SEARCH_PATHS = (
+ "$(inherited)",
+ "@loader_path/../Frameworks",
+ "@loader_path/Frameworks",
+ );
+ MACOSX_DEPLOYMENT_TARGET = 10.15;
+ OTHER_CFLAGS = "$(inherited)";
+ OTHER_LDFLAGS = "$(inherited)";
+ OTHER_SWIFT_FLAGS = "$(inherited)";
+ SDKROOT = iphoneos;
+ SUPPORTED_PLATFORMS = "iphonesimulator iphoneos";
+ SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited)";
+ SWIFT_VERSION = 5.0;
+ TARGETED_DEVICE_FAMILY = "1,2";
+ TARGET_NAME = SkeletonViewTests;
+ TVOS_DEPLOYMENT_TARGET = 9.0;
+ WATCHOS_DEPLOYMENT_TARGET = 7.0;
+ };
+ name = Debug;
+ };
+ OBJ_143 /* Release */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ CLANG_ENABLE_MODULES = YES;
+ CURRENT_PROJECT_VERSION = 1;
+ EMBEDDED_CONTENT_CONTAINS_SWIFT = YES;
+ FRAMEWORK_SEARCH_PATHS = (
+ "$(inherited)",
+ "$(PLATFORM_DIR)/Developer/Library/Frameworks",
+ );
+ HEADER_SEARCH_PATHS = "$(inherited)";
+ INFOPLIST_FILE = "SkeletonViewCore/Tests/Supporting Files/Info.plist";
+ IPHONEOS_DEPLOYMENT_TARGET = 14.0;
+ LD_RUNPATH_SEARCH_PATHS = (
+ "$(inherited)",
+ "@loader_path/../Frameworks",
+ "@loader_path/Frameworks",
+ );
+ MACOSX_DEPLOYMENT_TARGET = 10.15;
+ OTHER_CFLAGS = "$(inherited)";
+ OTHER_LDFLAGS = "$(inherited)";
+ OTHER_SWIFT_FLAGS = "$(inherited)";
+ SDKROOT = iphoneos;
+ SUPPORTED_PLATFORMS = "iphonesimulator iphoneos";
+ SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited)";
+ SWIFT_VERSION = 5.0;
+ TARGETED_DEVICE_FAMILY = "1,2";
+ TARGET_NAME = SkeletonViewTests;
+ TVOS_DEPLOYMENT_TARGET = 9.0;
+ WATCHOS_DEPLOYMENT_TARGET = 7.0;
+ };
+ name = Release;
+ };
+ OBJ_3 /* Debug */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ CLANG_ENABLE_OBJC_ARC = YES;
+ COMBINE_HIDPI_IMAGES = YES;
+ COPY_PHASE_STRIP = NO;
+ DEBUG_INFORMATION_FORMAT = dwarf;
DYLIB_INSTALL_NAME_BASE = "@rpath";
- INFOPLIST_FILE = "Configs/SkeletonView-iOS.plist";
- INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
+ ENABLE_NS_ASSERTIONS = YES;
+ GCC_OPTIMIZATION_LEVEL = 0;
+ GCC_PREPROCESSOR_DEFINITIONS = (
+ "$(inherited)",
+ "SWIFT_PACKAGE=1",
+ "DEBUG=1",
+ );
IPHONEOS_DEPLOYMENT_TARGET = 9.0;
- LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
- ONLY_ACTIVE_ARCH = NO;
- PRODUCT_BUNDLE_IDENTIFIER = "com.SkeletonView.SkeletonView-iOS";
- PRODUCT_NAME = SkeletonView;
- PROVISIONING_PROFILE_SPECIFIER = "";
- "PROVISIONING_PROFILE_SPECIFIER[sdk=macosx*]" = "";
- SKIP_INSTALL = YES;
+ MACOSX_DEPLOYMENT_TARGET = 10.10;
+ ONLY_ACTIVE_ARCH = YES;
+ OTHER_SWIFT_FLAGS = "$(inherited) -DXcode";
+ PRODUCT_NAME = "$(TARGET_NAME)";
+ SDKROOT = macosx;
+ SUPPORTED_PLATFORMS = macosx;
+ SUPPORTS_MACCATALYST = YES;
+ SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited) SWIFT_PACKAGE DEBUG";
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
- SWIFT_VERSION = 5.0;
+ USE_HEADERMAP = NO;
};
name = Debug;
};
- 52D6D9921BEFF229002C0205 /* Release */ = {
+ OBJ_4 /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
- APPLICATION_EXTENSION_API_ONLY = NO;
- CLANG_ENABLE_MODULES = YES;
- CODE_SIGN_IDENTITY = "Apple Development";
- "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "";
- "CODE_SIGN_IDENTITY[sdk=macosx*]" = "Apple Development";
- CODE_SIGN_STYLE = Automatic;
- DEFINES_MODULE = YES;
- DEVELOPMENT_TEAM = "";
- DYLIB_COMPATIBILITY_VERSION = 1;
- DYLIB_CURRENT_VERSION = 1;
+ CLANG_ENABLE_OBJC_ARC = YES;
+ COMBINE_HIDPI_IMAGES = YES;
+ COPY_PHASE_STRIP = YES;
+ DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
DYLIB_INSTALL_NAME_BASE = "@rpath";
- INFOPLIST_FILE = "Configs/SkeletonView-iOS.plist";
- INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
+ GCC_OPTIMIZATION_LEVEL = s;
+ GCC_PREPROCESSOR_DEFINITIONS = (
+ "$(inherited)",
+ "SWIFT_PACKAGE=1",
+ );
IPHONEOS_DEPLOYMENT_TARGET = 9.0;
- LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
- PRODUCT_BUNDLE_IDENTIFIER = "com.SkeletonView.SkeletonView-iOS";
- PRODUCT_NAME = SkeletonView;
- PROVISIONING_PROFILE_SPECIFIER = "";
- "PROVISIONING_PROFILE_SPECIFIER[sdk=macosx*]" = "";
- SKIP_INSTALL = YES;
- SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule";
- SWIFT_VERSION = 5.0;
+ MACOSX_DEPLOYMENT_TARGET = 10.10;
+ OTHER_SWIFT_FLAGS = "$(inherited) -DXcode";
+ PRODUCT_NAME = "$(TARGET_NAME)";
+ SDKROOT = macosx;
+ SUPPORTED_PLATFORMS = macosx;
+ SUPPORTS_MACCATALYST = YES;
+ SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited) SWIFT_PACKAGE";
+ SWIFT_COMPILATION_MODE = wholemodule;
+ SWIFT_OPTIMIZATION_LEVEL = "-O";
+ USE_HEADERMAP = NO;
};
name = Release;
};
- F5F89A021FABA607002E8FDA /* Debug */ = {
+ OBJ_83 /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
- ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
- ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
- CLANG_ANALYZER_NONNULL = YES;
- CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
- CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
- CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
- CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
- CODE_SIGN_IDENTITY = "Apple Development";
- CODE_SIGN_STYLE = Automatic;
- DEVELOPMENT_TEAM = "";
- GCC_C_LANGUAGE_STANDARD = gnu11;
- INFOPLIST_FILE = "$(SRCROOT)/Configs/SkeletonViewExampleInfo.plist";
+ CURRENT_PROJECT_VERSION = 1;
+ ENABLE_TESTABILITY = YES;
+ FRAMEWORK_SEARCH_PATHS = (
+ "$(inherited)",
+ "$(PLATFORM_DIR)/Developer/Library/Frameworks",
+ );
+ HEADER_SEARCH_PATHS = "$(inherited)";
+ INFOPLIST_FILE = "SkeletonViewCore/Sources/Supporting Files/Info.plist";
IPHONEOS_DEPLOYMENT_TARGET = 9.0;
- LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
- PRODUCT_BUNDLE_IDENTIFIER = com.juanpecatalan.SkeletonViewExample;
- PRODUCT_NAME = "$(TARGET_NAME)";
- PROVISIONING_PROFILE_SPECIFIER = "";
- SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG;
+ LD_RUNPATH_SEARCH_PATHS = (
+ "$(inherited)",
+ "$(TOOLCHAIN_DIR)/usr/lib/swift/macosx",
+ );
+ MACOSX_DEPLOYMENT_TARGET = 10.10;
+ OTHER_CFLAGS = "$(inherited)";
+ OTHER_LDFLAGS = "$(inherited)";
+ OTHER_SWIFT_FLAGS = "$(inherited)";
+ PRODUCT_BUNDLE_IDENTIFIER = SkeletonView;
+ PRODUCT_MODULE_NAME = "$(TARGET_NAME:c99extidentifier)";
+ PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)";
+ SDKROOT = iphoneos;
+ SKIP_INSTALL = YES;
+ SUPPORTED_PLATFORMS = "iphonesimulator iphoneos";
+ SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited)";
SWIFT_VERSION = 5.0;
TARGETED_DEVICE_FAMILY = "1,2";
+ TARGET_NAME = SkeletonView;
+ TVOS_DEPLOYMENT_TARGET = 9.0;
+ WATCHOS_DEPLOYMENT_TARGET = 2.0;
};
name = Debug;
};
- F5F89A031FABA607002E8FDA /* Release */ = {
+ OBJ_84 /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
- ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
- ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
- CLANG_ANALYZER_NONNULL = YES;
- CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
- CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
- CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
- CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
- CODE_SIGN_IDENTITY = "Apple Development";
- CODE_SIGN_STYLE = Automatic;
- DEVELOPMENT_TEAM = "";
- GCC_C_LANGUAGE_STANDARD = gnu11;
- INFOPLIST_FILE = "$(SRCROOT)/Configs/SkeletonViewExampleInfo.plist";
+ CURRENT_PROJECT_VERSION = 1;
+ ENABLE_TESTABILITY = YES;
+ FRAMEWORK_SEARCH_PATHS = (
+ "$(inherited)",
+ "$(PLATFORM_DIR)/Developer/Library/Frameworks",
+ );
+ HEADER_SEARCH_PATHS = "$(inherited)";
+ INFOPLIST_FILE = "SkeletonViewCore/Sources/Supporting Files/Info.plist";
IPHONEOS_DEPLOYMENT_TARGET = 9.0;
- LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
- PRODUCT_BUNDLE_IDENTIFIER = com.juanpecatalan.SkeletonViewExample;
- PRODUCT_NAME = "$(TARGET_NAME)";
- PROVISIONING_PROFILE_SPECIFIER = "";
- SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule";
+ LD_RUNPATH_SEARCH_PATHS = (
+ "$(inherited)",
+ "$(TOOLCHAIN_DIR)/usr/lib/swift/macosx",
+ );
+ MACOSX_DEPLOYMENT_TARGET = 10.10;
+ OTHER_CFLAGS = "$(inherited)";
+ OTHER_LDFLAGS = "$(inherited)";
+ OTHER_SWIFT_FLAGS = "$(inherited)";
+ PRODUCT_BUNDLE_IDENTIFIER = SkeletonView;
+ PRODUCT_MODULE_NAME = "$(TARGET_NAME:c99extidentifier)";
+ PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)";
+ SDKROOT = iphoneos;
+ SKIP_INSTALL = YES;
+ SUPPORTED_PLATFORMS = "iphonesimulator iphoneos";
+ SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited)";
SWIFT_VERSION = 5.0;
TARGETED_DEVICE_FAMILY = "1,2";
+ TARGET_NAME = SkeletonView;
+ TVOS_DEPLOYMENT_TARGET = 9.0;
+ WATCHOS_DEPLOYMENT_TARGET = 2.0;
};
name = Release;
};
/* End XCBuildConfiguration section */
/* Begin XCConfigurationList section */
- 17DD0E07207FB27400C56334 /* Build configuration list for PBXNativeTarget "SkeletonView-tvOS" */ = {
+ F556F59126CD1F3900A80B83 /* Build configuration list for PBXNativeTarget "SkeletonView tvOS" */ = {
isa = XCConfigurationList;
buildConfigurations = (
- 17DD0E05207FB27400C56334 /* Debug */,
- 17DD0E06207FB27400C56334 /* Release */,
+ F556F59226CD1F3900A80B83 /* Debug */,
+ F556F59326CD1F3900A80B83 /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
- 42ABD06A210B548200BEEFF4 /* Build configuration list for PBXNativeTarget "SkeletonViewExampleUICollectionView" */ = {
+ F556F67926CD458500A80B83 /* Build configuration list for PBXNativeTarget "SkeletonView tvOS Tests" */ = {
isa = XCConfigurationList;
buildConfigurations = (
- 42ABD06B210B548200BEEFF4 /* Debug */,
- 42ABD06C210B548200BEEFF4 /* Release */,
+ F556F67A26CD458500A80B83 /* Debug */,
+ F556F67B26CD458500A80B83 /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
- 52D6D9761BEFF229002C0205 /* Build configuration list for PBXProject "SkeletonView" */ = {
+ OBJ_141 /* Build configuration list for PBXNativeTarget "SkeletonView iOS Tests" */ = {
isa = XCConfigurationList;
buildConfigurations = (
- 52D6D98E1BEFF229002C0205 /* Debug */,
- 52D6D98F1BEFF229002C0205 /* Release */,
+ OBJ_142 /* Debug */,
+ OBJ_143 /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
- 52D6D9901BEFF229002C0205 /* Build configuration list for PBXNativeTarget "SkeletonView-iOS" */ = {
+ OBJ_2 /* Build configuration list for PBXProject "SkeletonView" */ = {
isa = XCConfigurationList;
buildConfigurations = (
- 52D6D9911BEFF229002C0205 /* Debug */,
- 52D6D9921BEFF229002C0205 /* Release */,
+ OBJ_3 /* Debug */,
+ OBJ_4 /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
- F5F89A011FABA607002E8FDA /* Build configuration list for PBXNativeTarget "SkeletonViewExample" */ = {
+ OBJ_82 /* Build configuration list for PBXNativeTarget "SkeletonView iOS" */ = {
isa = XCConfigurationList;
buildConfigurations = (
- F5F89A021FABA607002E8FDA /* Debug */,
- F5F89A031FABA607002E8FDA /* Release */,
+ OBJ_83 /* Debug */,
+ OBJ_84 /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
/* End XCConfigurationList section */
};
- rootObject = 52D6D9731BEFF229002C0205 /* Project object */;
+ rootObject = OBJ_1 /* Project object */;
}
diff --git a/SkeletonView.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/SkeletonView.xcodeproj/project.xcworkspace/contents.xcworkspacedata
index 919434a6..fe1aa713 100644
--- a/SkeletonView.xcodeproj/project.xcworkspace/contents.xcworkspacedata
+++ b/SkeletonView.xcodeproj/project.xcworkspace/contents.xcworkspacedata
@@ -4,4 +4,4 @@
-
+
\ No newline at end of file
diff --git a/SkeletonView.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings b/SkeletonView.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings
new file mode 100644
index 00000000..a72dc2b4
--- /dev/null
+++ b/SkeletonView.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings
@@ -0,0 +1,8 @@
+
+
+
+
+ IDEWorkspaceSharedSettings_AutocreateContextsIfNeeded
+
+
+
\ No newline at end of file
diff --git a/SkeletonView.xcodeproj/xcshareddata/xcschemes/SkeletonView-tvOS.xcscheme b/SkeletonView.xcodeproj/xcshareddata/xcschemes/SkeletonView iOS.xcscheme
similarity index 65%
rename from SkeletonView.xcodeproj/xcshareddata/xcschemes/SkeletonView-tvOS.xcscheme
rename to SkeletonView.xcodeproj/xcshareddata/xcschemes/SkeletonView iOS.xcscheme
index ecc7cf17..4eb1d33a 100644
--- a/SkeletonView.xcodeproj/xcshareddata/xcschemes/SkeletonView-tvOS.xcscheme
+++ b/SkeletonView.xcodeproj/xcshareddata/xcschemes/SkeletonView iOS.xcscheme
@@ -1,6 +1,6 @@
@@ -28,9 +28,17 @@
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
shouldUseLaunchSchemeArgsEnv = "YES">
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/SkeletonView.xcodeproj/xcshareddata/xcschemes/SkeletonView-iOS.xcscheme b/SkeletonView.xcodeproj/xcshareddata/xcschemes/SkeletonView tvOS.xcscheme
similarity index 62%
rename from SkeletonView.xcodeproj/xcshareddata/xcschemes/SkeletonView-iOS.xcscheme
rename to SkeletonView.xcodeproj/xcshareddata/xcschemes/SkeletonView tvOS.xcscheme
index 39e602d2..f3927b95 100644
--- a/SkeletonView.xcodeproj/xcshareddata/xcschemes/SkeletonView-iOS.xcscheme
+++ b/SkeletonView.xcodeproj/xcshareddata/xcschemes/SkeletonView tvOS.xcscheme
@@ -1,6 +1,6 @@
+
+
+
+
@@ -28,18 +42,17 @@
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
shouldUseLaunchSchemeArgsEnv = "YES">
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/SkeletonView.xcodeproj/xcshareddata/xcschemes/SkeletonViewExample.xcscheme b/SkeletonView.xcodeproj/xcshareddata/xcschemes/SkeletonViewExample.xcscheme
deleted file mode 100644
index dfd918d9..00000000
--- a/SkeletonView.xcodeproj/xcshareddata/xcschemes/SkeletonViewExample.xcscheme
+++ /dev/null
@@ -1,87 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/SkeletonView.xcodeproj/xcshareddata/xcschemes/SkeletonViewExampleUICollectionView.xcscheme b/SkeletonView.xcodeproj/xcshareddata/xcschemes/SkeletonViewExampleUICollectionView.xcscheme
deleted file mode 100644
index 368b8def..00000000
--- a/SkeletonView.xcodeproj/xcshareddata/xcschemes/SkeletonViewExampleUICollectionView.xcscheme
+++ /dev/null
@@ -1,91 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/SkeletonViewCore/Sources/API/AnimationBuilder/SkeletonAnimationBuilder.swift b/SkeletonViewCore/Sources/API/AnimationBuilder/SkeletonAnimationBuilder.swift
new file mode 100644
index 00000000..321c9b13
--- /dev/null
+++ b/SkeletonViewCore/Sources/API/AnimationBuilder/SkeletonAnimationBuilder.swift
@@ -0,0 +1,39 @@
+//
+// SkeletonAnimationBuilder.swift
+// SkeletonView-iOS
+//
+// Created by Juanpe Catalán on 17/11/2017.
+// Copyright © 2017 SkeletonView. All rights reserved.
+//
+
+import UIKit
+
+public typealias SkeletonLayerAnimation = (CALayer) -> CAAnimation
+
+public class SkeletonAnimationBuilder {
+
+ public init() { }
+
+ public func makeSlidingAnimation(withDirection direction: GradientDirection, duration: CFTimeInterval = 1.5, autoreverses: Bool = false) -> SkeletonLayerAnimation {
+ { _ in
+ let startPointAnim = CABasicAnimation(keyPath: #keyPath(CAGradientLayer.startPoint))
+ startPointAnim.fromValue = direction.startPoint.from
+ startPointAnim.toValue = direction.startPoint.to
+
+ let endPointAnim = CABasicAnimation(keyPath: #keyPath(CAGradientLayer.endPoint))
+ endPointAnim.fromValue = direction.endPoint.from
+ endPointAnim.toValue = direction.endPoint.to
+
+ let animGroup = CAAnimationGroup()
+ animGroup.animations = [startPointAnim, endPointAnim]
+ animGroup.duration = duration
+ animGroup.timingFunction = CAMediaTimingFunction(name: CAMediaTimingFunctionName.easeIn)
+ animGroup.repeatCount = .infinity
+ animGroup.autoreverses = autoreverses
+ animGroup.isRemovedOnCompletion = false
+
+ return animGroup
+ }
+ }
+
+}
diff --git a/SkeletonViewCore/Sources/API/Appearance/SkeletonAppearance.swift b/SkeletonViewCore/Sources/API/Appearance/SkeletonAppearance.swift
new file mode 100644
index 00000000..82ed15c2
--- /dev/null
+++ b/SkeletonViewCore/Sources/API/Appearance/SkeletonAppearance.swift
@@ -0,0 +1,39 @@
+//
+// Copyright SkeletonView. All Rights Reserved.
+//
+// Licensed under the MIT License (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// https://opensource.org/licenses/MIT
+//
+// SkeletonAppearance.swift
+//
+
+import UIKit
+
+public enum SkeletonAppearance {
+ public static var `default` = SkeletonViewAppearance.shared
+}
+
+// codebeat:disable[TOO_MANY_IVARS]
+public class SkeletonViewAppearance {
+
+ static var shared = SkeletonViewAppearance()
+
+ public var tintColor: UIColor = .skeletonDefault
+
+ public var gradient = SkeletonGradient(baseColor: .skeletonDefault)
+
+ public var multilineHeight: CGFloat = 15
+
+ public var multilineSpacing: CGFloat = 10
+
+ public var multilineLastLineFillPercent: Int = 70
+
+ public var multilineCornerRadius: Int = 0
+
+ public var renderSingleLineAsView: Bool = false
+
+}
+// codebeat:enable[TOO_MANY_IVARS]
diff --git a/Sources/Collections/CollectionViews/SkeletonCollectionViewProtocols.swift b/SkeletonViewCore/Sources/API/Collections/CollectionViews/SkeletonCollectionViewProtocols.swift
similarity index 100%
rename from Sources/Collections/CollectionViews/SkeletonCollectionViewProtocols.swift
rename to SkeletonViewCore/Sources/API/Collections/CollectionViews/SkeletonCollectionViewProtocols.swift
diff --git a/Sources/Collections/TableViews/SkeletonTableViewProtocols.swift b/SkeletonViewCore/Sources/API/Collections/TableViews/SkeletonTableViewProtocols.swift
similarity index 94%
rename from Sources/Collections/TableViews/SkeletonTableViewProtocols.swift
rename to SkeletonViewCore/Sources/API/Collections/TableViews/SkeletonTableViewProtocols.swift
index c7e8648a..fa1f7faa 100644
--- a/Sources/Collections/TableViews/SkeletonTableViewProtocols.swift
+++ b/SkeletonViewCore/Sources/API/Collections/TableViews/SkeletonTableViewProtocols.swift
@@ -8,6 +8,12 @@
import UIKit
+extension UITableView {
+ public static let automaticNumberOfSkeletonRows = -1
+}
+
+public typealias ReusableHeaderFooterIdentifier = String
+
public protocol SkeletonTableViewDataSource: UITableViewDataSource {
func numSections(in collectionSkeletonView: UITableView) -> Int
func collectionSkeletonView(_ skeletonView: UITableView, numberOfRowsInSection section: Int) -> Int
diff --git a/SkeletonViewCore/Sources/API/Deprecated.swift b/SkeletonViewCore/Sources/API/Deprecated.swift
new file mode 100644
index 00000000..5f6ad3d0
--- /dev/null
+++ b/SkeletonViewCore/Sources/API/Deprecated.swift
@@ -0,0 +1,36 @@
+//
+// Copyright SkeletonView. All Rights Reserved.
+//
+// Licensed under the MIT License (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// https://opensource.org/licenses/MIT
+//
+// Deprecated.swift
+//
+// Created by Juanpe Catalán on 18/8/21.
+
+import Foundation
+
+public extension Notification.Name {
+
+ @available(*, deprecated, renamed: "skeletonWillAppear")
+ static let willBeginShowingSkeletons = Notification.Name.skeletonWillAppearNotification
+
+ @available(*, deprecated, renamed: "skeletonDidAppear")
+ static let didShowSkeletons = Notification.Name.skeletonDidAppearNotification
+
+ @available(*, deprecated, renamed: "skeletonWillUpdate")
+ static let willBeginUpdatingSkeletons = Notification.Name.skeletonWillUpdateNotification
+
+ @available(*, deprecated, renamed: "skeletonDidUpdate")
+ static let didUpdateSkeletons = Notification.Name.skeletonDidUpdateNotification
+
+ @available(*, deprecated, renamed: "skeletonWillDisappear")
+ static let willBeginHidingSkeletons = Notification.Name.skeletonWillDisappearNotification
+
+ @available(*, deprecated, renamed: "skeletonDidDisappear")
+ static let didHideSkeletons = Notification.Name.skeletonDidDisappearNotification
+
+}
diff --git a/SkeletonViewCore/Sources/API/FoundationExtensions/Notification+SkeletonFlow.swift b/SkeletonViewCore/Sources/API/FoundationExtensions/Notification+SkeletonFlow.swift
new file mode 100644
index 00000000..51f82749
--- /dev/null
+++ b/SkeletonViewCore/Sources/API/FoundationExtensions/Notification+SkeletonFlow.swift
@@ -0,0 +1,25 @@
+//
+// Copyright SkeletonView. All Rights Reserved.
+//
+// Licensed under the MIT License (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// https://opensource.org/licenses/MIT
+//
+// Notification+SkeletonFlow.swift
+//
+// Created by Juanpe Catalán on 18/8/21.
+
+import Foundation
+
+public extension Notification.Name {
+
+ static let skeletonWillAppearNotification = Notification.Name("skeletonWillAppear")
+ static let skeletonDidAppearNotification = Notification.Name("skeletonDidAppear")
+ static let skeletonWillUpdateNotification = Notification.Name("skeletonWillUpdate")
+ static let skeletonDidUpdateNotification = Notification.Name("skeletonDidUpdate")
+ static let skeletonWillDisappearNotification = Notification.Name("skeletonWillDisappear")
+ static let skeletonDidDisappearNotification = Notification.Name("skeletonDidDisappear")
+
+}
diff --git a/SkeletonViewCore/Sources/API/Models/GradientDirection.swift b/SkeletonViewCore/Sources/API/Models/GradientDirection.swift
new file mode 100644
index 00000000..0cd6011a
--- /dev/null
+++ b/SkeletonViewCore/Sources/API/Models/GradientDirection.swift
@@ -0,0 +1,29 @@
+//
+// Copyright SkeletonView. All Rights Reserved.
+//
+// Licensed under the MIT License (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// https://opensource.org/licenses/MIT
+//
+// GradientDirection.swift
+//
+// Created by Juanpe Catalán on 19/8/21.
+
+import UIKit
+
+public enum GradientDirection {
+
+ case leftRight
+ case rightLeft
+ case topBottom
+ case bottomTop
+ case topLeftBottomRight
+ case bottomRightTopLeft
+
+ public func slidingAnimation(duration: CFTimeInterval = 1.5, autoreverses: Bool = false) -> SkeletonLayerAnimation {
+ return SkeletonAnimationBuilder().makeSlidingAnimation(withDirection: self, duration: duration, autoreverses: autoreverses)
+ }
+
+}
diff --git a/Sources/SkeletonGradient.swift b/SkeletonViewCore/Sources/API/Models/SkeletonGradient.swift
similarity index 65%
rename from Sources/SkeletonGradient.swift
rename to SkeletonViewCore/Sources/API/Models/SkeletonGradient.swift
index e75c33d3..189de744 100644
--- a/Sources/SkeletonGradient.swift
+++ b/SkeletonViewCore/Sources/API/Models/SkeletonGradient.swift
@@ -1,14 +1,20 @@
//
+// Copyright SkeletonView. All Rights Reserved.
+//
+// Licensed under the MIT License (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// https://opensource.org/licenses/MIT
+//
// SkeletonGradient.swift
-// SkeletonView-iOS
//
// Created by Juanpe Catalán on 05/11/2017.
-// Copyright © 2017 SkeletonView. All rights reserved.
-//
import UIKit
public struct SkeletonGradient {
+
private let gradientColors: [UIColor]
public var colors: [UIColor] {
@@ -22,4 +28,5 @@ public struct SkeletonGradient {
self.gradientColors = baseColor.makeGradient()
}
}
+
}
diff --git a/Sources/Transitions/SkeletonTransitionStyle.swift b/SkeletonViewCore/Sources/API/Models/SkeletonTransitionStyle.swift
similarity index 100%
rename from Sources/Transitions/SkeletonTransitionStyle.swift
rename to SkeletonViewCore/Sources/API/Models/SkeletonTransitionStyle.swift
diff --git a/SkeletonViewCore/Sources/API/Models/SkeletonType.swift b/SkeletonViewCore/Sources/API/Models/SkeletonType.swift
new file mode 100644
index 00000000..0d97d5d7
--- /dev/null
+++ b/SkeletonViewCore/Sources/API/Models/SkeletonType.swift
@@ -0,0 +1,39 @@
+//
+// Copyright SkeletonView. All Rights Reserved.
+//
+// Licensed under the MIT License (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// https://opensource.org/licenses/MIT
+//
+// SkeletonType.swift
+//
+// Created by Juanpe Catalán on 19/8/21.
+
+import UIKit
+
+public enum SkeletonType {
+
+ case solid
+ case gradient
+
+ var layer: CALayer {
+ switch self {
+ case .solid:
+ return CALayer()
+ case .gradient:
+ return CAGradientLayer()
+ }
+ }
+
+ func defaultLayerAnimation(isRTL: Bool) -> SkeletonLayerAnimation {
+ switch self {
+ case .solid:
+ return { $0.pulse }
+ case .gradient:
+ return { SkeletonAnimationBuilder().makeSlidingAnimation(withDirection: isRTL ? .rightLeft : .leftRight) }()
+ }
+ }
+
+}
diff --git a/SkeletonViewCore/Sources/API/SkeletonView.swift b/SkeletonViewCore/Sources/API/SkeletonView.swift
new file mode 100644
index 00000000..8f4f5f77
--- /dev/null
+++ b/SkeletonViewCore/Sources/API/SkeletonView.swift
@@ -0,0 +1,150 @@
+//
+// Copyright SkeletonView. All Rights Reserved.
+//
+// Licensed under the MIT License (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// https://opensource.org/licenses/MIT
+//
+// PublicSkeletonView.swift
+//
+// Created by Juanpe Catalán on 18/8/21.
+
+import UIKit
+
+public extension UIView {
+ /// Shows the skeleton without animation using the view that calls this method as root view.
+ ///
+ /// - Parameters:
+ /// - color: The color of the skeleton. Defaults to `SkeletonAppearance.default.tintColor`.
+ /// - transition: The style of the transition when the skeleton appears. Defaults to `.crossDissolve(0.25)`.
+ func showSkeleton(usingColor color: UIColor = SkeletonAppearance.default.tintColor, transition: SkeletonTransitionStyle = .crossDissolve(0.25)) {
+ _delayedShowSkeletonWorkItem?.cancel()
+ let config = SkeletonConfig(type: .solid, colors: [color], transition: transition)
+ showSkeleton(skeletonConfig: config)
+ }
+
+ /// Shows the skeleton using the view that calls this method as root view.
+ ///
+ /// - Parameters:
+ /// - color: The color of the skeleton. Defaults to `SkeletonAppearance.default.tintColor`.
+ /// - animated: If the skeleton is animated or not. Defaults to `true`.
+ /// - delay: The amount of time (measured in seconds) to wait before show the skeleton.
+ /// - transition: The style of the transition when the skeleton appears. Defaults to `.crossDissolve(0.25)`.
+ func showSkeleton(usingColor color: UIColor = SkeletonAppearance.default.tintColor, animated: Bool = true, delay: TimeInterval, transition: SkeletonTransitionStyle = .crossDissolve(0.25)) {
+ _delayedShowSkeletonWorkItem?.cancel()
+
+ _delayedShowSkeletonWorkItem = DispatchWorkItem { [weak self] in
+ let config = SkeletonConfig(type: .solid, colors: [color], animated: animated, transition: transition)
+ self?.showSkeleton(skeletonConfig: config)
+ }
+
+ DispatchQueue.main.asyncAfter(deadline: .now() + delay, execute: _delayedShowSkeletonWorkItem!)
+ }
+
+ /// Shows the gradient skeleton without animation using the view that calls this method as root view.
+ ///
+ /// - Parameters:
+ /// - gradient: The gradient of the skeleton. Defaults to `SkeletonAppearance.default.gradient`.
+ /// - transition: The style of the transition when the skeleton appears. Defaults to `.crossDissolve(0.25)`.
+ func showGradientSkeleton(usingGradient gradient: SkeletonGradient = SkeletonAppearance.default.gradient, transition: SkeletonTransitionStyle = .crossDissolve(0.25)) {
+ _delayedShowSkeletonWorkItem?.cancel()
+ let config = SkeletonConfig(type: .gradient, colors: gradient.colors, transition: transition)
+ showSkeleton(skeletonConfig: config)
+ }
+
+ /// Shows the gradient skeleton using the view that calls this method as root view.
+ ///
+ /// - Parameters:
+ /// - gradient: The gradient of the skeleton. Defaults to `SkeletonAppearance.default.gradient`.
+ /// - animated: If the skeleton is animated or not. Defaults to `true`.
+ /// - delay: The amount of time (measured in seconds) to wait before show the skeleton.
+ /// - transition: The style of the transition when the skeleton appears. Defaults to `.crossDissolve(0.25)`.
+ func showGradientSkeleton(
+ usingGradient gradient: SkeletonGradient = SkeletonAppearance.default.gradient,
+ animated: Bool = true,
+ delay: TimeInterval,
+ transition: SkeletonTransitionStyle = .crossDissolve(0.25)
+ ) {
+ _delayedShowSkeletonWorkItem?.cancel()
+
+ _delayedShowSkeletonWorkItem = DispatchWorkItem { [weak self] in
+ let config = SkeletonConfig(type: .gradient, colors: gradient.colors, animated: animated, transition: transition)
+ self?.showSkeleton(skeletonConfig: config)
+ }
+
+ DispatchQueue.main.asyncAfter(deadline: .now() + delay, execute: _delayedShowSkeletonWorkItem!)
+ }
+
+ /// Shows the animated skeleton using the view that calls this method as root view.
+ ///
+ /// If animation is nil, sliding animation will be used, with direction left to right.
+ ///
+ /// - Parameters:
+ /// - color: The color of skeleton. Defaults to `SkeletonAppearance.default.tintColor`.
+ /// - animation: The animation of the skeleton. Defaults to `nil`.
+ /// - transition: The style of the transition when the skeleton appears. Defaults to `.crossDissolve(0.25)`.
+ func showAnimatedSkeleton(usingColor color: UIColor = SkeletonAppearance.default.tintColor, animation: SkeletonLayerAnimation? = nil, transition: SkeletonTransitionStyle = .crossDissolve(0.25)) {
+ _delayedShowSkeletonWorkItem?.cancel()
+ let config = SkeletonConfig(type: .solid, colors: [color], animated: true, animation: animation, transition: transition)
+ showSkeleton(skeletonConfig: config)
+ }
+
+ /// Shows the gradient skeleton without animation using the view that calls this method as root view.
+ ///
+ /// If animation is nil, sliding animation will be used, with direction left to right.
+ ///
+ /// - Parameters:
+ /// - gradient: The gradient of the skeleton. Defaults to `SkeletonAppearance.default.gradient`.
+ /// - animation: The animation of the skeleton. Defaults to `nil`.
+ /// - transition: The style of the transition when the skeleton appears. Defaults to `.crossDissolve(0.25)`.
+ func showAnimatedGradientSkeleton(usingGradient gradient: SkeletonGradient = SkeletonAppearance.default.gradient, animation: SkeletonLayerAnimation? = nil, transition: SkeletonTransitionStyle = .crossDissolve(0.25)) {
+ _delayedShowSkeletonWorkItem?.cancel()
+ let config = SkeletonConfig(type: .gradient, colors: gradient.colors, animated: true, animation: animation, transition: transition)
+ showSkeleton(skeletonConfig: config)
+ }
+
+ func updateSkeleton(usingColor color: UIColor = SkeletonAppearance.default.tintColor) {
+ let config = SkeletonConfig(type: .solid, colors: [color])
+ updateSkeleton(skeletonConfig: config)
+ }
+
+ func updateGradientSkeleton(usingGradient gradient: SkeletonGradient = SkeletonAppearance.default.gradient) {
+ let config = SkeletonConfig(type: .gradient, colors: gradient.colors)
+ updateSkeleton(skeletonConfig: config)
+ }
+
+ func updateAnimatedSkeleton(usingColor color: UIColor = SkeletonAppearance.default.tintColor, animation: SkeletonLayerAnimation? = nil) {
+ let config = SkeletonConfig(type: .solid, colors: [color], animated: true, animation: animation)
+ updateSkeleton(skeletonConfig: config)
+ }
+
+ func updateAnimatedGradientSkeleton(usingGradient gradient: SkeletonGradient = SkeletonAppearance.default.gradient, animation: SkeletonLayerAnimation? = nil) {
+ let config = SkeletonConfig(type: .gradient, colors: gradient.colors, animated: true, animation: animation)
+ updateSkeleton(skeletonConfig: config)
+ }
+
+ func layoutSkeletonIfNeeded() {
+ _flowDelegate?.willBeginLayingSkeletonsIfNeeded(rootView: self)
+ recursiveLayoutSkeletonIfNeeded(root: self)
+ }
+
+ func hideSkeleton(reloadDataAfter reload: Bool = true, transition: SkeletonTransitionStyle = .crossDissolve(0.25)) {
+ _delayedShowSkeletonWorkItem?.cancel()
+ _flowDelegate?.willBeginHidingSkeletons(rootView: self)
+ recursiveHideSkeleton(reloadDataAfter: reload, transition: transition, root: self)
+ }
+
+ func startSkeletonAnimation(_ anim: SkeletonLayerAnimation? = nil) {
+ subviewsSkeletonables.recursiveSearch(leafBlock: startSkeletonLayerAnimationBlock(anim)) { subview in
+ subview.startSkeletonAnimation(anim)
+ }
+ }
+
+ func stopSkeletonAnimation() {
+ subviewsSkeletonables.recursiveSearch(leafBlock: stopSkeletonLayerAnimationBlock) { subview in
+ subview.stopSkeletonAnimation()
+ }
+ }
+}
diff --git a/SkeletonViewCore/Sources/API/UIKitExtensions/CALayer+Animations.swift b/SkeletonViewCore/Sources/API/UIKitExtensions/CALayer+Animations.swift
new file mode 100644
index 00000000..89d22194
--- /dev/null
+++ b/SkeletonViewCore/Sources/API/UIKitExtensions/CALayer+Animations.swift
@@ -0,0 +1,32 @@
+//
+// Copyright SkeletonView. All Rights Reserved.
+//
+// Licensed under the MIT License (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// https://opensource.org/licenses/MIT
+//
+// CALayer+Animations.swift
+//
+// Created by Juanpe Catalán on 18/8/21.
+
+import UIKit
+
+public extension CALayer {
+
+ var pulse: CAAnimation {
+ let pulseAnimation = CABasicAnimation(keyPath: #keyPath(CALayer.backgroundColor))
+ pulseAnimation.fromValue = backgroundColor
+
+ // swiftlint:disable:next force_unwrapping
+ pulseAnimation.toValue = UIColor(cgColor: backgroundColor!).complementaryColor.cgColor
+ pulseAnimation.duration = 1
+ pulseAnimation.timingFunction = CAMediaTimingFunction(name: CAMediaTimingFunctionName.easeInEaseOut)
+ pulseAnimation.autoreverses = true
+ pulseAnimation.repeatCount = .infinity
+ pulseAnimation.isRemovedOnCompletion = false
+ return pulseAnimation
+ }
+
+}
diff --git a/SkeletonViewCore/Sources/API/UIKitExtensions/UICollectionView+Extensions.swift b/SkeletonViewCore/Sources/API/UIKitExtensions/UICollectionView+Extensions.swift
new file mode 100644
index 00000000..b34361cd
--- /dev/null
+++ b/SkeletonViewCore/Sources/API/UIKitExtensions/UICollectionView+Extensions.swift
@@ -0,0 +1,34 @@
+//
+// Copyright SkeletonView. All Rights Reserved.
+//
+// Licensed under the MIT License (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// https://opensource.org/licenses/MIT
+//
+// UICollectionView+Extensions.swift
+//
+// Created by Juanpe Catalán on 19/8/21.
+
+import UIKit
+
+public extension UICollectionView {
+
+ static let automaticNumberOfSkeletonItems = -1
+
+ func prepareSkeleton(completion: @escaping (Bool) -> Void) {
+ guard let originalDataSource = self.dataSource as? SkeletonCollectionViewDataSource,
+ !(originalDataSource is SkeletonCollectionDataSource)
+ else { return }
+
+ let dataSource = SkeletonCollectionDataSource(collectionViewDataSource: originalDataSource, rowHeight: 0.0)
+ self.skeletonDataSource = dataSource
+ performBatchUpdates({
+ self.reloadData()
+ }) { done in
+ completion(done)
+
+ }
+ }
+}
diff --git a/SkeletonViewCore/Sources/API/UIKitExtensions/UILabel+IBInspectable.swift b/SkeletonViewCore/Sources/API/UIKitExtensions/UILabel+IBInspectable.swift
new file mode 100644
index 00000000..32c42ffa
--- /dev/null
+++ b/SkeletonViewCore/Sources/API/UIKitExtensions/UILabel+IBInspectable.swift
@@ -0,0 +1,36 @@
+//
+// Copyright SkeletonView. All Rights Reserved.
+//
+// Licensed under the MIT License (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// https://opensource.org/licenses/MIT
+//
+// UILabel+IBInspectable.swift
+//
+// Created by Juanpe Catalán on 19/8/21.
+
+import UIKit
+
+public extension UILabel {
+
+ @IBInspectable
+ var lastLineFillPercent: Int {
+ get { return lastLineFillingPercent }
+ set { lastLineFillingPercent = min(newValue, 100) }
+ }
+
+ @IBInspectable
+ var linesCornerRadius: Int {
+ get { return multilineCornerRadius }
+ set { multilineCornerRadius = newValue }
+ }
+
+ @IBInspectable
+ var skeletonLineSpacing: CGFloat {
+ get { return multilineSpacing }
+ set { multilineSpacing = newValue }
+ }
+
+}
diff --git a/SkeletonViewCore/Sources/API/UIKitExtensions/UITextView+IBInspectable.swift b/SkeletonViewCore/Sources/API/UIKitExtensions/UITextView+IBInspectable.swift
new file mode 100644
index 00000000..316ccfd6
--- /dev/null
+++ b/SkeletonViewCore/Sources/API/UIKitExtensions/UITextView+IBInspectable.swift
@@ -0,0 +1,36 @@
+//
+// Copyright SkeletonView. All Rights Reserved.
+//
+// Licensed under the MIT License (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// https://opensource.org/licenses/MIT
+//
+// UITextView+IBInspectable.swift
+//
+// Created by Juanpe Catalán on 19/8/21.
+
+import UIKit
+
+public extension UITextView {
+
+ @IBInspectable
+ var lastLineFillPercent: Int {
+ get { return lastLineFillingPercent }
+ set { lastLineFillingPercent = min(newValue, 100) }
+ }
+
+ @IBInspectable
+ var linesCornerRadius: Int {
+ get { return multilineCornerRadius }
+ set { multilineCornerRadius = newValue }
+ }
+
+ @IBInspectable
+ var skeletonLineSpacing: CGFloat {
+ get { return multilineSpacing }
+ set { multilineSpacing = newValue }
+ }
+
+}
diff --git a/SkeletonViewCore/Sources/API/UIKitExtensions/UIView+Debug.swift b/SkeletonViewCore/Sources/API/UIKitExtensions/UIView+Debug.swift
new file mode 100644
index 00000000..dfc33bc0
--- /dev/null
+++ b/SkeletonViewCore/Sources/API/UIKitExtensions/UIView+Debug.swift
@@ -0,0 +1,35 @@
+//
+// Copyright SkeletonView. All Rights Reserved.
+//
+// Licensed under the MIT License (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// https://opensource.org/licenses/MIT
+//
+// UIView+Debug.swift
+//
+// Created by Juanpe Catalán on 18/8/21.
+
+import UIKit
+
+public extension UIView {
+
+ /// Returns a string that describes the hierarchy of the skeleton, indicating
+ /// whether the receiver is skeletonable and all skeletonable children.
+ var skeletonDescription: String {
+ var description = "<\(type(of: self)): \(Unmanaged.passUnretained(self).toOpaque())"
+ let subSkeletons = subviewsSkeletonables
+
+ if !subSkeletons.isEmpty {
+ description += " | (\(subSkeletons.count)) subSkeletons"
+ }
+
+ if isSkeletonable {
+ description += " | ☠️ "
+ }
+
+ return description + ">"
+ }
+
+}
diff --git a/SkeletonViewCore/Sources/API/UIKitExtensions/UIView+Flags.swift b/SkeletonViewCore/Sources/API/UIKitExtensions/UIView+Flags.swift
new file mode 100644
index 00000000..2471dd4f
--- /dev/null
+++ b/SkeletonViewCore/Sources/API/UIKitExtensions/UIView+Flags.swift
@@ -0,0 +1,22 @@
+//
+// Copyright SkeletonView. All Rights Reserved.
+//
+// Licensed under the MIT License (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// https://opensource.org/licenses/MIT
+//
+// UIView+Flags.swift
+//
+// Created by Juanpe Catalán on 19/8/21.
+
+import UIKit
+
+public extension UIView {
+
+ var isSkeletonActive: Bool {
+ return _status == .on || subviewsSkeletonables.contains(where: { $0.isSkeletonActive })
+ }
+
+}
diff --git a/SkeletonViewCore/Sources/API/UIKitExtensions/UIView+IBInspectable.swift b/SkeletonViewCore/Sources/API/UIKitExtensions/UIView+IBInspectable.swift
new file mode 100644
index 00000000..b5a83e01
--- /dev/null
+++ b/SkeletonViewCore/Sources/API/UIKitExtensions/UIView+IBInspectable.swift
@@ -0,0 +1,42 @@
+//
+// Copyright SkeletonView. All Rights Reserved.
+//
+// Licensed under the MIT License (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// https://opensource.org/licenses/MIT
+//
+// UIView+IBInspectable.swift
+//
+// Created by Juanpe Catalán on 18/8/21.
+
+import UIKit
+
+public extension UIView {
+
+ @IBInspectable
+ var isSkeletonable: Bool {
+ get { _skeletonable }
+ set { _skeletonable = newValue }
+ }
+
+ @IBInspectable
+ var isHiddenWhenSkeletonIsActive: Bool {
+ get { _hiddenWhenSkeletonIsActive }
+ set { _hiddenWhenSkeletonIsActive = newValue }
+ }
+
+ @IBInspectable
+ var isUserInteractionDisabledWhenSkeletonIsActive: Bool {
+ get { _disabledWhenSkeletonIsActive }
+ set { _disabledWhenSkeletonIsActive = newValue }
+ }
+
+ @IBInspectable
+ var skeletonCornerRadius: Float {
+ get { _skeletonableCornerRadius }
+ set { _skeletonableCornerRadius = newValue }
+ }
+
+}
diff --git a/Sources/Collections/CollectionSkeletonProtocol.swift b/SkeletonViewCore/Sources/Internal/Collections/CollectionSkeleton.swift
similarity index 98%
rename from Sources/Collections/CollectionSkeletonProtocol.swift
rename to SkeletonViewCore/Sources/Internal/Collections/CollectionSkeleton.swift
index 9aff9706..578ad596 100644
--- a/Sources/Collections/CollectionSkeletonProtocol.swift
+++ b/SkeletonViewCore/Sources/Internal/Collections/CollectionSkeleton.swift
@@ -14,6 +14,7 @@ enum CollectionAssociatedKeys {
}
protocol CollectionSkeleton {
+
var skeletonDataSource: SkeletonCollectionDataSource? { get set }
var skeletonDelegate: SkeletonCollectionDelegate? { get set }
var estimatedNumberOfRows: Int { get }
@@ -23,9 +24,11 @@ protocol CollectionSkeleton {
func removeDummyDataSource(reloadAfter: Bool)
func disableUserInteraction()
func enableUserInteraction()
+
}
extension CollectionSkeleton where Self: UIScrollView {
+
var estimatedNumberOfRows: Int { return 0 }
func addDummyDataSource() {}
func removeDummyDataSource(reloadAfter: Bool) {}
@@ -43,4 +46,5 @@ extension CollectionSkeleton where Self: UIScrollView {
isScrollEnabled = true
}
}
+
}
diff --git a/Sources/Collections/SkeletonCollectionDataSource.swift b/SkeletonViewCore/Sources/Internal/Collections/SkeletonCollectionDataSource.swift
similarity index 98%
rename from Sources/Collections/SkeletonCollectionDataSource.swift
rename to SkeletonViewCore/Sources/Internal/Collections/SkeletonCollectionDataSource.swift
index dc86feb1..b18e9149 100644
--- a/Sources/Collections/SkeletonCollectionDataSource.swift
+++ b/SkeletonViewCore/Sources/Internal/Collections/SkeletonCollectionDataSource.swift
@@ -115,7 +115,7 @@ extension SkeletonCollectionDataSource: UICollectionViewDataSource {
extension SkeletonCollectionDataSource {
private func skeletonViewIfContainerSkeletonIsActive(container: UIView, view: UIView) {
guard container.isSkeletonActive,
- let skeletonConfig = container.currentSkeletonConfig else {
+ let skeletonConfig = container._currentSkeletonConfig else {
return
}
diff --git a/Sources/Collections/SkeletonCollectionDelegate.swift b/SkeletonViewCore/Sources/Internal/Collections/SkeletonCollectionDelegate.swift
similarity index 97%
rename from Sources/Collections/SkeletonCollectionDelegate.swift
rename to SkeletonViewCore/Sources/Internal/Collections/SkeletonCollectionDelegate.swift
index c9a02c54..3a8fd40d 100644
--- a/Sources/Collections/SkeletonCollectionDelegate.swift
+++ b/SkeletonViewCore/Sources/Internal/Collections/SkeletonCollectionDelegate.swift
@@ -56,7 +56,7 @@ extension SkeletonCollectionDelegate: UICollectionViewDelegate { }
extension SkeletonCollectionDelegate {
private func skeletonViewIfContainerSkeletonIsActive(container: UIView, view: UIView) {
guard container.isSkeletonActive,
- let skeletonConfig = container.currentSkeletonConfig else {
+ let skeletonConfig = container._currentSkeletonConfig else {
return
}
diff --git a/Sources/Collections/Generics/SkeletonReusableCell.swift b/SkeletonViewCore/Sources/Internal/Collections/SkeletonReusableCell.swift
similarity index 100%
rename from Sources/Collections/Generics/SkeletonReusableCell.swift
rename to SkeletonViewCore/Sources/Internal/Collections/SkeletonReusableCell.swift
diff --git a/SkeletonViewCore/Sources/Internal/Debug/SkeletonDebug.swift b/SkeletonViewCore/Sources/Internal/Debug/SkeletonDebug.swift
new file mode 100644
index 00000000..18b2dc8b
--- /dev/null
+++ b/SkeletonViewCore/Sources/Internal/Debug/SkeletonDebug.swift
@@ -0,0 +1,52 @@
+//
+// Copyright SkeletonView. All Rights Reserved.
+//
+// Licensed under the MIT License (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// https://opensource.org/licenses/MIT
+//
+// SkeletonDebug.swift
+//
+// Created by Juanpe Catalán on 18/8/21.
+
+import Foundation
+import UIKit
+
+enum SkeletonEnvironmentKey: String {
+ case debugMode = "SKELETON_DEBUG"
+}
+
+extension Dictionary {
+ subscript (_ key: SkeletonEnvironmentKey) -> Value? {
+ // swiftlint:disable:next force_cast
+ return self[key.rawValue as! Key]
+ }
+}
+
+func printSkeletonHierarchy(in view: UIView) {
+ skeletonLog(view.skeletonHierarchy())
+}
+
+func skeletonLog(_ message: String) {
+ #if DEBUG
+ if ProcessInfo.processInfo.environment[.debugMode] != nil {
+ print(message)
+ }
+ #endif
+}
+
+extension UIView {
+
+ func skeletonHierarchy(indentationLevel level: Int = 0) -> String {
+ var description = level == 0 ? "\n ⬇⬇ ☠️ Root view hierarchy with Skeletons ⬇⬇ \n" : ""
+ description += "\(level == 0 ? "\n" : 3.whitespaces) \(skeletonDescription) \n"
+ subviewsToSkeleton.forEach {
+ description += (level + 2).whitespaces
+ description += $0.skeletonHierarchy(indentationLevel: level + 1)
+ }
+ return description
+ }
+
+}
diff --git a/SkeletonViewCore/Sources/Internal/FoundationExtensions/DispatchQueue+Extensions.swift b/SkeletonViewCore/Sources/Internal/FoundationExtensions/DispatchQueue+Extensions.swift
new file mode 100644
index 00000000..20740e37
--- /dev/null
+++ b/SkeletonViewCore/Sources/Internal/FoundationExtensions/DispatchQueue+Extensions.swift
@@ -0,0 +1,37 @@
+//
+// Copyright SkeletonView. All Rights Reserved.
+//
+// Licensed under the MIT License (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// https://opensource.org/licenses/MIT
+//
+// DispatchQueue+Extensions.swift
+//
+// Created by Juanpe Catalán on 19/8/21.
+
+import Foundation
+
+extension DispatchQueue {
+
+ private static var _onceTracker = [String]()
+
+ class func once(token: String, block: () -> Void) {
+ objc_sync_enter(self)
+ defer { objc_sync_exit(self) }
+ guard !_onceTracker.contains(token) else { return }
+
+ _onceTracker.append(token)
+ block()
+ }
+
+ class func removeOnce(token: String, block: () -> Void) {
+ objc_sync_enter(self)
+ defer { objc_sync_exit(self) }
+ guard let index = _onceTracker.firstIndex(of: token) else { return }
+ _onceTracker.remove(at: index)
+ block()
+ }
+
+}
diff --git a/SkeletonViewCore/Sources/Internal/FoundationExtensions/Int+Extensions.swift b/SkeletonViewCore/Sources/Internal/FoundationExtensions/Int+Extensions.swift
new file mode 100644
index 00000000..c1149445
--- /dev/null
+++ b/SkeletonViewCore/Sources/Internal/FoundationExtensions/Int+Extensions.swift
@@ -0,0 +1,25 @@
+//
+// Copyright SkeletonView. All Rights Reserved.
+//
+// Licensed under the MIT License (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// https://opensource.org/licenses/MIT
+//
+// Int+Extensions.swift
+//
+
+import Foundation
+
+extension Int {
+
+ var whitespace: String {
+ whitespaces
+ }
+
+ var whitespaces: String {
+ String(repeating: " ", count: self)
+ }
+
+}
diff --git a/SkeletonViewCore/Sources/Internal/FoundationExtensions/Notification+Extensions.swift b/SkeletonViewCore/Sources/Internal/FoundationExtensions/Notification+Extensions.swift
new file mode 100644
index 00000000..959c6365
--- /dev/null
+++ b/SkeletonViewCore/Sources/Internal/FoundationExtensions/Notification+Extensions.swift
@@ -0,0 +1,22 @@
+//
+// Copyright SkeletonView. All Rights Reserved.
+//
+// Licensed under the MIT License (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// https://opensource.org/licenses/MIT
+//
+// Notification+Extensions.swift
+//
+// Created by Juanpe Catalán on 18/8/21.
+
+import UIKit
+
+extension Notification.Name {
+
+ static let applicationDidBecomeActiveNotification = UIApplication.didBecomeActiveNotification
+ static let applicationWillTerminateNotification = UIApplication.willTerminateNotification
+ static let applicationDidEnterForegroundNotification = UIApplication.didEnterBackgroundNotification
+
+}
diff --git a/SkeletonViewCore/Sources/Internal/FoundationExtensions/ProcessInfo+Extensions.swift b/SkeletonViewCore/Sources/Internal/FoundationExtensions/ProcessInfo+Extensions.swift
new file mode 100644
index 00000000..1b8032be
--- /dev/null
+++ b/SkeletonViewCore/Sources/Internal/FoundationExtensions/ProcessInfo+Extensions.swift
@@ -0,0 +1,26 @@
+//
+// Copyright SkeletonView. All Rights Reserved.
+//
+// Licensed under the MIT License (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// https://opensource.org/licenses/MIT
+//
+// ProcessInfo+Extensions.swift
+//
+// Created by Juanpe Catalán on 18/8/21.
+
+import Foundation
+
+extension ProcessInfo {
+
+ enum Constants {
+ static let testConfigurationFilePathKey = "XCTestConfigurationFilePath"
+ }
+
+ static var isRunningXCTest: Bool {
+ return processInfo.environment[Constants.testConfigurationFilePathKey] != nil
+ }
+
+}
diff --git a/Sources/Helpers/AssociationPolicy.swift b/SkeletonViewCore/Sources/Internal/Helpers/AssociationPolicy.swift
similarity index 98%
rename from Sources/Helpers/AssociationPolicy.swift
rename to SkeletonViewCore/Sources/Internal/Helpers/AssociationPolicy.swift
index 6d6323f0..e3fade58 100644
--- a/Sources/Helpers/AssociationPolicy.swift
+++ b/SkeletonViewCore/Sources/Internal/Helpers/AssociationPolicy.swift
@@ -19,7 +19,6 @@ enum AssociationPolicy: UInt {
protocol AssociatedObjects: AnyObject { }
-// transparent wrappers
extension AssociatedObjects {
/// wrapper around `objc_getAssociatedObject`
func ao_get(pkey: UnsafeRawPointer) -> Any? {
diff --git a/Sources/Helpers/RecursiveProtocol.swift b/SkeletonViewCore/Sources/Internal/Helpers/Recursive.swift
similarity index 100%
rename from Sources/Helpers/RecursiveProtocol.swift
rename to SkeletonViewCore/Sources/Internal/Helpers/Recursive.swift
diff --git a/Sources/Helpers/Swizzling.swift b/SkeletonViewCore/Sources/Internal/Helpers/Swizzling.swift
similarity index 56%
rename from Sources/Helpers/Swizzling.swift
rename to SkeletonViewCore/Sources/Internal/Helpers/Swizzling.swift
index 76d0e322..af3e24c8 100644
--- a/Sources/Helpers/Swizzling.swift
+++ b/SkeletonViewCore/Sources/Internal/Helpers/Swizzling.swift
@@ -2,25 +2,6 @@
import Foundation
-extension DispatchQueue {
- private static var _onceTracker = [String]()
-
- class func once(token: String, block: () -> Void) {
- objc_sync_enter(self); defer { objc_sync_exit(self) }
- guard !_onceTracker.contains(token) else { return }
-
- _onceTracker.append(token)
- block()
- }
-
- class func removeOnce(token: String, block: () -> Void) {
- objc_sync_enter(self); defer { objc_sync_exit(self) }
- guard let index = _onceTracker.firstIndex(of: token) else { return }
- _onceTracker.remove(at: index)
- block()
- }
-}
-
func swizzle(selector originalSelector: Selector, with swizzledSelector: Selector, inClass: AnyClass, usingClass: AnyClass) {
guard let originalMethod = class_getInstanceMethod(inClass, originalSelector),
let swizzledMethod = class_getInstanceMethod(usingClass, swizzledSelector)
diff --git a/Sources/Recoverable/RecoverableViewState.swift b/SkeletonViewCore/Sources/Internal/Models/RecoverableViewState.swift
similarity index 99%
rename from Sources/Recoverable/RecoverableViewState.swift
rename to SkeletonViewCore/Sources/Internal/Models/RecoverableViewState.swift
index 70358af2..281ef429 100644
--- a/Sources/Recoverable/RecoverableViewState.swift
+++ b/SkeletonViewCore/Sources/Internal/Models/RecoverableViewState.swift
@@ -9,6 +9,7 @@
import UIKit
struct RecoverableViewState {
+
var backgroundColor: UIColor?
var cornerRadius: CGFloat
var clipToBounds: Bool
@@ -20,6 +21,7 @@ struct RecoverableViewState {
self.cornerRadius = view.layer.cornerRadius
self.isUserInteractionsEnabled = view.isUserInteractionEnabled
}
+
}
struct RecoverableTextViewState {
diff --git a/Sources/SkeletonLayer.swift b/SkeletonViewCore/Sources/Internal/Models/SkeletonLayer.swift
similarity index 85%
rename from Sources/SkeletonLayer.swift
rename to SkeletonViewCore/Sources/Internal/Models/SkeletonLayer.swift
index 96063af6..fc065c09 100755
--- a/Sources/SkeletonLayer.swift
+++ b/SkeletonViewCore/Sources/Internal/Models/SkeletonLayer.swift
@@ -8,32 +8,8 @@
import UIKit
-public typealias SkeletonLayerAnimation = (CALayer) -> CAAnimation
-
-public enum SkeletonType {
- case solid
- case gradient
-
- var layer: CALayer {
- switch self {
- case .solid:
- return CALayer()
- case .gradient:
- return CAGradientLayer()
- }
- }
-
- func defaultLayerAnimation(isRTL: Bool) -> SkeletonLayerAnimation {
- switch self {
- case .solid:
- return { $0.pulse }
- case .gradient:
- return { SkeletonAnimationBuilder().makeSlidingAnimation(withDirection: isRTL ? .rightLeft : .leftRight) }()
- }
- }
-}
-
struct SkeletonLayer {
+
private var maskLayer: CALayer
private weak var holder: UIView?
@@ -111,16 +87,18 @@ struct SkeletonLayer {
maskLayer.updateMultilinesLayers(for: config)
}
- var holderAsTextView: ContainsMultilineText? {
- guard let textView = holder as? ContainsMultilineText,
+ var holderAsTextView: SkeletonTextNode? {
+ guard let textView = holder as? SkeletonTextNode,
(textView.numberOfLines == -1 || textView.numberOfLines == 0 || textView.numberOfLines > 1 || textView.numberOfLines == 1 && !SkeletonAppearance.default.renderSingleLineAsView) else {
return nil
}
return textView
}
+
}
extension SkeletonLayer {
+
func start(_ anim: SkeletonLayerAnimation? = nil, completion: (() -> Void)? = nil) {
let animation = anim ?? type.defaultLayerAnimation(isRTL: holder?.isRTL ?? false)
contentLayer.playAnimation(animation, key: "skeletonAnimation", completion: completion)
@@ -129,4 +107,5 @@ extension SkeletonLayer {
func stopAnimation() {
contentLayer.stopAnimation(forKey: "skeletonAnimation")
}
+
}
diff --git a/Sources/SkeletonConfig.swift b/SkeletonViewCore/Sources/Internal/SkeletonConfigs/SkeletonConfig.swift
similarity index 100%
rename from Sources/SkeletonConfig.swift
rename to SkeletonViewCore/Sources/Internal/SkeletonConfigs/SkeletonConfig.swift
diff --git a/SkeletonViewCore/Sources/Internal/SkeletonConfigs/SkeletonMultilinesLayerConfig.swift b/SkeletonViewCore/Sources/Internal/SkeletonConfigs/SkeletonMultilinesLayerConfig.swift
new file mode 100644
index 00000000..4d7e371a
--- /dev/null
+++ b/SkeletonViewCore/Sources/Internal/SkeletonConfigs/SkeletonMultilinesLayerConfig.swift
@@ -0,0 +1,36 @@
+//
+// Copyright SkeletonView. All Rights Reserved.
+//
+// Licensed under the MIT License (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// https://opensource.org/licenses/MIT
+//
+// SkeletonMultilinesLayerConfig.swift
+//
+// Created by Juanpe Catalán on 18/8/21.
+
+import UIKit
+
+struct SkeletonMultilinesLayerConfig {
+
+ var lines: Int
+ var lineHeight: CGFloat
+ var type: SkeletonType
+ var lastLineFillPercent: Int
+ var multilineCornerRadius: Int
+ var multilineSpacing: CGFloat
+ var paddingInsets: UIEdgeInsets
+ var alignment: NSTextAlignment
+ var isRTL: Bool
+
+ /// Returns padding insets taking into account if the RTL is activated
+ var calculatedPaddingInsets: UIEdgeInsets {
+ UIEdgeInsets(top: paddingInsets.top,
+ left: isRTL ? paddingInsets.right : paddingInsets.left,
+ bottom: paddingInsets.bottom,
+ right: isRTL ? paddingInsets.left : paddingInsets.right)
+ }
+
+}
diff --git a/SkeletonViewCore/Sources/Internal/SkeletonExtensions/GradientDirection+Animations.swift b/SkeletonViewCore/Sources/Internal/SkeletonExtensions/GradientDirection+Animations.swift
new file mode 100644
index 00000000..791b7857
--- /dev/null
+++ b/SkeletonViewCore/Sources/Internal/SkeletonExtensions/GradientDirection+Animations.swift
@@ -0,0 +1,56 @@
+//
+// Copyright SkeletonView. All Rights Reserved.
+//
+// Licensed under the MIT License (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// https://opensource.org/licenses/MIT
+//
+// GradientDirection+Animations.swift
+//
+// Created by Juanpe Catalán on 19/8/21.
+
+import UIKit
+
+typealias GradientAnimationPoint = (from: CGPoint, to: CGPoint)
+
+extension GradientDirection {
+
+ // codebeat:disable[ABC]
+ var startPoint: GradientAnimationPoint {
+ switch self {
+ case .leftRight:
+ return (from: CGPoint(x: -1, y: 0.5), to: CGPoint(x: 1, y: 0.5))
+ case .rightLeft:
+ return (from: CGPoint(x: 1, y: 0.5), to: CGPoint(x: -1, y: 0.5))
+ case .topBottom:
+ return (from: CGPoint(x: 0.5, y: -1), to: CGPoint(x: 0.5, y: 1))
+ case .bottomTop:
+ return (from: CGPoint(x: 0.5, y: 1), to: CGPoint(x: 0.5, y: -1))
+ case .topLeftBottomRight:
+ return (from: CGPoint(x: -1, y: -1), to: CGPoint(x: 1, y: 1))
+ case .bottomRightTopLeft:
+ return (from: CGPoint(x: 1, y: 1), to: CGPoint(x: -1, y: -1))
+ }
+ }
+
+ var endPoint: GradientAnimationPoint {
+ switch self {
+ case .leftRight:
+ return (from: CGPoint(x: 0, y: 0.5), to: CGPoint(x: 2, y: 0.5))
+ case .rightLeft:
+ return ( from: CGPoint(x: 2, y: 0.5), to: CGPoint(x: 0, y: 0.5))
+ case .topBottom:
+ return ( from: CGPoint(x: 0.5, y: 0), to: CGPoint(x: 0.5, y: 2))
+ case .bottomTop:
+ return ( from: CGPoint(x: 0.5, y: 2), to: CGPoint(x: 0.5, y: 0))
+ case .topLeftBottomRight:
+ return ( from: CGPoint(x: 0, y: 0), to: CGPoint(x: 2, y: 2))
+ case .bottomRightTopLeft:
+ return ( from: CGPoint(x: 2, y: 2), to: CGPoint(x: 0, y: 0))
+ }
+ }
+ // codebeat:enable[ABC]
+
+}
diff --git a/Sources/Helpers/PrepareForSkeletonProtocol.swift b/SkeletonViewCore/Sources/Internal/SkeletonExtensions/PrepareViewForSkeleton.swift
old mode 100755
new mode 100644
similarity index 61%
rename from Sources/Helpers/PrepareForSkeletonProtocol.swift
rename to SkeletonViewCore/Sources/Internal/SkeletonExtensions/PrepareViewForSkeleton.swift
index 643c1790..660e6683
--- a/Sources/Helpers/PrepareForSkeletonProtocol.swift
+++ b/SkeletonViewCore/Sources/Internal/SkeletonExtensions/PrepareViewForSkeleton.swift
@@ -1,14 +1,20 @@
//
-// PrepareForSkeleton.swift
-// SkeletonView-iOS
+// Copyright SkeletonView. All Rights Reserved.
//
-// Created by Juanpe Catalán on 04/11/2017.
-// Copyright © 2017 SkeletonView. All rights reserved.
+// Licensed under the MIT License (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// https://opensource.org/licenses/MIT
//
+// PrepareViewForSkeleton.swift
+//
+// Created by Juanpe Catalán on 04/11/2017.
import UIKit
extension UIView {
+
@objc func prepareViewForSkeleton() {
if isUserInteractionDisabledWhenSkeletonIsActive {
isUserInteractionEnabled = false
@@ -18,39 +24,10 @@ extension UIView {
self?.backgroundColor = .clear
}
}
+
}
extension UILabel {
- var desiredHeightBasedOnNumberOfLines: CGFloat {
- let spaceNeededForEachLine = lineHeight * CGFloat(numberOfLines)
- let spaceNeededForSpaces = skeletonLineSpacing * CGFloat(numberOfLines - 1)
- let padding = paddingInsets.top + paddingInsets.bottom
-
- return spaceNeededForEachLine + spaceNeededForSpaces + padding
- }
-
- func updateHeightConstraintsIfNeeded() {
- guard numberOfLines > 1 || numberOfLines == 0 else { return }
-
- // Workaround to simulate content when the label is contained in a `UIStackView`.
- if isSuperviewAStackView, bounds.height == 0 {
- // This is a placeholder text to simulate content because it's contained in a stack view in order to prevent that the content size will be zero.
- text = " "
- }
-
- let desiredHeight = desiredHeightBasedOnNumberOfLines
- if desiredHeight > definedMaxHeight {
- backupHeightConstraints = heightConstraints
- NSLayoutConstraint.deactivate(heightConstraints)
- setHeight(equalToConstant: desiredHeight)
- }
- }
-
- func restoreBackupHeightConstraintsIfNeeded() {
- guard !backupHeightConstraints.isEmpty else { return }
- NSLayoutConstraint.activate(backupHeightConstraints)
- backupHeightConstraints.removeAll()
- }
override func prepareViewForSkeleton() {
backgroundColor = .clear
@@ -68,6 +45,7 @@ extension UILabel {
}
extension UITextView {
+
override func prepareViewForSkeleton() {
backgroundColor = .clear
@@ -80,9 +58,11 @@ extension UITextView {
self?.textColor = .clear
}
}
+
}
extension UITextField {
+
override func prepareViewForSkeleton() {
backgroundColor = .clear
resignFirstResponder()
@@ -92,9 +72,11 @@ extension UITextField {
self?.placeholder = nil
}
}
+
}
extension UIImageView {
+
override func prepareViewForSkeleton() {
backgroundColor = .clear
@@ -106,9 +88,11 @@ extension UIImageView {
self?.image = nil
}
}
+
}
extension UIButton {
+
override func prepareViewForSkeleton() {
backgroundColor = .clear
@@ -120,9 +104,11 @@ extension UIButton {
self?.setTitle(nil, for: .normal)
}
}
+
}
extension UITableViewHeaderFooterView {
+
override func prepareViewForSkeleton() {
backgroundView?.backgroundColor = .clear
@@ -130,4 +116,5 @@ extension UITableViewHeaderFooterView {
isUserInteractionEnabled = false
}
}
+
}
diff --git a/Sources/Recoverable/Recoverable.swift b/SkeletonViewCore/Sources/Internal/SkeletonExtensions/Recoverable.swift
similarity index 98%
rename from Sources/Recoverable/Recoverable.swift
rename to SkeletonViewCore/Sources/Internal/SkeletonExtensions/Recoverable.swift
index 0890aecc..9cfb4b15 100644
--- a/Sources/Recoverable/Recoverable.swift
+++ b/SkeletonViewCore/Sources/Internal/SkeletonExtensions/Recoverable.swift
@@ -14,6 +14,7 @@ protocol Recoverable {
}
extension UIView: Recoverable {
+
var viewState: RecoverableViewState? {
get { return ao_get(pkey: &ViewAssociatedKeys.viewState) as? RecoverableViewState }
set { ao_setOptional(newValue, pkey: &ViewAssociatedKeys.viewState) }
@@ -41,9 +42,11 @@ extension UIView: Recoverable {
}
}
}
+
}
extension UILabel {
+
var labelState: RecoverableTextViewState? {
get { return ao_get(pkey: &ViewAssociatedKeys.labelViewState) as? RecoverableTextViewState }
set { ao_setOptional(newValue, pkey: &ViewAssociatedKeys.labelViewState) }
@@ -70,9 +73,11 @@ extension UILabel {
}
}
}
+
}
extension UITextView {
+
var textState: RecoverableTextViewState? {
get { return ao_get(pkey: &ViewAssociatedKeys.labelViewState) as? RecoverableTextViewState }
set { ao_setOptional(newValue, pkey: &ViewAssociatedKeys.labelViewState) }
@@ -93,9 +98,11 @@ extension UITextView {
}
}
}
+
}
extension UITextField {
+
var textState: RecoverableTextFieldState? {
get { return ao_get(pkey: &ViewAssociatedKeys.labelViewState) as? RecoverableTextFieldState }
set { ao_setOptional(newValue, pkey: &ViewAssociatedKeys.labelViewState) }
@@ -120,9 +127,11 @@ extension UITextField {
}
}
}
+
}
extension UIImageView {
+
var imageState: RecoverableImageViewState? {
get { return ao_get(pkey: &ViewAssociatedKeys.imageViewState) as? RecoverableImageViewState }
set { ao_setOptional(newValue, pkey: &ViewAssociatedKeys.imageViewState) }
@@ -139,9 +148,11 @@ extension UIImageView {
self?.image = self?.image == nil || forced ? self?.imageState?.image : self?.image
}
}
+
}
extension UIButton {
+
var buttonState: RecoverableButtonViewState? {
get { return ao_get(pkey: &ViewAssociatedKeys.buttonViewState) as? RecoverableButtonViewState }
set { ao_setOptional(newValue, pkey: &ViewAssociatedKeys.buttonViewState) }
@@ -160,9 +171,11 @@ extension UIButton {
}
}
}
+
}
extension UITableViewHeaderFooterView {
+
var headerFooterState: RecoverableTableViewHeaderFooterViewState? {
get { return ao_get(pkey: &ViewAssociatedKeys.headerFooterViewState) as? RecoverableTableViewHeaderFooterViewState }
set { ao_setOptional(newValue, pkey: &ViewAssociatedKeys.headerFooterViewState) }
@@ -179,4 +192,5 @@ extension UITableViewHeaderFooterView {
self?.backgroundView?.backgroundColor = self?.headerFooterState?.backgroundViewColor
}
}
+
}
diff --git a/SkeletonViewCore/Sources/Internal/SkeletonExtensions/SkeletonTextNode.swift b/SkeletonViewCore/Sources/Internal/SkeletonExtensions/SkeletonTextNode.swift
new file mode 100644
index 00000000..49bb04bc
--- /dev/null
+++ b/SkeletonViewCore/Sources/Internal/SkeletonExtensions/SkeletonTextNode.swift
@@ -0,0 +1,119 @@
+//
+// Copyright SkeletonView. All Rights Reserved.
+//
+// Licensed under the MIT License (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// https://opensource.org/licenses/MIT
+//
+// SkeletonTextNode.swift
+//
+// Created by Juanpe Catalán on 19/8/21.
+
+import UIKit
+
+protocol SkeletonTextNode {
+
+ var lineHeight: CGFloat { get }
+ var numberOfLines: Int { get }
+ var textAlignment: NSTextAlignment { get }
+ var lastLineFillingPercent: Int { get }
+ var multilineCornerRadius: Int { get }
+ var multilineSpacing: CGFloat { get }
+ var paddingInsets: UIEdgeInsets { get }
+
+}
+
+enum SkeletonTextNodeAssociatedKeys {
+ static var lastLineFillingPercent = "lastLineFillingPercent"
+ static var multilineCornerRadius = "multilineCornerRadius"
+ static var multilineSpacing = "multilineSpacing"
+ static var paddingInsets = "paddingInsets"
+ static var backupHeightConstraints = "backupHeightConstraints"
+}
+
+extension UILabel: SkeletonTextNode {
+
+ var lineHeight: CGFloat {
+ if let fontLineHeight = font?.lineHeight {
+ if let heightConstraints = backupHeightConstraints.first?.constant {
+ return (fontLineHeight > heightConstraints) ? heightConstraints : fontLineHeight
+ }
+ return fontLineHeight
+ }
+ return SkeletonAppearance.default.multilineHeight
+ }
+
+ var lastLineFillingPercent: Int {
+ get { return ao_get(pkey: &SkeletonTextNodeAssociatedKeys.lastLineFillingPercent) as? Int ?? SkeletonAppearance.default.multilineLastLineFillPercent }
+ set { ao_set(newValue, pkey: &SkeletonTextNodeAssociatedKeys.lastLineFillingPercent) }
+ }
+
+ var multilineCornerRadius: Int {
+ get { return ao_get(pkey: &SkeletonTextNodeAssociatedKeys.multilineCornerRadius) as? Int ?? SkeletonAppearance.default.multilineCornerRadius }
+ set { ao_set(newValue, pkey: &SkeletonTextNodeAssociatedKeys.multilineCornerRadius) }
+ }
+
+ var multilineSpacing: CGFloat {
+ get { return ao_get(pkey: &SkeletonTextNodeAssociatedKeys.multilineSpacing) as? CGFloat ?? SkeletonAppearance.default.multilineSpacing }
+ set { ao_set(newValue, pkey: &SkeletonTextNodeAssociatedKeys.multilineSpacing) }
+ }
+
+ var paddingInsets: UIEdgeInsets {
+ get { return ao_get(pkey: &SkeletonTextNodeAssociatedKeys.paddingInsets) as? UIEdgeInsets ?? .zero }
+ set { ao_set(newValue, pkey: &SkeletonTextNodeAssociatedKeys.paddingInsets) }
+ }
+
+ var backupHeightConstraints: [NSLayoutConstraint] {
+ get { return ao_get(pkey: &SkeletonTextNodeAssociatedKeys.backupHeightConstraints) as? [NSLayoutConstraint] ?? [] }
+ set { ao_set(newValue, pkey: &SkeletonTextNodeAssociatedKeys.backupHeightConstraints) }
+ }
+
+}
+
+extension UITextView: SkeletonTextNode {
+
+ var lineHeight: CGFloat {
+ if let fontLineHeight = font?.lineHeight {
+ if let heightConstraints = heightConstraints.first?.constant {
+ return (fontLineHeight > heightConstraints) ? heightConstraints : fontLineHeight
+ }
+
+ return fontLineHeight
+ }
+
+ return SkeletonAppearance.default.multilineHeight
+ }
+
+ var numberOfLines: Int {
+ -1
+ }
+
+ var lastLineFillingPercent: Int {
+ get {
+ let defaultValue = SkeletonAppearance.default.multilineLastLineFillPercent
+ return ao_get(pkey: &SkeletonTextNodeAssociatedKeys.lastLineFillingPercent) as? Int ?? defaultValue
+ }
+ set { ao_set(newValue, pkey: &SkeletonTextNodeAssociatedKeys.lastLineFillingPercent) }
+ }
+
+ var multilineCornerRadius: Int {
+ get {
+ let defaultValue = SkeletonAppearance.default.multilineCornerRadius
+ return ao_get(pkey: &SkeletonTextNodeAssociatedKeys.multilineCornerRadius) as? Int ?? defaultValue
+ }
+ set { ao_set(newValue, pkey: &SkeletonTextNodeAssociatedKeys.multilineCornerRadius) }
+ }
+
+ var multilineSpacing: CGFloat {
+ get { return ao_get(pkey: &SkeletonTextNodeAssociatedKeys.multilineSpacing) as? CGFloat ?? SkeletonAppearance.default.multilineSpacing }
+ set { ao_set(newValue, pkey: &SkeletonTextNodeAssociatedKeys.multilineSpacing) }
+ }
+
+ var paddingInsets: UIEdgeInsets {
+ get { return ao_get(pkey: &SkeletonTextNodeAssociatedKeys.paddingInsets) as? UIEdgeInsets ?? .zero }
+ set { ao_set(newValue, pkey: &SkeletonTextNodeAssociatedKeys.paddingInsets) }
+ }
+
+}
diff --git a/Sources/SubviewsSkeletonables.swift b/SkeletonViewCore/Sources/Internal/SkeletonExtensions/SubviewsSkeletonables.swift
similarity index 98%
rename from Sources/SubviewsSkeletonables.swift
rename to SkeletonViewCore/Sources/Internal/SkeletonExtensions/SubviewsSkeletonables.swift
index d7acba02..17a87880 100644
--- a/Sources/SubviewsSkeletonables.swift
+++ b/SkeletonViewCore/Sources/Internal/SkeletonExtensions/SubviewsSkeletonables.swift
@@ -3,6 +3,7 @@
import UIKit
extension UIView {
+
@objc var subviewsSkeletonables: [UIView] {
subviewsToSkeleton.filter { $0.isSkeletonable }
}
@@ -10,9 +11,11 @@ extension UIView {
@objc var subviewsToSkeleton: [UIView] {
subviews
}
+
}
extension UITableView {
+
override var subviewsToSkeleton: [UIView] {
// on `UIViewController'S onViewDidLoad`, the window is still nil.
// Some developer trying to call `view.showAnimatedSkeleton()`
@@ -20,6 +23,7 @@ extension UITableView {
guard window != nil else { return [] }
return subviews
}
+
}
extension UITableViewCell {
diff --git a/SkeletonViewCore/Sources/Internal/SkeletonFlowHandler.swift b/SkeletonViewCore/Sources/Internal/SkeletonFlowHandler.swift
new file mode 100644
index 00000000..ef1ef325
--- /dev/null
+++ b/SkeletonViewCore/Sources/Internal/SkeletonFlowHandler.swift
@@ -0,0 +1,50 @@
+// Copyright © 2018 SkeletonView. All rights reserved.
+
+import UIKit
+
+protocol SkeletonFlowDelegate: AnyObject {
+ func willBeginShowingSkeletons(rootView: UIView)
+ func didShowSkeletons(rootView: UIView)
+ func willBeginUpdatingSkeletons(rootView: UIView)
+ func didUpdateSkeletons(rootView: UIView)
+ func willBeginLayingSkeletonsIfNeeded(rootView: UIView)
+ func didLayoutSkeletonsIfNeeded(rootView: UIView)
+ func willBeginHidingSkeletons(rootView: UIView)
+ func didHideSkeletons(rootView: UIView)
+}
+
+class SkeletonFlowHandler: SkeletonFlowDelegate {
+ func willBeginShowingSkeletons(rootView: UIView) {
+ NotificationCenter.default.post(name: .skeletonWillAppearNotification, object: rootView, userInfo: nil)
+ rootView.startObservingAppLifecycleNotifications()
+ }
+
+ func didShowSkeletons(rootView: UIView) {
+ printSkeletonHierarchy(in: rootView)
+ NotificationCenter.default.post(name: .skeletonWillAppearNotification, object: rootView, userInfo: nil)
+ }
+
+ func willBeginUpdatingSkeletons(rootView: UIView) {
+ NotificationCenter.default.post(name: .skeletonWillAppearNotification, object: rootView, userInfo: nil)
+ }
+
+ func didUpdateSkeletons(rootView: UIView) {
+ NotificationCenter.default.post(name: .skeletonWillAppearNotification, object: rootView, userInfo: nil)
+ }
+
+ func willBeginLayingSkeletonsIfNeeded(rootView: UIView) {
+ }
+
+ func didLayoutSkeletonsIfNeeded(rootView: UIView) {
+ }
+
+ func willBeginHidingSkeletons(rootView: UIView) {
+ NotificationCenter.default.post(name: .skeletonWillDisappearNotification, object: rootView, userInfo: nil)
+ rootView.stopObservingAppLifecycleNotications()
+ }
+
+ func didHideSkeletons(rootView: UIView) {
+ rootView._flowDelegate = nil
+ NotificationCenter.default.post(name: .skeletonDidDisappearNotification, object: rootView, userInfo: nil)
+ }
+}
diff --git a/Sources/Builders/SkeletonLayerBuilder.swift b/SkeletonViewCore/Sources/Internal/SkeletonLayerBuilders/SkeletonLayerBuilder.swift
similarity index 96%
rename from Sources/Builders/SkeletonLayerBuilder.swift
rename to SkeletonViewCore/Sources/Internal/SkeletonLayerBuilders/SkeletonLayerBuilder.swift
index b4e155db..3c6f5ada 100644
--- a/Sources/Builders/SkeletonLayerBuilder.swift
+++ b/SkeletonViewCore/Sources/Internal/SkeletonLayerBuilders/SkeletonLayerBuilder.swift
@@ -5,6 +5,7 @@ import UIKit
/// Object that facilitates the creation of skeleton layers,
/// based on the builder pattern
class SkeletonLayerBuilder {
+
var skeletonType: SkeletonType?
var colors: [UIColor] = []
var holder: UIView?
@@ -17,7 +18,7 @@ class SkeletonLayerBuilder {
@discardableResult
func addColor(_ color: UIColor) -> SkeletonLayerBuilder {
- return addColors([color])
+ addColors([color])
}
@discardableResult
@@ -42,4 +43,5 @@ class SkeletonLayerBuilder {
colors: colors,
skeletonHolder: holder)
}
+
}
diff --git a/Sources/Builders/SkeletonMultilineLayerBuilder.swift b/SkeletonViewCore/Sources/Internal/SkeletonLayerBuilders/SkeletonMultilineLayerBuilder.swift
similarity index 97%
rename from Sources/Builders/SkeletonMultilineLayerBuilder.swift
rename to SkeletonViewCore/Sources/Internal/SkeletonLayerBuilders/SkeletonMultilineLayerBuilder.swift
index 801c0dcf..159a152a 100644
--- a/Sources/Builders/SkeletonMultilineLayerBuilder.swift
+++ b/SkeletonViewCore/Sources/Internal/SkeletonLayerBuilders/SkeletonMultilineLayerBuilder.swift
@@ -5,6 +5,7 @@ import UIKit
/// Object that facilitates the creation of skeleton layers for multiline
/// elements, based on the builder pattern
class SkeletonMultilineLayerBuilder {
+
var skeletonType: SkeletonType?
var index: Int?
var height: CGFloat?
@@ -79,7 +80,7 @@ class SkeletonMultilineLayerBuilder {
let layer = type.layer
layer.anchorPoint = .zero
- layer.name = CALayer.skeletonSubLayersName
+ layer.name = CALayer.Constants.skeletonSubLayersName
layer.updateLayerFrame(for: index,
totalLines: layer.skeletonSublayers.count,
size: CGSize(width: width, height: height),
@@ -93,4 +94,5 @@ class SkeletonMultilineLayerBuilder {
return layer
}
+
}
diff --git a/Sources/Extensions/CALayer+Extensions.swift b/SkeletonViewCore/Sources/Internal/UIKitExtensions/CALayer+Extensions.swift
similarity index 71%
rename from Sources/Extensions/CALayer+Extensions.swift
rename to SkeletonViewCore/Sources/Internal/UIKitExtensions/CALayer+Extensions.swift
index 21171104..9aa6f81f 100644
--- a/Sources/Extensions/CALayer+Extensions.swift
+++ b/SkeletonViewCore/Sources/Internal/UIKitExtensions/CALayer+Extensions.swift
@@ -1,62 +1,143 @@
//
-// SkeletonLayer+Animations.swift
-// SkeletonView-iOS
+// Copyright SkeletonView. All Rights Reserved.
//
-// Created by Juanpe Catalán on 03/11/2017.
-// Copyright © 2017 SkeletonView. All rights reserved.
+// Licensed under the MIT License (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
//
+// https://opensource.org/licenses/MIT
+//
+// CALayer+Tint.swift
+//
+// Created by Juanpe Catalán on 18/8/21.
import UIKit
-extension CALayer {
- @objc func tint(withColors colors: [UIColor]) {
+extension CAGradientLayer {
+
+ override func tint(withColors colors: [UIColor]) {
skeletonSublayers.recursiveSearch(leafBlock: {
- backgroundColor = colors.first?.cgColor
+ self.colors = colors.map { $0.cgColor }
}) {
$0.tint(withColors: colors)
}
}
+
}
-extension CAGradientLayer {
- override func tint(withColors colors: [UIColor]) {
+extension CALayer {
+
+ enum Constants {
+ static let skeletonSubLayersName = "SkeletonSubLayersName"
+ }
+
+ var skeletonSublayers: [CALayer] {
+ return sublayers?.filter { $0.name == Constants.skeletonSubLayersName } ?? [CALayer]()
+ }
+
+ @objc func tint(withColors colors: [UIColor]) {
skeletonSublayers.recursiveSearch(leafBlock: {
- self.colors = colors.map { $0.cgColor }
+ backgroundColor = colors.first?.cgColor
}) {
$0.tint(withColors: colors)
}
}
+
+ func playAnimation(_ anim: SkeletonLayerAnimation, key: String, completion: (() -> Void)? = nil) {
+ skeletonSublayers.recursiveSearch(leafBlock: {
+ DispatchQueue.main.async { CATransaction.begin() }
+ DispatchQueue.main.async { CATransaction.setCompletionBlock(completion) }
+ add(anim(self), forKey: key)
+ DispatchQueue.main.async { CATransaction.commit() }
+ }) {
+ $0.playAnimation(anim, key: key, completion: completion)
+ }
+ }
+
+ func stopAnimation(forKey key: String) {
+ skeletonSublayers.recursiveSearch(leafBlock: {
+ removeAnimation(forKey: key)
+ }) {
+ $0.stopAnimation(forKey: key)
+ }
+ }
+
+ func setOpacity(from: Int, to: Int, duration: TimeInterval, completion: (() -> Void)?) {
+ DispatchQueue.main.async { CATransaction.begin() }
+ let animation = CABasicAnimation(keyPath: #keyPath(CALayer.opacity))
+ animation.fromValue = from
+ animation.toValue = to
+ animation.duration = duration
+ animation.timingFunction = CAMediaTimingFunction(name: CAMediaTimingFunctionName.easeInEaseOut)
+ DispatchQueue.main.async { CATransaction.setCompletionBlock(completion) }
+ add(animation, forKey: "setOpacityAnimation")
+ DispatchQueue.main.async { CATransaction.commit() }
+ }
+
+ func insertSkeletonLayer(_ sublayer: SkeletonLayer, atIndex index: UInt32, transition: SkeletonTransitionStyle, completion: (() -> Void)? = nil) {
+ insertSublayer(sublayer.contentLayer, at: index)
+ switch transition {
+ case .none:
+ completion?()
+ case .crossDissolve(let duration):
+ sublayer.contentLayer.setOpacity(from: 0, to: 1, duration: duration, completion: completion)
+ }
+ }
+
}
-struct SkeletonMultilinesLayerConfig {
- var lines: Int
- var lineHeight: CGFloat
- var type: SkeletonType
- var lastLineFillPercent: Int
- var multilineCornerRadius: Int
- var multilineSpacing: CGFloat
- var paddingInsets: UIEdgeInsets
- var alignment: NSTextAlignment
- var isRTL: Bool
+private extension CALayer {
- /// Returns padding insets taking into account if the RTL is activated
- var calculatedPaddingInsets: UIEdgeInsets {
- UIEdgeInsets(top: paddingInsets.top,
- left: isRTL ? paddingInsets.right : paddingInsets.left,
- bottom: paddingInsets.bottom,
- right: isRTL ? paddingInsets.left : paddingInsets.right)
+ func alignLayerFrame(_ rect: CGRect, alignment: NSTextAlignment, isRTL: Bool) -> CGRect {
+ var newRect = rect
+
+ switch alignment {
+ case .natural where isRTL,
+ .right:
+ newRect.origin.x = (superlayer?.bounds.width ?? 0) - rect.origin.x - rect.width
+ case .center:
+ newRect.origin.x = rect.origin.x + ((superlayer?.bounds.width ?? 0) - rect.width) / 2
+ case .natural, .left, .justified:
+ break
+ @unknown default:
+ break
+ }
+
+ return newRect
+ }
+
+ func calculatedWidthForLine(at index: Int, totalLines: Int, lastLineFillPercent: Int, paddingInsets: UIEdgeInsets) -> CGFloat {
+ var width = bounds.width - paddingInsets.left - paddingInsets.right
+ if index == totalLines - 1 && totalLines != 1 {
+ width = width * CGFloat(lastLineFillPercent) / 100
+ }
+ return width
+ }
+
+ func calculateNumLines(for config: SkeletonMultilinesLayerConfig) -> Int {
+ let definedNumberOfLines = config.lines
+ let requiredSpaceForEachLine = config.lineHeight + config.multilineSpacing
+ let neededLines = round(CGFloat(bounds.height - config.paddingInsets.top - config.paddingInsets.bottom) / CGFloat(requiredSpaceForEachLine))
+ guard neededLines.isNormal else {
+ return 0
+ }
+
+ let calculatedNumberOfLines = Int(neededLines)
+ guard calculatedNumberOfLines > 0 else {
+ return 1
+ }
+
+ if definedNumberOfLines > 0, definedNumberOfLines <= calculatedNumberOfLines {
+ return definedNumberOfLines
+ }
+
+ return calculatedNumberOfLines
}
}
-// MARK: Skeleton sublayers
extension CALayer {
- static let skeletonSubLayersName = "SkeletonSubLayersName"
-
- var skeletonSublayers: [CALayer] {
- return sublayers?.filter { $0.name == CALayer.skeletonSubLayersName } ?? [CALayer]()
- }
- func addMultilinesLayers(for config: SkeletonMultilinesLayerConfig) {
+ func addMultilinesLayers(for config: SkeletonMultilinesLayerConfig) {
let numberOfSublayers = config.lines > 0 ? config.lines : calculateNumLines(for: config)
var height = config.lineHeight
@@ -65,16 +146,16 @@ extension CALayer {
}
let layerBuilder = SkeletonMultilineLayerBuilder()
- .setSkeletonType(config.type)
- .setCornerRadius(config.multilineCornerRadius)
- .setMultilineSpacing(config.multilineSpacing)
+ .setSkeletonType(config.type)
+ .setCornerRadius(config.multilineCornerRadius)
+ .setMultilineSpacing(config.multilineSpacing)
.setPadding(config.paddingInsets)
.setHeight(height)
.setAlignment(config.alignment)
.setIsRTL(config.isRTL)
(0.. CGFloat {
- var width = bounds.width - paddingInsets.left - paddingInsets.right
- if index == totalLines - 1 && totalLines != 1 {
- width = width * CGFloat(lastLineFillPercent) / 100
- }
- return width
- }
-
func updateLayerFrame(for index: Int, totalLines: Int, size: CGSize, multilineSpacing: CGFloat, paddingInsets: UIEdgeInsets, alignment: NSTextAlignment, isRTL: Bool) {
let spaceRequiredForEachLine = size.height + multilineSpacing
let newFrame = CGRect(x: paddingInsets.left,
@@ -131,91 +204,4 @@ extension CALayer {
}
}
- private func calculateNumLines(for config: SkeletonMultilinesLayerConfig) -> Int {
- let definedNumberOfLines = config.lines
- let requiredSpaceForEachLine = config.lineHeight + config.multilineSpacing
- let neededLines = round(CGFloat(bounds.height - config.paddingInsets.top - config.paddingInsets.bottom) / CGFloat(requiredSpaceForEachLine))
- guard neededLines.isNormal else {
- return 0
- }
-
- let calculatedNumberOfLines = Int(neededLines)
- guard calculatedNumberOfLines > 0 else {
- return 1
- }
-
- if definedNumberOfLines > 0, definedNumberOfLines <= calculatedNumberOfLines {
- return definedNumberOfLines
- }
-
- return calculatedNumberOfLines
- }
-
- private func alignLayerFrame(_ rect: CGRect, alignment: NSTextAlignment, isRTL: Bool) -> CGRect {
- var newRect = rect
-
- switch alignment {
- case .natural where isRTL,
- .right:
- newRect.origin.x = (superlayer?.bounds.width ?? 0) - rect.origin.x - rect.width
- case .center:
- newRect.origin.x = rect.origin.x + ((superlayer?.bounds.width ?? 0) - rect.width) / 2
- case .natural, .left, .justified:
- break
- @unknown default:
- break
- }
-
- return newRect
- }
-}
-
-// MARK: Animations
-public extension CALayer {
- var pulse: CAAnimation {
- let pulseAnimation = CABasicAnimation(keyPath: #keyPath(CALayer.backgroundColor))
- pulseAnimation.fromValue = backgroundColor
-
- // swiftlint:disable:next force_unwrapping
- pulseAnimation.toValue = UIColor(cgColor: backgroundColor!).complementaryColor.cgColor
- pulseAnimation.duration = 1
- pulseAnimation.timingFunction = CAMediaTimingFunction(name: CAMediaTimingFunctionName.easeInEaseOut)
- pulseAnimation.autoreverses = true
- pulseAnimation.repeatCount = .infinity
- pulseAnimation.isRemovedOnCompletion = false
- return pulseAnimation
- }
-
- func playAnimation(_ anim: SkeletonLayerAnimation, key: String, completion: (() -> Void)? = nil) {
- skeletonSublayers.recursiveSearch(leafBlock: {
- DispatchQueue.main.async { CATransaction.begin() }
- DispatchQueue.main.async { CATransaction.setCompletionBlock(completion) }
- add(anim(self), forKey: key)
- DispatchQueue.main.async { CATransaction.commit() }
- }) {
- $0.playAnimation(anim, key: key, completion: completion)
- }
- }
-
- func stopAnimation(forKey key: String) {
- skeletonSublayers.recursiveSearch(leafBlock: {
- removeAnimation(forKey: key)
- }) {
- $0.stopAnimation(forKey: key)
- }
- }
-}
-
-extension CALayer {
- func setOpacity(from: Int, to: Int, duration: TimeInterval, completion: (() -> Void)?) {
- DispatchQueue.main.async { CATransaction.begin() }
- let animation = CABasicAnimation(keyPath: #keyPath(CALayer.opacity))
- animation.fromValue = from
- animation.toValue = to
- animation.duration = duration
- animation.timingFunction = CAMediaTimingFunction(name: CAMediaTimingFunctionName.easeInEaseOut)
- DispatchQueue.main.async { CATransaction.setCompletionBlock(completion) }
- add(animation, forKey: "setOpacityAnimation")
- DispatchQueue.main.async { CATransaction.commit() }
- }
}
diff --git a/Sources/Collections/CollectionViews/UICollectionView+CollectionSkeleton.swift b/SkeletonViewCore/Sources/Internal/UIKitExtensions/UICollectionView+CollectionSkeleton.swift
similarity index 74%
rename from Sources/Collections/CollectionViews/UICollectionView+CollectionSkeleton.swift
rename to SkeletonViewCore/Sources/Internal/UIKitExtensions/UICollectionView+CollectionSkeleton.swift
index 701185d7..c5c9451b 100644
--- a/Sources/Collections/CollectionViews/UICollectionView+CollectionSkeleton.swift
+++ b/SkeletonViewCore/Sources/Internal/UIKitExtensions/UICollectionView+CollectionSkeleton.swift
@@ -9,7 +9,6 @@
import UIKit
extension UICollectionView: CollectionSkeleton {
- public static let automaticNumberOfSkeletonItems = -1
var estimatedNumberOfRows: Int {
guard let flowlayout = collectionViewLayout as? UICollectionViewFlowLayout else { return 0 }
@@ -63,25 +62,5 @@ extension UICollectionView: CollectionSkeleton {
self.dataSource = dataSource.originalCollectionViewDataSource
if reloadAfter { self.reloadData() }
}
-}
-
-extension UICollectionView: GenericCollectionView {
- var scrollView: UIScrollView { return self }
-}
-
-public extension UICollectionView {
- func prepareSkeleton(completion: @escaping (Bool) -> Void) {
- guard let originalDataSource = self.dataSource as? SkeletonCollectionViewDataSource,
- !(originalDataSource is SkeletonCollectionDataSource)
- else { return }
-
- let dataSource = SkeletonCollectionDataSource(collectionViewDataSource: originalDataSource, rowHeight: 0.0)
- self.skeletonDataSource = dataSource
- performBatchUpdates({
- self.reloadData()
- }) { done in
- completion(done)
-
- }
- }
+
}
diff --git a/Sources/Extensions/UIColor+Skeleton.swift b/SkeletonViewCore/Sources/Internal/UIKitExtensions/UIColor+Skeleton.swift
similarity index 84%
rename from Sources/Extensions/UIColor+Skeleton.swift
rename to SkeletonViewCore/Sources/Internal/UIKitExtensions/UIColor+Skeleton.swift
index 4a4f2c10..a219dc65 100644
--- a/Sources/Extensions/UIColor+Skeleton.swift
+++ b/SkeletonViewCore/Sources/Internal/UIKitExtensions/UIColor+Skeleton.swift
@@ -3,54 +3,8 @@
import UIKit
// codebeat:disable[TOO_MANY_IVARS]
-extension UIColor {
- convenience init(_ hex: UInt) {
- self.init(
- red: CGFloat((hex & 0xFF0000) >> 16) / 255.0,
- green: CGFloat((hex & 0x00FF00) >> 8) / 255.0,
- blue: CGFloat(hex & 0x0000FF) / 255.0,
- alpha: CGFloat(1.0)
- )
- }
-
- func isLight() -> Bool {
- guard let components = cgColor.components,
- components.count >= 3 else { return false }
- let brightness = ((components[0] * 299) + (components[1] * 587) + (components[2] * 114)) / 1000
- return !(brightness < 0.5)
- }
-
- public var complementaryColor: UIColor {
- if #available(iOS 13, tvOS 13, *) {
- return UIColor { _ in
- return self.isLight() ? self.darker : self.lighter
- }
- } else {
- return isLight() ? darker : lighter
- }
- }
-
- public var lighter: UIColor {
- adjust(by: 1.35)
- }
-
- public var darker: UIColor {
- adjust(by: 0.94)
- }
-
- func adjust(by percent: CGFloat) -> UIColor {
- var h: CGFloat = 0, s: CGFloat = 0, b: CGFloat = 0, a: CGFloat = 0
- getHue(&h, saturation: &s, brightness: &b, alpha: &a)
- return UIColor(hue: h, saturation: s, brightness: b * percent, alpha: a)
- }
-
- func makeGradient() -> [UIColor] {
- [self, self.complementaryColor, self]
- }
-}
-
public extension UIColor {
- // swiftlint:disable operator_usage_whitespace
+
static var greenSea = UIColor(0x16a085)
static var turquoise = UIColor(0x1abc9c)
static var emerald = UIColor(0x2ecc71)
@@ -72,7 +26,6 @@ public extension UIColor {
static var pomegranate = UIColor(0xc0392b)
static var silver = UIColor(0xbdc3c7)
static var asbestos = UIColor(0x7f8c8d)
- // swiftlint:enable operator_usage_whitespace
static var skeletonDefault: UIColor {
if #available(iOS 13, tvOS 13, *) {
@@ -88,5 +41,48 @@ public extension UIColor {
return .clouds
}
}
+
+ var complementaryColor: UIColor {
+ isLight ? darker : lighter
+ }
+
+ var lighter: UIColor {
+ adjust(by: 1.35)
+ }
+
+ var darker: UIColor {
+ adjust(by: 0.94)
+ }
+
+}
+
+extension UIColor {
+
+ convenience init(_ hex: UInt) {
+ self.init(
+ red: CGFloat((hex & 0xFF0000) >> 16) / 255.0,
+ green: CGFloat((hex & 0x00FF00) >> 8) / 255.0,
+ blue: CGFloat(hex & 0x0000FF) / 255.0,
+ alpha: CGFloat(1.0)
+ )
+ }
+
+ var isLight: Bool {
+ guard let components = cgColor.components,
+ components.count >= 3 else { return false }
+ let brightness = ((components[0] * 299) + (components[1] * 587) + (components[2] * 114)) / 1000
+ return !(brightness < 0.5)
+ }
+
+ func adjust(by percent: CGFloat) -> UIColor {
+ var h: CGFloat = 0, s: CGFloat = 0, b: CGFloat = 0, a: CGFloat = 0
+ getHue(&h, saturation: &s, brightness: &b, alpha: &a)
+ return UIColor(hue: h, saturation: s, brightness: b * percent, alpha: a)
+ }
+
+ func makeGradient() -> [UIColor] {
+ [self, self.complementaryColor, self]
+ }
+
}
// codebeat:enable[TOO_MANY_IVARS]
diff --git a/SkeletonViewCore/Sources/Internal/UIKitExtensions/UILabel+Extensions.swift b/SkeletonViewCore/Sources/Internal/UIKitExtensions/UILabel+Extensions.swift
new file mode 100644
index 00000000..b88e9dfb
--- /dev/null
+++ b/SkeletonViewCore/Sources/Internal/UIKitExtensions/UILabel+Extensions.swift
@@ -0,0 +1,54 @@
+//
+// Copyright SkeletonView. All Rights Reserved.
+//
+// Licensed under the MIT License (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// https://opensource.org/licenses/MIT
+//
+// UILabel+Extensions.swift
+//
+// Created by Juanpe Catalán on 19/8/21.
+
+import UIKit
+
+extension UILabel {
+
+ var skeletonPaddingInsets: UIEdgeInsets {
+ get { return paddingInsets }
+ set { paddingInsets = newValue }
+ }
+
+ var desiredHeightBasedOnNumberOfLines: CGFloat {
+ let spaceNeededForEachLine = lineHeight * CGFloat(numberOfLines)
+ let spaceNeededForSpaces = skeletonLineSpacing * CGFloat(numberOfLines - 1)
+ let padding = paddingInsets.top + paddingInsets.bottom
+
+ return spaceNeededForEachLine + spaceNeededForSpaces + padding
+ }
+
+ func updateHeightConstraintsIfNeeded() {
+ guard numberOfLines > 1 || numberOfLines == 0 else { return }
+
+ // Workaround to simulate content when the label is contained in a `UIStackView`.
+ if isSuperviewAStackView, bounds.height == 0 {
+ // This is a placeholder text to simulate content because it's contained in a stack view in order to prevent that the content size will be zero.
+ text = " "
+ }
+
+ let desiredHeight = desiredHeightBasedOnNumberOfLines
+ if desiredHeight > definedMaxHeight {
+ backupHeightConstraints = heightConstraints
+ NSLayoutConstraint.deactivate(heightConstraints)
+ setHeight(equalToConstant: desiredHeight)
+ }
+ }
+
+ func restoreBackupHeightConstraintsIfNeeded() {
+ guard !backupHeightConstraints.isEmpty else { return }
+ NSLayoutConstraint.activate(backupHeightConstraints)
+ backupHeightConstraints.removeAll()
+ }
+
+}
diff --git a/Sources/Collections/TableViews/UITableView+CollectionSkeleton.swift b/SkeletonViewCore/Sources/Internal/UIKitExtensions/UITableView+CollectionSkeleton.swift
similarity index 93%
rename from Sources/Collections/TableViews/UITableView+CollectionSkeleton.swift
rename to SkeletonViewCore/Sources/Internal/UIKitExtensions/UITableView+CollectionSkeleton.swift
index ea280db0..132041ed 100644
--- a/Sources/Collections/TableViews/UITableView+CollectionSkeleton.swift
+++ b/SkeletonViewCore/Sources/Internal/UIKitExtensions/UITableView+CollectionSkeleton.swift
@@ -8,10 +8,7 @@
import UIKit
-public typealias ReusableHeaderFooterIdentifier = String
-
extension UITableView: CollectionSkeleton {
- public static let automaticNumberOfSkeletonRows = -1
var estimatedNumberOfRows: Int {
return Int(ceil(frame.height / rowHeight))
@@ -74,14 +71,19 @@ extension UITableView: CollectionSkeleton {
if reloadAfter { self.reloadData() }
}
+
+}
- private func restoreRowHeight() {
+private extension UITableView {
+
+ func restoreRowHeight() {
guard let dataSource = self.dataSource as? SkeletonCollectionDataSource else { return }
rowHeight = dataSource.originalRowHeight
}
- private func calculateRowHeight() -> CGFloat {
+ func calculateRowHeight() -> CGFloat {
guard rowHeight == UITableView.automaticDimension else { return rowHeight }
return estimatedRowHeight
}
+
}
diff --git a/SkeletonViewCore/Sources/Internal/UIKitExtensions/UITableView+Extensions.swift b/SkeletonViewCore/Sources/Internal/UIKitExtensions/UITableView+Extensions.swift
new file mode 100644
index 00000000..372222f3
--- /dev/null
+++ b/SkeletonViewCore/Sources/Internal/UIKitExtensions/UITableView+Extensions.swift
@@ -0,0 +1,45 @@
+//
+// Copyright SkeletonView. All Rights Reserved.
+//
+// Licensed under the MIT License (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// https://opensource.org/licenses/MIT
+//
+// UITableView+Extensions.swift
+//
+// Created by Juanpe Catalán on 18/8/21.
+
+import UIKit
+
+extension UITableView {
+
+ var indexesOfVisibleSections: [Int] {
+ (0.. NSLayoutConstraint {
+ let heightConstraint = heightAnchor.constraint(equalToConstant: constant)
+ heightConstraint.identifier = "SkeletonView.Constraint.Height.\(constant)"
+ NSLayoutConstraint.activate([heightConstraint])
+ return heightConstraint
+ }
+
+ var nonContentSizeLayoutConstraints: [NSLayoutConstraint] {
+ constraints.filter({ "\(type(of: $0))" != "NSContentSizeLayoutConstraint" })
+ }
+
+ /// Animations
+
+ func startSkeletonLayerAnimationBlock(_ anim: SkeletonLayerAnimation? = nil) -> VoidBlock {
+ {
+ self._isSkeletonAnimated = true
+ guard let layer = self._skeletonLayer else { return }
+ layer.start(anim) { [weak self] in
+ self?._isSkeletonAnimated = false
+ }
+ }
+ }
+
+ var stopSkeletonLayerAnimationBlock: VoidBlock {
+ {
+ self._isSkeletonAnimated = false
+ guard let layer = self._skeletonLayer else { return }
+ layer.stopAnimation()
+ }
+ }
+
+ /// Skeleton Layer
+
+ func addSkeletonLayer(skeletonConfig config: SkeletonConfig) {
+ guard let skeletonLayer = SkeletonLayerBuilder()
+ .setSkeletonType(config.type)
+ .addColors(config.colors)
+ .setHolder(self)
+ .build()
+ else { return }
+
+ self._skeletonLayer = skeletonLayer
+ layer.insertSkeletonLayer(
+ skeletonLayer,
+ atIndex: UInt32.max,
+ transition: config.transition
+ ) { [weak self] in
+ guard let self = self else { return }
+
+ // Workaround to fix the problem when inserting a sublayer and
+ // the content offset is modified by the system.
+ (self as? UITextView)?.setContentOffset(.zero, animated: false)
+
+ if config.animated {
+ self.startSkeletonAnimation(config.animation)
+ }
+ }
+ _status = .on
+ }
+
+ func updateSkeletonLayer(skeletonConfig config: SkeletonConfig) {
+ guard let skeletonLayer = _skeletonLayer else { return }
+ skeletonLayer.update(usingColors: config.colors)
+ if config.animated {
+ startSkeletonAnimation(config.animation)
+ } else {
+ skeletonLayer.stopAnimation()
+ }
+ }
+
+ func layoutSkeletonLayerIfNeeded() {
+ guard let skeletonLayer = _skeletonLayer else { return }
+ skeletonLayer.layoutIfNeeded()
+ }
+
+ func removeSkeletonLayer() {
+ guard isSkeletonActive,
+ let skeletonLayer = _skeletonLayer,
+ let transitionStyle = _currentSkeletonConfig?.transition else { return }
+ skeletonLayer.stopAnimation()
+ _status = .off
+ skeletonLayer.removeLayer(transition: transitionStyle) {
+ self._skeletonLayer = nil
+ self._currentSkeletonConfig = nil
+ }
+ }
+
+}
diff --git a/SkeletonViewCore/Sources/Internal/UIKitExtensions/UIView+SkeletonView.swift b/SkeletonViewCore/Sources/Internal/UIKitExtensions/UIView+SkeletonView.swift
new file mode 100644
index 00000000..159a43fc
--- /dev/null
+++ b/SkeletonViewCore/Sources/Internal/UIKitExtensions/UIView+SkeletonView.swift
@@ -0,0 +1,121 @@
+//
+// Copyright SkeletonView. All Rights Reserved.
+//
+// Licensed under the MIT License (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// https://opensource.org/licenses/MIT
+//
+// UIView+SkeletonView.swift
+//
+// Created by Juanpe Catalán on 19/8/21.
+
+import UIKit
+
+extension UIView {
+
+ func showSkeleton(skeletonConfig config: SkeletonConfig) {
+ _isSkeletonAnimated = config.animated
+ _flowDelegate = SkeletonFlowHandler()
+ _flowDelegate?.willBeginShowingSkeletons(rootView: self)
+ recursiveShowSkeleton(skeletonConfig: config, root: self)
+ }
+
+ func updateSkeleton(skeletonConfig config: SkeletonConfig) {
+ _isSkeletonAnimated = config.animated
+ _flowDelegate?.willBeginUpdatingSkeletons(rootView: self)
+ recursiveUpdateSkeleton(skeletonConfig: config, root: self)
+ }
+
+ func recursiveLayoutSkeletonIfNeeded(root: UIView? = nil) {
+ subviewsSkeletonables.recursiveSearch(leafBlock: {
+ guard isSkeletonable, isSkeletonActive else { return }
+ layoutSkeletonLayerIfNeeded()
+ if let config = _currentSkeletonConfig, config.animated, !_isSkeletonAnimated {
+ startSkeletonAnimation(config.animation)
+ }
+ }) { subview in
+ subview.recursiveLayoutSkeletonIfNeeded()
+ }
+
+ if let root = root {
+ _flowDelegate?.didLayoutSkeletonsIfNeeded(rootView: root)
+ }
+ }
+
+ func recursiveHideSkeleton(reloadDataAfter reload: Bool, transition: SkeletonTransitionStyle, root: UIView? = nil) {
+ guard isSkeletonActive else { return }
+ if isHiddenWhenSkeletonIsActive {
+ isHidden = false
+ }
+ _currentSkeletonConfig?.transition = transition
+ unSwizzleLayoutSubviews()
+ unSwizzleTraitCollectionDidChange()
+ removeDummyDataSourceIfNeeded(reloadAfter: reload)
+ subviewsSkeletonables.recursiveSearch(leafBlock: {
+ recoverViewState(forced: false)
+ removeSkeletonLayer()
+ }) { subview in
+ subview.recursiveHideSkeleton(reloadDataAfter: reload, transition: transition)
+ }
+
+ if let root = root {
+ _flowDelegate?.didHideSkeletons(rootView: root)
+ }
+ }
+
+}
+
+private extension UIView {
+
+ func showSkeletonIfNotActive(skeletonConfig config: SkeletonConfig) {
+ guard !isSkeletonActive else { return }
+ saveViewState()
+
+ prepareViewForSkeleton()
+ addSkeletonLayer(skeletonConfig: config)
+ }
+
+ func recursiveShowSkeleton(skeletonConfig config: SkeletonConfig, root: UIView? = nil) {
+ if isHiddenWhenSkeletonIsActive {
+ isHidden = true
+ }
+ guard isSkeletonable && !isSkeletonActive else { return }
+ _currentSkeletonConfig = config
+ swizzleLayoutSubviews()
+ swizzleTraitCollectionDidChange()
+ addDummyDataSourceIfNeeded()
+ subviewsSkeletonables.recursiveSearch(leafBlock: {
+ showSkeletonIfNotActive(skeletonConfig: config)
+ }) { subview in
+ subview.recursiveShowSkeleton(skeletonConfig: config)
+ }
+
+ if let root = root {
+ _flowDelegate?.didShowSkeletons(rootView: root)
+ }
+ }
+
+ func recursiveUpdateSkeleton(skeletonConfig config: SkeletonConfig, root: UIView? = nil) {
+ guard isSkeletonActive else { return }
+ _currentSkeletonConfig = config
+ updateDummyDataSourceIfNeeded()
+ subviewsSkeletonables.recursiveSearch(leafBlock: {
+ if let skeletonLayer = _skeletonLayer,
+ skeletonLayer.type != config.type {
+ removeSkeletonLayer()
+ addSkeletonLayer(skeletonConfig: config)
+ } else {
+ updateSkeletonLayer(skeletonConfig: config)
+ }
+ }) { subview in
+ subview.recursiveUpdateSkeleton(skeletonConfig: config)
+ }
+
+ if let root = root {
+ _flowDelegate?.didUpdateSkeletons(rootView: root)
+ }
+ }
+
+}
diff --git a/SkeletonViewCore/Sources/Internal/UIKitExtensions/UIView+Swizzling.swift b/SkeletonViewCore/Sources/Internal/UIKitExtensions/UIView+Swizzling.swift
new file mode 100644
index 00000000..866c68d8
--- /dev/null
+++ b/SkeletonViewCore/Sources/Internal/UIKitExtensions/UIView+Swizzling.swift
@@ -0,0 +1,76 @@
+//
+// Copyright SkeletonView. All Rights Reserved.
+//
+// Licensed under the MIT License (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// https://opensource.org/licenses/MIT
+//
+// UIView+Swizzling.swift
+//
+// Created by Juanpe Catalán on 19/8/21.
+
+import UIKit
+
+extension UIView {
+
+ @objc func skeletonLayoutSubviews() {
+ guard Thread.isMainThread else { return }
+ skeletonLayoutSubviews()
+ guard isSkeletonActive else { return }
+ layoutSkeletonIfNeeded()
+ }
+
+ @objc func skeletonTraitCollectionDidChange(_ previousTraitCollection: UITraitCollection?) {
+ skeletonTraitCollectionDidChange(previousTraitCollection)
+ guard isSkeletonable, isSkeletonActive, let config = _currentSkeletonConfig else { return }
+ updateSkeleton(skeletonConfig: config)
+ }
+
+ func swizzleLayoutSubviews() {
+ DispatchQueue.main.asyncAfter(deadline: .now() + 0.01) {
+ DispatchQueue.once(token: "UIView.SkeletonView.swizzleLayoutSubviews") {
+ swizzle(selector: #selector(UIView.layoutSubviews),
+ with: #selector(UIView.skeletonLayoutSubviews),
+ inClass: UIView.self,
+ usingClass: UIView.self)
+ self.layoutSkeletonIfNeeded()
+ }
+ }
+ }
+
+ func unSwizzleLayoutSubviews() {
+ DispatchQueue.main.asyncAfter(deadline: .now() + 0.01) {
+ DispatchQueue.removeOnce(token: "UIView.SkeletonView.swizzleLayoutSubviews") {
+ swizzle(selector: #selector(UIView.skeletonLayoutSubviews),
+ with: #selector(UIView.layoutSubviews),
+ inClass: UIView.self,
+ usingClass: UIView.self)
+ }
+ }
+ }
+
+ func swizzleTraitCollectionDidChange() {
+ DispatchQueue.main.asyncAfter(deadline: .now() + 0.01) {
+ DispatchQueue.once(token: "UIView.SkeletonView.swizzleTraitCollectionDidChange") {
+ swizzle(selector: #selector(UIView.traitCollectionDidChange(_:)),
+ with: #selector(UIView.skeletonTraitCollectionDidChange(_:)),
+ inClass: UIView.self,
+ usingClass: UIView.self)
+ }
+ }
+ }
+
+ func unSwizzleTraitCollectionDidChange() {
+ DispatchQueue.main.asyncAfter(deadline: .now() + 0.01) {
+ DispatchQueue.removeOnce(token: "UIView.SkeletonView.swizzleTraitCollectionDidChange") {
+ swizzle(selector: #selector(UIView.skeletonTraitCollectionDidChange(_:)),
+ with: #selector(UIView.traitCollectionDidChange(_:)),
+ inClass: UIView.self,
+ usingClass: UIView.self)
+ }
+ }
+ }
+
+}
diff --git a/SkeletonViewCore/Sources/Internal/UIKitExtensions/UIView+Transitions.swift b/SkeletonViewCore/Sources/Internal/UIKitExtensions/UIView+Transitions.swift
new file mode 100644
index 00000000..66b3a610
--- /dev/null
+++ b/SkeletonViewCore/Sources/Internal/UIKitExtensions/UIView+Transitions.swift
@@ -0,0 +1,23 @@
+// Copyright © 2019 SkeletonView. All rights reserved.
+
+import UIKit
+
+extension UIView {
+
+ func startTransition(transitionBlock: @escaping () -> Void) {
+ guard let transitionStyle = _currentSkeletonConfig?.transition,
+ transitionStyle != .none else {
+ transitionBlock()
+ return
+ }
+
+ if case let .crossDissolve(duration) = transitionStyle {
+ UIView.transition(with: self,
+ duration: duration,
+ options: .transitionCrossDissolve,
+ animations: transitionBlock,
+ completion: nil)
+ }
+ }
+
+}
diff --git a/SkeletonViewCore/Sources/Supporting Files/Info.plist b/SkeletonViewCore/Sources/Supporting Files/Info.plist
new file mode 100644
index 00000000..57ada9f9
--- /dev/null
+++ b/SkeletonViewCore/Sources/Supporting Files/Info.plist
@@ -0,0 +1,25 @@
+
+
+
+ CFBundleDevelopmentRegion
+ en
+ CFBundleExecutable
+ $(EXECUTABLE_NAME)
+ CFBundleIdentifier
+ $(PRODUCT_BUNDLE_IDENTIFIER)
+ CFBundleInfoDictionaryVersion
+ 6.0
+ CFBundleName
+ $(PRODUCT_NAME)
+ CFBundlePackageType
+ FMWK
+ CFBundleShortVersionString
+ 1.0
+ CFBundleSignature
+ ????
+ CFBundleVersion
+ $(CURRENT_PROJECT_VERSION)
+ NSPrincipalClass
+
+
+
diff --git a/SkeletonViewCore/Tests/Debug/SkeletonDebugTests.swift b/SkeletonViewCore/Tests/Debug/SkeletonDebugTests.swift
new file mode 100644
index 00000000..71bbb1cf
--- /dev/null
+++ b/SkeletonViewCore/Tests/Debug/SkeletonDebugTests.swift
@@ -0,0 +1,85 @@
+//
+// Copyright SkeletonView. All Rights Reserved.
+//
+// Licensed under the MIT License (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// https://opensource.org/licenses/MIT
+//
+// SkeletonDebugTests.swift
+//
+// Created by Juanpe Catalán on 18/8/21.
+
+import XCTest
+@testable import SkeletonView
+
+class SkeletonDebugTests: XCTestCase {
+
+ func testSkeletonDescriptionWithViewNotSkeletonableNotReturnsSkullEmojiAndChildren() {
+ /// given
+ let view = UIView()
+ let expectedDescription = ""
+
+ /// when
+ let obtainedDescription = view.skeletonDescription
+
+ /// then
+ XCTAssertEqual(expectedDescription, obtainedDescription)
+ }
+
+ func testSkeletonDescriptionWithViewSkeletonableReturnsSkullEmojiButNotChildren() {
+ /// given
+ let view = UIView()
+ view.isSkeletonable = true
+ let expectedDescription = ""
+
+ /// when
+ let obtainedDescription = view.skeletonDescription
+
+ /// then
+ XCTAssertEqual(expectedDescription, obtainedDescription)
+ }
+
+ func testSkeletonDescriptionWithViewSkeletonableAndChildrenReturnsSkullEmojiAndChildren() {
+ /// given
+ let view = UIView()
+ let childView = UIView()
+ view.addSubview(childView)
+ view.isSkeletonable = true
+ childView.isSkeletonable = true
+ let expectedDescription = """
+
+ """
+
+ /// when
+ let obtainedDescription = view.skeletonDescription
+
+ /// then
+ XCTAssertEqual(expectedDescription, obtainedDescription)
+ }
+
+ func testSkeletonHierarchyWithSkeletonableViewsReturnsFullHierarchy() {
+ /// given
+ let view = UIView()
+ let childView = UIView()
+ let subchildView = UIView()
+ view.addSubview(childView)
+ childView.addSubview(subchildView)
+ view.isSkeletonable = true
+ childView.isSkeletonable = true
+ subchildView.isSkeletonable = true
+
+ let expectedDescription = "⬇⬇ ☠️ Root view hierarchy with Skeletons ⬇⬇"
+ .replacingOccurrences(of: " ", with: "")
+
+ /// when
+ let obtainedDescription = view.skeletonHierarchy()
+ .replacingOccurrences(of: "\n", with: "")
+ .replacingOccurrences(of: " ", with: "")
+
+ /// then
+ XCTAssertEqual(expectedDescription, obtainedDescription)
+ }
+
+}
diff --git a/SkeletonViewCore/Tests/Supporting Files/Info.plist b/SkeletonViewCore/Tests/Supporting Files/Info.plist
new file mode 100644
index 00000000..7c23420d
--- /dev/null
+++ b/SkeletonViewCore/Tests/Supporting Files/Info.plist
@@ -0,0 +1,25 @@
+
+
+
+ CFBundleDevelopmentRegion
+ en
+ CFBundleExecutable
+ $(EXECUTABLE_NAME)
+ CFBundleIdentifier
+ $(PRODUCT_BUNDLE_IDENTIFIER)
+ CFBundleInfoDictionaryVersion
+ 6.0
+ CFBundleName
+ $(PRODUCT_NAME)
+ CFBundlePackageType
+ BNDL
+ CFBundleShortVersionString
+ 1.0
+ CFBundleSignature
+ ????
+ CFBundleVersion
+ $(CURRENT_PROJECT_VERSION)
+ NSPrincipalClass
+
+
+
diff --git a/Sources/Appearance/SkeletonAppearance.swift b/Sources/Appearance/SkeletonAppearance.swift
deleted file mode 100644
index 94f6e0b3..00000000
--- a/Sources/Appearance/SkeletonAppearance.swift
+++ /dev/null
@@ -1,37 +0,0 @@
-// Copyright © 2017 SkeletonView. All rights reserved.
-
-import UIKit
-
-public protocol Appearance {
- var tintColor: UIColor { get set }
- var gradient: SkeletonGradient { get set }
- var multilineHeight: CGFloat { get set }
- var multilineSpacing: CGFloat { get set }
- var multilineLastLineFillPercent: Int { get set }
- var multilineCornerRadius: Int { get set }
- var renderSingleLineAsView: Bool { get set }
-}
-
-public enum SkeletonAppearance {
- public static var `default`: Appearance = SkeletonViewAppearance.shared
-}
-
-// codebeat:disable[TOO_MANY_IVARS]
-class SkeletonViewAppearance: Appearance {
- static var shared = SkeletonViewAppearance()
-
- var tintColor: UIColor = .skeletonDefault
-
- var gradient = SkeletonGradient(baseColor: .skeletonDefault)
-
- var multilineHeight: CGFloat = 15
-
- var multilineSpacing: CGFloat = 10
-
- var multilineLastLineFillPercent: Int = 70
-
- var multilineCornerRadius: Int = 0
-
- var renderSingleLineAsView: Bool = false
-}
-// codebeat:enable[TOO_MANY_IVARS]
diff --git a/Sources/Collections/Generics/GenericCollectionView.swift b/Sources/Collections/Generics/GenericCollectionView.swift
deleted file mode 100644
index 23682cbe..00000000
--- a/Sources/Collections/Generics/GenericCollectionView.swift
+++ /dev/null
@@ -1,13 +0,0 @@
-//
-// GenericCollectionView.swift
-// SkeletonView-iOS
-//
-// Created by Juanpe Catalán on 30/03/2018.
-// Copyright © 2018 SkeletonView. All rights reserved.
-//
-
-import UIKit
-
-protocol GenericCollectionView {
- var scrollView: UIScrollView { get }
-}
diff --git a/Sources/Debug/SkeletonDebug.swift b/Sources/Debug/SkeletonDebug.swift
deleted file mode 100644
index 192867e4..00000000
--- a/Sources/Debug/SkeletonDebug.swift
+++ /dev/null
@@ -1,49 +0,0 @@
-// Copyright © 2018 SkeletonView. All rights reserved.
-
-import Foundation
-import UIKit
-
-enum SkeletonEnvironmentKey: String {
- case debugMode = "SKELETON_DEBUG"
-}
-
-extension Dictionary {
- subscript (_ key: SkeletonEnvironmentKey) -> Value? {
- // swiftlint:disable:next force_cast
- return self[key.rawValue as! Key]
- }
-}
-
-func printSkeletonHierarchy(in view: UIView) {
- skeletonLog(view.skeletonHierarchy())
-}
-
-func skeletonLog(_ message: String) {
- if ProcessInfo.processInfo.environment[.debugMode] != nil {
- print(message)
- }
-}
-
-extension UIView {
- public var skeletonDescription: String {
- var description = "<\(type(of: self)): \(Unmanaged.passUnretained(self).toOpaque())"
- let subSkeletons = subviewsSkeletonables
- if !subSkeletons.isEmpty {
- description += " | (\(subSkeletons.count)) subSkeletons"
- }
- if isSkeletonable {
- description += " | ☠️ "
- }
- return description + ">"
- }
-
- public func skeletonHierarchy(index: Int = 0) -> String {
- var description = index == 0 ? "\n ⬇⬇ ☠️ Root view hierarchy with Skeletons ⬇⬇ \n" : ""
- description += "\(index == 0 ? "\n" : 3.whitespaces) \(skeletonDescription) \n"
- subviewsToSkeleton.forEach {
- description += (index + 2).whitespaces
- description += $0.skeletonHierarchy(index: index + 1)
- }
- return description
- }
-}
diff --git a/Sources/Extensions/Int+Whitespaces.swift b/Sources/Extensions/Int+Whitespaces.swift
deleted file mode 100644
index 86d2c67c..00000000
--- a/Sources/Extensions/Int+Whitespaces.swift
+++ /dev/null
@@ -1,13 +0,0 @@
-// Copyright © 2018 SkeletonView. All rights reserved.
-
-import Foundation
-
-extension Int {
- var whitespace: String {
- whitespaces
- }
-
- var whitespaces: String {
- String(repeating: " ", count: self)
- }
-}
diff --git a/Sources/Extensions/ProcessInfo+XCTest.swift b/Sources/Extensions/ProcessInfo+XCTest.swift
deleted file mode 100644
index d5c6166b..00000000
--- a/Sources/Extensions/ProcessInfo+XCTest.swift
+++ /dev/null
@@ -1,13 +0,0 @@
-// Copyright © 2020 SkeletonView. All rights reserved.
-
-import Foundation
-
-extension ProcessInfo {
- enum Constants {
- static let testConfigurationFilePathKey = "XCTestConfigurationFilePath"
- }
-
- static var isRunningXCTest: Bool {
- return processInfo.environment[Constants.testConfigurationFilePathKey] != nil
- }
-}
diff --git a/Sources/Extensions/UITableView+VisibleSections.swift b/Sources/Extensions/UITableView+VisibleSections.swift
deleted file mode 100644
index 3cb3ce83..00000000
--- a/Sources/Extensions/UITableView+VisibleSections.swift
+++ /dev/null
@@ -1,38 +0,0 @@
-// Copyright © 2020 SkeletonView. All rights reserved.
-
-import UIKit
-
-extension UITableView {
- var indexesOfVisibleSections: [Int] {
- (0.. NSLayoutConstraint {
- let heightConstraint = heightAnchor.constraint(equalToConstant: constant)
- heightConstraint.identifier = "SkeletonView.Constraint.Height.\(constant)"
- NSLayoutConstraint.activate([heightConstraint])
- return heightConstraint
- }
-
- var nonContentSizeLayoutConstraints: [NSLayoutConstraint] {
- constraints.filter({ "\(type(of: $0))" != "NSContentSizeLayoutConstraint" })
- }
-}
diff --git a/Sources/Extensions/UIView+Frame.swift b/Sources/Extensions/UIView+Frame.swift
deleted file mode 100644
index 323e6555..00000000
--- a/Sources/Extensions/UIView+Frame.swift
+++ /dev/null
@@ -1,55 +0,0 @@
-//
-// UIView+Frame.swift
-// SkeletonView-iOS
-//
-// Created by Juanpe Catalán on 06/11/2017.
-// Copyright © 2017 SkeletonView. All rights reserved.
-//
-
-import UIKit
-
-// MARK: Frame
-extension UIView {
- var definedMaxBounds: CGRect {
- if let parentStackView = (superview as? UIStackView) {
- var origin: CGPoint = .zero
- switch parentStackView.alignment {
- case .trailing:
- origin.x = definedMaxWidth
- default:
- break
- }
- return CGRect(origin: origin, size: definedMaxSize)
- }
- return CGRect(origin: .zero, size: definedMaxSize)
- }
-
- var definedMaxSize: CGSize {
- CGSize(width: definedMaxWidth, height: definedMaxHeight)
- }
-
- var definedMaxWidth: CGFloat {
- max(between: frame.size.width, andContantsOf: widthConstraints)
- }
-
- var definedMaxHeight: CGFloat {
- max(between: frame.size.height, andContantsOf: heightConstraints)
- }
-
- var isRTL: Bool {
- if #available(iOS 10.0, *), #available(tvOS 10.0, *) {
- return effectiveUserInterfaceLayoutDirection == .rightToLeft
- } else {
- return false
- }
- }
-
- private func max(between value: CGFloat, andContantsOf constraints: [NSLayoutConstraint]) -> CGFloat {
- let max = constraints.reduce(value, { max, constraint in
- var tempMax = max
- if constraint.constant > tempMax { tempMax = constraint.constant }
- return tempMax
- })
- return max
- }
-}
diff --git a/Sources/Extensions/UIView+IBInspectable.swift b/Sources/Extensions/UIView+IBInspectable.swift
deleted file mode 100644
index 989a4d2d..00000000
--- a/Sources/Extensions/UIView+IBInspectable.swift
+++ /dev/null
@@ -1,53 +0,0 @@
-// Copyright © 2017 SkeletonView. All rights reserved.
-
-import UIKit
-
-public extension UIView {
- @IBInspectable
- var isSkeletonable: Bool {
- get { return skeletonable }
- set { skeletonable = newValue }
- }
-
- @IBInspectable
- var isHiddenWhenSkeletonIsActive: Bool {
- get { return hiddenWhenSkeletonIsActive }
- set { hiddenWhenSkeletonIsActive = newValue }
- }
-
- @IBInspectable
- var isUserInteractionDisabledWhenSkeletonIsActive: Bool {
- get { return disabledWhenSkeletonIsActive }
- set { disabledWhenSkeletonIsActive = newValue }
- }
-
- @IBInspectable
- var skeletonCornerRadius: Float {
- get { return skeletonableCornerRadius }
- set { skeletonableCornerRadius = newValue }
- }
-
- var isSkeletonActive: Bool {
- return status == .on || subviewsSkeletonables.contains(where: { $0.isSkeletonActive })
- }
-
- private var skeletonable: Bool {
- get { return ao_get(pkey: &ViewAssociatedKeys.skeletonable) as? Bool ?? false }
- set { ao_set(newValue, pkey: &ViewAssociatedKeys.skeletonable) }
- }
-
- private var hiddenWhenSkeletonIsActive: Bool {
- get { return ao_get(pkey: &ViewAssociatedKeys.hiddenWhenSkeletonIsActive) as? Bool ?? false }
- set { ao_set(newValue, pkey: &ViewAssociatedKeys.hiddenWhenSkeletonIsActive) }
- }
-
- private var disabledWhenSkeletonIsActive: Bool {
- get { return ao_get(pkey: &ViewAssociatedKeys.disabledWhenSkeletonIsActive) as? Bool ?? true }
- set { ao_set(newValue, pkey: &ViewAssociatedKeys.disabledWhenSkeletonIsActive) }
- }
-
- private var skeletonableCornerRadius: Float {
- get { return ao_get(pkey: &ViewAssociatedKeys.skeletonCornerRadius) as? Float ?? 0.0 }
- set { ao_set(newValue, pkey: &ViewAssociatedKeys.skeletonCornerRadius) }
- }
-}
diff --git a/Sources/Extensions/UIView+UIApplicationDelegate.swift b/Sources/Extensions/UIView+UIApplicationDelegate.swift
deleted file mode 100644
index cdb1fdd4..00000000
--- a/Sources/Extensions/UIView+UIApplicationDelegate.swift
+++ /dev/null
@@ -1,43 +0,0 @@
-//
-// UIView+UIApplicationDelegate.swift
-// SkeletonView-iOS
-//
-// Created by Juanpe Catalán on 08/02/2018.
-// Copyright © 2018 SkeletonView. All rights reserved.
-//
-
-import UIKit
-
-extension UIView {
- enum Constants {
- static let becomeActiveNotification = UIApplication.didBecomeActiveNotification
- static let enterForegroundNotification = UIApplication.didEnterBackgroundNotification
- static let willTerminateNotification = UIApplication.willTerminateNotification
- static let needAnimatedSkeletonKey = "needAnimateSkeleton"
- }
-
- func addAppNotificationsObservers() {
- NotificationCenter.default.addObserver(self, selector: #selector(appDidBecomeActive), name: Constants.becomeActiveNotification, object: nil)
- NotificationCenter.default.addObserver(self, selector: #selector(appDidEnterBackground), name: Constants.enterForegroundNotification, object: nil)
- NotificationCenter.default.addObserver(self, selector: #selector(willTerminateNotification), name: Constants.enterForegroundNotification, object: nil)
- }
-
- func removeAppNoticationsObserver() {
- NotificationCenter.default.removeObserver(self, name: Constants.becomeActiveNotification, object: nil)
- NotificationCenter.default.removeObserver(self, name: Constants.enterForegroundNotification, object: nil)
- }
-
- @objc func appDidBecomeActive() {
- if UserDefaults.standard.bool(forKey: Constants.needAnimatedSkeletonKey) {
- startSkeletonAnimation()
- }
- }
-
- @objc func appDidEnterBackground() {
- UserDefaults.standard.set((isSkeletonActive && isSkeletonAnimated), forKey: Constants.needAnimatedSkeletonKey)
- }
-
- @objc func willTerminateNotification() {
- UserDefaults.standard.set(false, forKey: Constants.needAnimatedSkeletonKey)
- }
-}
diff --git a/Sources/Multilines/ContainsMultilineText.swift b/Sources/Multilines/ContainsMultilineText.swift
deleted file mode 100644
index 70bf569c..00000000
--- a/Sources/Multilines/ContainsMultilineText.swift
+++ /dev/null
@@ -1,21 +0,0 @@
-// Copyright © 2017 SkeletonView. All rights reserved.
-
-import UIKit
-
-enum MultilineAssociatedKeys {
- static var lastLineFillingPercent = "lastLineFillingPercent"
- static var multilineCornerRadius = "multilineCornerRadius"
- static var multilineSpacing = "multilineSpacing"
- static var paddingInsets = "paddingInsets"
- static var backupHeightConstraints = "backupHeightConstraints"
-}
-
-protocol ContainsMultilineText {
- var lineHeight: CGFloat { get }
- var numberOfLines: Int { get }
- var textAlignment: NSTextAlignment { get }
- var lastLineFillingPercent: Int { get }
- var multilineCornerRadius: Int { get }
- var multilineSpacing: CGFloat { get }
- var paddingInsets: UIEdgeInsets { get }
-}
diff --git a/Sources/Multilines/UILabel+Multiline.swift b/Sources/Multilines/UILabel+Multiline.swift
deleted file mode 100644
index b0b88634..00000000
--- a/Sources/Multilines/UILabel+Multiline.swift
+++ /dev/null
@@ -1,65 +0,0 @@
-// Copyright © 2018 SkeletonView. All rights reserved.
-
-import UIKit
-
-public extension UILabel {
- @IBInspectable
- var lastLineFillPercent: Int {
- get { return lastLineFillingPercent }
- set { lastLineFillingPercent = min(newValue, 100) }
- }
-
- @IBInspectable
- var linesCornerRadius: Int {
- get { return multilineCornerRadius }
- set { multilineCornerRadius = newValue }
- }
-
- @IBInspectable
- var skeletonLineSpacing: CGFloat {
- get { return multilineSpacing }
- set { multilineSpacing = newValue }
- }
-
- var skeletonPaddingInsets: UIEdgeInsets {
- get { return paddingInsets }
- set { paddingInsets = newValue }
- }
-}
-
-extension UILabel: ContainsMultilineText {
- var lineHeight: CGFloat {
- if let fontLineHeight = font?.lineHeight {
- if let heightConstraints = backupHeightConstraints.first?.constant {
- return (fontLineHeight > heightConstraints) ? heightConstraints : fontLineHeight
- }
- return fontLineHeight
- }
- return SkeletonAppearance.default.multilineHeight
- }
-
- var lastLineFillingPercent: Int {
- get { return ao_get(pkey: &MultilineAssociatedKeys.lastLineFillingPercent) as? Int ?? SkeletonAppearance.default.multilineLastLineFillPercent }
- set { ao_set(newValue, pkey: &MultilineAssociatedKeys.lastLineFillingPercent) }
- }
-
- var multilineCornerRadius: Int {
- get { return ao_get(pkey: &MultilineAssociatedKeys.multilineCornerRadius) as? Int ?? SkeletonAppearance.default.multilineCornerRadius }
- set { ao_set(newValue, pkey: &MultilineAssociatedKeys.multilineCornerRadius) }
- }
-
- var multilineSpacing: CGFloat {
- get { return ao_get(pkey: &MultilineAssociatedKeys.multilineSpacing) as? CGFloat ?? SkeletonAppearance.default.multilineSpacing }
- set { ao_set(newValue, pkey: &MultilineAssociatedKeys.multilineSpacing) }
- }
-
- var paddingInsets: UIEdgeInsets {
- get { return ao_get(pkey: &MultilineAssociatedKeys.paddingInsets) as? UIEdgeInsets ?? .zero }
- set { ao_set(newValue, pkey: &MultilineAssociatedKeys.paddingInsets) }
- }
-
- var backupHeightConstraints: [NSLayoutConstraint] {
- get { return ao_get(pkey: &MultilineAssociatedKeys.backupHeightConstraints) as? [NSLayoutConstraint] ?? [] }
- set { ao_set(newValue, pkey: &MultilineAssociatedKeys.backupHeightConstraints) }
- }
-}
diff --git a/Sources/Multilines/UITextView+Multiline.swift b/Sources/Multilines/UITextView+Multiline.swift
deleted file mode 100644
index c4058371..00000000
--- a/Sources/Multilines/UITextView+Multiline.swift
+++ /dev/null
@@ -1,72 +0,0 @@
-// Copyright © 2018 SkeletonView. All rights reserved.
-
-import UIKit
-
-public extension UITextView {
- @IBInspectable
- var lastLineFillPercent: Int {
- get { return lastLineFillingPercent }
- set { lastLineFillingPercent = min(newValue, 100) }
- }
-
- @IBInspectable
- var linesCornerRadius: Int {
- get { return multilineCornerRadius }
- set { multilineCornerRadius = newValue }
- }
-
- @IBInspectable
- var skeletonLineSpacing: CGFloat {
- get { return multilineSpacing }
- set { multilineSpacing = newValue }
- }
-
- var skeletonPaddingInsets: UIEdgeInsets {
- get { return paddingInsets }
- set { paddingInsets = newValue }
- }
-}
-
-extension UITextView: ContainsMultilineText {
- var lineHeight: CGFloat {
- if let fontLineHeight = font?.lineHeight {
- if let heightConstraints = heightConstraints.first?.constant {
- return (fontLineHeight > heightConstraints) ? heightConstraints : fontLineHeight
- }
-
- return fontLineHeight
- }
-
- return SkeletonAppearance.default.multilineHeight
- }
-
- var numberOfLines: Int {
- -1
- }
-
- var lastLineFillingPercent: Int {
- get {
- let defaultValue = SkeletonAppearance.default.multilineLastLineFillPercent
- return ao_get(pkey: &MultilineAssociatedKeys.lastLineFillingPercent) as? Int ?? defaultValue
- }
- set { ao_set(newValue, pkey: &MultilineAssociatedKeys.lastLineFillingPercent) }
- }
-
- var multilineCornerRadius: Int {
- get {
- let defaultValue = SkeletonAppearance.default.multilineCornerRadius
- return ao_get(pkey: &MultilineAssociatedKeys.multilineCornerRadius) as? Int ?? defaultValue
- }
- set { ao_set(newValue, pkey: &MultilineAssociatedKeys.multilineCornerRadius) }
- }
-
- var multilineSpacing: CGFloat {
- get { return ao_get(pkey: &MultilineAssociatedKeys.multilineSpacing) as? CGFloat ?? SkeletonAppearance.default.multilineSpacing }
- set { ao_set(newValue, pkey: &MultilineAssociatedKeys.multilineSpacing) }
- }
-
- var paddingInsets: UIEdgeInsets {
- get { return ao_get(pkey: &MultilineAssociatedKeys.paddingInsets) as? UIEdgeInsets ?? .zero }
- set { ao_set(newValue, pkey: &MultilineAssociatedKeys.paddingInsets) }
- }
-}
diff --git a/Sources/SkeletonAnimationBuilder.swift b/Sources/SkeletonAnimationBuilder.swift
deleted file mode 100644
index e23863e5..00000000
--- a/Sources/SkeletonAnimationBuilder.swift
+++ /dev/null
@@ -1,86 +0,0 @@
-//
-// SkeletonAnimationBuilder.swift
-// SkeletonView-iOS
-//
-// Created by Juanpe Catalán on 17/11/2017.
-// Copyright © 2017 SkeletonView. All rights reserved.
-//
-
-import UIKit
-
-typealias GradientAnimationPoint = (from: CGPoint, to: CGPoint)
-
-public enum GradientDirection {
- case leftRight
- case rightLeft
- case topBottom
- case bottomTop
- case topLeftBottomRight
- case bottomRightTopLeft
-
- public func slidingAnimation(duration: CFTimeInterval = 1.5, autoreverses: Bool = false) -> SkeletonLayerAnimation {
- return SkeletonAnimationBuilder().makeSlidingAnimation(withDirection: self, duration: duration, autoreverses: autoreverses)
- }
-
- // codebeat:disable[ABC]
- var startPoint: GradientAnimationPoint {
- switch self {
- case .leftRight:
- return (from: CGPoint(x: -1, y: 0.5), to: CGPoint(x: 1, y: 0.5))
- case .rightLeft:
- return (from: CGPoint(x: 1, y: 0.5), to: CGPoint(x: -1, y: 0.5))
- case .topBottom:
- return (from: CGPoint(x: 0.5, y: -1), to: CGPoint(x: 0.5, y: 1))
- case .bottomTop:
- return (from: CGPoint(x: 0.5, y: 1), to: CGPoint(x: 0.5, y: -1))
- case .topLeftBottomRight:
- return (from: CGPoint(x: -1, y: -1), to: CGPoint(x: 1, y: 1))
- case .bottomRightTopLeft:
- return (from: CGPoint(x: 1, y: 1), to: CGPoint(x: -1, y: -1))
- }
- }
-
- var endPoint: GradientAnimationPoint {
- switch self {
- case .leftRight:
- return (from: CGPoint(x: 0, y: 0.5), to: CGPoint(x: 2, y: 0.5))
- case .rightLeft:
- return ( from: CGPoint(x: 2, y: 0.5), to: CGPoint(x: 0, y: 0.5))
- case .topBottom:
- return ( from: CGPoint(x: 0.5, y: 0), to: CGPoint(x: 0.5, y: 2))
- case .bottomTop:
- return ( from: CGPoint(x: 0.5, y: 2), to: CGPoint(x: 0.5, y: 0))
- case .topLeftBottomRight:
- return ( from: CGPoint(x: 0, y: 0), to: CGPoint(x: 2, y: 2))
- case .bottomRightTopLeft:
- return ( from: CGPoint(x: 2, y: 2), to: CGPoint(x: 0, y: 0))
- }
- }
- // codebeat:enable[ABC]
-}
-
-public class SkeletonAnimationBuilder {
- public init() { }
-
- public func makeSlidingAnimation(withDirection direction: GradientDirection, duration: CFTimeInterval = 1.5, autoreverses: Bool = false) -> SkeletonLayerAnimation {
- return { _ in
- let startPointAnim = CABasicAnimation(keyPath: #keyPath(CAGradientLayer.startPoint))
- startPointAnim.fromValue = direction.startPoint.from
- startPointAnim.toValue = direction.startPoint.to
-
- let endPointAnim = CABasicAnimation(keyPath: #keyPath(CAGradientLayer.endPoint))
- endPointAnim.fromValue = direction.endPoint.from
- endPointAnim.toValue = direction.endPoint.to
-
- let animGroup = CAAnimationGroup()
- animGroup.animations = [startPointAnim, endPointAnim]
- animGroup.duration = duration
- animGroup.timingFunction = CAMediaTimingFunction(name: CAMediaTimingFunctionName.easeIn)
- animGroup.repeatCount = .infinity
- animGroup.autoreverses = autoreverses
- animGroup.isRemovedOnCompletion = false
-
- return animGroup
- }
- }
-}
diff --git a/Sources/SkeletonFlow.swift b/Sources/SkeletonFlow.swift
deleted file mode 100644
index 84fafd17..00000000
--- a/Sources/SkeletonFlow.swift
+++ /dev/null
@@ -1,59 +0,0 @@
-// Copyright © 2018 SkeletonView. All rights reserved.
-
-import UIKit
-
-protocol SkeletonFlowDelegate: AnyObject {
- func willBeginShowingSkeletons(rootView: UIView)
- func didShowSkeletons(rootView: UIView)
- func willBeginUpdatingSkeletons(rootView: UIView)
- func didUpdateSkeletons(rootView: UIView)
- func willBeginLayingSkeletonsIfNeeded(rootView: UIView)
- func didLayoutSkeletonsIfNeeded(rootView: UIView)
- func willBeginHidingSkeletons(rootView: UIView)
- func didHideSkeletons(rootView: UIView)
-}
-
-class SkeletonFlowHandler: SkeletonFlowDelegate {
- func willBeginShowingSkeletons(rootView: UIView) {
- NotificationCenter.default.post(name: .willBeginShowingSkeletons, object: rootView, userInfo: nil)
- rootView.addAppNotificationsObservers()
- }
-
- func didShowSkeletons(rootView: UIView) {
- printSkeletonHierarchy(in: rootView)
- NotificationCenter.default.post(name: .didShowSkeletons, object: rootView, userInfo: nil)
- }
-
- func willBeginUpdatingSkeletons(rootView: UIView) {
- NotificationCenter.default.post(name: .willBeginUpdatingSkeletons, object: rootView, userInfo: nil)
- }
-
- func didUpdateSkeletons(rootView: UIView) {
- NotificationCenter.default.post(name: .didUpdateSkeletons, object: rootView, userInfo: nil)
- }
-
- func willBeginLayingSkeletonsIfNeeded(rootView: UIView) {
- }
-
- func didLayoutSkeletonsIfNeeded(rootView: UIView) {
- }
-
- func willBeginHidingSkeletons(rootView: UIView) {
- NotificationCenter.default.post(name: .willBeginHidingSkeletons, object: rootView, userInfo: nil)
- rootView.removeAppNoticationsObserver()
- }
-
- func didHideSkeletons(rootView: UIView) {
- rootView.flowDelegate = nil
- NotificationCenter.default.post(name: .didHideSkeletons, object: rootView, userInfo: nil)
- }
-}
-
-public extension Notification.Name {
- static let willBeginShowingSkeletons = Notification.Name("willBeginShowingSkeletons")
- static let didShowSkeletons = Notification.Name("didShowSkeletons")
- static let willBeginUpdatingSkeletons = Notification.Name("willBeginUpdatingSkeletons")
- static let didUpdateSkeletons = Notification.Name("didUpdateSkeletons")
- static let willBeginHidingSkeletons = Notification.Name("willBeginHidingSkeletons")
- static let didHideSkeletons = Notification.Name("didHideSkeletons")
-}
diff --git a/Sources/SkeletonView.swift b/Sources/SkeletonView.swift
deleted file mode 100755
index d028a95d..00000000
--- a/Sources/SkeletonView.swift
+++ /dev/null
@@ -1,372 +0,0 @@
-// Copyright © 2017 SkeletonView. All rights reserved.
-
-import UIKit
-
-public extension UIView {
- /// Shows the skeleton without animation using the view that calls this method as root view.
- ///
- /// - Parameters:
- /// - color: The color of the skeleton. Defaults to `SkeletonAppearance.default.tintColor`.
- /// - transition: The style of the transition when the skeleton appears. Defaults to `.crossDissolve(0.25)`.
- func showSkeleton(usingColor color: UIColor = SkeletonAppearance.default.tintColor, transition: SkeletonTransitionStyle = .crossDissolve(0.25)) {
- delayedShowSkeletonWorkItem?.cancel()
- let config = SkeletonConfig(type: .solid, colors: [color], transition: transition)
- showSkeleton(skeletonConfig: config)
- }
-
- /// Shows the skeleton using the view that calls this method as root view.
- ///
- /// - Parameters:
- /// - color: The color of the skeleton. Defaults to `SkeletonAppearance.default.tintColor`.
- /// - animated: If the skeleton is animated or not. Defaults to `true`.
- /// - delay: The amount of time (measured in seconds) to wait before show the skeleton.
- /// - transition: The style of the transition when the skeleton appears. Defaults to `.crossDissolve(0.25)`.
- func showSkeleton(usingColor color: UIColor = SkeletonAppearance.default.tintColor, animated: Bool = true, delay: TimeInterval, transition: SkeletonTransitionStyle = .crossDissolve(0.25)) {
- delayedShowSkeletonWorkItem?.cancel()
-
- delayedShowSkeletonWorkItem = DispatchWorkItem { [weak self] in
- let config = SkeletonConfig(type: .solid, colors: [color], animated: animated, transition: transition)
- self?.showSkeleton(skeletonConfig: config)
- }
-
- DispatchQueue.main.asyncAfter(deadline: .now() + delay, execute: delayedShowSkeletonWorkItem!)
- }
-
- /// Shows the gradient skeleton without animation using the view that calls this method as root view.
- ///
- /// - Parameters:
- /// - gradient: The gradient of the skeleton. Defaults to `SkeletonAppearance.default.gradient`.
- /// - transition: The style of the transition when the skeleton appears. Defaults to `.crossDissolve(0.25)`.
- func showGradientSkeleton(usingGradient gradient: SkeletonGradient = SkeletonAppearance.default.gradient, transition: SkeletonTransitionStyle = .crossDissolve(0.25)) {
- delayedShowSkeletonWorkItem?.cancel()
- let config = SkeletonConfig(type: .gradient, colors: gradient.colors, transition: transition)
- showSkeleton(skeletonConfig: config)
- }
-
- /// Shows the gradient skeleton using the view that calls this method as root view.
- ///
- /// - Parameters:
- /// - gradient: The gradient of the skeleton. Defaults to `SkeletonAppearance.default.gradient`.
- /// - animated: If the skeleton is animated or not. Defaults to `true`.
- /// - delay: The amount of time (measured in seconds) to wait before show the skeleton.
- /// - transition: The style of the transition when the skeleton appears. Defaults to `.crossDissolve(0.25)`.
- func showGradientSkeleton(
- usingGradient gradient: SkeletonGradient = SkeletonAppearance.default.gradient,
- animated: Bool = true,
- delay: TimeInterval,
- transition: SkeletonTransitionStyle = .crossDissolve(0.25)
- ) {
- delayedShowSkeletonWorkItem?.cancel()
-
- delayedShowSkeletonWorkItem = DispatchWorkItem { [weak self] in
- let config = SkeletonConfig(type: .gradient, colors: gradient.colors, animated: animated, transition: transition)
- self?.showSkeleton(skeletonConfig: config)
- }
-
- DispatchQueue.main.asyncAfter(deadline: .now() + delay, execute: delayedShowSkeletonWorkItem!)
- }
-
- /// Shows the animated skeleton using the view that calls this method as root view.
- ///
- /// If animation is nil, sliding animation will be used, with direction left to right.
- ///
- /// - Parameters:
- /// - color: The color of skeleton. Defaults to `SkeletonAppearance.default.tintColor`.
- /// - animation: The animation of the skeleton. Defaults to `nil`.
- /// - transition: The style of the transition when the skeleton appears. Defaults to `.crossDissolve(0.25)`.
- func showAnimatedSkeleton(usingColor color: UIColor = SkeletonAppearance.default.tintColor, animation: SkeletonLayerAnimation? = nil, transition: SkeletonTransitionStyle = .crossDissolve(0.25)) {
- delayedShowSkeletonWorkItem?.cancel()
- let config = SkeletonConfig(type: .solid, colors: [color], animated: true, animation: animation, transition: transition)
- showSkeleton(skeletonConfig: config)
- }
-
- /// Shows the gradient skeleton without animation using the view that calls this method as root view.
- ///
- /// If animation is nil, sliding animation will be used, with direction left to right.
- ///
- /// - Parameters:
- /// - gradient: The gradient of the skeleton. Defaults to `SkeletonAppearance.default.gradient`.
- /// - animation: The animation of the skeleton. Defaults to `nil`.
- /// - transition: The style of the transition when the skeleton appears. Defaults to `.crossDissolve(0.25)`.
- func showAnimatedGradientSkeleton(usingGradient gradient: SkeletonGradient = SkeletonAppearance.default.gradient, animation: SkeletonLayerAnimation? = nil, transition: SkeletonTransitionStyle = .crossDissolve(0.25)) {
- delayedShowSkeletonWorkItem?.cancel()
- let config = SkeletonConfig(type: .gradient, colors: gradient.colors, animated: true, animation: animation, transition: transition)
- showSkeleton(skeletonConfig: config)
- }
-
- func updateSkeleton(usingColor color: UIColor = SkeletonAppearance.default.tintColor) {
- let config = SkeletonConfig(type: .solid, colors: [color])
- updateSkeleton(skeletonConfig: config)
- }
-
- func updateGradientSkeleton(usingGradient gradient: SkeletonGradient = SkeletonAppearance.default.gradient) {
- let config = SkeletonConfig(type: .gradient, colors: gradient.colors)
- updateSkeleton(skeletonConfig: config)
- }
-
- func updateAnimatedSkeleton(usingColor color: UIColor = SkeletonAppearance.default.tintColor, animation: SkeletonLayerAnimation? = nil) {
- let config = SkeletonConfig(type: .solid, colors: [color], animated: true, animation: animation)
- updateSkeleton(skeletonConfig: config)
- }
-
- func updateAnimatedGradientSkeleton(usingGradient gradient: SkeletonGradient = SkeletonAppearance.default.gradient, animation: SkeletonLayerAnimation? = nil) {
- let config = SkeletonConfig(type: .gradient, colors: gradient.colors, animated: true, animation: animation)
- updateSkeleton(skeletonConfig: config)
- }
-
- func layoutSkeletonIfNeeded() {
- flowDelegate?.willBeginLayingSkeletonsIfNeeded(rootView: self)
- recursiveLayoutSkeletonIfNeeded(root: self)
- }
-
- func hideSkeleton(reloadDataAfter reload: Bool = true, transition: SkeletonTransitionStyle = .crossDissolve(0.25)) {
- delayedShowSkeletonWorkItem?.cancel()
- flowDelegate?.willBeginHidingSkeletons(rootView: self)
- recursiveHideSkeleton(reloadDataAfter: reload, transition: transition, root: self)
- }
-
- func startSkeletonAnimation(_ anim: SkeletonLayerAnimation? = nil) {
- subviewsSkeletonables.recursiveSearch(leafBlock: startSkeletonLayerAnimationBlock(anim)) { subview in
- subview.startSkeletonAnimation(anim)
- }
- }
-
- func stopSkeletonAnimation() {
- subviewsSkeletonables.recursiveSearch(leafBlock: stopSkeletonLayerAnimationBlock) { subview in
- subview.stopSkeletonAnimation()
- }
- }
-}
-
-extension UIView {
- @objc func skeletonLayoutSubviews() {
- guard Thread.isMainThread else { return }
- skeletonLayoutSubviews()
- guard isSkeletonActive else { return }
- layoutSkeletonIfNeeded()
- }
-
- @objc func skeletonTraitCollectionDidChange(_ previousTraitCollection: UITraitCollection?) {
- skeletonTraitCollectionDidChange(previousTraitCollection)
- guard isSkeletonable, isSkeletonActive, let config = currentSkeletonConfig else { return }
- updateSkeleton(skeletonConfig: config)
- }
-
- func showSkeleton(skeletonConfig config: SkeletonConfig) {
- isSkeletonAnimated = config.animated
- flowDelegate = SkeletonFlowHandler()
- flowDelegate?.willBeginShowingSkeletons(rootView: self)
- recursiveShowSkeleton(skeletonConfig: config, root: self)
- }
-
- private func recursiveShowSkeleton(skeletonConfig config: SkeletonConfig, root: UIView? = nil) {
- if isHiddenWhenSkeletonIsActive {
- isHidden = true
- }
- guard isSkeletonable && !isSkeletonActive else { return }
- currentSkeletonConfig = config
- swizzleLayoutSubviews()
- swizzleTraitCollectionDidChange()
- addDummyDataSourceIfNeeded()
- subviewsSkeletonables.recursiveSearch(leafBlock: {
- showSkeletonIfNotActive(skeletonConfig: config)
- }) { subview in
- subview.recursiveShowSkeleton(skeletonConfig: config)
- }
-
- if let root = root {
- flowDelegate?.didShowSkeletons(rootView: root)
- }
- }
-
- private func showSkeletonIfNotActive(skeletonConfig config: SkeletonConfig) {
- guard !isSkeletonActive else { return }
- saveViewState()
-
- prepareViewForSkeleton()
- addSkeletonLayer(skeletonConfig: config)
- }
-
- func updateSkeleton(skeletonConfig config: SkeletonConfig) {
- isSkeletonAnimated = config.animated
- flowDelegate?.willBeginUpdatingSkeletons(rootView: self)
- recursiveUpdateSkeleton(skeletonConfig: config, root: self)
- }
-
- private func recursiveUpdateSkeleton(skeletonConfig config: SkeletonConfig, root: UIView? = nil) {
- guard isSkeletonActive else { return }
- currentSkeletonConfig = config
- updateDummyDataSourceIfNeeded()
- subviewsSkeletonables.recursiveSearch(leafBlock: {
- if let skeletonLayer = skeletonLayer,
- skeletonLayer.type != config.type {
- removeSkeletonLayer()
- addSkeletonLayer(skeletonConfig: config)
- } else {
- updateSkeletonLayer(skeletonConfig: config)
- }
- }) { subview in
- subview.recursiveUpdateSkeleton(skeletonConfig: config)
- }
-
- if let root = root {
- flowDelegate?.didUpdateSkeletons(rootView: root)
- }
- }
-
- private func recursiveLayoutSkeletonIfNeeded(root: UIView? = nil) {
- subviewsSkeletonables.recursiveSearch(leafBlock: {
- guard isSkeletonable, isSkeletonActive else { return }
- layoutSkeletonLayerIfNeeded()
- if let config = currentSkeletonConfig, config.animated, !isSkeletonAnimated {
- startSkeletonAnimation(config.animation)
- }
- }) { subview in
- subview.recursiveLayoutSkeletonIfNeeded()
- }
-
- if let root = root {
- flowDelegate?.didLayoutSkeletonsIfNeeded(rootView: root)
- }
- }
-
- private func recursiveHideSkeleton(reloadDataAfter reload: Bool, transition: SkeletonTransitionStyle, root: UIView? = nil) {
- guard isSkeletonActive else { return }
- if isHiddenWhenSkeletonIsActive {
- isHidden = false
- }
- currentSkeletonConfig?.transition = transition
- unSwizzleLayoutSubviews()
- unSwizzleTraitCollectionDidChange()
- removeDummyDataSourceIfNeeded(reloadAfter: reload)
- subviewsSkeletonables.recursiveSearch(leafBlock: {
- recoverViewState(forced: false)
- removeSkeletonLayer()
- }) { subview in
- subview.recursiveHideSkeleton(reloadDataAfter: reload, transition: transition)
- }
-
- if let root = root {
- flowDelegate?.didHideSkeletons(rootView: root)
- }
- }
-
- private func startSkeletonLayerAnimationBlock(_ anim: SkeletonLayerAnimation? = nil) -> VoidBlock {
- return {
- self.isSkeletonAnimated = true
- guard let layer = self.skeletonLayer else { return }
- layer.start(anim) { [weak self] in
- self?.isSkeletonAnimated = false
- }
- }
- }
-
- private var stopSkeletonLayerAnimationBlock: VoidBlock {
- return {
- self.isSkeletonAnimated = false
- guard let layer = self.skeletonLayer else { return }
- layer.stopAnimation()
- }
- }
-
- private func swizzleLayoutSubviews() {
- DispatchQueue.main.asyncAfter(deadline: .now() + 0.01) {
- DispatchQueue.once(token: "UIView.SkeletonView.swizzleLayoutSubviews") {
- swizzle(selector: #selector(UIView.layoutSubviews),
- with: #selector(UIView.skeletonLayoutSubviews),
- inClass: UIView.self,
- usingClass: UIView.self)
- self.layoutSkeletonIfNeeded()
- }
- }
- }
-
- private func unSwizzleLayoutSubviews() {
- DispatchQueue.main.asyncAfter(deadline: .now() + 0.01) {
- DispatchQueue.removeOnce(token: "UIView.SkeletonView.swizzleLayoutSubviews") {
- swizzle(selector: #selector(UIView.skeletonLayoutSubviews),
- with: #selector(UIView.layoutSubviews),
- inClass: UIView.self,
- usingClass: UIView.self)
- }
- }
- }
-
- private func swizzleTraitCollectionDidChange() {
- DispatchQueue.main.asyncAfter(deadline: .now() + 0.01) {
- DispatchQueue.once(token: "UIView.SkeletonView.swizzleTraitCollectionDidChange") {
- swizzle(selector: #selector(UIView.traitCollectionDidChange(_:)),
- with: #selector(UIView.skeletonTraitCollectionDidChange(_:)),
- inClass: UIView.self,
- usingClass: UIView.self)
- }
- }
- }
-
- private func unSwizzleTraitCollectionDidChange() {
- DispatchQueue.main.asyncAfter(deadline: .now() + 0.01) {
- DispatchQueue.removeOnce(token: "UIView.SkeletonView.swizzleTraitCollectionDidChange") {
- swizzle(selector: #selector(UIView.skeletonTraitCollectionDidChange(_:)),
- with: #selector(UIView.traitCollectionDidChange(_:)),
- inClass: UIView.self,
- usingClass: UIView.self)
- }
- }
- }
-}
-
-extension UIView {
- func addSkeletonLayer(skeletonConfig config: SkeletonConfig) {
- guard let skeletonLayer = SkeletonLayerBuilder()
- .setSkeletonType(config.type)
- .addColors(config.colors)
- .setHolder(self)
- .build()
- else { return }
-
- self.skeletonLayer = skeletonLayer
- layer.insertSkeletonLayer(
- skeletonLayer,
- atIndex: UInt32.max,
- transition: config.transition
- ) { [weak self] in
- guard let self = self else { return }
-
- /// Workaround to fix the problem when inserting a sublayer and
- /// the content offset is modified by the system.
- (self as? UITextView)?.setContentOffset(.zero, animated: false)
-
- if config.animated {
- self.startSkeletonAnimation(config.animation)
- }
- }
- status = .on
- }
-
- func updateSkeletonLayer(skeletonConfig config: SkeletonConfig) {
- guard let skeletonLayer = skeletonLayer else { return }
- skeletonLayer.update(usingColors: config.colors)
- if config.animated {
- startSkeletonAnimation(config.animation)
- } else {
- skeletonLayer.stopAnimation()
- }
- }
-
- func layoutSkeletonLayerIfNeeded() {
- guard let skeletonLayer = skeletonLayer else { return }
- skeletonLayer.layoutIfNeeded()
- }
-
- func removeSkeletonLayer() {
- guard isSkeletonActive,
- let skeletonLayer = skeletonLayer,
- let transitionStyle = currentSkeletonConfig?.transition else { return }
- skeletonLayer.stopAnimation()
- status = .off
- skeletonLayer.removeLayer(transition: transitionStyle) {
- self.skeletonLayer = nil
- self.currentSkeletonConfig = nil
- }
- }
-}
diff --git a/Sources/Transitions/UIView+Transitions.swift b/Sources/Transitions/UIView+Transitions.swift
deleted file mode 100644
index 2c8f8495..00000000
--- a/Sources/Transitions/UIView+Transitions.swift
+++ /dev/null
@@ -1,34 +0,0 @@
-// Copyright © 2019 SkeletonView. All rights reserved.
-
-import UIKit
-
-extension CALayer {
- func insertSkeletonLayer(_ sublayer: SkeletonLayer, atIndex index: UInt32, transition: SkeletonTransitionStyle, completion: (() -> Void)? = nil) {
- insertSublayer(sublayer.contentLayer, at: index)
- switch transition {
- case .none:
- completion?()
- case .crossDissolve(let duration):
- sublayer.contentLayer.setOpacity(from: 0, to: 1, duration: duration, completion: completion)
- }
- }
-}
-
-extension UIView {
- func startTransition(transitionBlock: @escaping () -> Void) {
- guard let transitionStyle = currentSkeletonConfig?.transition,
- transitionStyle != .none
- else {
- transitionBlock()
- return
- }
-
- if case let .crossDissolve(duration) = transitionStyle {
- UIView.transition(with: self,
- duration: duration,
- options: .transitionCrossDissolve,
- animations: transitionBlock,
- completion: nil)
- }
- }
-}
diff --git a/README_es.md b/Translations/README_es.md
similarity index 89%
rename from README_es.md
rename to Translations/README_es.md
index 246639d4..5a56850c 100644
--- a/README_es.md
+++ b/Translations/README_es.md
@@ -1,4 +1,4 @@
-![](Assets/header2.jpg)
+![](../Assets/header2.jpg)
@@ -18,7 +18,7 @@
• Contribuir
-**🌎 README está disponible en estos idiomas: [🇬🇧](https://github.com/Juanpe/SkeletonView/blob/master/README.md) . [🇨🇳](https://github.com/Juanpe/SkeletonView/blob/master/README_zh.md) . [🇧🇷](https://github.com/Juanpe/SkeletonView/blob/master/README_pt-br.md) . [🇰🇷](https://github.com/Juanpe/SkeletonView/blob/master/README_ko.md) . [🇫🇷](https://github.com/Juanpe/SkeletonView/blob/master/README_fr.md)**
+**🌎 README está disponible en estos idiomas: [🇬🇧](../README.md) . [🇨🇳](README_zh.md) . [🇧🇷](README_pt-br.md) . [🇰🇷](README_ko.md) . [🇫🇷](README_fr.md)**
Hoy en día, La mayoría de las apps tiene procesos asíncronos, como peticiones a una API, procesos que tardan mucho tiempo, etc. Mientras estos procesos se están ejecutando, se suele mostrar un aburrido spinner indicando que algo está pasando.
@@ -104,7 +104,7 @@ avatarImageView.isSkeletonable = true
```
**Con IB/Storyboards:**
-![](Assets/storyboard.png)
+![](../Assets/storyboard.png)
3️⃣ Una vez indicado, solo tienes que mostrar el **skeleton**. Tienes **4** opciones:
@@ -134,16 +134,16 @@ avatarImageView.isSkeletonable = true
-
+
|
-
+
|
-
+
|
-
+
|
@@ -225,7 +225,7 @@ El resto del proceso es exactamente igual que con las `UITableView`.
### 🔠 Textos
-![](Assets/multilines2.png)
+![](../Assets/multilines2.png)
Cuando usas elementos que contienen texto,`SkeletonView` dibujo líneas para simular el texto.
@@ -236,8 +236,8 @@ Puedes especificar algunos atributos para estos elementos:
| Atributo | Valores | Por defecto | Vista previa
| ------- | ------- |------- | -------
-| **Porcentaje de relleno** de la última línea. | `0...100` | `70%` | ![](Assets/multiline_lastline.png)
-| **Radio de las esquinas** de las líneas. | `0...10` | `0` | ![](Assets/multiline_corner.png)
+| **Porcentaje de relleno** de la última línea. | `0...100` | `70%` | ![](../Assets/multiline_lastline.png)
+| **Radio de las esquinas** de las líneas. | `0...10` | `0` | ![](../Assets/multiline_corner.png)
Para modificar alguno de los valores lo puedes hacer **con código**::
```swift
@@ -247,7 +247,7 @@ descriptionTextView.linesCornerRadius = 5
O usando **IB/Storyboards**:
-![](Assets/multiline_customize.png)
+![](../Assets/multiline_customize.png)
### 🦋 Apariencia
@@ -297,7 +297,7 @@ Además, **SkeletonView** añade 20 colores flat 🤙🏼
```UIColor.turquoise, UIColor.greenSea, UIColor.sunFlower, UIColor.flatOrange ...```
-![](Assets/flatcolors.png)
+![](../Assets/flatcolors.png)
###### Imagen extraída de la web [https://flatuicolors.com](https://flatuicolors.com)
@@ -338,12 +338,12 @@ view.showAnimatedGradientSkeleton(usingGradient: gradient, animation: animation)
| Dirección | Vista previa
|------- | -------
-| .leftRight | ![](Assets/sliding_left_to_right.gif)
-| .rightLeft | ![](Assets/sliding_right_to_left.gif)
-| .topBottom | ![](Assets/sliding_top_to_bottom.gif)
-| .bottomTop | ![](Assets/sliding_bottom_to_top.gif)
-| .topLeftBottomRight | ![](Assets/sliding_topLeft_to_bottomRight.gif)
-| .bottomRightTopLeft | ![](Assets/sliding_bottomRight_to_topLeft.gif)
+| .leftRight | ![](../Assets/sliding_left_to_right.gif)
+| .rightLeft | ![](../Assets/sliding_right_to_left.gif)
+| .topBottom | ![](../Assets/sliding_top_to_bottom.gif)
+| .bottomTop | ![](../Assets/sliding_bottom_to_top.gif)
+| .topLeftBottomRight | ![](../Assets/sliding_topLeft_to_bottomRight.gif)
+| .bottomRightTopLeft | ![](../Assets/sliding_bottomRight_to_topLeft.gif)
> **😉 ¡Truco!**
>
@@ -379,10 +379,10 @@ La transición por defecto es `crossDissolve(0.25)`
-
+
|
-
+
|
@@ -408,12 +408,12 @@ view.showSkeleton()
| Configuración | Resultado|
|:-------:|:-------:|
-| | |
-| | |
-| | |
-|| |
-| | |
-| | |
+| | |
+| | |
+| | |
+|| |
+| | |
+| | |
@@ -421,7 +421,7 @@ view.showSkeleton()
Esta ilustración muestra como deberías específicar qué elementos son skeletonables cuando estás usando una `UITableView`:
-
+
**Actualiza el skeleton**
@@ -447,17 +447,17 @@ var skeletonDescription: String
```
Y es representada de la siguiente manera:
-![](Assets/debug_description.png)
+![](../Assets/debug_description.png)
Para activar el **modo debug**. Solo tienes que añadir una variable de entorno con esta clave `SKELETON_DEBUG` y activarla.
-![](Assets/debug_mode.png)
+![](../Assets/debug_mode.png)
Entonces, cuando el skeleton aparece, tu podrás ver la jerarquía de vistas en la consola de Xcode.
Abre para ver un ejemplo
-
+
diff --git a/README_fr.md b/Translations/README_fr.md
similarity index 90%
rename from README_fr.md
rename to Translations/README_fr.md
index 5104a587..92bf7cae 100644
--- a/README_fr.md
+++ b/Translations/README_fr.md
@@ -1,4 +1,4 @@
-![](Assets/header2.jpg)
+![](../Assets/header2.jpg)
@@ -24,12 +24,7 @@
-🌎 Traductions :
-[Original](https://github.com/Juanpe/SkeletonView)
-[🇨🇳](https://github.com/Juanpe/SkeletonView/blob/master/README_zh.md) [@WhatsXie](https://twitter.com/WhatsXie)
-[🇧🇷](https://github.com/Juanpe/SkeletonView/blob/master/README_pt-br.md) [@brunomunizaf](https://twitter.com/brunomuniz_af)
-[🇰🇷](https://github.com/Juanpe/SkeletonView/blob/master/README_ko.md) [@techinpark](https://twitter.com/techinpark)
-[🇫🇷](https://github.com/Juanpe/SkeletonView/blob/master/README_fr.md) [@OmarJalil](https://github.com/OmarJalil)
+**🌎 Traductions: [🇬🇧](../README.md) . [🇨🇳](README_zh.md) . [🇧🇷](README_pt-br.md) . [🇰🇷](README_ko.md) . [🇫🇷](README_fr.md)**
Aujourd'hui, presque toutes les applications ont des processus asynchrones, tels que les requêtes Api, les processus de longue durée, etc. Et pendant que les processus fonctionnent, les développeurs affichent généralement une vue de chargement pour montrer aux utilisateurs que quelque chose se passe.
@@ -80,7 +75,7 @@ Profitez-en! 🙂
## 🎬 Guides
- [](https://youtu.be/75kgOhWsPNA)
+ [](https://youtu.be/75kgOhWsPNA)
## 📲 Installation
@@ -127,7 +122,7 @@ avatarImageView.isSkeletonable = true
```
**Utilisation des IB/Storyboards:**
-![](Assets/storyboard.png)
+![](../Assets/storyboard.png)
**Une fois que vous avez défini les vues, vous pouvez montrer le **squelette**. Pour le faire, vous avez quatre choix :
@@ -157,16 +152,16 @@ avatarImageView.isSkeletonable = true
-
+
|
-
+
|
-
+
|
-
+
|
@@ -263,7 +258,7 @@ Il n'y a qu'une seule méthode à mettre en œuvre pour faire connaître au Sque
Voici une illustration qui montre comment vous devez spécifier quels éléments sont squelettisables lorsque vous utilisez une `UITableView` :
-![](Assets/tableview_scheme.png)
+![](../Assets/tableview_scheme.png)
Comme vous pouvez le voir, nous devons faire `skeletonable` la tableview, la cellule et les éléments de l'interface visuelle, mais nous n'avons pas besoin de faire `skeletonable` le `contentView`.
@@ -283,7 +278,7 @@ Le reste du processus ressemble à une `UITableView`.
### 📰 Texte multiligne
-![](Assets/multilines2.png)
+![](../Assets/multilines2.png)
Lorsqu'on utilise des éléments avec du texte, `SkeletonView` dessine des lignes pour simuler le texte.
En outre, vous pouvez décider combien de lignes vous voulez. Si `numberOfLines` est réglé à zéro, il calculera le combien de lignes sont nécessaires pour remplir tout le squelette et il sera dessiné. Au contraire, si vous le réglez sur un, deux ou tout autre nombre supérieur à zéro, il ne dessinera que ce nombre de lignes.
@@ -294,8 +289,8 @@ Vous pouvez définir certaines propriétés pour les éléments multilignes.
| Propriété | Valeurs | Par défaut | Aperçu
| ------- | ------- |------- | -------
-| **Pourcentage de remplissage** de la dernière ligne. | `0...100` | `70%` | ![](Assets/multiline_lastline.png)
-| **Corner radius** des lignes. (**NEW**) | `0...10` | `0` | ![](Assets/multiline_corner.png)
+| **Pourcentage de remplissage** de la dernière ligne. | `0...100` | `70%` | ![](../Assets/multiline_lastline.png)
+| **Corner radius** des lignes. (**NEW**) | `0...10` | `0` | ![](../Assets/multiline_corner.png)
Pour modifier le pourcentage ou le rayon **à l'aide du code**, définissez les propriétés :
@@ -306,7 +301,7 @@ descriptionTextView.linesCornerRadius = 5
Ou, si vous préférez, utilisez l'**IB/Storyboard** :
-![](Assets/multiline_customize.png)
+![](../Assets/multiline_customize.png)
### 🎨 Couleurs personnalisées
@@ -328,7 +323,7 @@ En outre, `SkeletonView` dispose de 20 couleurs unies 🤙🏼
`UIColor.turquoise, UIColor.greenSea, UIColor.sunFlower, UIColor.flatOrange ...`
-![](Assets/flatcolors.png)
+![](../Assets/flatcolors.png)
###### Image tirée du site web [https://flatuicolors.com](https://flatuicolors.com)
### 🦋 Présentation
@@ -396,12 +391,12 @@ view.showAnimatedGradientSkeleton(usingGradient : gradient, animation : animatio
| Direction | Aperçu
|------- | -------
-| .leftRight | ![](Assets/sliding_left_to_right.gif)
-| .rightLeft | ![](Assets/sliding_right_to_left.gif)
-| .topBottom | ![](Assets/sliding_top_to_bottom.gif)
-| .bottomTop | ![](Assets/sliding_bottom_to_top.gif)
-| .topLeftBottomRight | ![](Assets/sliding_topLeft_to_bottomRight.gif)
-| .bottomRightTopLeft | ![](Assets/sliding_bottomRight_to_topLeft.gif)
+| .leftRight | ![](../Assets/sliding_left_to_right.gif)
+| .rightLeft | ![](../Assets/sliding_right_to_left.gif)
+| .topBottom | ![](../Assets/sliding_top_to_bottom.gif)
+| .bottomTop | ![](../Assets/sliding_bottom_to_top.gif)
+| .topLeftBottomRight | ![](../Assets/sliding_topLeft_to_bottomRight.gif)
+| .bottomRightTopLeft | ![](../Assets/sliding_bottomRight_to_topLeft.gif)
> **😉 TRICK!**
Il existe une autre façon de créer des animations de glissement, en utilisant simplement ce raccourci :
@@ -433,10 +428,10 @@ La valeur par défaut est `crossDissolve(0.25)`.
-
+
|
-
+
|
@@ -456,12 +451,12 @@ view.showSkeleton()
| Configuration | Résultat|
|:-------:|:-------:|
-| | |
-| | |
-| | |
-|| |
-| | |
-| | |
+| | |
+| | |
+| | |
+|| |
+| | |
+| | |
### 🔬 Débugger
@@ -473,17 +468,17 @@ var skeletonDescription : String
```
La représentation du squelette ressemble à ceci :
-![](Assets/debug_description.png)
+![](../Assets/debug_description.png)
En outre, vous pouvez activer le nouveau mode **debug**. Il suffit d'ajouter la variable d'environnement `SKELETON_DEBUG` et de l'activer.
-![](Assets/debug_mode.png)
+![](../Assets/debug_mode.png)
Ensuite, lorsque le squelette apparaît, vous pouvez voir la hiérarchie des vues dans la console Xcode.
Ouvrez pour voir un exemple de sortie
-
+
### 📚 Documentation
diff --git a/README_ko.md b/Translations/README_ko.md
similarity index 90%
rename from README_ko.md
rename to Translations/README_ko.md
index f96f3b0c..f4603ef2 100644
--- a/README_ko.md
+++ b/Translations/README_ko.md
@@ -1,4 +1,4 @@
-![](Assets/header2.jpg)
+![](../Assets/header2.jpg)
@@ -23,12 +23,7 @@
-🌎 번역에 도움을 주신분들:
-[Original](https://github.com/Juanpe/SkeletonView)
-[🇨🇳](https://github.com/Juanpe/SkeletonView/blob/master/README_zh.md) [@WhatsXie](https://twitter.com/WhatsXie)
-[🇧🇷](https://github.com/Juanpe/SkeletonView/blob/master/README_pt-br.md) [@brunomunizaf](https://twitter.com/brunomuniz_af)
-[🇰🇷](https://github.com/Juanpe/SkeletonView/blob/master/README_ko.md) [@techinpark](https://twitter.com/techinpark)
-[🇫🇷](https://github.com/Juanpe/SkeletonView/blob/master/README_fr.md) [@OmarJalil](https://github.com/OmarJalil)
+**🌎 번역에 도움을 주신분들: [🇬🇧](../README.md) . [🇨🇳](README_zh.md) . [🇧🇷](README_pt-br.md) . [🇰🇷](README_ko.md) . [🇫🇷](README_fr.md)**
오늘날 거의 대부분의 앱들은 비동기 방식의 API 호출을 사용하는 프로세스를 가지고 있습니다.
프로세스가 작동하는동안 개발자들은 작업이 실행되고 있다는것을 사용자들에게 보여주기 위해서 로딩 뷰를 배치합니다.
@@ -72,7 +67,7 @@
## 🎬 사용가이드
- [](https://youtu.be/75kgOhWsPNA)
+ [](https://youtu.be/75kgOhWsPNA)
## 📲 설치 방법
@@ -123,7 +118,7 @@ avatarImageView.isSkeletonable = true
```
**인터페이스빌더 / 스토리보드를 이용하는 방법:**
-![](Assets/storyboard.png)
+![](../Assets/storyboard.png)
**3.** 당신이 뷰를 세팅할때, **skeleton** 옵션을 사용 할 수 있습니다. 총 **4** 가지 옵션을 지원합니다:
@@ -153,16 +148,16 @@ avatarImageView.isSkeletonable = true
-
+
|
-
+
|
-
+
|
-
+
|
@@ -224,7 +219,7 @@ func collectionSkeletonView(_ skeletonView: UITableView, numberOfRowsInSection s
아래의 그림은 `UITableView` 에서 특정한 요소에 skeleton 을 지정하는 방법을 보여주는 이미지 입니다:
-![](Assets/tableview_scheme.png)
+![](../Assets/tableview_scheme.png)
위의 이미지에서 보이듯, 테이블 뷰와 셀에 들어가는 UI 요소들에는 적용을 해야하지만, `contentView`에 skeleton을 적용할 필요는 없습니다.
@@ -245,7 +240,7 @@ public protocol SkeletonCollectionViewDataSource: UICollectionViewDataSource {
### 📰 Multiline text
-![](Assets/multilines2.png)
+![](../Assets/multilines2.png)
텍스트가 들어있는 요소를 사용한다면, ```SkeletonView``` 에서 텍스트의 라인을 그려줍니다.
그리고, 원하는 라인 수를 설정할 수 있습니다. 만약 ```numberOfLines``` 을 0으로 설정한다면, 자동으로 필요한 라인수를 계산해서 그려줍니다. 대신 값이 설정되어있다면 설정된 수만큼의 라인이 그려집니다.
@@ -257,8 +252,8 @@ public protocol SkeletonCollectionViewDataSource: UICollectionViewDataSource {
| 속성 | 값 | 기본값 | 미리보기 |
| ----------------------------------------------- | --------- | ----- | ---------------------------------- |
-| 마지막 라인의 **퍼센트** 를 지정 할 수 있습니다. | `0...100` | `70%` | ![](Assets/multiline_lastline.png) |
-| 라인의 **Corner radius** 를 지정할 수 있습니다. (**새로운기능**) | `0...10` | `0` | ![](Assets/multiline_corner.png) |
+| 마지막 라인의 **퍼센트** 를 지정 할 수 있습니다. | `0...100` | `70%` | ![](../Assets/multiline_lastline.png) |
+| 라인의 **Corner radius** 를 지정할 수 있습니다. (**새로운기능**) | `0...10` | `0` | ![](../Assets/multiline_corner.png) |
@@ -270,7 +265,7 @@ descriptionTextView.linesCornerRadius = 5
혹은 **IB/Storyboard** 를 이용하실 수 있습니다:
-![](Assets/multiline_customize.png)
+![](../Assets/multiline_customize.png)
### 🎨 Custom colors
@@ -292,7 +287,7 @@ view.showGradientSkeleton(usingGradient: gradient) // Gradient
```UIColor.turquoise, UIColor.greenSea, UIColor.sunFlower, UIColor.flatOrange ...```
-![](Assets/flatcolors.png)
+![](../Assets/flatcolors.png)
###### 위 이미지는 [https://flatuicolors.com](https://flatuicolors.com) 사이트에서 발췌했습니다.
### 🦋 Appearance
@@ -360,12 +355,12 @@ view.showAnimatedGradientSkeleton(usingGradient: gradient, animation: animation)
| 방향 | 미리보기 |
| ------------------- | ---------------------------------------------- |
-| .leftRight | ![](Assets/sliding_left_to_right.gif) |
-| .rightLeft | ![](Assets/sliding_right_to_left.gif) |
-| .topBottom | ![](Assets/sliding_top_to_bottom.gif) |
-| .bottomTop | ![](Assets/sliding_bottom_to_top.gif) |
-| .topLeftBottomRight | ![](Assets/sliding_topLeft_to_bottomRight.gif) |
-| .bottomRightTopLeft | ![](Assets/sliding_bottomRight_to_topLeft.gif) |
+| .leftRight | ![](../Assets/sliding_left_to_right.gif) |
+| .rightLeft | ![](../Assets/sliding_right_to_left.gif) |
+| .topBottom | ![](../Assets/sliding_top_to_bottom.gif) |
+| .bottomTop | ![](../Assets/sliding_bottom_to_top.gif) |
+| .topLeftBottomRight | ![](../Assets/sliding_topLeft_to_bottomRight.gif) |
+| .bottomRightTopLeft | ![](../Assets/sliding_bottomRight_to_topLeft.gif) |
> **😉 꿀팁!**
슬라이딩 애니메이션을 만들기 위한 또다른 방법이 있습니다, 아래의 코드를 참조하세요:
@@ -381,10 +376,10 @@ view.showAnimatedGradientSkeleton(usingGradient: gradient, animation: animation)
| 설정값 | 결과 |
| ----------------------------------------- | --------------------------------------------- |
-| ![](Assets/no_skeletonable.png) | ![](Assets/no_skeletonables_result.png) |
-| ![](Assets/container_no_skeletonable.png) | ![](Assets/no_skeletonables_result.png) |
-| ![](Assets/container_skeletonable.png) | ![](Assets/container_skeletonable_result.png) |
-| ![](Assets/all_skeletonables.png) | ![](Assets/all_skeletonables_result.png) |
+| ![](../Assets/no_skeletonable.png) | ![](../Assets/no_skeletonables_result.png) |
+| ![](../Assets/container_no_skeletonable.png) | ![](../Assets/no_skeletonables_result.png) |
+| ![](../Assets/container_skeletonable.png) | ![](../Assets/container_skeletonable_result.png) |
+| ![](../Assets/all_skeletonables.png) | ![](../Assets/all_skeletonables_result.png) |
### 🔬 디버그
@@ -398,17 +393,17 @@ var skeletonDescription: String
```
skeleton은 이렇게 생겼습니다:
-![](Assets/debug_description.png)
+![](../Assets/debug_description.png)
그리고, 새로운 **디버그 모드**를 활성화 시킬 수 있습니다. 간단하게 `SKELETON_DEBUG` 이라는 환경 변수를 추가해 활성화 하면 됩니다.
-![](Assets/debug_mode.png)
+![](../Assets/debug_mode.png)
그런 이후 skeleton이 나오면 Xcode 콘솔창에서 계층 구조를 볼 수 있습니다.
예제를 확인해보세요.
-
+
diff --git a/README_pt-br.md b/Translations/README_pt-br.md
similarity index 90%
rename from README_pt-br.md
rename to Translations/README_pt-br.md
index 2d6df2a3..535317b1 100755
--- a/README_pt-br.md
+++ b/Translations/README_pt-br.md
@@ -1,4 +1,4 @@
-![](Assets/header2.jpg)
+![](../Assets/header2.jpg)
@@ -23,12 +23,7 @@
-🌎 Traduções:
-[Original](https://github.com/Juanpe/SkeletonView)
-[🇨🇳](https://github.com/Juanpe/SkeletonView/blob/master/README_zh.md) [@WhatsXie](https://twitter.com/WhatsXie)
-[🇧🇷](https://github.com/Juanpe/SkeletonView/blob/master/README_pt-br.md) [@brunomunizaf](https://twitter.com/brunomuniz_af)
-[🇰🇷](https://github.com/Juanpe/SkeletonView/blob/master/README_ko.md) [@techinpark](https://twitter.com/techinpark)
-[🇫🇷](https://github.com/Juanpe/SkeletonView/blob/master/README_fr.md) [@OmarJalil](https://github.com/OmarJalil)
+**🌎 Traduções: [🇬🇧](../README.md) . [🇨🇳](README_zh.md) . [🇧🇷](README_pt-br.md) . [🇰🇷](README_ko.md) . [🇫🇷](README_fr.md)**
Hoje, quase todos os apps têm processos assíncronos, como requisições de API, processos longos, etc. E enquanto os processos estão ocorrendo, normalmente os desenvolvedores usam uma view que mostra os usuarios que algo está ocorrendo.
@@ -117,7 +112,7 @@ avatarImageView.isSkeletonable = true
```
**Usando IB/Storyboards:**
-![](Assets/storyboard.png)
+![](../Assets/storyboard.png)
**3.** Uma vez que você setou as views, você pode mostrar o **skeleton**. Para fazê-lo, você tem **4** escolhas:
@@ -147,16 +142,16 @@ avatarImageView.isSkeletonable = true
-
+
|
-
+
|
-
+
|
-
+
|
@@ -226,7 +221,7 @@ O resto do processo é o mesmo da ```UITableView```
### 📰 Texto de várias linhas
-![](Assets/multilines2.png)
+![](../Assets/multilines2.png)
Quando você usar elementos com texto, ```SkeletonView``` desenha linhas para simular o texto.
Além disso, você pode decidir quantas linhas você quer. Se ```numberOfLines``` está setado para zero (0), haverá um cálculo para saber quantas linhas são necessárias para preencher o skeleton inteiro e será desenhado. Caso contrário, se você setar para um (1) ou qualquer outro número maior que zero, só serão desenhadas aquele número de linhas.
@@ -238,8 +233,8 @@ Você pode setar algumas propriedades para elementos de várias linhas.
| Property | Values | Default | Preview
| ------- | ------- |------- | -------
-| **Filling percent** of the last line. | `0...100` | `70%` | ![](Assets/multiline_lastline.png)
-| **Corner radius** of lines. (**NEW**) | `0...10` | `0` | ![](Assets/multiline_corner.png)
+| **Filling percent** of the last line. | `0...100` | `70%` | ![](../Assets/multiline_lastline.png)
+| **Corner radius** of lines. (**NEW**) | `0...10` | `0` | ![](../Assets/multiline_corner.png)
@@ -251,7 +246,7 @@ descriptionTextView.linesCornerRadius = 5
Ou, se você preferir use **IB/Storyboard**:
-![](Assets/multiline_customize.png)
+![](../Assets/multiline_customize.png)
### 🎨 Cores customizadas
@@ -273,7 +268,7 @@ Além do mais, ```SkeletonView``` tem 20 cores flat 🤙🏼
```UIColor.turquoise, UIColor.greenSea, UIColor.sunFlower, UIColor.flatOrange ...```
-![](Assets/flatcolors.png)
+![](../Assets/flatcolors.png)
###### Imagem capturada do site [https://flatuicolors.com](https://flatuicolors.com)
### 🦋 Aparência
@@ -341,12 +336,12 @@ view.showAnimatedGradientSkeleton(usingGradient: gradient, animation: animation)
| Direction | Preview
|------- | -------
-| .leftRight | ![](Assets/sliding_left_to_right.gif)
-| .rightLeft | ![](Assets/sliding_right_to_left.gif)
-| .topBottom | ![](Assets/sliding_top_to_bottom.gif)
-| .bottomTop | ![](Assets/sliding_bottom_to_top.gif)
-| .topLeftBottomRight | ![](Assets/sliding_topLeft_to_bottomRight.gif)
-| .bottomRightTopLeft | ![](Assets/sliding_bottomRight_to_topLeft.gif)
+| .leftRight | ![](../Assets/sliding_left_to_right.gif)
+| .rightLeft | ![](../Assets/sliding_right_to_left.gif)
+| .topBottom | ![](../Assets/sliding_top_to_bottom.gif)
+| .bottomTop | ![](../Assets/sliding_bottom_to_top.gif)
+| .topLeftBottomRight | ![](../Assets/sliding_topLeft_to_bottomRight.gif)
+| .bottomRightTopLeft | ![](../Assets/sliding_bottomRight_to_topLeft.gif)
> **😉 TRUQUE!**
Existe outra forma de criar sliding animations, apenas usando este atalho:
@@ -362,10 +357,10 @@ Porque uma imagem vale mais que mil palavras:
| Configuration | Result
|------- | -------
-|![](Assets/no_skeletonable.png) | ![](Assets/no_skeletonables_result.png)
-|![](Assets/container_no_skeletonable.png) | ![](Assets/no_skeletonables_result.png)
-|![](Assets/container_skeletonable.png) | ![](Assets/container_skeletonable_result.png)
-|![](Assets/all_skeletonables.png) | ![](Assets/all_skeletonables_result.png)
+|![](../Assets/no_skeletonable.png) | ![](../Assets/no_skeletonables_result.png)
+|![](../Assets/container_no_skeletonable.png) | ![](../Assets/no_skeletonables_result.png)
+|![](../Assets/container_skeletonable.png) | ![](../Assets/container_skeletonable_result.png)
+|![](../Assets/all_skeletonables.png) | ![](../Assets/all_skeletonables_result.png)
diff --git a/README_zh.md b/Translations/README_zh.md
similarity index 89%
rename from README_zh.md
rename to Translations/README_zh.md
index f152213a..6008c4b8 100755
--- a/README_zh.md
+++ b/Translations/README_zh.md
@@ -1,4 +1,4 @@
-![](Assets/header2.jpg)
+![](../Assets/header2.jpg)
@@ -23,12 +23,7 @@
-🌎 翻译: [ [原版的](https://github.com/Juanpe/SkeletonView) ]
-[Original](https://github.com/Juanpe/SkeletonView)
-[🇨🇳](https://github.com/Juanpe/SkeletonView/blob/master/README_zh.md) [@WhatsXie](https://twitter.com/WhatsXie)
-[🇧🇷](https://github.com/Juanpe/SkeletonView/blob/master/README_pt-br.md) [@brunomunizaf](https://twitter.com/brunomuniz_af)
-[🇰🇷](https://github.com/Juanpe/SkeletonView/blob/master/README_ko.md) [@techinpark](https://twitter.com/techinpark)
-[🇫🇷](https://github.com/Juanpe/SkeletonView/blob/master/README_fr.md) [@OmarJalil](https://github.com/OmarJalil)
+**🌎 翻译: [🇬🇧](../README.md) . [🇨🇳](README_zh.md) . [🇧🇷](README_pt-br.md) . [🇰🇷](README_ko.md) . [🇫🇷](README_fr.md)**
今天,几乎所有的应用程序都有异步流程,例如:Api请求、长时间运行的流程等。虽然流程正在运行,但通常开发人员会设置一个加载视图来向用户显示正在发生的事情。
@@ -116,7 +111,7 @@ avatarImageView.isSkeletonable = true
```
**使用 IB/Storyboards:**
-![](Assets/storyboard.png)
+![](../Assets/storyboard.png)
**3.** 设置视图后,可以显示 **skeleton**. 并且您有 **4** 种效果可供选择:
@@ -146,16 +141,16 @@ avatarImageView.isSkeletonable = true
-
+
|
-
+
|
-
+
|
-
+
|
@@ -226,7 +221,7 @@ public protocol SkeletonCollectionViewDataSource: UICollectionViewDataSource {
### 📰 多行文字
-![](Assets/multilines2.png)
+![](../Assets/multilines2.png)
使用带有文本的元素时, ```SkeletonView``` 绘制线条以模拟文本。此外,您可以决定您想要多少行。如果 ```numberOfLines``` 设置为零,它将计算填充整个骨架所需的行数,并将绘制它。相反,如果将其设置为一,二或任何大于零的数字,它将只绘制此行数。
@@ -237,8 +232,8 @@ public protocol SkeletonCollectionViewDataSource: UICollectionViewDataSource {
| 属性 | 值范围 | 默认 | 延时
| ------- | ------- |------- | -------
-| **Filling percent** 最后一行的长度百分比 | `0...100` | `70%` | ![](Assets/multiline_lastline.png)
-| **Corner radius** 条目圆角半径. (**新**) | `0...10` | `0` | ![](Assets/multiline_corner.png)
+| **Filling percent** 最后一行的长度百分比 | `0...100` | `70%` | ![](../Assets/multiline_lastline.png)
+| **Corner radius** 条目圆角半径. (**新**) | `0...10` | `0` | ![](../Assets/multiline_corner.png)
@@ -251,7 +246,7 @@ descriptionTextView.linesCornerRadius = 5
或者,如果您更喜欢使用 **IB/Storyboard**:
-![](Assets/multiline_customize.png)
+![](../Assets/multiline_customize.png)
### 🎨 自定义颜色
@@ -273,7 +268,7 @@ view.showGradientSkeleton(usingGradient: gradient) // 梯度效果
```UIColor.turquoise, UIColor.greenSea, UIColor.sunFlower, UIColor.flatOrange ...```
-![](Assets/flatcolors.png)
+![](../Assets/flatcolors.png)
###### 从网站 [https://flatuicolors.com](https://flatuicolors.com)捕获的图像
### 🤓 自定义动画
@@ -316,12 +311,12 @@ view.showAnimatedGradientSkeleton(usingGradient: gradient, animation: animation)
| 方向 | 效果
|------- | -------
-| .leftRight | ![](Assets/sliding_left_to_right.gif)
-| .rightLeft | ![](Assets/sliding_right_to_left.gif)
-| .topBottom | ![](Assets/sliding_top_to_bottom.gif)
-| .bottomTop | ![](Assets/sliding_bottom_to_top.gif)
-| .topLeftBottomRight | ![](Assets/sliding_topLeft_to_bottomRight.gif)
-| .bottomRightTopLeft | ![](Assets/sliding_bottomRight_to_topLeft.gif)
+| .leftRight | ![](../Assets/sliding_left_to_right.gif)
+| .rightLeft | ![](../Assets/sliding_right_to_left.gif)
+| .topBottom | ![](../Assets/sliding_top_to_bottom.gif)
+| .bottomTop | ![](../Assets/sliding_bottom_to_top.gif)
+| .topLeftBottomRight | ![](../Assets/sliding_topLeft_to_bottomRight.gif)
+| .bottomRightTopLeft | ![](../Assets/sliding_bottomRight_to_topLeft.gif)
> **😉 技巧!**
存在另一种创建滑动动画的方法,只需使用此快捷方式:
@@ -337,10 +332,10 @@ view.showAnimatedGradientSkeleton(usingGradient: gradient, animation: animation)
| 分组 | 结果
|------- | -------
-|![](Assets/no_skeletonable.png) | ![](Assets/no_skeletonables_result.png)
-|![](Assets/container_no_skeletonable.png) | ![](Assets/no_skeletonables_result.png)
-|![](Assets/container_skeletonable.png) | ![](Assets/container_skeletonable_result.png)
-|![](Assets/all_skeletonables.png) | ![](Assets/all_skeletonables_result.png)
+|![](../Assets/no_skeletonable.png) | ![](../Assets/no_skeletonables_result.png)
+|![](../Assets/container_no_skeletonable.png) | ![](../Assets/no_skeletonables_result.png)
+|![](../Assets/container_skeletonable.png) | ![](../Assets/container_skeletonable_result.png)
+|![](../Assets/all_skeletonables.png) | ![](../Assets/all_skeletonables_result.png)