Compare commits

...

68 Commits

Author SHA1 Message Date
Juanpe Catalán c2720898ac feat: BUMP version 1.2.3 2018-07-25 08:52:15 +02:00
Juanpe Catalán 9e395c7747 feat: Update CHANGELOG file 2018-07-25 08:50:08 +02:00
Juanpe Catalán b8aa587af6 Merge pull request #78 from hisaac/master
fix: Typos in README and method signature
2018-07-24 15:13:51 +02:00
Juanpe Catalán 349f7eb48e Merge pull request #77 from giantramen/master
feat: Use Stack View to Calculate Bounds
2018-07-24 11:59:13 +02:00
Juanpe Catalán 4f874a84f0 feat: Bump version 1.2.2 2018-07-24 08:34:26 +02:00
Juanpe Catalán a6de5342a4 Merge branch 'master' of https://github.com/Juanpe/SkeletonView 2018-07-24 08:27:42 +02:00
Juanpe Catalán 404da95cbe feat: New branding 2018-07-24 08:27:39 +02:00
Isaac Halvorson ebe7f3e463 Add default implementation of old method and deprecation message 2018-07-19 10:03:47 -05:00
Isaac Halvorson ad5cf2a21f Fix a couple small typos in README and a method signature 2018-07-19 09:37:15 -05:00
Kamin, Grant 7afe87160a Use Stack View to Calculate Bounds
Labels inside of stack views are not aligned properly
because we were assuming leading alignment.
Calculating the origin based off of the stack view alignment
instead.
2018-07-06 09:04:10 -05:00
Juanpe Catalán 7c7be7c80c Merge pull request #73 from giantramen/master
fix: UIStackView Label Issue #23
2018-06-26 16:25:59 +02:00
giantramen ff42bd02e2 Fix UIStackView Label Issue
Fixes issue where SkeletonView sets the text of each label to nil, UIStackView sets the height of each label to 0 and lays them out on top of each other.
2018-06-26 09:20:49 -05:00
Juanpe Catalán 0136c8576c feat: Update README 2018-06-06 10:36:19 +02:00
Juanpe Catalán 76c526385d Merge branch 'master' of https://github.com/Juanpe/SkeletonView 2018-06-06 10:20:16 +02:00
Juanpe Catalán 2b633e5ab6 BUMP version 1.2.1 2018-06-06 10:20:12 +02:00
Juanpe Catalán 5c19df67df Merge pull request #68 from eduardbosch/patch-1
Revert wrong README change
2018-06-06 10:00:59 +02:00
Juanpe Catalán b1778542d7 Merge pull request #69 from eduardbosch/patch-2
Fix tipo and remove space
2018-06-06 10:00:30 +02:00
Eduard Bosch Bertran ad5c87eea2 Fix tipo and remove space 2018-06-06 09:32:13 +02:00
Eduard Bosch Bertran 09813e530c Revert wrong README change
I've just reverted a missing ` in the README in this commit https://github.com/Juanpe/SkeletonView/commit/c06ae2d72c640a8fddf520991f3a3b274ad91ffd
2018-06-06 09:28:49 +02:00
Juanpe Catalán 23489159dd Update CHANGELOG.md 2018-06-05 17:51:11 +02:00
Juanpe Catalán c06ae2d72c feat: Update REAMDE 2018-06-05 17:16:53 +02:00
Juanpe Catalán 02b56f2707 feat: change some texts in README file 2018-06-05 17:14:48 +02:00
Juanpe Catalán fe40f4b6bf feat: Resize multiline asset 2018-06-05 17:07:54 +02:00
Juanpe Catalán 8b4f0b38b1 feat: update README file 2018-06-05 17:06:10 +02:00
Juanpe Catalán 44ce71e6b2 Merge pull request #67 from Juanpe/viewstate
View State
2018-06-05 13:30:44 +02:00
Juanpe Catalán d4ea1e78c2 feat: Add public headers for tvOS 2018-06-05 13:27:33 +02:00
Juanpe Catalán 00dc7e7b5d Merge branch 'master' into viewstate 2018-06-05 13:07:43 +02:00
Juanpe Catalán 3f947c08ca feat: remove unuseful code 2018-06-05 13:07:33 +02:00
Juanpe Catalán 5d8a30ba82 Merge pull request #15 from B4V4-G/master
enhancement: change corner radius for multilines
2018-06-05 12:54:45 +02:00
Juanpe Catalán aa08656fdd Merge branch 'master' into viewstate 2018-06-05 12:22:54 +02:00
Juanpe Catalán 15b1a33ade Merge pull request #62 from eduardbosch/feature/support_inspectables_with_carthage
feat: Support inspectable properties when using Carthage
2018-06-05 10:27:09 +02:00
Eduard Bosch Bertran d66adce904 chore: Add swift files with inspectables as public headers 2018-06-03 14:21:24 +02:00
Juanpe Catalán 06ddf69bd4 Update README.md 2018-05-16 11:51:00 +02:00
Juanpe Catalán bd0640a4c4 Update README.md 2018-05-16 11:35:31 +02:00
Juanpe Catalán 53a276c66b Update README.md 2018-05-16 11:34:59 +02:00
Juanpe Catalán be7fc21d03 Update README.md 2018-05-14 15:38:30 +02:00
Juanpe Catalán 3ac704eb07 Update README.md 2018-05-14 15:28:32 +02:00
Juanpe Catalán 987d12cbc5 Update issue_template.md 2018-05-14 13:42:05 +02:00
Juanpe Catalán a37948b6c1 Update README.md 2018-05-14 12:54:53 +02:00
Juanpe Catalán 2b15498ef3 Create view state 2018-05-14 00:43:24 +02:00
Juanpe Catalán bcde3e2ed6 fix: Don’t take account of content size layout constraints 2018-05-14 00:34:01 +02:00
Juanpe Catalán 719a5f507b feat: refactor some method signatures 2018-05-05 13:25:39 +02:00
Juanpe Catalán 340f792880 Update CHANGELOG.md 2018-05-01 13:33:26 +02:00
Juanpe Catalán f516eab8e2 feat: Add some link in mentions section 2018-05-01 13:00:34 +02:00
Juanpe Catalán 3506ffbfb5 feat: Add mentions in README file 2018-05-01 12:50:43 +02:00
Juanpe Catalán 2a895dfe35 feat: Add donate button 2018-05-01 12:27:30 +02:00
Juanpe Catalán 261ff5a451 feat: Update shields in README file 2018-04-30 14:19:15 +02:00
Juanpe Catalán 0995f0d9c9 fix: Add some missing files to tvOS framework 2018-04-30 14:00:37 +02:00
Juanpe Catalán 1e7be16ccb feat: Bump version to 1.2 2018-04-30 13:58:13 +02:00
Juanpe Catalán c1b96b7838 feat: Update README file 2018-04-30 13:53:35 +02:00
Juanpe Catalán d856c5b670 feat: Travis: Bump to Xcode 9.3 2018-04-30 13:53:18 +02:00
Juanpe Catalán 2af1fd28b7 Merge branch 'master' of https://github.com/Juanpe/SkeletonView 2018-04-30 13:49:36 +02:00
Juanpe Catalán 9806ec9eac feat: Remove gitignore contraints 2018-04-30 13:49:32 +02:00
Juanpe Catalán 55372f0c8f feat: Update project for Xcode 9.3 and Swift 4.1 2018-04-30 13:46:21 +02:00
Juanpe Catalán 331f949807 Merge pull request #53 from mihai8804858/tvos-support
feat: Add support for tvOS
2018-04-30 13:39:44 +02:00
Juanpe Catalán 6604c64b03 feat: Add dummy delegate 2018-04-30 13:38:43 +02:00
Juanpe Catalán 9306f69b78 feat: Update gitignore 2018-04-30 13:36:37 +02:00
Mihai Seremet 30f4cbcc7a Add support for tvOS 2018-04-16 14:36:40 +03:00
Juanpe Catalán 7e2849e26b fix: Issue #46 2018-03-30 14:31:05 +02:00
Juanpe Catalán 6f628a3382 feat: Add total downloads in README file 2018-03-30 13:55:54 +02:00
Juanpe Catalán 793c79f3e2 Merge branch 'master' of https://github.com/Juanpe/SkeletonView 2018-02-14 20:35:35 +01:00
Juanpe Catalán 20c2fe7e98 fix: Problem when app enter in foreground 2018-02-14 20:35:09 +01:00
Juanpe Catalán b3a6fca8fa Update CHANGELOG.md 2018-02-14 09:41:10 +01:00
Juanpe Catalán 5bcf7f114e feat: Update CHANGELOG file 2018-02-14 09:25:42 +01:00
Juanpe Catalán 145982894a feat: Update example with UITableView with automatic dimension 2018-02-14 09:23:09 +01:00
Juanpe Catalán e89de65a2b fix: Problem setting skeletonIsAnimated property 2018-02-12 19:11:07 +01:00
Juanpe Catalán 34b9122e0a feat: Update CHANGELOG file 2018-02-09 00:56:55 +01:00
3stud1ant3 e0fbf88912 feat: change corner radius for multilines from storyboard 2017-11-24 23:42:01 +05:00
44 changed files with 868 additions and 156 deletions
+2
View File
@@ -1,5 +1,7 @@
⚠️ Please fill out this template when filing an issue.
#### 🙏🏼 *Please check if it already exists other issue related with yours.*
### What did you do?
*Please replace this with what you did.*
+1
View File
@@ -21,6 +21,7 @@ xcuserdata/
*.moved-aside
*.xccheckout
*.xcscmblueprint
.DS_Store
## Obj-C/Swift specific
*.hmap
+1 -1
View File
@@ -1 +1 @@
4.0
4.1
+2 -1
View File
@@ -1,6 +1,7 @@
language: objective-c
osx_image: xcode9
osx_image: xcode9.3
script:
- xcodebuild -project SkeletonView.xcodeproj -target SkeletonView-iOS -sdk iphonesimulator -destination 'platform=iOS Simulator,name=iPhone 7,OS=11'
- xcodebuild -project SkeletonView.xcodeproj -target SkeletonView-tvOS -sdk appletvsimulator -destination 'platform=tvOS Simulator,name=Apple TV,OS=11'
- xcodebuild -project SkeletonView.xcodeproj -target SkeletonViewExample -sdk iphonesimulator -destination 'platform=iOS Simulator,name=iPhone 7,OS=11'
after_success:
Binary file not shown.

After

Width:  |  Height:  |  Size: 54 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 31 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 176 KiB

After

Width:  |  Height:  |  Size: 55 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 32 KiB

After

Width:  |  Height:  |  Size: 10 KiB

