[🇨🇳](https://github.com/Juanpe/SkeletonView/blob/master/README_zh.md) by [@WhatsXie](https://twitter.com/WhatsXie)</br>
[🇧🇷](https://github.com/Juanpe/SkeletonView/blob/master/README_pt-br.md) by [@brunomunizaf](https://twitter.com/brunomuniz_af)</br>
[🇰🇷](https://github.com/Juanpe/SkeletonView/blob/master/README_ko.md) by [@techinpark](https://twitter.com/techinpark)
**🌎 README is available in other languages: [🇪🇸](https://github.com/Juanpe/SkeletonView/blob/develop/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)**
Today almost all apps have async processes, such as Api requests, long running processes, etc. And while the processes are working, usually developers place a loading view to show users that something is going on.
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.
```SkeletonView``` has been conceived to address this need, an elegant way to show users that something is happening and also prepare them to which contents he is waiting.
**SkeletonView** has been conceived to address this need, an elegant way to show users that something is happening and also prepare them for which contents are waiting.
Enjoy it! 🙂
* [Features](#-features)
* [Guides](#-guides)
* [Installation](#-installation)
* [Cocoapods](#using-cocoapods)
* [Carthage](#using-carthage)
* [SPM](#using-swift-package-manager)
* [How to use](#-how-to-use)
* [Collections](#-collections)
* [Multiline text](#-multiline-text)
* [Custom colors](#-custom-colors)
* [Appearance](#-appearance)
* [Custom animations](#-custom-animations)
* [Transitions](#-transitions)
* [Hierarchy](#-hierarchy)
* [Debug](#-debug)
* [Documentation](#-documentation)
* [Supported OS & SDK Versions](#-supported-os--sdk-versions)
|[**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
#### Using [Swift Package Manager](https://github.com/apple/swift-package-manager)
Once you have your Swift package set up, adding `SkeletonView` as a dependency is as easy as adding it to the `dependencies` value of your `Package.swift`.
>>```SkeletonView``` is recursive, so if you want show the skeleton in all skeletonable views, you only need to call the show method in the main container view. For example, with UIViewControllers
### Extra
#### Skeleton views layout
Sometimes skeleton layout may not fit your layout because the parent view bounds have changed. ~For example, rotating the device.~
You can relayout the skeleton views like so:
```swift
override func viewDidLayoutSubviews() {
view.layoutSkeletonIfNeeded()
}
```
⚠️⚠️ You shouldn't call this method. From *version 1.8.1* you don't need to call this method, the library does automatically. So, you can use this method *ONLY* in the cases when you need to update the layout of the skeleton manually.
#### Update skeleton configuration
> 📣 **IMPORTANT!**
>
> `SkeletonView` is recursive, so if you want show the skeleton in all skeletonable views, you only need to call the show method in the main container view. For example, with `UIViewControllers`.
You can change the skeleton configuration at any time like its colour, animation, etc. with the following methods:
> 1️⃣ If you are using resizable cells (**`tableView.rowHeight = UITableViewAutomaticDimension`**), it's mandatory define the **`estimatedRowHeight`**.
>
> 2️⃣ When you add elements in a **`UITableViewCell`** you should add it to **`contentView`** and not to the cell directly.
> ```swift
> self.contentView.addSubview(titleLabel) ✅
> self.addSubview(titleLabel) ❌
> ```
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`
#### UICollectionView
**UICollectionView**
For ```UICollectionView```, you need to conform to ```SkeletonCollectionViewDataSource``` protocol.
For `UICollectionView`, you need to conform to `SkeletonCollectionViewDataSource` protocol.
The rest of the process is the same as ```UITableView```
### 📰 Multiline text
### 🔠 Texts

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.
##### 🎛 Customize
You can set some properties for multilines elements.
...
...
@@ -309,32 +261,10 @@ Or, if you prefer use **IB/Storyboard**:

### 🎨 Custom colors
You can decide which color the skeleton is tinted with. You only need to pass as a parameter the color or gradient you want.
###### Image captured from website [https://flatuicolors.com](https://flatuicolors.com)
### 🦋 Appearance
**NEW** The skeletons have a default appearance. So, when you don't specify the color, gradient or multilines properties, `SkeletonView` uses the default values.
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
...
...
@@ -353,7 +283,7 @@ Default values:
-*default: 0*
To get these default values you can use `SkeletonAppearance.default`. Using this property you can set the values as well:
```Swift
```swift
SkeletonAppearance.default.multilineHeight=20
SkeletonAppearance.default.tintColor=.green
```
...
...
@@ -365,9 +295,33 @@ You can also specifiy these line appearance properties on a per-label basis:
-**skeletonPaddingInsets**: UIEdgeInsets
### 🤓 Custom animations
### 🎨 Custom colors
You can decide which color the skeleton is tinted with. You only need to pass as a parameter the color or gradient you want.
> Exist another way to create sliding animations, just using this shortcut:
> ```swift
> let animation = GradientDirection.leftToRight.slidingAnimation()
> ```
### 🏄 Transitions
```SkeletonView``` has build-in transitions to **show** or **hide** the skeletons in a *smoother* way 🤙
**SkeletonView** has built-in transitions to **show** or **hide** the skeletons in a *smoother* way 🤙
To use the transition, simply add the ```transition``` parameter to your ```showSkeleton()``` or ```hideSkeleton()``` function with the transition time, like this:
...
...
@@ -454,7 +411,11 @@ The default value is `crossDissolve(0.25)`
</table>
### 👨👧👦 Hierarchy
## ✨ Miscellaneous
**Hierarchy**
Since ```SkeletonView``` is recursive, and we want skeleton to be very efficient, we want to stop recursion as soon as possible. For this reason, you must set the container view as `Skeletonable`, because Skeleton will stop looking for `skeletonable` subviews as soon as a view is not Skeletonable, breaking then the recursion.
...
...
@@ -465,7 +426,7 @@ In this example we have a `UIViewController` with a `ContainerView` and a `UITab
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.~
You can relayout the skeleton views like so:
```swift
overridefuncviewDidLayoutSubviews(){
view.layoutSkeletonIfNeeded()
}
```
> 📣 **IMPORTANT!**
>
> You shouldn't call this method. From **version 1.8.1** you don't need to call this method, the library does automatically. So, you can use this method **ONLY** in the cases when you need to update the layout of the skeleton manually.
**Update skeleton**
You can change the skeleton configuration at any time like its colour, animation, etc. with the following methods: