Compare commits

...

84 Commits

Author SHA1 Message Date
Juanpe 30c92f0992 Bump version 1.31.0 2024-04-18 11:15:17 +00:00
Sean Najera 2f5274827d remove trailing comma in Package.swift (#557)
Fixes a syntax error, which is preventing SkeletonView from being added as a dependency in client projects
2024-04-18 13:14:51 +02:00
Juanpe Catalán 5699404ce2 Update SkeletonView.podspec 2024-01-15 10:41:52 +01:00
Juanpe Catalán 3d7ff3b255 Update release.yml 2024-01-15 10:35:50 +01:00
Juanpe Catalán 52cce6ea55 Update CD.yml 2024-01-15 10:30:38 +01:00
Dmitry Kuleshov 3269c97f42 Add PrivacyInfo manifest file (#552)
* Add PrivacyInfo manifest file

* Update package file
2024-01-15 10:21:29 +01:00
Juanpe 0f5eaf82e8 Bump version 1.30.4 2022-10-20 11:01:43 +00:00
André Pacheco Neves 739a4f5d78 Fix skeletons interfering with attributed strings in text-based views (#520)
When enabling skeleton mode in a text-based view (`UILabel`,
`UITextView`, `UITextField`), it sets the `textColor` to `.clear`,
which is fine when `text` is used, but causes problems when
`attributedText` is used, as it effectively "resets" the string to have
a single color.

Additionally, when a `UILabel` is nested inside a `UIStackView` a
dummy string `" "` was set on the label's `text` so that it didn't have
a 0 height content size. However, this workaround didn't consider the
case where the label already had a non-empty text, meaning that this
(intrusive) `text = " "` broke existing code by clearing the label's
contents.

By improving the corresponding `RecoverableXState` structs, we are able
to preserve each element's contents and state as skeleton is disabled.

Fixes #518.

## Changes

- Create new `RecoverableLabelState` containing a `attributedText` and
`text`, and use it on `UILabel`.

- Update `RecoverableTextViewState` and `RecoverableTextFieldState` to
have a `attributedText`.

- Check if `UILabel`'s `text` is empty before setting dummy value when
enabling skeleton mode in a label nested inside a `UIStackView`.
2022-10-20 12:59:00 +02:00
Sebastian Nicklas 0058d510a9 The translation was written in an overly polite tone, which sounded kind (#519)
of strange in the context of library documentation.

Co-authored-by: Sebastian Nicklas <sebastian@iconicfinance.io>
2022-10-20 12:55:18 +02:00
Lucas Zischka 6a51bc8cc0 Add German translation (#515)
* Setup german translation file

- Create copy of english readme
- Link to it as German translation

* Translate header

* Translate Features

* Translate Installation

* Whoops i translated in the wrong file, switch them out

* Translate Usage

* Translate Collections

* Translate Texts

* Translate Appearance

* Better translation for Solid

* Even better translation for Solid

* Translate Custom colors

* Add back german translation link to readme

got lost in commit d6726af

* Translate Animations

* Fix linking

* Fix code formating

* Another code formatting fix

* Fix Asset linking

* Translate Transitions

* Translate Miscellaneous

* Translate the rest
2022-10-04 10:16:34 +02:00
Juanpe b6b0fc894c Bump version 1.30.3 2022-09-29 09:09:01 +00:00
Michał Zaborowski cb4d48d603 Update lifecycle handlers (#514) 2022-09-28 17:34:42 +02:00
Juanpe 6604aae989 Bump version 1.30.2 2022-09-05 07:27:37 +00:00
Alexander ca7d2edcee Fix "complementaryColor" color isn't changed after updating the application theme (#496) 2022-09-05 09:26:20 +02:00
Juanpe Catalán 3688549eb8 Update Stale action 2022-08-29 08:48:23 +02:00
Juanpe Catalán f27a4f69ff Create needs-attention.yml 2022-08-29 08:40:38 +02:00
Juanpe 2ac515b97e Bump version 1.30.1 2022-08-16 08:36:34 +00:00
Tom Cheung 969f068480 Bugfix/tableview insetgrouped (#494)
* Fixed TableView skeleton cannot hide if style is insetGrouped

* Fixed show skeleton button not visible

* Update the fix base on PR comments
2022-08-16 10:35:13 +02:00
Juanpe Catalán fbc2e6f8d2 Update README.md 2022-08-11 21:00:45 +02:00
Juanpe Catalán 8be6c81729 Revert changes in the Package file 2022-08-11 20:16:10 +02:00
Juanpe Catalán 87c4706be8 Testing XCFramework 2022-08-11 20:13:19 +02:00
Juanpe b4d6dc2602 Bump version 1.30.0 2022-08-11 16:33:23 +00:00
Carlos Enumo f859d197f3 Add prepareViewForSkeleton to SkeletonCollectionViewDataSource (#505) 2022-08-11 18:32:08 +02:00
Juanpe 3a11e233c7 Bump version 1.29.4 2022-08-11 16:15:54 +00:00
dependabot[bot] ddd4fdbb1f Bump tzinfo from 1.2.5 to 1.2.10 (#507)
Bumps [tzinfo](https://github.com/tzinfo/tzinfo) from 1.2.5 to 1.2.10.
- [Release notes](https://github.com/tzinfo/tzinfo/releases)
- [Changelog](https://github.com/tzinfo/tzinfo/blob/master/CHANGES.md)
- [Commits](https://github.com/tzinfo/tzinfo/compare/v1.2.5...v1.2.10)

---
updated-dependencies:
- dependency-name: tzinfo
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-08-11 18:14:28 +02:00
Juanpe Catalán 00394e0b9f Add Swift Package Index badge for platforms 2022-06-01 08:35:50 +02:00
Juanpe daea88df8f Bump version 1.29.3 2022-06-01 06:32:58 +00:00
dependabot[bot] b640c1d8ee Bump cocoapods-downloader from 1.2.2 to 1.6.3 (#497)
Bumps [cocoapods-downloader](https://github.com/CocoaPods/cocoapods-downloader) from 1.2.2 to 1.6.3.
- [Release notes](https://github.com/CocoaPods/cocoapods-downloader/releases)
- [Changelog](https://github.com/CocoaPods/cocoapods-downloader/blob/master/CHANGELOG.md)
- [Commits](https://github.com/CocoaPods/cocoapods-downloader/compare/1.2.2...1.6.3)

---
updated-dependencies:
- dependency-name: cocoapods-downloader
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-06-01 08:31:25 +02:00
Juanpe 2eaf72ed0e Bump version 1.29.2 2022-01-18 14:21:59 +00:00
Juanpe Catalán 9e61ff3a85 Fix crash when text is empty (#483) 2022-01-18 15:20:32 +01:00
Juanpe Catalán 204b871f17 Update CD.yml 2022-01-18 14:56:28 +01:00
Juanpe Catalán ecb41f1885 Update stale.yml 2022-01-15 10:17:58 +01:00
Juanpe dffbd8cbfd Bump version 1.29.1 2022-01-10 15:33:01 +00:00
Juanpe Catalán 458e5fc29b Fix animation when the transition is .none (#481) 2022-01-10 16:32:00 +01:00
Juanpe a6f335df01 Bump version 1.29.0 2022-01-10 10:24:35 +00:00
Juanpe Catalán 106692fbfb Create new `SkeletonGradient constructor (#480) 2022-01-10 11:23:07 +01:00
Juanpe Catalán cb4dcfd07a Update CD.yml 2022-01-10 11:11:19 +01:00
Juanpe 419172104d Bump version 1.28.0 2022-01-10 10:09:04 +00:00
Juanpe Catalán b40a771510 Improved number of lines calculation (#479)
* Create SkeletonTextNumberOfLines

* Update README format
2022-01-10 11:07:31 +01:00
Juanpe Catalán 73b137cda6 Update CD.yml 2022-01-10 11:07:16 +01:00
Juanpe add7401058 Bump version 1.27.0 2022-01-08 12:40:21 +00:00
Tom Cheung 947e2a63c2 Add skeletonCornerRadius in SkeletonAppearance (#478)
* Add skeletonCornerRadius in SkeletonAppearance

* Remove unnecessary type casting
2022-01-08 13:39:03 +01:00
Juanpe Catalán c5462de1db Update CD.yml 2022-01-08 11:25:33 +01:00
Juanpe 00b5d614b6 Bump version 1.26.2 2022-01-08 10:22:27 +00:00
Nick Thompson 8ba48071de Fix last line text alignment when using padding insets (#477) 2022-01-08 11:20:59 +01:00
Jackson a0980380f2 Add ExampleViewController for programatically creating ViewController (#475)
* Add ExampleViewController for programatically creating view

* Update UITextViewByCodeViewController
2022-01-07 17:05:02 +01:00
Juanpe Catalán dd80fabeea Rename pod_trunk to pod_trunk.yml 2022-01-07 17:04:21 +01:00
Juanpe Catalán d89a70052c Create pod trunk workflow 2022-01-07 17:03:43 +01:00
Juanpe cd12c64e18 Bump version 1.26.1 2022-01-07 15:56:40 +00:00
Juanpe Catalán 2edd715a87 Fix skeleton flow notifications triggered multiple times (#476)
* Fix notification names

* Fix problem with multiple notifications
2022-01-07 16:55:19 +01:00
Juanpe f3cc8f0aba Bump version 1.26.0 2021-11-23 10:41:10 +00:00
Juanpe Catalán a9c22f502a Improve multiline height calculation (#466)
* update line height logic

* update property name

* update README

* update README

* Update README.md

* fix typo
2021-11-23 11:25:59 +01:00
Juanpe ee17db61c6 Bump version 1.25.2 2021-10-21 14:49:00 +00:00
Sharma Elanthiraiyan ff1a7e299b Vertically center align UILabel's skeleton. (#456)
- Introduce `shouldCenterTextVertically`  in `SkeletonTextNode` to center align UILabels and keep UITextViews unaltered.
- Shift down CALayers after assigning frames in `updateMultilinesLayers` function in `CALayer+Extensions.swift`
2021-10-21 16:47:42 +02:00
Juanpe Catalán 4994907234 Update README.md 2021-10-20 09:39:41 +02:00
Juanpe 17fb1b9950 Bump version 1.25.1 2021-09-14 05:58:22 +00:00
Juanpe Catalán 138dc8bf82 Update CD.yml 2021-09-14 07:55:33 +02:00
Juanpe Catalán 0b308f5ef5 Update release.yml 2021-09-14 07:52:13 +02:00
Sharma Elanthiraiyan af94b7e30b Global setter for useFontLineHeight (#454)
- Add useFontLineHeight to SkeletonViewAppearance.
- Update README file to include useFontLineHeight under SkeletonAppearance.
2021-09-14 07:14:50 +02:00
Juanpe 14c138ec3e Bump version 1.25.0 2021-09-09 07:46:08 +00:00
Sharma Elanthiraiyan 2691572392 Apply lastLineFillPercent for single line views as well. (#449)
* Apply lastLineFillPercent for single line views as well.
Fixes #430

* Update readme to include single_lastline.png

* Remove singleline_lastline.png asset added to demo last line in single line views.

* Simplify lastLineFillPercent related update in readme file.

* Fix grammar in readme.
2021-09-09 09:39:26 +02:00
Juanpe 1b9586e2d7 Bump version 1.24.4 2021-08-23 12:00:05 +00:00
Juanpe Catalán a819e69cee make skeletonPaddingInsets public again (#446) 2021-08-23 13:58:33 +02:00
Juanpe 88cd082d8e Bump version 1.24.3 2021-08-23 10:36:24 +00:00
Juanpe Catalán 1ab26cd869 Merge branch 'main' of https://github.com/Juanpe/SkeletonView 2021-08-23 12:29:16 +02:00
Juanpe Catalán 8e369c9df2 fix build fails 2021-08-23 12:29:01 +02:00
Juanpe 5fc720d3ab Bump version 1.24.2 2021-08-23 10:24:52 +00:00
Juanpe Catalán 34ce9365f6 Update main.yml 2021-08-23 12:22:06 +02:00
Juanpe Catalán 3708c0da7f Improve debug description and create SkeletonExtensions (#444)
* create sk extension and improve debug

* update README

* fix readme

* Update README.md

* include SkeletonTreeNode
2021-08-23 12:20:47 +02:00
Juanpe 9103c14cc5 Bump version 1.24.0 2021-08-19 15:48:14 +00:00
Juanpe Catalán 5ce17f7a40 Add new property useFontLineHeight to disable the auto-adjustment (#443) 2021-08-19 17:46:59 +02:00
Juanpe dfc2d60daa Bump version 1.23.1 2021-08-19 12:48:19 +00:00
Juanpe Catalán d8436f79f6 Codebase refactor (#442)
* files reorganization (#432)

* fix podspec

* only include swift files

* Fix broken readme paths (#433)

* update links

* fix french link

* split skeleton debug to public and internal methods (#434)

* Add build phase to execute SwiftLint (#435)

* update tvOS tests

* Refactor Extensions folder (#436)

* Reorganize SkeletonAppearance (#437)

* reorganize helpers and builders folders (#438)

* Refactor flow and multilines (#439)

* Reorganize collections folder (#440)

* reorganize collections folder

* update podspec

* Refactor SkeletonView facade (#441)

* reorganize collections folder

* update podspec

* refactor skeletonview facade

* fix conflict

* update iOS example

* fix github workflows

* update tvOS example project build settings
2021-08-19 14:45:33 +02:00
Juanpe 35db69e513 Bump version 1.23.0 2021-08-19 06:15:26 +00:00
ankitagarwal007 6b5002b9a7 Use fontLine for skeleton in labels (#427)
Co-authored-by: Ankit Agarwal <ankit.agarwal@naukri.com>
2021-08-19 08:04:01 +02:00
Juanpe 2d9f3192d3 Bump version 1.22.0 2021-08-17 17:08:39 +00:00
Sofia Silva ae44d9f07a Align last line of skeleton view according to text alignment (#431)
* feature: align last line of skeleton view according to text alignment

* code review changes
2021-08-17 19:03:13 +02:00
Juanpe Catalán 25c47d3029 update file header 2021-08-02 19:10:46 +02:00
Juanpe 11c90283ff Bump version 1.21.2 2021-07-23 13:54:10 +00:00
Juanpe Catalán 49fafccd3f set status off before the transition is finished (#423) 2021-07-23 15:52:52 +02:00
Juanpe 1f70ee4573 Bump version 1.21.1 2021-07-13 11:51:26 +00:00
dependabot[bot] d13369a0dd Bump addressable from 2.6.0 to 2.8.0 (#420)
Bumps [addressable](https://github.com/sporkmonger/addressable) from 2.6.0 to 2.8.0.
- [Release notes](https://github.com/sporkmonger/addressable/releases)
- [Changelog](https://github.com/sporkmonger/addressable/blob/main/CHANGELOG.md)
- [Commits](https://github.com/sporkmonger/addressable/compare/addressable-2.6.0...addressable-2.8.0)

---
updated-dependencies:
- dependency-name: addressable
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2021-07-13 13:50:06 +02:00
Juanpe Catalán 35d63041d2 Update README.md 2021-07-05 20:01:41 +02:00
Juanpe 4514b509cc Bump version 1.21.0 2021-07-02 14:10:57 +00:00
173 changed files with 6004 additions and 2788 deletions
-10
View File
@@ -1,10 +0,0 @@
daysUntilStale: 7
daysUntilClose: 7
onlyLabels:
- awaiting user input
staleLabel: given up
markComment: >
🤖 This issue has been automatically marked as stale because it has not had
recent activity. It will be closed if no further activity occurs. Thank you
for your contributions 🙂
closeComment: false
+5 -15
View File
@@ -1,19 +1,16 @@
name: CD
on:
pull_request:
pull_request_target:
branches: [main]
types: [closed]
jobs:
release_version:
if: github.event.pull_request.milestone == null && github.event.pull_request.merged == true
runs-on: ubuntu-latest
runs-on: macOS-latest
steps:
- uses: actions/checkout@v2
- name: Setup fastlane
run: brew install fastlane
- name: Publish release
id: publish_release
@@ -32,9 +29,10 @@ jobs:
branch: 'main'
commit_message: 'Bump version ${{ steps.publish_release.outputs.tag_name }}'
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Deploy to Cocoapods
continue-on-error: true
env:
COCOAPODS_TRUNK_TOKEN: ${{ secrets.COCOAPODS_TRUNK_TOKEN }}
run: |
@@ -42,14 +40,6 @@ jobs:
pod lib lint --allow-warnings
pod trunk push --allow-warnings
- name: Communicate on PR released
uses: unsplash/comment-on-pr@master
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
msg: |
Congratulations! 🎉 This was released as part of [SkeletonView ${{ steps.publish_release.outputs.tag_name }}](${{ steps.publish_release.outputs.html_url }}) 🚀
- name: Tweet the release
uses: ethomson/send-tweet-action@v1
with:
@@ -61,4 +51,4 @@ jobs:
🎉 New release ${{ steps.publish_release.outputs.tag_name }} is out 🚀
Check out all the changes here:
${{ steps.publish_release.outputs.html_url }}
${{ steps.publish_release.outputs.html_url }}
+7 -4
View File
@@ -3,6 +3,7 @@ name: CI
on:
pull_request:
branches: [main]
workflow_dispatch:
jobs:
build:
@@ -10,10 +11,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'] }}'
+18
View File
@@ -0,0 +1,18 @@
name: Issue Needs Attention
# This workflow is triggered on issue comments.
on:
issue_comment:
types: created
jobs:
applyNeedsAttentionLabel:
name: Apply Needs Attention Label
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Apply Needs Attention Label
uses: hramos/needs-attention@v1
with:
repo-token: ${{ secrets.GITHUB_TOKEN }}
response-required-label: 'awaiting user info'
needs-attention-label: 'needs triage'
+16
View File
@@ -0,0 +1,16 @@
name: Pod trunk
on: [workflow_dispatch]
jobs:
release_version:
runs-on: macOS-latest
steps:
- uses: actions/checkout@v2
- name: Deploy to Cocoapods
env:
COCOAPODS_TRUNK_TOKEN: ${{ secrets.COCOAPODS_TRUNK_TOKEN }}
run: |
set -eo pipefail
pod lib lint --allow-warnings
pod trunk push --allow-warnings
+13 -4
View File
@@ -7,9 +7,6 @@ jobs:
steps:
- uses: actions/checkout@v2
- name: Setup fastlane
run: brew install fastlane
- name: Publish release
id: publish_release
uses: release-drafter/release-drafter@v5
@@ -35,4 +32,16 @@ jobs:
run: |
set -eo pipefail
pod lib lint --allow-warnings
pod trunk push --allow-warnings
pod trunk push --allow-warnings
- name: Tweet the release
uses: ethomson/send-tweet-action@v1
with:
consumer-key: ${{ secrets.TWITTER_CONSUMER_API_KEY }}
consumer-secret: ${{ secrets.TWITTER_CONSUMER_API_SECRET }}
access-token: ${{ secrets.TWITTER_ACCESS_TOKEN }}
access-token-secret: ${{ secrets.TWITTER_ACCESS_TOKEN_SECRET }}
status: |
🎉 New release ${{ steps.publish_release.outputs.tag_name }} is out 🚀
Check out all the changes here:
${{ steps.publish_release.outputs.html_url }}
+18
View File
@@ -0,0 +1,18 @@
name: 'Close stale issues and PRs'
on:
schedule:
- cron: '30 5 * * *'
jobs:
stale:
runs-on: ubuntu-latest
steps:
- uses: actions/stale@v4
with:
close-issue-message: 'Closing this issue after a prolonged period of inactivity. If this issue is still present in the latest release, please feel free to create a new issue with up-to-date information.'
stale-issue-message: '🤖 This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions 🙂'
days-before-stale: 5
days-before-close: 3
enable-statistics: true
operations-per-run: 60
only-labels: 'awaiting user input'
+9 -4
View File
@@ -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
@@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<Workspace
version = "1.0">
<FileRef
location = "self:">
</FileRef>
</Workspace>
Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

-24
View File
@@ -1,24 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleDevelopmentRegion</key>
<string>en</string>
<key>CFBundleExecutable</key>
<string>$(EXECUTABLE_NAME)</string>
<key>CFBundleIdentifier</key>
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
<string>$(PRODUCT_NAME)</string>
<key>CFBundlePackageType</key>
<string>FMWK</string>
<key>CFBundleShortVersionString</key>
<string>1.3</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
<string>$(CURRENT_PROJECT_VERSION)</string>
</dict>
</plist>
@@ -1,6 +0,0 @@
{
"info" : {
"version" : 1,
"author" : "xcode"
}
}

Before

Width:  |  Height:  |  Size: 933 B

After

Width:  |  Height:  |  Size: 933 B

Before

Width:  |  Height:  |  Size: 8.0 KiB

After

Width:  |  Height:  |  Size: 8.0 KiB

@@ -0,0 +1,33 @@
{
"colors" : [
{
"color" : {
"platform" : "universal",
"reference" : "systemBlueColor"
},
"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
}
}
@@ -0,0 +1,6 @@
{
"info" : {
"author" : "xcode",
"version" : 1
}
}

Before

Width:  |  Height:  |  Size: 933 B

After

Width:  |  Height:  |  Size: 933 B

@@ -1,9 +1,9 @@
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="17701" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES" initialViewController="Va7-1y-Tel">
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="19455" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES" initialViewController="Va7-1y-Tel">
<device id="retina5_9" orientation="portrait" appearance="light"/>
<dependencies>
<deployment identifier="iOS"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="17703"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="19454"/>
<capability name="Safe area layout guides" minToolsVersion="9.0"/>
<capability name="System colors in document resources" minToolsVersion="11.0"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
@@ -12,7 +12,7 @@
<!--Item-->
<scene sceneID="tne-QT-ifu">
<objects>
<viewController id="BYZ-38-t0r" customClass="ViewController" customModule="SkeletonViewExample" customModuleProvider="target" sceneMemberID="viewController">
<viewController id="BYZ-38-t0r" customClass="ViewController" customModule="iOS_Example" customModuleProvider="target" sceneMemberID="viewController">
<view key="view" contentMode="scaleToFill" id="8bC-Xf-vdC">
<rect key="frame" x="0.0" y="0.0" width="375" height="812"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
@@ -50,7 +50,7 @@
<userDefinedRuntimeAttribute type="boolean" keyPath="isSkeletonable" value="YES"/>
</userDefinedRuntimeAttributes>
</imageView>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Label" textAlignment="natural" lineBreakMode="tailTruncation" numberOfLines="3" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="CJW-A4-Fb8">
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Label" textAlignment="center" lineBreakMode="tailTruncation" numberOfLines="3" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="CJW-A4-Fb8">
<rect key="frame" x="166" y="27" width="166" height="12"/>
<color key="backgroundColor" red="0.92156862750000001" green="0.16862745100000001" blue="0.54901960780000003" alpha="1" colorSpace="calibratedRGB"/>
<fontDescription key="fontDescription" type="system" pointSize="10"/>
@@ -88,8 +88,8 @@
<rect key="frame" x="0.0" y="287" width="375" height="282"/>
<color key="separatorColor" red="0.1061807256" green="0.84678786989999999" blue="0.031482450150000001" alpha="1" colorSpace="custom" customColorSpace="displayP3"/>
<prototypes>
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" preservesSuperviewLayoutMargins="YES" selectionStyle="default" indentationWidth="10" reuseIdentifier="CellIdentifier" rowHeight="120" id="2dN-Bd-tdy" customClass="Cell" customModule="SkeletonViewExample" customModuleProvider="target">
<rect key="frame" x="0.0" y="28" width="375" height="120"/>
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" preservesSuperviewLayoutMargins="YES" selectionStyle="default" indentationWidth="10" reuseIdentifier="CellIdentifier" rowHeight="120" id="2dN-Bd-tdy" customClass="Cell" customModule="iOS_Example" customModuleProvider="target">
<rect key="frame" x="0.0" y="44.666666030883789" width="375" height="120"/>
<autoresizingMask key="autoresizingMask"/>
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" preservesSuperviewLayoutMargins="YES" insetsLayoutMarginsFromSafeArea="NO" tableViewCell="2dN-Bd-tdy" id="7IN-F3-Mr6">
<rect key="frame" x="0.0" y="0.0" width="375" height="120"/>
@@ -299,7 +299,7 @@
<!--Item-->
<scene sceneID="Cfc-AT-AS1">
<objects>
<viewController id="dv8-ph-Ehg" sceneMemberID="viewController">
<viewController id="dv8-ph-Ehg" customClass="UITextViewByCodeViewController" customModule="iOS_Example" customModuleProvider="target" sceneMemberID="viewController">
<view key="view" contentMode="scaleToFill" id="Jwx-gI-Qod">
<rect key="frame" x="0.0" y="0.0" width="375" height="812"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
@@ -5,12 +5,12 @@ import UIKit
class HeaderFooterSection: UITableViewHeaderFooterView {
lazy var titleLabel: UILabel = {
let label = UILabel()
let label = UILabel()
label.text = " "
label.isSkeletonable = true
label.linesCornerRadius = 5
label.linesCornerRadius = 10
return label
}()
@@ -13,13 +13,15 @@
<key>CFBundleName</key>
<string>$(PRODUCT_NAME)</string>
<key>CFBundlePackageType</key>
<string>APPL</string>
<string>$(PRODUCT_BUNDLE_PACKAGE_TYPE)</string>
<key>CFBundleShortVersionString</key>
<string>1.3</string>
<string>1.0</string>
<key>CFBundleVersion</key>
<string>1</string>
<key>LSRequiresIPhoneOS</key>
<true/>
<key>UIApplicationSupportsIndirectInputEvents</key>
<true/>
<key>UILaunchStoryboardName</key>
<string>LaunchScreen</string>
<key>UIMainStoryboardFile</key>
@@ -0,0 +1,44 @@
// Copyright © 2022 SkeletonView. All rights reserved.
import UIKit
import SkeletonView
class UITextViewByCodeViewController: UIViewController {
lazy var textView: UITextView = {
let tv = UITextView()
tv.text = " "
tv.linesCornerRadius = 10
tv.isSkeletonable = true
tv.translatesAutoresizingMaskIntoConstraints = false
return tv
}()
override func viewDidLoad() {
super.viewDidLoad()
setupUI()
setupElementsConstraints()
showSkeletonForElements()
}
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
}
func setupUI() {
view.addSubview(textView)
}
func setupElementsConstraints() {
textView.topAnchor.constraint(equalTo: self.view.safeAreaLayoutGuide.topAnchor, constant: 10).isActive = true
textView.leftAnchor.constraint(equalTo: self.view.safeAreaLayoutGuide.leftAnchor, constant: 10).isActive = true
textView.rightAnchor.constraint(equalTo: self.view.safeAreaLayoutGuide.rightAnchor, constant: -10).isActive = true
textView.heightAnchor.constraint(equalToConstant: 100).isActive = true
}
func showSkeletonForElements() {
textView.showSkeleton()
}
}
@@ -76,8 +76,8 @@ class ViewController: UIViewController {
}
@IBAction func showOrHideSkeleton(_ sender: Any) {
showOrHideSkeletonButton.setTitle((view.isSkeletonActive ? "Show skeleton" : "Hide skeleton"), for: .normal)
view.isSkeletonActive ? hideSkeleton() : showSkeleton()
showOrHideSkeletonButton.setTitle((view.sk.isSkeletonActive ? "Show skeleton" : "Hide skeleton"), for: .normal)
view.sk.isSkeletonActive ? hideSkeleton() : showSkeleton()
}
@IBAction func transitionDurationStepperAction(_ sender: Any) {
@@ -0,0 +1,457 @@
// !$*UTF8*$!
{
archiveVersion = 1;
classes = {
};
objectVersion = 50;
objects = {
/* Begin PBXBuildFile section */
E21D8BB727888D050041DBCE /* UITextViewByCodeViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = E21D8BB627888D050041DBCE /* UITextViewByCodeViewController.swift */; };
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 */
E21D8BB627888D050041DBCE /* UITextViewByCodeViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UITextViewByCodeViewController.swift; sourceTree = "<group>"; };
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 = "<group>"; };
F556F5B826CD20A300A80B83 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = "<group>"; };
F556F5BA26CD20A300A80B83 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = "<group>"; };
F556F5BC26CD20A300A80B83 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = "<group>"; };
F556F5BD26CD20A300A80B83 /* AppDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = "<group>"; };
F556F5BE26CD20A300A80B83 /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
F556F5D926CD21CB00A80B83 /* SkeletonView.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = SkeletonView.xcodeproj; path = ../../SkeletonView.xcodeproj; sourceTree = "<group>"; };
F556F6E626CE813F00A80B83 /* Cell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Cell.swift; sourceTree = "<group>"; };
F556F6EC26CE813F00A80B83 /* Constants.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Constants.swift; sourceTree = "<group>"; };
F556F6ED26CE813F00A80B83 /* HeaderFooterSection.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = HeaderFooterSection.swift; sourceTree = "<group>"; };
/* 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 = "<group>";
};
F556F5A026CD201B00A80B83 /* Products */ = {
isa = PBXGroup;
children = (
F556F59F26CD201B00A80B83 /* iOS Example.app */,
);
name = Products;
sourceTree = "<group>";
};
F556F5B626CD20A300A80B83 /* Sources */ = {
isa = PBXGroup;
children = (
F556F6E626CE813F00A80B83 /* Cell.swift */,
F556F6EC26CE813F00A80B83 /* Constants.swift */,
F556F6ED26CE813F00A80B83 /* HeaderFooterSection.swift */,
F556F5B726CD20A300A80B83 /* ViewController.swift */,
E21D8BB627888D050041DBCE /* UITextViewByCodeViewController.swift */,
F556F5B826CD20A300A80B83 /* Assets.xcassets */,
F556F5B926CD20A300A80B83 /* LaunchScreen.storyboard */,
F556F5BB26CD20A300A80B83 /* Main.storyboard */,
F556F5BD26CD20A300A80B83 /* AppDelegate.swift */,
F556F5BE26CD20A300A80B83 /* Info.plist */,
);
path = Sources;
sourceTree = "<group>";
};
F556F5DA26CD21CB00A80B83 /* Products */ = {
isa = PBXGroup;
children = (
F556F5E026CD21CB00A80B83 /* SkeletonView.framework */,
F556F5E226CD21CB00A80B83 /* SkeletonViewTests.xctest */,
F556F5E426CD21CB00A80B83 /* SkeletonView.framework */,
F556F6EB26CE813F00A80B83 /* SkeletonView tvOS Tests.xctest */,
);
name = Products;
sourceTree = "<group>";
};
/* 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 = 1300;
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 */,
E21D8BB727888D050041DBCE /* UITextViewByCodeViewController.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 = "<group>";
};
F556F5BB26CD20A300A80B83 /* Main.storyboard */ = {
isa = PBXVariantGroup;
children = (
F556F5BC26CD20A300A80B83 /* Base */,
);
name = Main.storyboard;
sourceTree = "<group>";
};
/* 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 = 12.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 = 12.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 */;
}
@@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<Workspace
version = "1.0">
<FileRef
location = "self:">
</FileRef>
</Workspace>
@@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>IDEDidComputeMac32BitWarning</key>
<true/>
</dict>
</plist>
@@ -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.
}
}
@@ -0,0 +1,11 @@
{
"colors" : [
{
"idiom" : "universal"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
@@ -0,0 +1,11 @@
{
"images" : [
{
"idiom" : "tv"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
@@ -0,0 +1,17 @@
{
"info" : {
"author" : "xcode",
"version" : 1
},
"layers" : [
{
"filename" : "Front.imagestacklayer"
},
{
"filename" : "Middle.imagestacklayer"
},
{
"filename" : "Back.imagestacklayer"
}
]
}
@@ -0,0 +1,11 @@
{
"images" : [
{
"idiom" : "tv"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
@@ -0,0 +1,11 @@
{
"images" : [
{
"idiom" : "tv"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
@@ -0,0 +1,16 @@
{
"images" : [
{
"idiom" : "tv",
"scale" : "1x"
},
{
"idiom" : "tv",
"scale" : "2x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
@@ -0,0 +1,6 @@
{
"info" : {
"author" : "xcode",
"version" : 1
}
}
@@ -0,0 +1,17 @@
{
"info" : {
"author" : "xcode",
"version" : 1
},
"layers" : [
{
"filename" : "Front.imagestacklayer"
},
{
"filename" : "Middle.imagestacklayer"
},
{
"filename" : "Back.imagestacklayer"
}
]
}
@@ -0,0 +1,16 @@
{
"images" : [
{
"idiom" : "tv",
"scale" : "1x"
},
{
"idiom" : "tv",
"scale" : "2x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
@@ -0,0 +1,6 @@
{
"info" : {
"author" : "xcode",
"version" : 1
}
}
@@ -0,0 +1,16 @@
{
"images" : [
{
"idiom" : "tv",
"scale" : "1x"
},
{
"idiom" : "tv",
"scale" : "2x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
@@ -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
}
}
@@ -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
}
}
@@ -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
}
}
@@ -0,0 +1,6 @@
{
"info" : {
"author" : "xcode",
"version" : 1
}
}
@@ -0,0 +1,24 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<document type="com.apple.InterfaceBuilder.AppleTV.Storyboard" version="3.0" toolsVersion="13122.16" targetRuntime="AppleTV" propertyAccessControl="none" useAutolayout="YES" launchScreen="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES" initialViewController="BYZ-38-t0r">
<dependencies>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="13104.12"/>
<capability name="Safe area layout guides" minToolsVersion="9.0"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>
<scenes>
<!--View Controller-->
<scene sceneID="tne-QT-ifu">
<objects>
<viewController id="BYZ-38-t0r" sceneMemberID="viewController">
<view key="view" contentMode="scaleToFill" id="8bC-Xf-vdC">
<rect key="frame" x="0.0" y="0.0" width="1920" height="1080"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<color key="backgroundColor" red="0.0" green="0.0" blue="0.0" alpha="0.0" colorSpace="custom" customColorSpace="sRGB"/>
<viewLayoutGuide key="safeArea" id="wu6-TO-1qx"/>
</view>
</viewController>
<placeholder placeholderIdentifier="IBFirstResponder" id="dkx-z0-nzr" sceneMemberID="firstResponder"/>
</objects>
</scene>
</scenes>
</document>
@@ -0,0 +1,28 @@
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder.AppleTV.Storyboard" version="3.0" toolsVersion="13122.16" targetRuntime="AppleTV" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES" initialViewController="BYZ-38-t0r">
<dependencies>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="13104.12"/>
<capability name="Safe area layout guides" minToolsVersion="9.0"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>
<scenes>
<!--View Controller-->
<scene sceneID="tne-QT-ifu">
<objects>
<viewController id="BYZ-38-t0r" customClass="ViewController" customModuleProvider="target" sceneMemberID="viewController">
<layoutGuides>
<viewControllerLayoutGuide type="top" id="y3c-jy-aDJ"/>
<viewControllerLayoutGuide type="bottom" id="wfy-db-euE"/>
</layoutGuides>
<view key="view" contentMode="scaleToFill" id="8bC-Xf-vdC">
<rect key="frame" x="0.0" y="0.0" width="1920" height="1080"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<color key="backgroundColor" red="0.0" green="0.0" blue="0.0" alpha="0.0" colorSpace="custom" customColorSpace="sRGB"/>
<viewLayoutGuide key="safeArea" id="wu6-TO-1qx"/>
</view>
</viewController>
<placeholder placeholderIdentifier="IBFirstResponder" id="dkx-z0-nzr" sceneMemberID="firstResponder"/>
</objects>
</scene>
</scenes>
</document>
@@ -13,12 +13,22 @@
<key>CFBundleName</key>
<string>$(PRODUCT_NAME)</string>
<key>CFBundlePackageType</key>
<string>FMWK</string>
<string>$(PRODUCT_BUNDLE_PACKAGE_TYPE)</string>
<key>CFBundleShortVersionString</key>
<string>1.0</string>
<key>CFBundleVersion</key>
<string>$(CURRENT_PROJECT_VERSION)</string>
<key>NSPrincipalClass</key>
<string></string>
<string>1</string>
<key>LSRequiresIPhoneOS</key>
<true/>
<key>UILaunchStoryboardName</key>
<string>LaunchScreen</string>
<key>UIMainStoryboardFile</key>
<string>Main</string>
<key>UIRequiredDeviceCapabilities</key>
<array>
<string>arm64</string>
</array>
<key>UIUserInterfaceStyle</key>
<string>Automatic</string>
</dict>
</plist>
@@ -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.
}
}
@@ -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 = "<group>"; };
F556F60B26CD224900A80B83 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = "<group>"; };
F556F60D26CD224900A80B83 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = "<group>"; };
F556F60F26CD224900A80B83 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = "<group>"; };
F556F61026CD224900A80B83 /* AppDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = "<group>"; };
F556F61126CD224900A80B83 /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
F556F61826CD224F00A80B83 /* SkeletonView.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = SkeletonView.xcodeproj; path = ../../SkeletonView.xcodeproj; sourceTree = "<group>"; };
/* 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 = "<group>";
};
F556F5F526CD221300A80B83 /* Products */ = {
isa = PBXGroup;
children = (
F556F5F426CD221300A80B83 /* tvOS Example.app */,
);
name = Products;
sourceTree = "<group>";
};
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 = "<group>";
};
F556F61926CD224F00A80B83 /* Products */ = {
isa = PBXGroup;
children = (
F556F61F26CD224F00A80B83 /* SkeletonView.framework */,
F556F62126CD224F00A80B83 /* SkeletonViewTests.xctest */,
F556F62326CD224F00A80B83 /* SkeletonView.framework */,
F556F6FF26CE88DC00A80B83 /* SkeletonView tvOS Tests.xctest */,
);
name = Products;
sourceTree = "<group>";
};
/* 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 = 1300;
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 = "<group>";
};
F556F60E26CD224900A80B83 /* Main.storyboard */ = {
isa = PBXVariantGroup;
children = (
F556F60F26CD224900A80B83 /* Base */,
);
name = Main.storyboard;
sourceTree = "<group>";
};
/* 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 = 12.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 = 12.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 = 12.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 = 12.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 */;
}
@@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<Workspace
version = "1.0">
<FileRef
location = "self:">
</FileRef>
</Workspace>
@@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>IDEDidComputeMac32BitWarning</key>
<true/>
</dict>
</plist>
+4 -4
View File
@@ -7,8 +7,8 @@ GEM
minitest (~> 5.1)
thread_safe (~> 0.3, >= 0.3.4)
tzinfo (~> 1.1)
addressable (2.6.0)
public_suffix (>= 2.0.2, < 4.0)
addressable (2.8.0)
public_suffix (>= 2.0.2, < 5.0)
atomos (0.1.3)
babosa (1.0.2)
claide (1.0.2)
@@ -36,7 +36,7 @@ GEM
fuzzy_match (~> 2.0.4)
nap (~> 1.0)
cocoapods-deintegrate (1.0.4)
cocoapods-downloader (1.2.2)
cocoapods-downloader (1.6.3)
cocoapods-plugins (1.0.0)
nap
cocoapods-search (1.0.0)
@@ -182,7 +182,7 @@ GEM
tty-screen (0.7.0)
tty-spinner (0.9.1)
tty-cursor (~> 0.7)
tzinfo (1.2.5)
tzinfo (1.2.10)
thread_safe (~> 0.1)
uber (0.1.0)
unf (0.1.4)
+21 -14
View File
@@ -1,23 +1,30 @@
// swift-tools-version:5.0
// swift-tools-version:5.3
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",
resources: [.copy("Supporting Files/PrivacyInfo.xcprivacy")]
),
.testTarget(
name: "SkeletonViewTests",
dependencies: ["SkeletonView"],
path: "SkeletonViewCore/Tests"
)
],
swiftLanguageVersions: [.v5]
)
+85 -43
View File
@@ -8,7 +8,7 @@
<a href="https://cocoapods.org/pods/SkeletonView"><img src="https://img.shields.io/cocoapods/v/SkeletonView.svg?style=flat"></a>
<a href="https://github.com/Carthage/Carthage/"><img src="https://img.shields.io/badge/Carthage-compatible-4BC51D.svg?style=flat"></a>
<a href="https://swift.org/package-manager/"><img src="https://img.shields.io/badge/SPM-supported-Green.svg?style=flat"></a>
<img src="https://img.shields.io/badge/platforms-iOS_tvOS-green" />
<img src="https://img.shields.io/endpoint?url=https%3A%2F%2Fswiftpackageindex.com%2Fapi%2Fpackages%2FJuanpe%2FSkeletonView%2Fbadge%3Ftype%3Dplatforms"/>
<a href="https://badge.bow-swift.io/recipe?name=SkeletonView&description=An%20elegant%20way%20to%20show%20users%20that%20something%20is%20happening%20and%20also%20prepare%20them%20to%20which%20contents%20he%20is%20waiting&url=https://github.com/juanpe/skeletonview&owner=Juanpe&avatar=https://avatars0.githubusercontent.com/u/1409041?v=4&tag=1.20.0"><img src="https://raw.githubusercontent.com/bow-swift/bow-art/master/badges/nef-playgrounds-badge.svg" alt="SkeletonView Playground" style="height:20px"></a>
</p>
@@ -21,7 +21,7 @@
• <a href="#-contributing">Contributing</a>
</p>
**🌎 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) . [🇩🇪](Translations/README_de.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.
@@ -39,7 +39,6 @@ Enjoy it! 🙂
- [🔠 Texts](#-texts)
- [🦋 Appearance](#-appearance)
- [🎨 Custom colors](#-custom-colors)
- [Image captured from website https://flatuicolors.com](#image-captured-from-website-httpsflatuicolorscom)
- [🏃‍♀️ Animations](#-animations)
- [🏄 Transitions](#-transitions)
- [✨ Miscellaneous](#-miscellaneous)
@@ -64,9 +63,9 @@ Enjoy it! 🙂
## 🎬 Guides
| [![](https://img.youtube.com/vi/75kgOhWsPNA/maxresdefault.jpg)](https://youtu.be/75kgOhWsPNA)|[![](https://img.youtube.com/vi/MVCiM_VdxVA/maxresdefault.jpg)](https://youtu.be/MVCiM_VdxVA)|[![](https://img.youtube.com/vi/Qq3Evspeea8/maxresdefault.jpg)](https://youtu.be/Qq3Evspeea8)|[![](https://img.youtube.com/vi/ZOoPtBwDRT0/maxresdefault.jpg)](https://youtu.be/ZOoPtBwDRT0)|[![](https://img.youtube.com/vi/Zx1Pg1gPfxA/maxresdefault.jpg)](https://www.youtube.com/watch?v=Zx1Pg1gPfxA)
|:---: | :---: |:---: | :---: | :---:
|[**SkeletonView Guides - Getting started**](https://youtu.be/75kgOhWsPNA)|[**How to Create Loading View with Skeleton View in Swift 5.2**](https://youtu.be/MVCiM_VdxVA) by iKh4ever Studio|[**Create Skeleton Loading View in App (Swift 5) - Xcode 11, 2020**](https://youtu.be/Qq3Evspeea8) by iOS Academy| [**Add An Elegant Loading Animation in Swift***](https://youtu.be/ZOoPtBwDRT0) by Gary Tokman| [**Cómo crear una ANIMACIÓN de CARGA de DATOS en iOS**](https://www.youtube.com/watch?v=Zx1Pg1gPfxA) by MoureDev
| [![](https://img.youtube.com/vi/75kgOhWsPNA/maxresdefault.jpg)](https://youtu.be/75kgOhWsPNA)|[![](https://img.youtube.com/vi/MVCiM_VdxVA/maxresdefault.jpg)](https://youtu.be/MVCiM_VdxVA)|[![](https://img.youtube.com/vi/Qq3Evspeea8/maxresdefault.jpg)](https://youtu.be/Qq3Evspeea8)|[![](https://img.youtube.com/vi/Zx1Pg1gPfxA/maxresdefault.jpg)](https://www.youtube.com/watch?v=Zx1Pg1gPfxA)
|:---: | :---: | :---: | :---:
|[**SkeletonView Guides - Getting started**](https://youtu.be/75kgOhWsPNA)|[**How to Create Loading View with Skeleton View in Swift 5.2**](https://youtu.be/MVCiM_VdxVA) by iKh4ever Studio|[**Create Skeleton Loading View in App (Swift 5) - Xcode 11, 2020**](https://youtu.be/Qq3Evspeea8) by iOS Academy| [**Cómo crear una ANIMACIÓN de CARGA de DATOS en iOS**](https://www.youtube.com/watch?v=Zx1Pg1gPfxA) by MoureDev
## 📲 Installation
@@ -91,6 +90,10 @@ dependencies: [
]
```
> 📣 **IMPORTANT!**
>
> Since version 1.30.0, `SkeletonView` supports **XCFrameworks**, so if you want to install it as a **XCFramework**, please use [this repo](https://github.com/Juanpe/SkeletonView-XCFramework.git) instead.
## 🐒 Usage
@@ -251,6 +254,7 @@ public protocol SkeletonCollectionViewDataSource: UICollectionViewDataSource {
func collectionSkeletonView(_ skeletonView: UICollectionView, supplementaryViewIdentifierOfKind: String, at indexPath: IndexPath) -> ReusableCellIdentifier? // default: nil
func collectionSkeletonView(_ skeletonView: UICollectionView, skeletonCellForItemAt indexPath: IndexPath) -> UICollectionViewCell? // default: nil
func collectionSkeletonView(_ skeletonView: UICollectionView, prepareCellForSkeleton cell: UICollectionViewCell, at indexPath: IndexPath)
func collectionSkeletonView(_ skeletonView: UICollectionView, prepareViewForSkeleton view: UICollectionReusableView, at indexPath: IndexPath)
}
```
@@ -262,17 +266,19 @@ The rest of the process is the same as ```UITableView```
![](Assets/multilines2.png)
When using elements with text, ```SkeletonView``` draws lines to simulate text.
Besides, you can decide how many lines you want. If ```numberOfLines``` is set to zero, it will calculate how many lines needed to populate the whole skeleton and it will be drawn. Instead, if you set it to one, two or any number greater than zero, it will only draw this number of lines.
You can set some properties for multilines elements.
| Property | Values | Default | Preview
| Property | Type | 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)
| **lastLineFillPercent** | `CGFloat` | `70`| ![](Assets/multiline_lastline.png)
| **linesCornerRadius** | `Int` | `0` | ![](Assets/multiline_corner.png)
| **skeletonLineSpacing** | `CGFloat` | `10` | ![](Assets/multiline_lineSpacing.png)
| **skeletonPaddingInsets** | `UIEdgeInsets` | `.zero` | ![](Assets/multiline_insets.png)
| **skeletonTextLineHeight** | `SkeletonTextLineHeight` | `.fixed(15)` | ![](Assets/multiline_lineHeight.png)
| **skeletonTextNumberOfLines** | `SkeletonTextNumberOfLines` | `.inherited` | ![](Assets/multiline_corner.png)
<br />
To modify the percent or radius **using code**, set the properties:
```swift
@@ -284,25 +290,55 @@ Or, if you prefer use **IB/Storyboard**:
![](Assets/multiline_customize.png)
<br />
**How to define the number of lines?**
By default, the number of lines is the same as the value of the `numberOfLines` property. And, if it's set to **zero**, it'll calculate how many lines are needed to populate the whole skeleton and draw it.
However, if you want to set a specific number of skeleton lines you can do it by setting the `skeletonTextNumberOfLines` property. This property has two possible values, `inherited` which returns `numberOfLines` value and `custom(Int)` which returns the specific number of lines specified as the associated value.
For example:
```swift
label.skeletonTextNumberOfLines = 3 // .custom(3)
```
<br />
> **⚠️ DEPRECATED!**
>
> **useFontLineHeight** has been deprecated. You can use **skeletonTextLineHeight** instead:
> ```swift
> descriptionTextView.skeletonTextLineHeight = .relativeToFont
> ```
> **📣 IMPORTANT!**
>
> Please note that for views without multiple lines, the single line will be considered
> as the last line.
### 🦋 Appearance
The skeletons have a default appearance. So, when you don't specify the color, gradient or multilines properties, `SkeletonView` uses the default values.
Default values:
- **tintColor**: UIColor
- **tintColor**: `UIColor`
- *default: `.skeletonDefault` (same as `.clouds` but adaptive to dark mode)*
- **gradient**: SkeletonGradient
- *default: `SkeletonGradient(baseColor: .skeletonDefault)`*
- **multilineHeight**: CGFloat
- **multilineHeight**: `CGFloat`
- *default: 15*
- **multilineSpacing**: CGFloat
- **multilineSpacing**: `CGFloat`
- *default: 10*
- **multilineLastLineFillPercent**: Int
- **multilineLastLineFillPercent**: `Int`
- *default: 70*
- **multilineCornerRadius**: Int
- **multilineCornerRadius**: `Int`
- *default: 0*
- **skeletonCornerRadius**: CGFloat (IBInspectable) (Make your skeleton view with corner)
- **skeletonCornerRadius**: `CGFloat` (IBInspectable) (Make your skeleton view with corner)
- *default: 0*
To get these default values you can use `SkeletonAppearance.default`. Using this property you can set the values as well:
@@ -311,11 +347,12 @@ SkeletonAppearance.default.multilineHeight = 20
SkeletonAppearance.default.tintColor = .green
```
You can also specifiy these line appearance properties on a per-label basis:
- **lastLineFillPercent**: Int
- **linesCornerRadius**: Int
- **skeletonLineSpacing**: CGFloat
- **skeletonPaddingInsets**: UIEdgeInsets
> **⚠️ DEPRECATED!**
>
> **useFontLineHeight** has been deprecated. You can use **textLineHeight** instead:
> ```swift
> SkeletonAppearance.default.textLineHeight = .relativeToFont
> ```
### 🎨 Custom colors
@@ -462,16 +499,6 @@ view.showSkeleton()
**Hierarchy in collections**
Here is an illustration that shows how you should specify which elements are skeletonables when you are using an `UITableView`:
<img src="Assets/tableview_scheme.png" width="700px">
As you can see, we have to make skeletonable the tableview, the cell and the UI elements, but we don't need to set as skeletonable the `contentView`
**Skeleton views layout**
Sometimes skeleton layout may not fit your layout because the parent view bounds have changed. ~For example, rotating the device.~
@@ -519,6 +546,14 @@ By default, the user interaction is disabled for skeletonized items, but if you
view.isUserInteractionDisabledWhenSkeletonIsActive = false // The view will be active when the skeleton will be active.
```
**Don't use the font line height for the skeleton lines in labels**
False to disable skeleton to auto-adjust to font height for a `UILabel` or `UITextView`. By default, the skeleton lines height is auto-adjusted to font height to more accurately reflect the text in the label rect rather than using the bounding box.
```swift
label.useFontLineHeight = false
```
**Delayed show skeleton**
You can delay the presentation of the skeleton if the views update quickly.
@@ -541,14 +576,11 @@ func showGradientSkeleton(usingGradient: SkeletonGradient,
To facilitate the debug tasks when something is not working fine. **`SkeletonView`** has some new tools.
First, `UIView` has available a new property with his skeleton info:
First, `UIView` has available a property with his skeleton info:
```swift
var skeletonDescription: String
var sk.skeletonTreeDescription: String
```
The skeleton representation looks like this:
![](Assets/debug_description.png)
Besides, you can activate the new **debug mode**. You just add the environment variable `SKELETON_DEBUG` and activate it.
@@ -556,11 +588,21 @@ Besides, you can activate the new **debug mode**. You just add the environment v
Then, when the skeleton appears, you can see the view hierarchy in the Xcode console.
<details>
<summary>Open to see an output example </summary>
<img src="Assets/hierarchy_output.png" />
</details>
```
{
"type" : "UIView", // UITableView, UILabel...
"isSkeletonable" : true,
"reference" : "0x000000014751ce30",
"children" : [
{
"type" : "UIView",
"isSkeletonable" : true,
"children" : [ ... ],
"reference" : "0x000000014751cfa0"
}
]
}
```
**Supported OS & SDK Versions**
+13
View File
@@ -0,0 +1,13 @@
<?xml version="1.0" encoding="UTF-8"?>
<Workspace
version = "1.0">
<FileRef
location = "group:SkeletonView.xcodeproj">
</FileRef>
<FileRef
location = "group:Examples/iOS Example/iOS Example.xcodeproj">
</FileRef>
<FileRef
location = "group:Examples/tvOS Example/tvOS Example.xcodeproj">
</FileRef>
</Workspace>
@@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>IDEDidComputeMac32BitWarning</key>
<true/>
</dict>
</plist>
+3 -3
View File
@@ -1,6 +1,6 @@
Pod::Spec.new do |s|
s.name = "SkeletonView"
s.version = "1.20.0"
s.version = "1.31.0"
s.summary = "An elegant way to show users that something is happening and also prepare them to which contents he is waiting"
s.description = <<-DESC
Today almost all apps have async processes, as API requests, long runing processes, etc. And while the processes are working, usually developers place a loading view to show users that something is going on.
@@ -9,10 +9,10 @@ Pod::Spec.new do |s|
s.homepage = "https://github.com/Juanpe/SkeletonView"
s.license = { :type => "MIT", :file => "LICENSE" }
s.author = { "Juanpe Catalán" => "juanpecm@gmail.com" }
s.social_media_url = "https://twitter.com/JuanpeCatalan"
s.social_media_url = "https://x.com/JuanpeCatalan"
s.ios.deployment_target = "9.0"
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
File diff suppressed because it is too large Load Diff
@@ -4,4 +4,4 @@
<FileRef
location = "self:">
</FileRef>
</Workspace>
</Workspace>
@@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>IDEWorkspaceSharedSettings_AutocreateContextsIfNeeded</key>
<false/>
</dict>
</plist>
@@ -3,6 +3,17 @@
<plist version="1.0">
<dict>
<key>FILEHEADER</key>
<string> ___COPYRIGHT___</string>
<string>
// Copyright SkeletonView. All Rights Reserved.
//
// Licensed under the MIT License (the &quot;License&quot;);
// 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
//
// ___FILENAME___
//
// Created by ___FULLUSERNAME___ on ___DATE___.</string>
</dict>
</plist>
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "1020"
LastUpgradeVersion = "1300"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"
@@ -14,9 +14,9 @@
buildForAnalyzing = "YES">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "17DD0DFF207FB27400C56334"
BlueprintIdentifier = "SkeletonView::SkeletonView"
BuildableName = "SkeletonView.framework"
BlueprintName = "SkeletonView-tvOS"
BlueprintName = "SkeletonView iOS"
ReferencedContainer = "container:SkeletonView.xcodeproj">
</BuildableReference>
</BuildActionEntry>
@@ -28,9 +28,17 @@
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
shouldUseLaunchSchemeArgsEnv = "YES">
<Testables>
<TestableReference
skipped = "NO">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "SkeletonView::SkeletonViewTests"
BuildableName = "SkeletonViewTests.xctest"
BlueprintName = "SkeletonView iOS Tests"
ReferencedContainer = "container:SkeletonView.xcodeproj">
</BuildableReference>
</TestableReference>
</Testables>
<AdditionalOptions>
</AdditionalOptions>
</TestAction>
<LaunchAction
buildConfiguration = "Debug"
@@ -42,17 +50,6 @@
debugDocumentVersioning = "YES"
debugServiceExtension = "internal"
allowLocationSimulation = "YES">
<MacroExpansion>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "17DD0DFF207FB27400C56334"
BuildableName = "SkeletonView.framework"
BlueprintName = "SkeletonView-tvOS"
ReferencedContainer = "container:SkeletonView.xcodeproj">
</BuildableReference>
</MacroExpansion>
<AdditionalOptions>
</AdditionalOptions>
</LaunchAction>
<ProfileAction
buildConfiguration = "Release"
@@ -60,15 +57,6 @@
savedToolIdentifier = ""
useCustomWorkingDirectory = "NO"
debugDocumentVersioning = "YES">
<MacroExpansion>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "17DD0DFF207FB27400C56334"
BuildableName = "SkeletonView.framework"
BlueprintName = "SkeletonView-tvOS"
ReferencedContainer = "container:SkeletonView.xcodeproj">
</BuildableReference>
</MacroExpansion>
</ProfileAction>
<AnalyzeAction
buildConfiguration = "Debug">
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "1020"
LastUpgradeVersion = "1300"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"
@@ -14,9 +14,23 @@
buildForAnalyzing = "YES">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "52D6D97B1BEFF229002C0205"
BlueprintIdentifier = "F556F56426CD1F3900A80B83"
BuildableName = "SkeletonView.framework"
BlueprintName = "SkeletonView-iOS"
BlueprintName = "SkeletonView tvOS"
ReferencedContainer = "container:SkeletonView.xcodeproj">
</BuildableReference>
</BuildActionEntry>
<BuildActionEntry
buildForTesting = "YES"
buildForRunning = "NO"
buildForProfiling = "NO"
buildForArchiving = "NO"
buildForAnalyzing = "NO">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "F556F67026CD458500A80B83"
BuildableName = "SkeletonView tvOS Tests.xctest"
BlueprintName = "SkeletonView tvOS Tests"
ReferencedContainer = "container:SkeletonView.xcodeproj">
</BuildableReference>
</BuildActionEntry>
@@ -28,18 +42,17 @@
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
shouldUseLaunchSchemeArgsEnv = "YES">
<Testables>
<TestableReference
skipped = "NO">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "F556F67026CD458500A80B83"
BuildableName = "SkeletonView tvOS Tests.xctest"
BlueprintName = "SkeletonView tvOS Tests"
ReferencedContainer = "container:SkeletonView.xcodeproj">
</BuildableReference>
</TestableReference>
</Testables>
<MacroExpansion>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "52D6D97B1BEFF229002C0205"
BuildableName = "SkeletonView.framework"
BlueprintName = "SkeletonView-iOS"
ReferencedContainer = "container:SkeletonView.xcodeproj">
</BuildableReference>
</MacroExpansion>
<AdditionalOptions>
</AdditionalOptions>
</TestAction>
<LaunchAction
buildConfiguration = "Debug"
@@ -51,17 +64,6 @@
debugDocumentVersioning = "YES"
debugServiceExtension = "internal"
allowLocationSimulation = "YES">
<MacroExpansion>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "52D6D97B1BEFF229002C0205"
BuildableName = "SkeletonView.framework"
BlueprintName = "SkeletonView-iOS"
ReferencedContainer = "container:SkeletonView.xcodeproj">
</BuildableReference>
</MacroExpansion>
<AdditionalOptions>
</AdditionalOptions>
</LaunchAction>
<ProfileAction
buildConfiguration = "Release"
@@ -72,9 +74,9 @@
<MacroExpansion>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "52D6D97B1BEFF229002C0205"
BlueprintIdentifier = "F556F56426CD1F3900A80B83"
BuildableName = "SkeletonView.framework"
BlueprintName = "SkeletonView-iOS"
BlueprintName = "SkeletonView tvOS"
ReferencedContainer = "container:SkeletonView.xcodeproj">
</BuildableReference>
</MacroExpansion>
@@ -1,91 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "1020"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"
buildImplicitDependencies = "YES">
<BuildActionEntries>
<BuildActionEntry
buildForTesting = "YES"
buildForRunning = "YES"
buildForProfiling = "YES"
buildForArchiving = "YES"
buildForAnalyzing = "YES">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "F5F899F11FABA607002E8FDA"
BuildableName = "SkeletonViewExample.app"
BlueprintName = "SkeletonViewExample"
ReferencedContainer = "container:SkeletonView.xcodeproj">
</BuildableReference>
</BuildActionEntry>
</BuildActionEntries>
</BuildAction>
<TestAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
shouldUseLaunchSchemeArgsEnv = "YES">
<Testables>
</Testables>
<MacroExpansion>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "F5F899F11FABA607002E8FDA"
BuildableName = "SkeletonViewExample.app"
BlueprintName = "SkeletonViewExample"
ReferencedContainer = "container:SkeletonView.xcodeproj">
</BuildableReference>
</MacroExpansion>
<AdditionalOptions>
</AdditionalOptions>
</TestAction>
<LaunchAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
launchStyle = "0"
useCustomWorkingDirectory = "NO"
ignoresPersistentStateOnLaunch = "NO"
debugDocumentVersioning = "YES"
debugServiceExtension = "internal"
allowLocationSimulation = "YES">
<BuildableProductRunnable
runnableDebuggingMode = "0">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "F5F899F11FABA607002E8FDA"
BuildableName = "SkeletonViewExample.app"
BlueprintName = "SkeletonViewExample"
ReferencedContainer = "container:SkeletonView.xcodeproj">
</BuildableReference>
</BuildableProductRunnable>
<AdditionalOptions>
</AdditionalOptions>
</LaunchAction>
<ProfileAction
buildConfiguration = "Release"
shouldUseLaunchSchemeArgsEnv = "YES"
savedToolIdentifier = ""
useCustomWorkingDirectory = "NO"
debugDocumentVersioning = "YES">
<BuildableProductRunnable
runnableDebuggingMode = "0">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "F5F899F11FABA607002E8FDA"
BuildableName = "SkeletonViewExample.app"
BlueprintName = "SkeletonViewExample"
ReferencedContainer = "container:SkeletonView.xcodeproj">
</BuildableReference>
</BuildableProductRunnable>
</ProfileAction>
<AnalyzeAction
buildConfiguration = "Debug">
</AnalyzeAction>
<ArchiveAction
buildConfiguration = "Release"
revealArchiveInOrganizer = "YES">
</ArchiveAction>
</Scheme>
@@ -1,91 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "1020"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"
buildImplicitDependencies = "YES">
<BuildActionEntries>
<BuildActionEntry
buildForTesting = "YES"
buildForRunning = "YES"
buildForProfiling = "YES"
buildForArchiving = "YES"
buildForAnalyzing = "YES">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "42ABD05A210B548200BEEFF4"
BuildableName = "SkeletonViewExampleUICollectionView.app"
BlueprintName = "SkeletonViewExampleUICollectionView"
ReferencedContainer = "container:SkeletonView.xcodeproj">
</BuildableReference>
</BuildActionEntry>
</BuildActionEntries>
</BuildAction>
<TestAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
shouldUseLaunchSchemeArgsEnv = "YES">
<Testables>
</Testables>
<MacroExpansion>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "42ABD05A210B548200BEEFF4"
BuildableName = "SkeletonViewExampleUICollectionView.app"
BlueprintName = "SkeletonViewExampleUICollectionView"
ReferencedContainer = "container:SkeletonView.xcodeproj">
</BuildableReference>
</MacroExpansion>
<AdditionalOptions>
</AdditionalOptions>
</TestAction>
<LaunchAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
launchStyle = "0"
useCustomWorkingDirectory = "NO"
ignoresPersistentStateOnLaunch = "NO"
debugDocumentVersioning = "YES"
debugServiceExtension = "internal"
allowLocationSimulation = "YES">
<BuildableProductRunnable
runnableDebuggingMode = "0">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "42ABD05A210B548200BEEFF4"
BuildableName = "SkeletonViewExampleUICollectionView.app"
BlueprintName = "SkeletonViewExampleUICollectionView"
ReferencedContainer = "container:SkeletonView.xcodeproj">
</BuildableReference>
</BuildableProductRunnable>
<AdditionalOptions>
</AdditionalOptions>
</LaunchAction>
<ProfileAction
buildConfiguration = "Release"
shouldUseLaunchSchemeArgsEnv = "YES"
savedToolIdentifier = ""
useCustomWorkingDirectory = "NO"
debugDocumentVersioning = "YES">
<BuildableProductRunnable
runnableDebuggingMode = "0">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "42ABD05A210B548200BEEFF4"
BuildableName = "SkeletonViewExampleUICollectionView.app"
BlueprintName = "SkeletonViewExampleUICollectionView"
ReferencedContainer = "container:SkeletonView.xcodeproj">
</BuildableReference>
</BuildableProductRunnable>
</ProfileAction>
<AnalyzeAction
buildConfiguration = "Debug">
</AnalyzeAction>
<ArchiveAction
buildConfiguration = "Release"
revealArchiveInOrganizer = "YES">
</ArchiveAction>
</Scheme>
@@ -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
}
}
}
@@ -0,0 +1,43 @@
//
// 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 lazy var textLineHeight: SkeletonTextLineHeight = .fixed(SkeletonAppearance.default.multilineHeight)
public var multilineSpacing: CGFloat = 10
public var multilineLastLineFillPercent: Int = 70
public var multilineCornerRadius: Int = 0
public var renderSingleLineAsView: Bool = false
public var skeletonCornerRadius: Float = 0
}
// codebeat:enable[TOO_MANY_IVARS]
@@ -15,6 +15,7 @@ public protocol SkeletonCollectionViewDataSource: UICollectionViewDataSource {
func collectionSkeletonView(_ skeletonView: UICollectionView, supplementaryViewIdentifierOfKind: String, at indexPath: IndexPath) -> ReusableCellIdentifier?
func collectionSkeletonView(_ skeletonView: UICollectionView, skeletonCellForItemAt indexPath: IndexPath) -> UICollectionViewCell?
func collectionSkeletonView(_ skeletonView: UICollectionView, prepareCellForSkeleton cell: UICollectionViewCell, at indexPath: IndexPath)
func collectionSkeletonView(_ skeletonView: UICollectionView, prepareViewForSkeleton view: UICollectionReusableView, at indexPath: IndexPath)
}
public extension SkeletonCollectionViewDataSource {
@@ -35,6 +36,8 @@ public extension SkeletonCollectionViewDataSource {
}
func collectionSkeletonView(_ skeletonView: UICollectionView, prepareCellForSkeleton cell: UICollectionViewCell, at indexPath: IndexPath) { }
func collectionSkeletonView(_ skeletonView: UICollectionView, prepareViewForSkeleton view: UICollectionReusableView, at indexPath: IndexPath) { }
}
public protocol SkeletonCollectionViewDelegate: UICollectionViewDelegate { }
@@ -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
@@ -0,0 +1,94 @@
//
// 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 UIKit
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
}
public extension UIView {
@available(*, deprecated, renamed: "sk.treeNodesDescription")
var skeletonDescription: String {
sk.skeletonTreeDescription
}
@available(*, deprecated, renamed: "sk.isSkeletonActive")
var isSkeletonActive: Bool {
sk.isSkeletonActive
}
}
public extension UILabel {
@IBInspectable
@available(*, deprecated, renamed: "skeletonTextLineHeight")
var useFontLineHeight: Bool {
get {
textLineHeight == .relativeToFont
}
set {
textLineHeight = newValue ? .relativeToFont : .fixed(SkeletonAppearance.default.multilineHeight)
}
}
}
public extension UITextView {
@IBInspectable
@available(*, deprecated, renamed: "skeletonTextLineHeight")
var useFontLineHeight: Bool {
get {
textLineHeight == .relativeToFont
}
set {
textLineHeight = newValue ? .relativeToFont : .fixed(SkeletonAppearance.default.multilineHeight)
}
}
}
public extension SkeletonViewAppearance {
@available(*, deprecated, renamed: "textLineHeight")
var useFontLineHeight: Bool {
get {
textLineHeight == .relativeToFont
}
set {
textLineHeight = newValue ? .relativeToFont : .fixed(SkeletonAppearance.default.multilineHeight)
}
}
}
@@ -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")
}
@@ -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)
}
}
@@ -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,9 @@ public struct SkeletonGradient {
self.gradientColors = baseColor.makeGradient()
}
}
public init(colors: [UIColor]) {
self.gradientColors = colors
}
}
@@ -0,0 +1,30 @@
//
// 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
//
// SkeletonTextLineHeight.swift
//
// Created by Juanpe Catalán on 22/11/21.
import UIKit
public enum SkeletonTextLineHeight: Equatable {
/// Calculates the line height based on the font line height.
case relativeToFont
/// Calculates the line height based on the height constraints.
///
/// If no constraints exist, the height will be set to the `multilineHeight`
/// value defined in the `SkeletonAppearance`.
case relativeToConstraints
/// Returns the specific height specified as the associated value.
case fixed(CGFloat)
}
@@ -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
//
// SkeletonTextNumberOfLines.swift
//
// Created by Juanpe Catalán on 10/1/22.
import UIKit
public enum SkeletonTextNumberOfLines: Equatable, ExpressibleByIntegerLiteral {
/// Returns `numberOfLines` value.
case inherited
/// Returns the specific number of lines specified as the associated value.
case custom(Int)
}
public extension SkeletonTextNumberOfLines {
init(integerLiteral value: Int) {
self = .custom(value)
}
}
@@ -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) }()
}
}
}
@@ -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
//
// SkeletonExtended.swift
//
// Created by Juanpe Catalán on 23/8/21.
import Foundation
/// Type that acts as a generic extension point for all `SkeletonViewExtended` types.
public struct SkeletonViewExtension<ExtendedType> {
/// Stores the type or meta-type of any extended type.
public private(set) var type: ExtendedType
/// Create an instance from the provided value.
///
/// - Parameter type: Instance being extended.
public init(_ type: ExtendedType) {
self.type = type
}
}
/// Protocol describing the `sk` extension points for SkeletonView extended types.
public protocol SkeletonViewExtended {
/// Type being extended.
associatedtype ExtendedType
/// Instance SkeletonView extension point.
var sk: SkeletonViewExtension<ExtendedType> { get set }
}
extension SkeletonViewExtended {
/// Instance SkeletonView extension point.
public var sk: SkeletonViewExtension<Self> {
get { SkeletonViewExtension(self) }
// swiftlint:disable:next unused_setter_value
set {}
}
}
@@ -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()
}
}
}
@@ -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
}
}
@@ -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)
}
}
}

Some files were not shown because too many files have changed in this diff Show More