+45 -2
View File
@@ -1,13 +1,56 @@
# Change Log
All notable changes to this project will be documented in this file
## [Needed(1.1)(WIP)](https://github.com/Juanpe/SkeletonView/releases/tag/1.1)
## [Typo (1.2.3)](https://github.com/Juanpe/SkeletonView/releases/tag/1.2.3)
### Fixes
- Fix typo in `SkeletonTableViewDataSource` protocol
### Improvements
- Now it takes in account the `UIStackView` to calculate the `SkeletonLayer` bounds (thanks @giantramen)
## [New face (1.2.2)](https://github.com/Juanpe/SkeletonView/releases/tag/1.2.2)
### New
- Rebranding
### Bug fixes
- Solved issue [#23](https://github.com/Juanpe/SkeletonView/issues/23). Problem with UIStackView. (thanks @giantramen)
## [State (1.2.1)](https://github.com/Juanpe/SkeletonView/releases/tag/1.2.1)
### New
- You can set the corner radius multiline elements (thanks @B4V4-G)
- Save view state when skeleton appears and recovery when it is hidden (@juanpe)
### Bug fixes
- Solved issue [#51](https://github.com/Juanpe/SkeletonView/issues/51). Support inspectable properties when using Carthage. (thanks @eduardbosch)
## [On TV (1.2)](https://github.com/Juanpe/SkeletonView/releases/tag/1.2)
### New
- Now ```SkeletonView``` is **tvOS** compatible! 🎉. (thanks @mihai8804858)
### Bug fixes
- Solved issue [#46](https://github.com/Juanpe/SkeletonView/issues/46). It crashes the application when tap on it, didSelect called and crash.
## [Hotfix (1.1.1)](https://github.com/Juanpe/SkeletonView/releases/tag/1.1.1)
### Bug fixes
- Now yes, solved issue [#39](https://github.com/Juanpe/SkeletonView/issues/39)
## [Needed (1.1)](https://github.com/Juanpe/SkeletonView/releases/tag/1.1)
### New
- Now ```SkeletonView```supports **UICollectionViews**! 🎉. (thanks @Renatdz)
### Bug fixes
- Solved issue #39. Gradient animation did not work when app becomes active.
- Solved issue [#39](https://github.com/Juanpe/SkeletonView/issues/39). Gradient animation did not work when app becomes active.
## [Resizable (1.0.5)](https://github.com/Juanpe/SkeletonView/releases/tag/1.0.5)
@@ -15,7 +15,7 @@
<key>CFBundlePackageType</key>
<string>FMWK</string>
<key>CFBundleShortVersionString</key>
<string>1.0.5</string>
<string>1.2.1</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
+24
View File
@@ -0,0 +1,24 @@
<?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>$(DEVELOPMENT_LANGUAGE)</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.0</string>
<key>CFBundleVersion</key>
<string>$(CURRENT_PROJECT_VERSION)</string>
<key>NSPrincipalClass</key>
<string></string>
</dict>
</plist>
+1 -1
View File
@@ -15,7 +15,7 @@
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>CFBundleShortVersionString</key>
<string>1.0.5</string>
<string>1.2.1</string>
<key>CFBundleVersion</key>
<string>1</string>
<key>LSRequiresIPhoneOS</key>
+12 -6
View File
@@ -1,11 +1,11 @@
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="13771" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES" initialViewController="BYZ-38-t0r">
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="14113" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES" initialViewController="BYZ-38-t0r">
<device id="retina4_7" orientation="portrait">
<adaptation id="fullscreen"/>
</device>
<dependencies>
<deployment identifier="iOS"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="13772"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="14088"/>
<capability name="Constraints to layout margins" minToolsVersion="6.0"/>
<capability name="Safe area layout guides" minToolsVersion="9.0"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
@@ -19,7 +19,7 @@
<rect key="frame" x="0.0" y="0.0" width="375" height="667"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<tableView clipsSubviews="YES" contentMode="scaleToFill" alwaysBounceVertical="YES" dataMode="prototypes" style="plain" separatorStyle="none" rowHeight="120" estimatedRowHeight="-1" sectionHeaderHeight="28" sectionFooterHeight="28" translatesAutoresizingMaskIntoConstraints="NO" id="UCB-SP-lQk">
<tableView clipsSubviews="YES" contentMode="scaleToFill" alwaysBounceVertical="YES" dataMode="prototypes" style="plain" separatorStyle="none" rowHeight="-1" estimatedRowHeight="-1" sectionHeaderHeight="28" sectionFooterHeight="28" translatesAutoresizingMaskIntoConstraints="NO" id="UCB-SP-lQk">
<rect key="frame" x="0.0" y="263" width="375" height="264"/>
<color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
<color key="separatorColor" red="0.1061807256" green="0.84678786989999999" blue="0.031482450150000001" alpha="1" colorSpace="custom" customColorSpace="displayP3"/>
@@ -31,7 +31,7 @@
<rect key="frame" x="0.0" y="0.0" width="375" height="120"/>
<autoresizingMask key="autoresizingMask"/>
<subviews>
<imageView userInteractionEnabled="NO" contentMode="scaleToFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" translatesAutoresizingMaskIntoConstraints="NO" id="oiE-tt-nc2">
<imageView userInteractionEnabled="NO" contentMode="scaleToFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="avatar" translatesAutoresizingMaskIntoConstraints="NO" id="oiE-tt-nc2">
<rect key="frame" x="15" y="18" width="82" height="82"/>
<color key="backgroundColor" red="0.56078431370000004" green="0.59607843140000005" blue="0.7843137255" alpha="0.90709546230000004" colorSpace="calibratedRGB"/>
<constraints>
@@ -52,6 +52,9 @@
<nil key="highlightedColor"/>
<userDefinedRuntimeAttributes>
<userDefinedRuntimeAttribute type="boolean" keyPath="isSkeletonable" value="YES"/>
<userDefinedRuntimeAttribute type="number" keyPath="linesCornerRadius">
<integer key="value" value="0"/>
</userDefinedRuntimeAttribute>
</userDefinedRuntimeAttributes>
</label>
</subviews>
@@ -76,7 +79,7 @@
</tableViewCell>
</prototypes>
<userDefinedRuntimeAttributes>
<userDefinedRuntimeAttribute type="boolean" keyPath="isSkeletonable" value="YES"/>
<userDefinedRuntimeAttribute type="boolean" keyPath="isSkeletonable" value="NO"/>
</userDefinedRuntimeAttributes>
<connections>
<outlet property="dataSource" destination="BYZ-38-t0r" id="Hxi-nC-gbY"/>
@@ -99,6 +102,9 @@
<userDefinedRuntimeAttribute type="number" keyPath="lastLineFillPercent">
<integer key="value" value="40"/>
</userDefinedRuntimeAttribute>
<userDefinedRuntimeAttribute type="number" keyPath="linesCornerRadius">
<integer key="value" value="6"/>
</userDefinedRuntimeAttribute>
</userDefinedRuntimeAttributes>
</textView>
<imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="avatar" translatesAutoresizingMaskIntoConstraints="NO" id="nMj-pU-5wJ">
@@ -207,7 +213,7 @@
</viewController>
<placeholder placeholderIdentifier="IBFirstResponder" id="dkx-z0-nzr" sceneMemberID="firstResponder"/>
</objects>
<point key="canvasLocation" x="-482" y="-6"/>
<point key="canvasLocation" x="-2582" y="-400"/>
</scene>
</scenes>
<resources>
+6 -1
View File
@@ -40,6 +40,11 @@ class ViewController: UIViewController {
return skeletonTypeSelector.selectedSegmentIndex == 0 ? .solid : .gradient
}
override func viewDidLoad() {
super.viewDidLoad()
tableview.isSkeletonable = true
}
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
view.showAnimatedSkeleton()
@@ -131,7 +136,7 @@ extension ViewController: SkeletonTableViewDataSource {
return 9
}
func collectionSkeletonView(_ skeletonView: UITableView, cellIdenfierForRowAt indexPath: IndexPath) -> ReusableCellIdentifier {
func collectionSkeletonView(_ skeletonView: UITableView, cellIdentifierForRowAt indexPath: IndexPath) -> ReusableCellIdentifier {
return "CellIdentifier"
}
+55 -17
View File
@@ -1,25 +1,34 @@
![](Assets/header.jpg)
![](Assets/header2.jpg)
<p align="center">
<a href="https://travis-ci.org/Juanpe/SkeletonView">
<img src="https://img.shields.io/travis/Juanpe/SkeletonView.svg">
</a>
<img src="https://img.shields.io/badge/Swift-4.0-orange.svg" />
<a href="https://instagram.github.io/IGListKit/">
<img src="https://img.shields.io/cocoapods/p/SkeletonView.svg" alt="Platforms">
</a>
<img src="https://img.shields.io/badge/Swift-4.1-orange.svg" />
<a href="https://cocoapods.org/pods/SkeletonView">
<img src="https://img.shields.io/cocoapods/v/SkeletonView.svg" alt="CocoaPods" />
</a>
<a href="https://github.com/Carthage/Carthage">
<img src="https://img.shields.io/badge/carthage-compatible-4BC51D.svg?style=flat" alt="Carthage" />
</a>
<a href="https://cocoapods.org/pods/SkeletonView">
<img src="https://img.shields.io/cocoapods/dt/SkeletonView.svg?style=flat" alt="CocoaPods downloads" />
</a>
<a href="https://twitter.com/JuanpeCatalan">
<img src="https://img.shields.io/badge/contact-@JuanpeCatalan-blue.svg?style=flat" alt="Twitter: @JuanpeCatalan" />
</a>
<a href="https://opensource.org/licenses/MIT">
<img src="https://img.shields.io/badge/License-MIT-yellow.svg" alt="License" />
<a href="https://www.paypal.com/cgi-bin/webscr?cmd=_donations&business=MJ4Y2D9DEX6FL&lc=ES&item_name=SkeletonView&currency_code=EUR&bn=PP%2dDonationsBF%3abtn_donate_SM%2egif%3aNonHosted">
<img src="https://img.shields.io/badge/Donate-PayPal-green.svg" alt="Paypal" />
</a>
<a href="https://twitter.com/intent/tweet?text=Wow%20This%20library%20is%20awesome:&url=https%3A%2F%2Fgithub.com%2FJuanpe%2FSkeletonView">
<img src="https://img.shields.io/twitter/url/https/github.com/Juanpe/SkeletonView.svg?style=social" alt="License" />
</a>
<a href="https://twitter.com/JuanpeCatalan">
<img src="https://img.shields.io/twitter/follow/JuanpeCatalan.svg?style=social&label=Follow" alt="Twitter" />
</a>
</p>
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.
@@ -42,7 +51,8 @@ Enjoy it! 🙂
* [Hierarchy](#-hierarchy)
* [Documentation](#-documentation)
* [Next steps](#-next-steps)
* [Contributed](#-contributed)
* [Contributing](#-contributing)
* [Mentions](#-mentions)
* [Author](#-author)
* [License](#-license)
@@ -60,14 +70,13 @@ Enjoy it! 🙂
### 📋 Supported OS & SDK Versions
* iOS 9.0+
* tvOS 9.0+
* Swift 4
### 🔮 Example
To run the example project, clone the repo and run `SkeletonViewExample` target.
![](Assets/demoApp2.png)
## 📲 Installation
#### Using [CocoaPods](https://cocoapods.org)
@@ -162,7 +171,7 @@ If you want to show the skeleton in a ```UITableView```, you need to conform to
public protocol SkeletonTableViewDataSource: UITableViewDataSource {
func numSections(in collectionSkeletonView: UITableView) -> Int
func collectionSkeletonView(_ skeletonView: UITableView, numberOfRowsInSection section: Int) -> Int
func collectionSkeletonView(_ skeletonView: UITableView, cellIdenfierForRowAt indexPath: IndexPath) -> ReusableCellIdentifier
func collectionSkeletonView(_ skeletonView: UITableView, cellIdentifierForRowAt indexPath: IndexPath) -> ReusableCellIdentifier
}
```
As you can see, this protocol inherits from ```UITableViewDataSource```, so you can replace this protocol with the skeleton protocol.
@@ -182,12 +191,12 @@ func collectionSkeletonView(_ skeletonView: UITableView, numberOfRowsInSection s
There is only one method you need to implement to let Skeleton know the cell identifier. This method doesn't have default implementation:
``` swift
func collectionSkeletonView(_ skeletonView: UITableView, cellIdenfierForRowAt indexPath: IndexPath) -> ReusableCellIdentifier
func collectionSkeletonView(_ skeletonView: UITableView, cellIdentifierForRowAt indexPath: IndexPath) -> ReusableCellIdentifier
```
**Example**
``` swift
func collectionSkeletonView(_ skeletonView: UITableView, cellIdenfierForRowAt indexPath: IndexPath) -> ReusableCellIdentifier {
func collectionSkeletonView(_ skeletonView: UITableView, cellIdentifierForRowAt indexPath: IndexPath) -> ReusableCellIdentifier {
return "CellIdentifier"
}
```
@@ -217,17 +226,27 @@ The rest of the process is the same as ```UITableView```
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.
**NEW** Now, you can set the filling percent of the last line. **Default: 70%**
##### 🎛 Customize
To modify the percent **using code**, set the property:
You can set some properties for multilines elements.
| Property | Values | Default | Preview
| ------- | ------- |------- | -------
| **Filling percent** of the last line. | `0...100` | `70%` | ![](Assets/multiline_lastline.png)
| **Corner radius** of lines. (**NEW**) | `0...10` | `0` | ![](Assets/multiline_corner.png)
To modify the percent or radius **using code**, set the properties:
```swift
descriptionTextView.lastLineFillPercent = 50
descriptionTextView.linesCornerRadius = 5
```
Or, if you prefer use **IB/Storyboard**:
![](Assets/lastline_storyboard.png)
![](Assets/multiline_customize.png)
### 🎨 Custom colors
@@ -294,7 +313,7 @@ view.showAnimatedGradientSkeleton(usingGradient: gradient, animation: animation)
|------- | -------
| .leftRight | ![](Assets/sliding_left_to_right.gif)
| .rightLeft | ![](Assets/sliding_right_to_left.gif)
| .topBottom | ![](Assets/sliding_top_to_bottom.gif)
| .topBottom | ![](Assets/sliding_top_to_bottom.gif)
| .bottomTop | ![](Assets/sliding_bottom_to_top.gif)
| .topLeftBottomRight | ![](Assets/sliding_topLeft_to_bottomRight.gif)
| .bottomRightTopLeft | ![](Assets/sliding_bottomRight_to_topLeft.gif)
@@ -329,12 +348,13 @@ Coming soon...😅
* [x] Add more gradient animations
* [x] Supported resizable cells
* [x] CollectionView compatible
* [ ] Add recovery state
* [x] tvOS compatible
* [x] Add recovery state
* [ ] Custom collections compatible
* [ ] Add animations when it shows/hides the skeletons
* [ ] MacOS and WatchOS compatible
## ❤️ Contributed
## ❤️ Contributing
This is an open source project, so feel free to contribute. How?
- Open an [issue](https://github.com/Juanpe/SkeletonView/issues/new).
- Send feedback via [email](mailto://juanpecatalan.com).
@@ -344,12 +364,30 @@ See [all contributors](https://github.com/Juanpe/SkeletonView/graphs/contributor
###### Project generated with [SwiftPlate](https://github.com/JohnSundell/SwiftPlate)
## 📢 Mentions
- [iOS Dev Weekly #327](https://iosdevweekly.com/issues/327#start)
- [Hacking with Swift Articles](https://www.hackingwithswift.com/articles/40/skeletonview-makes-loading-content-beautiful)
- [Top 10 Swift Articles November](https://medium.mybridge.co/swift-top-10-articles-for-the-past-month-v-nov-2017-dfed7861cd65)
- [30 Amazing iOS Swift Libraries (v2018)](https://medium.mybridge.co/30-amazing-ios-swift-libraries-for-the-past-year-v-2018-7cf15027eee9)
- [AppCoda Weekly #44](http://digest.appcoda.com/issues/appcoda-weekly-issue-44-81899)
- [iOS Cookies Newsletter #103](https://us11.campaign-archive.com/?u=cd1f3ed33c6527331d82107ba&id=48131a516d)
- [Swift Developments Newsletter #113](https://andybargh.com/swiftdevelopments-113/)
- [iOS Goodies #204](http://ios-goodies.com/post/167557280951/week-204)
- [Swift Weekly #96](http://digest.swiftweekly.com/issues/swift-weekly-issue-96-81759)
- [CocoaControls](https://www.cocoacontrols.com/controls/skeletonview)
- [Awesome iOS Newsletter #74](https://ios.libhunt.com/newsletter/74)
## 👨🏻‍💻 Author
[1.1]: http://i.imgur.com/tXSoThF.png
[1]: http://www.twitter.com/JuanpeCatalan
* Juanpe Catalán [![alt text][1.1]][1]
<a class="bmc-button" target="_blank" href="https://www.buymeacoffee.com/CDou4xtIK"><img src="https://www.buymeacoffee.com/assets/img/custom_images/orange_img.png" alt="Buy me a coffee" style="height: 41px !important;width: 174px !important;box-shadow: 0px 3px 2px 0px rgba(190, 190, 190, 0.5) !important;-webkit-box-shadow: 0px 3px 2px 0px rgba(190, 190, 190, 0.5) !important;"><span style="margin-left:5px"></span></a>
## 👮🏻 License
```
+2 -1
View File
@@ -1,6 +1,6 @@
Pod::Spec.new do |s|
s.name = "SkeletonView"
s.version = "1.1"
s.version = "1.2.3"
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.
@@ -11,6 +11,7 @@ Pod::Spec.new do |s|
s.author = { "Juanpe Catalán" => "juanpecm@gmail.com" }
s.social_media_url = "https://twitter.com/JuanpeCatalan"
s.ios.deployment_target = "9.0"
s.tvos.deployment_target = "9.0"
s.source = { :git => "https://github.com/Juanpe/SkeletonView.git", :tag => s.version.to_s }
s.source_files = "Sources/**/*"
end
+272 -16
View File
@@ -7,15 +7,47 @@
objects = {
/* Begin PBXBuildFile section */
17DD0E08207FB28900C56334 /* CollectionSkeletonProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = F5F899EC1FAB9F04002E8FDA /* CollectionSkeletonProtocol.swift */; };
17DD0E09207FB28900C56334 /* SkeletonCollectionDataSource.swift in Sources */ = {isa = PBXBuildFile; fileRef = F5F899EA1FAB9DA3002E8FDA /* SkeletonCollectionDataSource.swift */; };
17DD0E0A207FB28900C56334 /* SkeletonCollectionViewProtocols.swift in Sources */ = {isa = PBXBuildFile; fileRef = F5307E381FB1078E00EE67C5 /* SkeletonCollectionViewProtocols.swift */; };
17DD0E0B207FB28900C56334 /* SkeletonTableViewProtocols.swift in Sources */ = {isa = PBXBuildFile; fileRef = F5307E361FB1076E00EE67C5 /* SkeletonTableViewProtocols.swift */; };
17DD0E0C207FB28900C56334 /* UICollectionView+CollectionSkeleton.swift in Sources */ = {isa = PBXBuildFile; fileRef = F54CF5E32024CEB000330B0D /* UICollectionView+CollectionSkeleton.swift */; };
17DD0E0D207FB28900C56334 /* UITableView+CollectionSkeleton.swift in Sources */ = {isa = PBXBuildFile; fileRef = F54CF5E22024CEAF00330B0D /* UITableView+CollectionSkeleton.swift */; };
17DD0E0E207FB28900C56334 /* UIView+CollectionSkeleton.swift in Sources */ = {isa = PBXBuildFile; fileRef = F54CF5E12024CEAF00330B0D /* UIView+CollectionSkeleton.swift */; };
17DD0E0F207FB28C00C56334 /* CALayer+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = F5F622421FAC81FD007C062A /* CALayer+Extensions.swift */; };
17DD0E10207FB28C00C56334 /* UIColor+Skeleton.swift in Sources */ = {isa = PBXBuildFile; fileRef = F5F622401FAC6E31007C062A /* UIColor+Skeleton.swift */; };
17DD0E11207FB28C00C56334 /* UIView+Frame.swift in Sources */ = {isa = PBXBuildFile; fileRef = F5307E2D1FB0E5E400EE67C5 /* UIView+Frame.swift */; };
17DD0E12207FB28C00C56334 /* UIView+IBInspectable.swift in Sources */ = {isa = PBXBuildFile; fileRef = F5F899CF1FAA6A4D002E8FDA /* UIView+IBInspectable.swift */; };
17DD0E13207FB28C00C56334 /* UIView+UIApplicationDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = F587FB85202CEC95002DB5FE /* UIView+UIApplicationDelegate.swift */; };
17DD0E14207FB28F00C56334 /* SkeletonAnimationBuilder.swift in Sources */ = {isa = PBXBuildFile; fileRef = F51DE1081FBF70A70037919A /* SkeletonAnimationBuilder.swift */; };
17DD0E15207FB28F00C56334 /* SkeletonDefaultConfig.swift in Sources */ = {isa = PBXBuildFile; fileRef = F5307E2F1FB0EC9D00EE67C5 /* SkeletonDefaultConfig.swift */; };
17DD0E16207FB28F00C56334 /* SkeletonGradient.swift in Sources */ = {isa = PBXBuildFile; fileRef = F5307E2B1FAF6BC900EE67C5 /* SkeletonGradient.swift */; };
17DD0E17207FB28F00C56334 /* SkeletonLayer.swift in Sources */ = {isa = PBXBuildFile; fileRef = F5F899E81FAB9D2B002E8FDA /* SkeletonLayer.swift */; };
17DD0E18207FB28F00C56334 /* SkeletonView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8933C7841EB5B820000D00A4 /* SkeletonView.swift */; };
17DD0E19207FB28F00C56334 /* SkeletonFlow.swift in Sources */ = {isa = PBXBuildFile; fileRef = F587FB83202CBFC8002DB5FE /* SkeletonFlow.swift */; };
17DD0E1C207FB32100C56334 /* AssociationPolicy.swift in Sources */ = {isa = PBXBuildFile; fileRef = F5F899D11FAB9630002E8FDA /* AssociationPolicy.swift */; };
17DD0E1D207FB32100C56334 /* ContainsMultilineText.swift in Sources */ = {isa = PBXBuildFile; fileRef = F5307E3A1FB123C100EE67C5 /* ContainsMultilineText.swift */; };
17DD0E1E207FB32100C56334 /* PrepareForSkeletonProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = F56B94451FAE20AF0095662F /* PrepareForSkeletonProtocol.swift */; };
17DD0E1F207FB32100C56334 /* RecursiveProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = F5307E311FB0F42F00EE67C5 /* RecursiveProtocol.swift */; };
3B83EE4720C41488005178A4 /* ContainsMultilineText.swift in Headers */ = {isa = PBXBuildFile; fileRef = 3B83EE4520C41488005178A4 /* ContainsMultilineText.swift */; settings = {ATTRIBUTES = (Public, ); }; };
3B83EE4820C41488005178A4 /* UIView+IBInspectable.swift in Headers */ = {isa = PBXBuildFile; fileRef = 3B83EE4620C41488005178A4 /* UIView+IBInspectable.swift */; settings = {ATTRIBUTES = (Public, ); }; };
8748240D20C6A88A00E92179 /* UIView+IBInspectable.swift in Headers */ = {isa = PBXBuildFile; fileRef = F5F899CF1FAA6A4D002E8FDA /* UIView+IBInspectable.swift */; settings = {ATTRIBUTES = (Public, ); }; };
8748240E20C6A88E00E92179 /* ContainsMultilineText.swift in Headers */ = {isa = PBXBuildFile; fileRef = F5307E3A1FB123C100EE67C5 /* ContainsMultilineText.swift */; settings = {ATTRIBUTES = (Public, ); }; };
88DEA97F1FCDBD78006C80EF /* Constants.swift in Sources */ = {isa = PBXBuildFile; fileRef = 88DEA97D1FCDBD1F006C80EF /* Constants.swift */; };
8933C7851EB5B820000D00A4 /* SkeletonView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8933C7841EB5B820000D00A4 /* SkeletonView.swift */; };
F51DE1091FBF70A70037919A /* SkeletonAnimationBuilder.swift in Sources */ = {isa = PBXBuildFile; fileRef = F51DE1081FBF70A70037919A /* SkeletonAnimationBuilder.swift */; };
F51DF871206E91B300D23301 /* SkeletonReusableCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = F51DF870206E91B300D23301 /* SkeletonReusableCell.swift */; };
F51DF873206E91FB00D23301 /* GenericCollectionView.swift in Sources */ = {isa = PBXBuildFile; fileRef = F51DF872206E91FB00D23301 /* GenericCollectionView.swift */; };
F51DF879206E9F5500D23301 /* SkeletonCollectionDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = F51DF878206E9F5500D23301 /* SkeletonCollectionDelegate.swift */; };
F51ED28320973CBB008B2434 /* SkeletonCollectionDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = F51DF878206E9F5500D23301 /* SkeletonCollectionDelegate.swift */; };
F51ED28420973CC6008B2434 /* GenericCollectionView.swift in Sources */ = {isa = PBXBuildFile; fileRef = F51DF872206E91FB00D23301 /* GenericCollectionView.swift */; };
F51ED28520973CC9008B2434 /* SkeletonReusableCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = F51DF870206E91B300D23301 /* SkeletonReusableCell.swift */; };
F5307E2C1FAF6BC900EE67C5 /* SkeletonGradient.swift in Sources */ = {isa = PBXBuildFile; fileRef = F5307E2B1FAF6BC900EE67C5 /* SkeletonGradient.swift */; };
F5307E2E1FB0E5E400EE67C5 /* UIView+Frame.swift in Sources */ = {isa = PBXBuildFile; fileRef = F5307E2D1FB0E5E400EE67C5 /* UIView+Frame.swift */; };
F5307E301FB0EC9D00EE67C5 /* SkeletonDefaultConfig.swift in Sources */ = {isa = PBXBuildFile; fileRef = F5307E2F1FB0EC9D00EE67C5 /* SkeletonDefaultConfig.swift */; };
F5307E321FB0F42F00EE67C5 /* RecursiveProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = F5307E311FB0F42F00EE67C5 /* RecursiveProtocol.swift */; };
F5307E371FB1076E00EE67C5 /* SkeletonTableViewDataSource.swift in Sources */ = {isa = PBXBuildFile; fileRef = F5307E361FB1076E00EE67C5 /* SkeletonTableViewDataSource.swift */; };
F5307E391FB1078E00EE67C5 /* SkeletonCollectionViewDataSource.swift in Sources */ = {isa = PBXBuildFile; fileRef = F5307E381FB1078E00EE67C5 /* SkeletonCollectionViewDataSource.swift */; };
F5307E371FB1076E00EE67C5 /* SkeletonTableViewProtocols.swift in Sources */ = {isa = PBXBuildFile; fileRef = F5307E361FB1076E00EE67C5 /* SkeletonTableViewProtocols.swift */; };
F5307E391FB1078E00EE67C5 /* SkeletonCollectionViewProtocols.swift in Sources */ = {isa = PBXBuildFile; fileRef = F5307E381FB1078E00EE67C5 /* SkeletonCollectionViewProtocols.swift */; };
F5307E3B1FB123C100EE67C5 /* ContainsMultilineText.swift in Sources */ = {isa = PBXBuildFile; fileRef = F5307E3A1FB123C100EE67C5 /* ContainsMultilineText.swift */; };
F5307E411FB3B84500EE67C5 /* SkeletonView.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 52D6D97C1BEFF229002C0205 /* SkeletonView.framework */; };
F5307E421FB3B84500EE67C5 /* SkeletonView.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 52D6D97C1BEFF229002C0205 /* SkeletonView.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
@@ -25,6 +57,12 @@
F56B94461FAE20AF0095662F /* PrepareForSkeletonProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = F56B94451FAE20AF0095662F /* PrepareForSkeletonProtocol.swift */; };
F587FB84202CBFC8002DB5FE /* SkeletonFlow.swift in Sources */ = {isa = PBXBuildFile; fileRef = F587FB83202CBFC8002DB5FE /* SkeletonFlow.swift */; };
F587FB86202CEC95002DB5FE /* UIView+UIApplicationDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = F587FB85202CEC95002DB5FE /* UIView+UIApplicationDelegate.swift */; };
F58A6E6B20A8C54100612494 /* RecoverableViewState.swift in Sources */ = {isa = PBXBuildFile; fileRef = F58A6E6A20A8C54100612494 /* RecoverableViewState.swift */; };
F58A6E6C20A8C54100612494 /* RecoverableViewState.swift in Sources */ = {isa = PBXBuildFile; fileRef = F58A6E6A20A8C54100612494 /* RecoverableViewState.swift */; };
F58A6E6E20A8C66300612494 /* Recoverable.swift in Sources */ = {isa = PBXBuildFile; fileRef = F58A6E6D20A8C66300612494 /* Recoverable.swift */; };
F58A6E6F20A8C66300612494 /* Recoverable.swift in Sources */ = {isa = PBXBuildFile; fileRef = F58A6E6D20A8C66300612494 /* Recoverable.swift */; };
F5D3FB0B209DCAA300003FCF /* SubviewsSkeletonables.swift in Sources */ = {isa = PBXBuildFile; fileRef = F5D3FB0A209DCAA300003FCF /* SubviewsSkeletonables.swift */; };
F5D3FB0C209DCAA300003FCF /* SubviewsSkeletonables.swift in Sources */ = {isa = PBXBuildFile; fileRef = F5D3FB0A209DCAA300003FCF /* SubviewsSkeletonables.swift */; };
F5F622411FAC6E31007C062A /* UIColor+Skeleton.swift in Sources */ = {isa = PBXBuildFile; fileRef = F5F622401FAC6E31007C062A /* UIColor+Skeleton.swift */; };
F5F622431FAC81FD007C062A /* CALayer+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = F5F622421FAC81FD007C062A /* CALayer+Extensions.swift */; };
F5F622451FACA338007C062A /* Cell.swift in Sources */ = {isa = PBXBuildFile; fileRef = F5F622441FACA338007C062A /* Cell.swift */; };
@@ -65,17 +103,24 @@
/* End PBXCopyFilesBuildPhase section */
/* Begin PBXFileReference section */
17DD0E00207FB27400C56334 /* SkeletonView.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = SkeletonView.framework; sourceTree = BUILT_PRODUCTS_DIR; };
17DD0E1A207FB2C200C56334 /* SkeletonView-tvOS.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "SkeletonView-tvOS.plist"; sourceTree = "<group>"; };
17DD0E1B207FB2C200C56334 /* SkeletonView-iOS.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "SkeletonView-iOS.plist"; sourceTree = "<group>"; };
3B83EE4520C41488005178A4 /* ContainsMultilineText.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = ContainsMultilineText.swift; path = Sources/Helpers/ContainsMultilineText.swift; sourceTree = "<group>"; };
3B83EE4620C41488005178A4 /* UIView+IBInspectable.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = "UIView+IBInspectable.swift"; path = "Sources/Extensions/UIView+IBInspectable.swift"; sourceTree = "<group>"; };
52D6D97C1BEFF229002C0205 /* SkeletonView.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = SkeletonView.framework; sourceTree = BUILT_PRODUCTS_DIR; };
88DEA97D1FCDBD1F006C80EF /* Constants.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Constants.swift; sourceTree = "<group>"; };
8933C7841EB5B820000D00A4 /* SkeletonView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SkeletonView.swift; sourceTree = "<group>"; };
AD2FAA261CD0B6D800659CF4 /* SkeletonView.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = SkeletonView.plist; sourceTree = "<group>"; };
F51DE1081FBF70A70037919A /* SkeletonAnimationBuilder.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SkeletonAnimationBuilder.swift; sourceTree = "<group>"; };
F51DF870206E91B300D23301 /* SkeletonReusableCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SkeletonReusableCell.swift; sourceTree = "<group>"; };
F51DF872206E91FB00D23301 /* GenericCollectionView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GenericCollectionView.swift; sourceTree = "<group>"; };
F51DF878206E9F5500D23301 /* SkeletonCollectionDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SkeletonCollectionDelegate.swift; sourceTree = "<group>"; };
F5307E2B1FAF6BC900EE67C5 /* SkeletonGradient.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SkeletonGradient.swift; sourceTree = "<group>"; };
F5307E2D1FB0E5E400EE67C5 /* UIView+Frame.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UIView+Frame.swift"; sourceTree = "<group>"; };
F5307E2F1FB0EC9D00EE67C5 /* SkeletonDefaultConfig.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SkeletonDefaultConfig.swift; sourceTree = "<group>"; };
F5307E311FB0F42F00EE67C5 /* RecursiveProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RecursiveProtocol.swift; sourceTree = "<group>"; };
F5307E361FB1076E00EE67C5 /* SkeletonTableViewDataSource.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SkeletonTableViewDataSource.swift; sourceTree = "<group>"; };
F5307E381FB1078E00EE67C5 /* SkeletonCollectionViewDataSource.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SkeletonCollectionViewDataSource.swift; sourceTree = "<group>"; };
F5307E361FB1076E00EE67C5 /* SkeletonTableViewProtocols.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SkeletonTableViewProtocols.swift; sourceTree = "<group>"; };
F5307E381FB1078E00EE67C5 /* SkeletonCollectionViewProtocols.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SkeletonCollectionViewProtocols.swift; sourceTree = "<group>"; };
F5307E3A1FB123C100EE67C5 /* ContainsMultilineText.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContainsMultilineText.swift; sourceTree = "<group>"; };
F54CF5E12024CEAF00330B0D /* UIView+CollectionSkeleton.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "UIView+CollectionSkeleton.swift"; sourceTree = "<group>"; };
F54CF5E22024CEAF00330B0D /* UITableView+CollectionSkeleton.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "UITableView+CollectionSkeleton.swift"; sourceTree = "<group>"; };
@@ -83,6 +128,9 @@
F56B94451FAE20AF0095662F /* PrepareForSkeletonProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PrepareForSkeletonProtocol.swift; sourceTree = "<group>"; };
F587FB83202CBFC8002DB5FE /* SkeletonFlow.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SkeletonFlow.swift; sourceTree = "<group>"; };
F587FB85202CEC95002DB5FE /* UIView+UIApplicationDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UIView+UIApplicationDelegate.swift"; sourceTree = "<group>"; };
F58A6E6A20A8C54100612494 /* RecoverableViewState.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RecoverableViewState.swift; sourceTree = "<group>"; };
F58A6E6D20A8C66300612494 /* Recoverable.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Recoverable.swift; sourceTree = "<group>"; };
F5D3FB0A209DCAA300003FCF /* SubviewsSkeletonables.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SubviewsSkeletonables.swift; sourceTree = "<group>"; };
F5F622401FAC6E31007C062A /* UIColor+Skeleton.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UIColor+Skeleton.swift"; sourceTree = "<group>"; };
F5F622421FAC81FD007C062A /* CALayer+Extensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "CALayer+Extensions.swift"; sourceTree = "<group>"; };
F5F622441FACA338007C062A /* Cell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Cell.swift; sourceTree = "<group>"; };
@@ -101,6 +149,13 @@
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
17DD0DFC207FB27400C56334 /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
);
runOnlyForDeploymentPostprocessing = 0;
};
52D6D9781BEFF229002C0205 /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
@@ -122,6 +177,8 @@
52D6D9721BEFF229002C0205 = {
isa = PBXGroup;
children = (
3B83EE4520C41488005178A4 /* ContainsMultilineText.swift */,
3B83EE4620C41488005178A4 /* UIView+IBInspectable.swift */,
F5F899F31FABA607002E8FDA /* Example */,
8933C7811EB5B7E0000D00A4 /* Sources */,
52D6D99C1BEFF38C002C0205 /* Configs */,
@@ -135,6 +192,7 @@
children = (
52D6D97C1BEFF229002C0205 /* SkeletonView.framework */,
F5F899F21FABA607002E8FDA /* SkeletonViewExample.app */,
17DD0E00207FB27400C56334 /* SkeletonView.framework */,
);
name = Products;
sourceTree = "<group>";
@@ -151,15 +209,17 @@
8933C7811EB5B7E0000D00A4 /* Sources */ = {
isa = PBXGroup;
children = (
F58A6E7020A8C87100612494 /* Recoverable */,
F5307E331FB1068500EE67C5 /* Collections */,
F5307E341FB106A500EE67C5 /* Extensions */,
F5307E351FB106BF00EE67C5 /* Helpers */,
F51DE1081FBF70A70037919A /* SkeletonAnimationBuilder.swift */,
F5307E2F1FB0EC9D00EE67C5 /* SkeletonDefaultConfig.swift */,
F587FB83202CBFC8002DB5FE /* SkeletonFlow.swift */,
F5307E2B1FAF6BC900EE67C5 /* SkeletonGradient.swift */,
F5F899E81FAB9D2B002E8FDA /* SkeletonLayer.swift */,
8933C7841EB5B820000D00A4 /* SkeletonView.swift */,
F587FB83202CBFC8002DB5FE /* SkeletonFlow.swift */,
F5D3FB0A209DCAA300003FCF /* SubviewsSkeletonables.swift */,
);
path = Sources;
sourceTree = "<group>";
@@ -167,20 +227,48 @@
DD7502721C68FC1B006590AF /* Frameworks */ = {
isa = PBXGroup;
children = (
AD2FAA261CD0B6D800659CF4 /* SkeletonView.plist */,
17DD0E1B207FB2C200C56334 /* SkeletonView-iOS.plist */,
17DD0E1A207FB2C200C56334 /* SkeletonView-tvOS.plist */,
);
name = Frameworks;
sourceTree = "<group>";
};
F51DF874206E94D300D23301 /* CollectionViews */ = {
isa = PBXGroup;
children = (
F54CF5E32024CEB000330B0D /* UICollectionView+CollectionSkeleton.swift */,
F5307E381FB1078E00EE67C5 /* SkeletonCollectionViewProtocols.swift */,
);
path = CollectionViews;
sourceTree = "<group>";
};
F51DF875206E94DA00D23301 /* TableViews */ = {
isa = PBXGroup;
children = (
F54CF5E22024CEAF00330B0D /* UITableView+CollectionSkeleton.swift */,
F5307E361FB1076E00EE67C5 /* SkeletonTableViewProtocols.swift */,
);
path = TableViews;
sourceTree = "<group>";
};
F51DF877206E950000D23301 /* Generics */ = {
isa = PBXGroup;
children = (
F51DF872206E91FB00D23301 /* GenericCollectionView.swift */,
F51DF870206E91B300D23301 /* SkeletonReusableCell.swift */,
);
path = Generics;
sourceTree = "<group>";
};
F5307E331FB1068500EE67C5 /* Collections */ = {
isa = PBXGroup;
children = (
F51DF877206E950000D23301 /* Generics */,
F51DF875206E94DA00D23301 /* TableViews */,
F51DF874206E94D300D23301 /* CollectionViews */,
F5F899EC1FAB9F04002E8FDA /* CollectionSkeletonProtocol.swift */,
F5F899EA1FAB9DA3002E8FDA /* SkeletonCollectionDataSource.swift */,
F5307E381FB1078E00EE67C5 /* SkeletonCollectionViewDataSource.swift */,
F5307E361FB1076E00EE67C5 /* SkeletonTableViewDataSource.swift */,
F54CF5E32024CEB000330B0D /* UICollectionView+CollectionSkeleton.swift */,
F54CF5E22024CEAF00330B0D /* UITableView+CollectionSkeleton.swift */,
F51DF878206E9F5500D23301 /* SkeletonCollectionDelegate.swift */,
F54CF5E12024CEAF00330B0D /* UIView+CollectionSkeleton.swift */,
);
path = Collections;
@@ -209,6 +297,15 @@
path = Helpers;
sourceTree = "<group>";
};
F58A6E7020A8C87100612494 /* Recoverable */ = {
isa = PBXGroup;
children = (
F58A6E6A20A8C54100612494 /* RecoverableViewState.swift */,
F58A6E6D20A8C66300612494 /* Recoverable.swift */,
);
path = Recoverable;
sourceTree = "<group>";
};
F5F899F31FABA607002E8FDA /* Example */ = {
isa = PBXGroup;
children = (
@@ -241,16 +338,45 @@
/* End PBXGroup section */
/* Begin PBXHeadersBuildPhase section */
17DD0DFD207FB27400C56334 /* Headers */ = {
isa = PBXHeadersBuildPhase;
buildActionMask = 2147483647;
files = (
8748240D20C6A88A00E92179 /* UIView+IBInspectable.swift in Headers */,
8748240E20C6A88E00E92179 /* ContainsMultilineText.swift in Headers */,
);
runOnlyForDeploymentPostprocessing = 0;
};
52D6D9791BEFF229002C0205 /* Headers */ = {
isa = PBXHeadersBuildPhase;
buildActionMask = 2147483647;
files = (
3B83EE4720C41488005178A4 /* ContainsMultilineText.swift in Headers */,
3B83EE4820C41488005178A4 /* UIView+IBInspectable.swift in Headers */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXHeadersBuildPhase section */
/* Begin PBXNativeTarget section */
17DD0DFF207FB27400C56334 /* SkeletonView-tvOS */ = {
isa = PBXNativeTarget;
buildConfigurationList = 17DD0E07207FB27400C56334 /* Build configuration list for PBXNativeTarget "SkeletonView-tvOS" */;
buildPhases = (
17DD0DFB207FB27400C56334 /* Sources */,
17DD0DFC207FB27400C56334 /* Frameworks */,
17DD0DFD207FB27400C56334 /* Headers */,
17DD0DFE207FB27400C56334 /* Resources */,
);
buildRules = (
);
dependencies = (
);
name = "SkeletonView-tvOS";
productName = "SkeletonView-tvOS";
productReference = 17DD0E00207FB27400C56334 /* SkeletonView.framework */;
productType = "com.apple.product-type.framework";
};
52D6D97B1BEFF229002C0205 /* SkeletonView-iOS */ = {
isa = PBXNativeTarget;
buildConfigurationList = 52D6D9901BEFF229002C0205 /* Build configuration list for PBXNativeTarget "SkeletonView-iOS" */;
@@ -295,9 +421,13 @@
isa = PBXProject;
attributes = {
LastSwiftUpdateCheck = 0910;
LastUpgradeCheck = 0920;
LastUpgradeCheck = 0930;
ORGANIZATIONNAME = SkeletonView;
TargetAttributes = {
17DD0DFF207FB27400C56334 = {
CreatedOnToolsVersion = 9.3;
ProvisioningStyle = Automatic;
};
52D6D97B1BEFF229002C0205 = {
CreatedOnToolsVersion = 7.1;
DevelopmentTeam = KWEMDK92F4;
@@ -324,12 +454,20 @@
projectRoot = "";
targets = (
52D6D97B1BEFF229002C0205 /* SkeletonView-iOS */,
17DD0DFF207FB27400C56334 /* SkeletonView-tvOS */,
F5F899F11FABA607002E8FDA /* SkeletonViewExample */,
);
};
/* End PBXProject section */
/* Begin PBXResourcesBuildPhase section */
17DD0DFE207FB27400C56334 /* Resources */ = {
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
files = (
);
runOnlyForDeploymentPostprocessing = 0;
};
52D6D97A1BEFF229002C0205 /* Resources */ = {
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
@@ -350,31 +488,72 @@
/* End PBXResourcesBuildPhase section */
/* Begin PBXSourcesBuildPhase section */
17DD0DFB207FB27400C56334 /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
17DD0E1F207FB32100C56334 /* RecursiveProtocol.swift in Sources */,
17DD0E1E207FB32100C56334 /* PrepareForSkeletonProtocol.swift in Sources */,
F51ED28520973CC9008B2434 /* SkeletonReusableCell.swift in Sources */,
17DD0E17207FB28F00C56334 /* SkeletonLayer.swift in Sources */,
17DD0E08207FB28900C56334 /* CollectionSkeletonProtocol.swift in Sources */,
F58A6E6C20A8C54100612494 /* RecoverableViewState.swift in Sources */,
17DD0E0B207FB28900C56334 /* SkeletonTableViewProtocols.swift in Sources */,
17DD0E0D207FB28900C56334 /* UITableView+CollectionSkeleton.swift in Sources */,
17DD0E0E207FB28900C56334 /* UIView+CollectionSkeleton.swift in Sources */,
F51ED28320973CBB008B2434 /* SkeletonCollectionDelegate.swift in Sources */,
F58A6E6F20A8C66300612494 /* Recoverable.swift in Sources */,
17DD0E18207FB28F00C56334 /* SkeletonView.swift in Sources */,
17DD0E19207FB28F00C56334 /* SkeletonFlow.swift in Sources */,
17DD0E09207FB28900C56334 /* SkeletonCollectionDataSource.swift in Sources */,
17DD0E0C207FB28900C56334 /* UICollectionView+CollectionSkeleton.swift in Sources */,
17DD0E13207FB28C00C56334 /* UIView+UIApplicationDelegate.swift in Sources */,
F5D3FB0C209DCAA300003FCF /* SubviewsSkeletonables.swift in Sources */,
17DD0E12207FB28C00C56334 /* UIView+IBInspectable.swift in Sources */,
17DD0E14207FB28F00C56334 /* SkeletonAnimationBuilder.swift in Sources */,
17DD0E11207FB28C00C56334 /* UIView+Frame.swift in Sources */,
17DD0E15207FB28F00C56334 /* SkeletonDefaultConfig.swift in Sources */,
17DD0E10207FB28C00C56334 /* UIColor+Skeleton.swift in Sources */,
F51ED28420973CC6008B2434 /* GenericCollectionView.swift in Sources */,
17DD0E0A207FB28900C56334 /* SkeletonCollectionViewProtocols.swift in Sources */,
17DD0E1C207FB32100C56334 /* AssociationPolicy.swift in Sources */,
17DD0E1D207FB32100C56334 /* ContainsMultilineText.swift in Sources */,
17DD0E0F207FB28C00C56334 /* CALayer+Extensions.swift in Sources */,
17DD0E16207FB28F00C56334 /* SkeletonGradient.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
52D6D9771BEFF229002C0205 /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
F5F899D01FAA6A4D002E8FDA /* UIView+IBInspectable.swift in Sources */,
F54CF5E42024CEB000330B0D /* UIView+CollectionSkeleton.swift in Sources */,
F5307E371FB1076E00EE67C5 /* SkeletonTableViewDataSource.swift in Sources */,
F5307E371FB1076E00EE67C5 /* SkeletonTableViewProtocols.swift in Sources */,
8933C7851EB5B820000D00A4 /* SkeletonView.swift in Sources */,
F5307E301FB0EC9D00EE67C5 /* SkeletonDefaultConfig.swift in Sources */,
F58A6E6B20A8C54100612494 /* RecoverableViewState.swift in Sources */,
F54CF5E52024CEB000330B0D /* UITableView+CollectionSkeleton.swift in Sources */,
F5307E321FB0F42F00EE67C5 /* RecursiveProtocol.swift in Sources */,
F5F622431FAC81FD007C062A /* CALayer+Extensions.swift in Sources */,
F5F899ED1FAB9F04002E8FDA /* CollectionSkeletonProtocol.swift in Sources */,
F58A6E6E20A8C66300612494 /* Recoverable.swift in Sources */,
F5307E2C1FAF6BC900EE67C5 /* SkeletonGradient.swift in Sources */,
F587FB86202CEC95002DB5FE /* UIView+UIApplicationDelegate.swift in Sources */,
F5F899EB1FAB9DA3002E8FDA /* SkeletonCollectionDataSource.swift in Sources */,
F5F622411FAC6E31007C062A /* UIColor+Skeleton.swift in Sources */,
F587FB84202CBFC8002DB5FE /* SkeletonFlow.swift in Sources */,
F5D3FB0B209DCAA300003FCF /* SubviewsSkeletonables.swift in Sources */,
F5F899D21FAB9630002E8FDA /* AssociationPolicy.swift in Sources */,
F54CF5E62024CEB000330B0D /* UICollectionView+CollectionSkeleton.swift in Sources */,
F56B94461FAE20AF0095662F /* PrepareForSkeletonProtocol.swift in Sources */,
F5307E391FB1078E00EE67C5 /* SkeletonCollectionViewDataSource.swift in Sources */,
F5307E391FB1078E00EE67C5 /* SkeletonCollectionViewProtocols.swift in Sources */,
F51DF873206E91FB00D23301 /* GenericCollectionView.swift in Sources */,
F5307E3B1FB123C100EE67C5 /* ContainsMultilineText.swift in Sources */,
F5F899E91FAB9D2B002E8FDA /* SkeletonLayer.swift in Sources */,
F5307E2E1FB0E5E400EE67C5 /* UIView+Frame.swift in Sources */,
F51DF871206E91B300D23301 /* SkeletonReusableCell.swift in Sources */,
F51DF879206E9F5500D23301 /* SkeletonCollectionDelegate.swift in Sources */,
F51DE1091FBF70A70037919A /* SkeletonAnimationBuilder.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
@@ -420,6 +599,70 @@
/* End PBXVariantGroup section */
/* Begin XCBuildConfiguration section */
17DD0E05207FB27400C56334 /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
CLANG_ANALYZER_NONNULL = YES;
CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
CLANG_ENABLE_OBJC_WEAK = YES;
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
CODE_SIGN_IDENTITY = "";
CODE_SIGN_STYLE = Automatic;
DEFINES_MODULE = YES;
DYLIB_COMPATIBILITY_VERSION = 1;
DYLIB_CURRENT_VERSION = 1;
DYLIB_INSTALL_NAME_BASE = "@rpath";
GCC_C_LANGUAGE_STANDARD = gnu11;
INFOPLIST_FILE = "Configs/SkeletonView-tvOS.plist";
INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
PRODUCT_BUNDLE_IDENTIFIER = "com.SkeletonView.SkeletonView-tvOS";
PRODUCT_NAME = SkeletonView;
SDKROOT = appletvos;
SKIP_INSTALL = YES;
SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG;
SWIFT_VERSION = 4.0;
TARGETED_DEVICE_FAMILY = 3;
TVOS_DEPLOYMENT_TARGET = 9.0;
};
name = Debug;
};
17DD0E06207FB27400C56334 /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
CLANG_ANALYZER_NONNULL = YES;
CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
CLANG_ENABLE_OBJC_WEAK = YES;
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
CODE_SIGN_IDENTITY = "";
CODE_SIGN_STYLE = Automatic;
DEFINES_MODULE = YES;
DYLIB_COMPATIBILITY_VERSION = 1;
DYLIB_CURRENT_VERSION = 1;
DYLIB_INSTALL_NAME_BASE = "@rpath";
GCC_C_LANGUAGE_STANDARD = gnu11;
INFOPLIST_FILE = "Configs/SkeletonView-tvOS.plist";
INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
PRODUCT_BUNDLE_IDENTIFIER = "com.SkeletonView.SkeletonView-tvOS";
PRODUCT_NAME = SkeletonView;
SDKROOT = appletvos;
SKIP_INSTALL = YES;
SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule";
SWIFT_VERSION = 4.0;
TARGETED_DEVICE_FAMILY = 3;
TVOS_DEPLOYMENT_TARGET = 9.0;
};
name = Release;
};
52D6D98E1BEFF229002C0205 /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
@@ -432,12 +675,14 @@
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_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_RANGE_LOOP_ANALYSIS = YES;
@@ -489,12 +734,14 @@
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_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_RANGE_LOOP_ANALYSIS = YES;
@@ -539,7 +786,7 @@
DYLIB_COMPATIBILITY_VERSION = 1;
DYLIB_CURRENT_VERSION = 1;
DYLIB_INSTALL_NAME_BASE = "@rpath";
INFOPLIST_FILE = Configs/SkeletonView.plist;
INFOPLIST_FILE = "Configs/SkeletonView-iOS.plist";
INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
IPHONEOS_DEPLOYMENT_TARGET = 9.0;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
@@ -564,7 +811,7 @@
DYLIB_COMPATIBILITY_VERSION = 1;
DYLIB_CURRENT_VERSION = 1;
DYLIB_INSTALL_NAME_BASE = "@rpath";
INFOPLIST_FILE = Configs/SkeletonView.plist;
INFOPLIST_FILE = "Configs/SkeletonView-iOS.plist";
INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
IPHONEOS_DEPLOYMENT_TARGET = 9.0;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
@@ -629,6 +876,15 @@
/* End XCBuildConfiguration section */
/* Begin XCConfigurationList section */
17DD0E07207FB27400C56334 /* Build configuration list for PBXNativeTarget "SkeletonView-tvOS" */ = {
isa = XCConfigurationList;
buildConfigurations = (
17DD0E05207FB27400C56334 /* Debug */,
17DD0E06207FB27400C56334 /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
52D6D9761BEFF229002C0205 /* Build configuration list for PBXProject "SkeletonView" */ = {
isa = XCConfigurationList;
buildConfigurations = (
@@ -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>
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "0920"
LastUpgradeVersion = "0930"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"
@@ -26,7 +26,6 @@
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
language = ""
shouldUseLaunchSchemeArgsEnv = "YES">
<Testables>
</Testables>
@@ -37,7 +36,6 @@
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
language = ""
launchStyle = "0"
useCustomWorkingDirectory = "NO"
ignoresPersistentStateOnLaunch = "NO"
@@ -0,0 +1,80 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "0930"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"
buildImplicitDependencies = "YES">
<BuildActionEntries>
<BuildActionEntry
buildForTesting = "YES"
buildForRunning = "YES"
buildForProfiling = "YES"
buildForArchiving = "YES"
buildForAnalyzing = "YES">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "17DD0DFF207FB27400C56334"
BuildableName = "SkeletonView.framework"
BlueprintName = "SkeletonView-tvOS"
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>
<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">
<MacroExpansion>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "17DD0DFF207FB27400C56334"
BuildableName = "SkeletonView.framework"
BlueprintName = "SkeletonView-tvOS"
ReferencedContainer = "container:SkeletonView.xcodeproj">
</BuildableReference>
</MacroExpansion>
<AdditionalOptions>
</AdditionalOptions>
</LaunchAction>
<ProfileAction
buildConfiguration = "Release"
shouldUseLaunchSchemeArgsEnv = "YES"
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">
</AnalyzeAction>
<ArchiveAction
buildConfiguration = "Release"
revealArchiveInOrganizer = "YES">
</ArchiveAction>
</Scheme>
@@ -8,25 +8,26 @@
import UIKit
enum DataSourceAssociatedKeys {
enum CollectionAssociatedKeys {
static var dummyDataSource = "dummyDataSource"
static var dummyDelegate = "dummyDelegate"
}
protocol CollectionSkeleton {
var skeletonDataSource: SkeletonCollectionDataSource? { get set }
var skeletonDelegate: SkeletonCollectionDelegate? { get set }
var estimatedNumberOfRows: Int { get }
func addDummyDataSource()
func removeDummyDataSource(reloadAfter: Bool)
func disableScrolling()
func enableScrolling()
func disableUserInteraction()
func enableUserInteraction()
}
extension CollectionSkeleton where Self: UIScrollView {
var estimatedNumberOfRows: Int { return 0 }
func addDummyDataSource() {}
func removeDummyDataSource(reloadAfter: Bool) {}
func disableScrolling() { isScrollEnabled = false }
func enableScrolling() { isScrollEnabled = true }
func disableUserInteraction() { isUserInteractionEnabled = false }
func enableUserInteraction() { isUserInteractionEnabled = true }
}
@@ -1,5 +1,5 @@
//
// SkeletonUICollectionViewDataSource.swift
// SkeletonCollectionViewProtocols.swift
// SkeletonView-iOS
//
// Created by Juanpe Catalán on 06/11/2017.
@@ -24,3 +24,5 @@ public extension SkeletonCollectionViewDataSource {
func numSections(in collectionSkeletonView: UICollectionView) -> Int { return 1 }
}
public protocol SkeletonCollectionViewDelegate: UICollectionViewDelegate { }
@@ -16,19 +16,27 @@ extension UICollectionView: CollectionSkeleton {
}
var skeletonDataSource: SkeletonCollectionDataSource? {
get { return objc_getAssociatedObject(self, &DataSourceAssociatedKeys.dummyDataSource) as? SkeletonCollectionDataSource }
get { return objc_getAssociatedObject(self, &CollectionAssociatedKeys.dummyDataSource) as? SkeletonCollectionDataSource }
set {
objc_setAssociatedObject(self, &DataSourceAssociatedKeys.dummyDataSource, newValue, AssociationPolicy.retain.objc)
objc_setAssociatedObject(self, &CollectionAssociatedKeys.dummyDataSource, newValue, AssociationPolicy.retain.objc)
self.dataSource = newValue
}
}
var skeletonDelegate: SkeletonCollectionDelegate? {
get { return objc_getAssociatedObject(self, &CollectionAssociatedKeys.dummyDelegate) as? SkeletonCollectionDelegate }
set {
objc_setAssociatedObject(self, &CollectionAssociatedKeys.dummyDelegate, newValue, AssociationPolicy.retain.objc)
self.delegate = newValue
}
}
func addDummyDataSource() {
guard let originalDataSource = self.dataSource as? SkeletonCollectionViewDataSource,
!(originalDataSource is SkeletonCollectionDataSource)
else { return }
let dataSource = SkeletonCollectionDataSource(collectionViewDataSource: originalDataSource, rowHeight: 0.0)
let dataSource = SkeletonCollectionDataSource(collectionViewDataSource: originalDataSource)
self.skeletonDataSource = dataSource
reloadData()
}
@@ -39,5 +47,8 @@ extension UICollectionView: CollectionSkeleton {
self.dataSource = dataSource.originalCollectionViewDataSource
if reloadAfter { self.reloadData() }
}
}
extension UICollectionView: GenericCollectionView {
var scrollView: UIScrollView { return self }
}
@@ -0,0 +1,13 @@
//
// GenericCollectionView.swift
// SkeletonView-iOS
//
// Created by Juanpe Catalán on 30/03/2018.
// Copyright © 2018 SkeletonView. All rights reserved.
//
import UIKit
protocol GenericCollectionView {
var scrollView: UIScrollView { get }
}
@@ -0,0 +1,15 @@
//
// SkeletonReusableCell.swift
// SkeletonView-iOS
//
// Created by Juanpe Catalán on 30/03/2018.
// Copyright © 2018 SkeletonView. All rights reserved.
//
import UIKit
public protocol SkeletonReusableCell { }
extension UITableViewCell: SkeletonReusableCell { }
extension UICollectionViewCell: SkeletonReusableCell { }
@@ -36,11 +36,10 @@ extension SkeletonCollectionDataSource: UITableViewDataSource {
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cellIdentifier = originalTableViewDataSource?.collectionSkeletonView(tableView, cellIdenfierForRowAt: indexPath) ?? ""
let cellIdentifier = originalTableViewDataSource?.collectionSkeletonView(tableView, cellIdentifierForRowAt: indexPath) ?? ""
let cell = tableView.dequeueReusableCell(withIdentifier: cellIdentifier, for: indexPath)
return cell
}
}
// MARK: - UICollectionViewDataSource
@@ -59,5 +58,4 @@ extension SkeletonCollectionDataSource: UICollectionViewDataSource {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: cellIdentifier, for: indexPath)
return cell
}
}
@@ -0,0 +1,26 @@
//
// SkeletonCollectionDelegate.swift
// SkeletonView-iOS
//
// Created by Juanpe Catalán on 30/03/2018.
// Copyright © 2018 SkeletonView. All rights reserved.
//
import UIKit
class SkeletonCollectionDelegate: NSObject {
weak var originalTableViewDelegate: SkeletonTableViewDelegate?
weak var originalCollectionViewDelegate: SkeletonCollectionViewDelegate?
init(tableViewDelegate: SkeletonTableViewDelegate? = nil, collectionViewDelegate: SkeletonCollectionViewDelegate? = nil) {
self.originalTableViewDelegate = tableViewDelegate
self.originalCollectionViewDelegate = collectionViewDelegate
}
}
// MARK: - UITableViewDataSource
extension SkeletonCollectionDelegate: UITableViewDelegate { }
// MARK: - UICollectionViewDataSource
extension SkeletonCollectionDelegate: UICollectionViewDelegate { }
@@ -1,5 +1,5 @@
//
// SkeletonUITableViewDataSource.swift
// SkeletonTableViewProtocols.swift
// SkeletonView-iOS
//
// Created by Juanpe Catalán on 06/11/2017.
@@ -11,7 +11,7 @@ import UIKit
public protocol SkeletonTableViewDataSource: UITableViewDataSource {
func numSections(in collectionSkeletonView: UITableView) -> Int
func collectionSkeletonView(_ skeletonView: UITableView, numberOfRowsInSection section: Int) -> Int
func collectionSkeletonView(_ skeletonView: UITableView, cellIdenfierForRowAt indexPath: IndexPath) -> ReusableCellIdentifier
func collectionSkeletonView(_ skeletonView: UITableView, cellIdentifierForRowAt indexPath: IndexPath) -> ReusableCellIdentifier
}
public extension SkeletonTableViewDataSource {
@@ -21,4 +21,14 @@ public extension SkeletonTableViewDataSource {
}
func numSections(in collectionSkeletonView: UITableView) -> Int { return 1 }
/// Keeping the misspelled version around until it can be deprecated
/// Right now, it just calls the new correctly spelled method and returns its result
@available(*, deprecated, renamed: "collectionSkeletonView(_:cellIdentifierForRowAt:)")
func collectionSkeletonView(_ skeletonView: UITableView, cellIdenfierForRowAt indexPath: IndexPath) -> ReusableCellIdentifier {
return collectionSkeletonView(skeletonView, cellIdentifierForRowAt: indexPath)
}
}
public protocol SkeletonTableViewDelegate: UITableViewDelegate {
}
@@ -15,13 +15,21 @@ extension UITableView: CollectionSkeleton {
}
var skeletonDataSource: SkeletonCollectionDataSource? {
get { return objc_getAssociatedObject(self, &DataSourceAssociatedKeys.dummyDataSource) as? SkeletonCollectionDataSource }
get { return objc_getAssociatedObject(self, &CollectionAssociatedKeys.dummyDataSource) as? SkeletonCollectionDataSource }
set {
objc_setAssociatedObject(self, &DataSourceAssociatedKeys.dummyDataSource, newValue, AssociationPolicy.retain.objc)
objc_setAssociatedObject(self, &CollectionAssociatedKeys.dummyDataSource, newValue, AssociationPolicy.retain.objc)
self.dataSource = newValue
}
}
var skeletonDelegate: SkeletonCollectionDelegate? {
get { return objc_getAssociatedObject(self, &CollectionAssociatedKeys.dummyDelegate) as? SkeletonCollectionDelegate }
set {
objc_setAssociatedObject(self, &CollectionAssociatedKeys.dummyDelegate, newValue, AssociationPolicy.retain.objc)
self.delegate = newValue
}
}
func addDummyDataSource() {
guard let originalDataSource = self.dataSource as? SkeletonTableViewDataSource,
!(originalDataSource is SkeletonCollectionDataSource)
@@ -38,7 +46,7 @@ extension UITableView: CollectionSkeleton {
self.dataSource = dataSource.originalTableViewDataSource
if reloadAfter { self.reloadData() }
}
private func restoreRowHeight() {
guard let dataSource = self.dataSource as? SkeletonCollectionDataSource else { return }
rowHeight = dataSource.rowHeight
@@ -50,3 +58,6 @@ extension UITableView: CollectionSkeleton {
return estimatedRowHeight
}
}
@@ -12,12 +12,12 @@ extension UIView {
func addDummyDataSourceIfNeeded() {
guard let collection = self as? CollectionSkeleton else { return }
collection.addDummyDataSource()
collection.disableScrolling()
collection.disableUserInteraction()
}
func removeDummyDataSourceIfNeeded(reloadAfter reload: Bool = true) {
guard let collection = self as? CollectionSkeleton else { return }
collection.removeDummyDataSource(reloadAfter: reload)
collection.enableScrolling()
collection.enableUserInteraction()
}
}
+2 -2
View File
@@ -36,7 +36,7 @@ extension CALayer {
return sublayers?.filter { $0.name == CALayer.skeletonSubLayersName } ?? [CALayer]()
}
func addMultilinesLayers(lines: Int, type: SkeletonType, lastLineFillPercent: Int) {
func addMultilinesLayers(lines: Int, type: SkeletonType, lastLineFillPercent: Int, multilineCornerRadius: Int) {
let numberOfSublayers = calculateNumLines(maxLines: lines)
for index in 0..<numberOfSublayers {
var width = bounds.width
@@ -45,7 +45,7 @@ extension CALayer {
width = width * CGFloat(lastLineFillPercent)/100;
}
let layer = SkeletonLayerFactory().makeMultilineLayer(withType: type, for: index, width: width)
let layer = SkeletonLayerFactory().makeMultilineLayer(withType: type, for: index, width: width, multilineCornerRadius: multilineCornerRadius)
addSublayer(layer)
}
}
+18 -2
View File
@@ -12,6 +12,18 @@ import UIKit
extension UIView {
var maxBoundsEstimated: CGRect {
if let parentStackView = (superview as? UIStackView) {
var origin: CGPoint = .zero
switch parentStackView.alignment {
case .center:
origin.x = maxWidthEstimated / 2
case .trailing:
origin.x = maxWidthEstimated
default:
break
}
return CGRect(origin: origin, size: maxSizeEstimated)
}
return CGRect(origin: .zero, size: maxSizeEstimated)
}
@@ -20,12 +32,12 @@ extension UIView {
}
var maxWidthEstimated: CGFloat {
let constraintsWidth = constraints.filter({ $0.firstAttribute == NSLayoutAttribute.width })
let constraintsWidth = nonContentSizeLayoutConstraints.filter({ $0.firstAttribute == NSLayoutAttribute.width })
return max(between: frame.size.width, andContantsOf: constraintsWidth)
}
var maxHeightEstimated: CGFloat {
let constraintsHeight = constraints.filter({ $0.firstAttribute == NSLayoutAttribute.height })
let constraintsHeight = nonContentSizeLayoutConstraints.filter({ $0.firstAttribute == NSLayoutAttribute.height })
return max(between: frame.size.height, andContantsOf: constraintsHeight)
}
@@ -37,4 +49,8 @@ extension UIView {
})
return max
}
var nonContentSizeLayoutConstraints: [NSLayoutConstraint] {
return constraints.filter({ "\(type(of: $0))" != "NSContentSizeLayoutConstraint" })
}
}
@@ -14,6 +14,7 @@ private enum AssociatedKeys {
static var skeletonLayer = "layer"
static var flowDelegate = "flowDelegate"
static var isSkeletonAnimated = "isSkeletonAnimated"
static var viewState = "viewState"
}
public extension UIView {
@@ -51,6 +52,11 @@ extension UIView {
set { objc_setAssociatedObject(self, &AssociatedKeys.status, newValue, AssociationPolicy.retain.objc) }
}
var viewState: RecoverableViewState? {
get { return objc_getAssociatedObject(self, &AssociatedKeys.viewState) as? RecoverableViewState }
set { objc_setAssociatedObject(self, &AssociatedKeys.viewState, newValue, AssociationPolicy.retain.objc) }
}
var skeletonIsAnimated: Bool! {
get { return objc_getAssociatedObject(self, &AssociatedKeys.isSkeletonAnimated) as? Bool ?? false }
set { objc_setAssociatedObject(self, &AssociatedKeys.isSkeletonAnimated, newValue, AssociationPolicy.retain.objc) }
+53 -29
View File
@@ -9,50 +9,74 @@
import UIKit
private enum AssociatedKeys {
static var lastLineFillingPercent = "lastLineFillingPercent"
static var lastLineFillingPercent = "lastLineFillingPercent"
static var multilineCornerRadius = "multilineCornerRadius"
}
protocol ContainsMultilineText {
var numLines: Int { get }
var lastLineFillingPercent: Int { get }
var numLines: Int { get }
var lastLineFillingPercent: Int { get }
var multilineCornerRadius: Int { get }
}
extension ContainsMultilineText {
var numLines: Int { return 0 }
var numLines: Int { return 0 }
}
public extension UILabel {
@IBInspectable
var lastLineFillPercent: Int {
get { return lastLineFillingPercent }
set { lastLineFillingPercent = min(newValue, 100) }
}
@IBInspectable
var lastLineFillPercent: Int {
get { return lastLineFillingPercent }
set { lastLineFillingPercent = min(newValue, 100) }
}
@IBInspectable
var linesCornerRadius: Int {
get { return multilineCornerRadius }
set { multilineCornerRadius = min(newValue, 10) }
}
}
public extension UITextView {
@IBInspectable
var lastLineFillPercent: Int {
get { return lastLineFillingPercent }
set { lastLineFillingPercent = min(newValue, 100) }
}
@IBInspectable
var lastLineFillPercent: Int {
get { return lastLineFillingPercent }
set { lastLineFillingPercent = min(newValue, 100) }
}
@IBInspectable
var linesCornerRadius: Int {
get { return multilineCornerRadius }
set { multilineCornerRadius = min(newValue, 10) }
}
}
extension UILabel: ContainsMultilineText {
var numLines: Int {
return numberOfLines
}
var lastLineFillingPercent: Int {
get { return objc_getAssociatedObject(self, &AssociatedKeys.lastLineFillingPercent) as? Int ?? SkeletonDefaultConfig.multilineLastLineFillPercent }
set { objc_setAssociatedObject(self, &AssociatedKeys.lastLineFillingPercent, newValue, AssociationPolicy.retain.objc) }
}
var numLines: Int {
return numberOfLines
}
var lastLineFillingPercent: Int {
get { return objc_getAssociatedObject(self, &AssociatedKeys.lastLineFillingPercent) as? Int ?? SkeletonDefaultConfig.multilineLastLineFillPercent }
set { objc_setAssociatedObject(self, &AssociatedKeys.lastLineFillingPercent, newValue, AssociationPolicy.retain.objc) }
}
var multilineCornerRadius: Int {
get { return objc_getAssociatedObject(self, &AssociatedKeys.multilineCornerRadius) as? Int ?? SkeletonDefaultConfig.multilineCornerRadius }
set { objc_setAssociatedObject(self, &AssociatedKeys.multilineCornerRadius, newValue, AssociationPolicy.retain.objc) }
}
}
extension UITextView: ContainsMultilineText {
var lastLineFillingPercent: Int {
get { return objc_getAssociatedObject(self, &AssociatedKeys.lastLineFillingPercent) as? Int ?? SkeletonDefaultConfig.multilineLastLineFillPercent }
set { objc_setAssociatedObject(self, &AssociatedKeys.lastLineFillingPercent, newValue, AssociationPolicy.retain.objc) }
}
var lastLineFillingPercent: Int {
get { return objc_getAssociatedObject(self, &AssociatedKeys.lastLineFillingPercent) as? Int ?? SkeletonDefaultConfig.multilineLastLineFillPercent }
set { objc_setAssociatedObject(self, &AssociatedKeys.lastLineFillingPercent, newValue, AssociationPolicy.retain.objc) }
}
var multilineCornerRadius: Int {
get { return objc_getAssociatedObject(self, &AssociatedKeys.multilineCornerRadius) as? Int ?? SkeletonDefaultConfig.multilineCornerRadius }
set { objc_setAssociatedObject(self, &AssociatedKeys.multilineCornerRadius, newValue, AssociationPolicy.retain.objc) }
}
}
@@ -14,14 +14,14 @@ protocol PrepareForSkeleton {
extension UILabel: PrepareForSkeleton {
func prepareViewForSkeleton() {
text = nil
text = " "
resignFirstResponder()
}
}
extension UITextView: PrepareForSkeleton {
func prepareViewForSkeleton() {
text = nil
text = " "
resignFirstResponder()
}
}
+69
View File
@@ -0,0 +1,69 @@
//
// Recoverable.swift
// SkeletonView
//
// Created by Juanpe Catalán on 13/05/2018.
// Copyright © 2018 SkeletonView. All rights reserved.
//
import UIKit
protocol Recoverable {
var viewState: RecoverableViewState? { get set }
func saveViewState()
func recoverViewState(forced: Bool)
}
extension UIView: Recoverable {
@objc func saveViewState() {
viewState = RecoverableViewState(view: self)
}
@objc func recoverViewState(forced: Bool) {
guard let safeViewState = viewState else { return }
layer.cornerRadius = safeViewState.cornerRadius
layer.masksToBounds = safeViewState.clipToBounds
if safeViewState.backgroundColor != backgroundColor || forced {
backgroundColor = safeViewState.backgroundColor
}
}
}
extension UILabel {
override func saveViewState() {
super.saveViewState()
viewState?.text = text
}
override func recoverViewState(forced: Bool) {
super.recoverViewState(forced: forced)
text = text == " " || forced ? viewState?.text : text
}
}
extension UITextView {
override func saveViewState() {
super.saveViewState()
viewState?.text = text
}
override func recoverViewState(forced: Bool) {
super.recoverViewState(forced: forced)
text = text == " " || forced ? viewState?.text : text
}
}
extension UIImageView {
override func saveViewState() {
super.saveViewState()
viewState?.image = image
}
override func recoverViewState(forced: Bool) {
super.recoverViewState(forced: forced)
image = image == nil || forced ? viewState?.image : image
}
}
@@ -0,0 +1,29 @@
//
// RecoverableViewState.swift
// SkeletonView
//
// Created by Juanpe Catalán on 13/05/2018.
// Copyright © 2018 SkeletonView. All rights reserved.
//
import UIKit
struct RecoverableViewState {
var backgroundColor: UIColor?
var cornerRadius: CGFloat
var clipToBounds: Bool
// UI text
var text: String?
// UI image
var image: UIImage?
}
extension RecoverableViewState {
init(view: UIView) {
self.backgroundColor = view.backgroundColor
self.clipToBounds = view.layer.masksToBounds
self.cornerRadius = view.layer.cornerRadius
}
}
+12 -10
View File
@@ -9,14 +9,16 @@
import UIKit
public enum SkeletonDefaultConfig {
public static let tintColor = UIColor.clouds
public static let gradient = SkeletonGradient(baseColor: tintColor)
public static let multilineHeight: CGFloat = 15
public static let multilineSpacing: CGFloat = 10
public static let multilineLastLineFillPercent = 70
public static let tintColor = UIColor.clouds
public static let gradient = SkeletonGradient(baseColor: tintColor)
public static let multilineHeight: CGFloat = 15
public static let multilineSpacing: CGFloat = 10
public static let multilineLastLineFillPercent = 70
public static let multilineCornerRadius = 0
}
+6 -2
View File
@@ -14,12 +14,16 @@ class SkeletonLayerFactory {
return SkeletonLayer(withType: type, usingColors: colors, andSkeletonHolder: holder)
}
func makeMultilineLayer(withType type: SkeletonType, for index: Int, width: CGFloat) -> CALayer {
func makeMultilineLayer(withType type: SkeletonType, for index: Int, width: CGFloat, multilineCornerRadius: Int) -> CALayer {
let spaceRequiredForEachLine = SkeletonDefaultConfig.multilineHeight + SkeletonDefaultConfig.multilineSpacing
let layer = type.layer
layer.anchorPoint = .zero
layer.name = CALayer.skeletonSubLayersName
layer.frame = CGRect(x: 0.0, y: CGFloat(index) * spaceRequiredForEachLine, width: width, height: SkeletonDefaultConfig.multilineHeight)
layer.cornerRadius = CGFloat(multilineCornerRadius)
layer.masksToBounds = true
return layer
}
}
@@ -77,7 +81,7 @@ struct SkeletonLayer {
func addMultilinesIfNeeded() {
guard let multiLineView = holder as? ContainsMultilineText else { return }
maskLayer.addMultilinesLayers(lines: multiLineView.numLines, type: type, lastLineFillPercent: multiLineView.lastLineFillingPercent)
maskLayer.addMultilinesLayers(lines: multiLineView.numLines, type: type, lastLineFillPercent: multiLineView.lastLineFillingPercent, multilineCornerRadius: multiLineView.multilineCornerRadius)
}
}
+5 -38
View File
@@ -51,17 +51,19 @@ public extension UIView {
extension UIView {
func showSkeleton(withType type: SkeletonType = .solid, usingColors colors: [UIColor], animated: Bool = false, animation: SkeletonLayerAnimation? = nil) {
skeletonIsAnimated = animated
flowDelegate = SkeletonFlowHandler()
flowDelegate?.willBeginShowingSkeletons(withRootView: self)
recursiveShowSkeleton(withType: type, usingColors: colors, animated: animated, animation: animation)
}
fileprivate func recursiveShowSkeleton(withType type: SkeletonType = .solid, usingColors colors: [UIColor], animated: Bool = false, animation: SkeletonLayerAnimation? = nil) {
fileprivate func recursiveShowSkeleton(withType type: SkeletonType, usingColors colors: [UIColor], animated: Bool, animation: SkeletonLayerAnimation?) {
addDummyDataSourceIfNeeded()
recursiveSearch(inArray: subviewsSkeletonables,
leafBlock: {
guard !isSkeletonActive else { return }
isUserInteractionEnabled = false
saveViewState()
(self as? PrepareForSkeleton)?.prepareViewForSkeleton()
addSkeletonLayer(withType: type, usingColors: colors, animated: animated, animation: animation)
}) {
@@ -69,11 +71,12 @@ extension UIView {
}
}
fileprivate func recursiveHideSkeleton(reloadDataAfter reload: Bool = true) {
fileprivate func recursiveHideSkeleton(reloadDataAfter reload: Bool) {
removeDummyDataSourceIfNeeded()
isUserInteractionEnabled = true
recursiveSearch(inArray: subviewsSkeletonables,
leafBlock: {
recoverViewState(forced: false)
removeSkeletonLayer()
}, recursiveBlock: {
$0.recursiveHideSkeleton(reloadDataAfter: reload)
@@ -95,42 +98,6 @@ extension UIView {
}
}
extension UIView {
@objc var subviewsSkeletonables: [UIView] {
return subviews.filter { $0.isSkeletonable }
}
}
extension UITableView {
override var subviewsSkeletonables: [UIView] {
return visibleCells.filter { $0.isSkeletonable }
}
}
extension UITableViewCell {
override var subviewsSkeletonables: [UIView] {
return contentView.subviews.filter { $0.isSkeletonable }
}
}
extension UICollectionView {
override var subviewsSkeletonables: [UIView] {
return subviews.filter { $0.isSkeletonable }
}
}
extension UICollectionViewCell {
override var subviewsSkeletonables: [UIView] {
return contentView.subviews.filter { $0.isSkeletonable }
}
}
extension UIStackView {
override var subviewsSkeletonables: [UIView] {
return arrangedSubviews.filter { $0.isSkeletonable }
}
}
extension UIView {
func addSkeletonLayer(withType type: SkeletonType, usingColors colors: [UIColor], gradientDirection direction: GradientDirection? = nil, animated: Bool, animation: SkeletonLayerAnimation? = nil) {
+45
View File
@@ -0,0 +1,45 @@
//
// SubviewsSkeletonables.swift
// SkeletonView
//
// Created by Juanpe Catalán on 05/05/2018.
// Copyright © 2018 SkeletonView. All rights reserved.
//
import UIKit
extension UIView {
@objc var subviewsSkeletonables: [UIView] {
return subviews.filter { $0.isSkeletonable }
}
}
extension UITableView {
override var subviewsSkeletonables: [UIView] {
return visibleCells.filter { $0.isSkeletonable }
}
}
extension UITableViewCell {
override var subviewsSkeletonables: [UIView] {
return contentView.subviews.filter { $0.isSkeletonable }
}
}
extension UICollectionView {
override var subviewsSkeletonables: [UIView] {
return subviews.filter { $0.isSkeletonable }
}
}
extension UICollectionViewCell {
override var subviewsSkeletonables: [UIView] {
return contentView.subviews.filter { $0.isSkeletonable }
}
}
extension UIStackView {
override var subviewsSkeletonables: [UIView] {
return arrangedSubviews.filter { $0.isSkeletonable }
}
}