Compare commits

...

699 Commits

Author SHA1 Message Date
Guglielmo Faglioni 795fd7d0f1 Fallback to non-skeleton Header (#416)
Sometimes my collectionview's header doesn't need to be 'skeletoned' while the content does.  

When  collectionSkeletonView(_ skeletonView: UICollectionView, supplementaryViewIdentifierOfKind: String, at indexPath: IndexPath) -> ReusableCellIdentifier? returns nil, it's best if we fallback to the non-skeleton header.
2021-07-02 16:05:16 +02:00
Juanpe Catalán 6cc6f5aa80 Update README.md 2021-06-29 11:08:52 +02:00
Juanpe Catalán 3ecc3c3b39 Update README.md 2021-06-29 11:06:05 +02:00
Juanpe Catalán 511535921f Update README.md 2021-06-29 11:05:20 +02:00
Juanpe a6d1ae0b95 Bump version 1.20.0 2021-06-28 15:47:21 +00:00
Juanpe Catalán 220fc4016d Fixed background color warning in UITableViewHeaderFooterView (#417) 2021-06-28 17:45:59 +02:00
Juanpe Catalán ee94dd8aec Update README.md 2021-06-24 16:00:38 +02:00
Juanpe Catalán be2aa4f4ab create CD workflow 2021-06-24 13:26:25 +02:00
Juanpe 55f16d9d51 Bump version 1.19.0 2021-06-24 06:21:47 +00:00
Nemanja Markicevic 9fccaf4fbd Add prepareCellForSkeleton for UITableView and UICollectionView (#415)
* Add prepareCellForSkeleton for UITableView and UICollectionView

* Update README to add collectionSkeletonView(_ skeletonView: UICollectionView, prepareCellForSkeleton cell: UICollectionViewCell, at indexPath: IndexPath)

* Update README.md

Co-authored-by: Juanpe Catalán <juanpecm@gmail.com>
2021-06-24 08:09:36 +02:00
Juanpe Catalán 58959a5f9b Add both skeletonCellForRowAt and skeletonCellForItemAt methods (#414)
* add skeletonCellForIndexPath

* included in README file the new data source methods

* fix typo in the README file
2021-06-23 17:49:31 +02:00
Juanpe Catalán 5838f7881b update README 2021-06-22 13:09:46 +02:00
Juanpe 41173471f6 Bump version 1.18.0 2021-06-22 10:59:04 +00:00
Juanpe Catalán 12e5688b31 Delay the presentation of the skeletons (#411) 2021-06-22 12:54:33 +02:00
Juanpe Catalán 816b2965ff Improved the algorithm that calculates the number of skeleton lines for UITextViews (#410) 2021-06-22 11:23:08 +02:00
Juanpe e12e4a0fd1 Bump version 1.17.2 2021-06-11 20:24:41 +00:00
Richard L Zarth III 6f78f5c378 Replace SkeletonCollectionDataSource.automaticNumberOfRows with UITableView.automaticNumberOfSkeletonRows and UICollectionView.automaticNumberOfSkeletonItems (#409) 2021-06-11 22:21:27 +02:00
Juanpe Catalán c8fdd6998d fix bug remove constraints wrongly (#406)
* check if the constraints were modified and then restore the original

* identify constraints added by SkeletonView

* move removal of skeleton constraint to recoverable protocol implementation
2021-06-11 11:33:23 +02:00
Juanpe Catalán 134463e529 Update README.md 2021-06-10 19:40:41 +02:00
Juanpe ee59239c59 Bump version 1.17.1 2021-06-10 17:36:12 +00:00
Juanpe Catalán f1e61aa9c0 fix typo isUserInteractionDisabledWhenSkeletonIsActive (#404)
* fix typo

* update README
2021-06-10 19:34:18 +02:00
Juanpe 135778aa1a Bump version 1.17.0 2021-06-10 17:24:00 +00:00
Juanpe Catalán e8d5eb61d8 update README file 2021-06-10 19:19:29 +02:00
Juanpe Catalán c2a029ed51 create disableWhenSkeletonIsActive property 2021-06-10 19:14:05 +02:00
Sam Harrison a1c8276980 Make CI action build targets, not just clean (#403) 2021-06-10 19:01:01 +02:00
Sam Harrison e9ac3a5ab3 Fix TableViewCell skeleton not being removed & automaticNumberOfRows reference (#402)
* Change TableView subviewsToSkeleton to all subviews

* Fix reference to automaticNumberOfRows from pr #401
2021-06-10 18:59:21 +02:00
Richard L Zarth III fb83a62f7b Add SkeletonCollectionDataSource.automaticNumberOfRows Constant (#401)
* Add automaticNumberOfRows constant to SkeletonCollectionDataSource.

* Update tableView(_:numberOfRowsInSection:) and collectionView(_:numberOfItemsInSection:) to use the new automaticNumberOfRows constant.

* Update README.

* Update README.md

Add an **IMPORTANT!** header to the automaticNumberOfRows mention in the README.

Co-authored-by: Juanpe Catalán <juanpecm@gmail.com>

Co-authored-by: Juanpe Catalán <juanpecm@gmail.com>
2021-06-09 18:45:44 +02:00
Juanpe Catalán 12521c1d87 update Info.plist 2021-05-31 17:20:11 +02:00
Juanpe c266035888 Bump version 1.16.0 2021-05-31 15:09:22 +00:00
Juanpe Catalán 74b5172ea5 use the right delegate method for footers (#394) 2021-05-11 19:15:41 +02:00
Michael Henry 318e629d04 update the UILabel placeholder to use an empty space #388 (#389) 2021-05-11 19:02:41 +02:00
StasMalinovsky 62193db76f Added estimated number of rows for UICollectionViewFlowLayout with vertical scroll direction. (#385) 2021-04-30 13:26:25 +02:00
Juanpe 19e7866d3d Bump version 1.15.0 2021-04-13 06:50:02 +00:00
Corey Davis 36668f450b [BUG] Fix crashing on NaN value (#382) 2021-04-12 18:25:43 +02:00
Michael Henry 1bdb3b9c72 fix #383 UITableViewAlertForLayoutOutsideViewHierarchy warning (#384) 2021-04-12 11:09:48 +02:00
Juanpe 6c4e9091a7 Bump version 1.14.0 2021-04-08 10:03:16 +00:00
Alex Lykesas 61a6efbc7b UnSwizzle methods when SkeletonView is hidden (#381)
* Add InputAccessoryView to textField

* Add method to removeOnce Add unSwizzleMethods that are called when recursiveHideSkeleton

Co-authored-by: Alexandros Lykesas <alexandros.lykesas@untis.at>
2021-04-08 11:59:32 +02:00
Juanpe Catalán 4143a6065c feat: add workaround to simulate the content of labels contained in a stack view (#380) 2021-03-29 18:00:34 +02:00
Juanpe Catalán f3baeedc14 Update pod_lib_lint.yml 2021-02-15 15:44:10 +01:00
Juanpe Catalán 29f7d8fd6a create pod lib lint workflow 2021-02-15 15:39:32 +01:00
Juanpe Catalán 83e1600a73 remove useless code from release workflow 2021-02-15 15:34:26 +01:00
Juanpe Catalán 450cecbd9c update release workflow 2021-02-15 15:33:44 +01:00
Juanpe 1676f8720a Bump version 1.13.0 2021-02-15 14:23:42 +00:00
Juanpe Catalán 32ab6d3852 unify jobs 2021-02-15 15:19:09 +01:00
Josh Brunner 7ce5e0623a Fixed a deprecation warning where the AssociatedObjects protocol was inheriting from class instead of AnyObject per Xcode's suggestion (#376) 2021-02-08 23:06:32 +01:00
Juanpe Catalán f0c7d2d6a0 modify release workflow steps 2021-02-08 10:11:52 +01:00
Juanpe Catalán 26476fd3ed bump version 1.12.1 2021-02-08 10:07:11 +01:00
Juanpe Catalán f0c2cf4ab4 Update stale.yml 2021-02-08 09:53:37 +01:00
Juanpe Catalán cadf8bb136 Update stale.yml 2021-02-08 09:45:48 +01:00
Juanpe Catalán 91c8f953ca Merge branch 'main' of https://github.com/Juanpe/SkeletonView into main 2021-02-08 09:41:38 +01:00
Juanpe Catalán 0a91aebf2a fix: recover isUserInteractionEnabled value when the skeleton disappears (#375) 2021-02-08 09:41:33 +01:00
Juanpe Catalán 7d8a057b64 fix: recover isUserInteractionEnabled value when the skeleton disappears (#375) 2021-02-08 09:38:34 +01:00
Juanpe Catalán 06f7d240ff update all “develop” references (#374) 2021-02-05 21:51:24 +01:00
Juanpe Catalán c4c725eea3 revert change in "change-template" 2021-02-03 14:21:27 +01:00
Juanpe Catalán cc9dbdb499 update "change-template" in release-drafter.yml 2021-02-03 14:20:16 +01:00
Keshavamurthy GN c6dfcf9c1a Fixed: UITextField placeholder text is visible while skeleton is showing (#356)
* Fixed: UITextField placeholder text is visible while skeleton is showing #345
Setting placeholder to nil on prepareViewForSkeleton() method
Created RecoverableTextFieldState, which has textColor and placeholder properties, Added UITextField extension in Recoverable.swift, setting the values on recoverViewStage 'forced' is true

* Update PrepareForSkeletonProtocol.swift
2021-02-03 14:18:30 +01:00
Juanpe Catalán dd7e5243bd fix syntax in release.yml 2021-02-03 14:04:44 +01:00
Juanpe Catalán 7e002ddce0 update release-drafter config considering a feature as minor 2021-02-03 14:00:43 +01:00
Juanpe Catalán 6dcfb325dc remove SwiftLint's warnings (#372) 2021-02-03 09:21:14 +01:00
Juanpe Catalán 7b5739295a Remove CHANGELOG condition in Dangerfile 2021-02-03 09:04:59 +01:00
Juanpe Catalán 2e1808ea50 fix: remove temp height constraints after hiding the skeleton (#371) 2021-02-03 09:03:40 +01:00
Juanpe Catalán cec3aeb781 refactor release.yml file 2021-02-02 08:59:26 +01:00
Juanpe Catalán b16400294d update commit job 2021-02-01 19:44:05 +01:00
Juanpe Catalán abb8ea55f6 remove scripts folder 2021-02-01 19:39:00 +01:00
Juanpe Catalán c833da20f8 Merge branch 'develop' of https://github.com/Juanpe/SkeletonView into develop 2021-02-01 19:36:17 +01:00
Juanpe Catalán 292fadf5b0 bump version 1.12.0 2021-02-01 19:36:06 +01:00
Juanpe Catalán 2ce041901c remove pod lib lint 2021-02-01 19:35:10 +01:00
Juanpe Catalán 961cc77661 update order release workflow 2021-02-01 19:33:23 +01:00
Juanpe Catalán 11b623fb13 Update release.yml 2021-02-01 19:23:48 +01:00
Juanpe Catalán 4899802b01 Update release.yml 2021-02-01 19:14:29 +01:00
Juanpe Catalán 0dfe1ca43b Update release.yml 2021-02-01 19:11:00 +01:00
Juanpe Catalán 499d01c232 Update release.yml 2021-02-01 19:07:22 +01:00
Juanpe Catalán f8f368ab8a Update release.yml 2021-02-01 19:02:14 +01:00
Juanpe Catalán 023a57a763 Merge branch 'develop' of https://github.com/Juanpe/SkeletonView into develop 2021-02-01 19:00:58 +01:00
Juanpe Catalán d426a0916e create new lane to bump podspec version 2021-02-01 19:00:51 +01:00
Juanpe Catalán 611c248c51 Update release.yml 2021-02-01 18:52:49 +01:00
Juanpe Catalán 6f20c34d56 Update release.yml 2021-02-01 18:40:01 +01:00
Juanpe Catalán be25b572f8 Update release.yml 2021-02-01 18:27:51 +01:00
Juanpe Catalán 3c67812453 Update main.yml 2021-02-01 18:23:39 +01:00
Juanpe Catalán 0431eb2a7d Update release.yml 2021-02-01 18:20:55 +01:00
Juanpe Catalán fa0b95d923 Update release-drafter.yml 2021-02-01 18:18:15 +01:00
Juanpe Catalán 523cd1c657 Create release_notes.yml 2021-02-01 18:14:27 +01:00
Juanpe Catalán 29e65c70d3 Create release-drafter.yml 2021-02-01 18:13:12 +01:00
Juanpe Catalán 4b7360a011 Update release.yml 2021-02-01 18:12:11 +01:00
Juanpe Catalán 2753c54216 feat: add script to update version 2021-02-01 18:10:22 +01:00
Juanpe Catalán c7b3bc67be Update release.yml 2021-02-01 18:08:03 +01:00
Juanpe Catalán 0c8bbf1fed Update release.yml 2021-02-01 17:58:55 +01:00
Juanpe Catalán 2e99bc98bf Update release.yml 2021-02-01 17:57:43 +01:00
Juanpe Catalán d5d52d1416 Update release.yml 2021-02-01 17:41:18 +01:00
Juanpe Catalán 91c7735d0c Create release.yml 2021-02-01 15:27:24 +01:00
Juanpe Catalán 18c5c1deb8 feat: remove useless corner radius constraint (#369)
* remove useless corner radius constraint

* update CHANGELOG
2021-02-01 12:13:48 +01:00
Juanpe Catalán 1ecfa31743 feat: add more templates to create issues (#368) 2021-01-31 17:11:46 +01:00
Juanpe Catalán 82b70ea1ee Update validations.yml 2021-01-31 14:20:25 +01:00
Juanpe Catalán d8ee06f1c5 Update validations.yml 2021-01-31 13:44:08 +01:00
Juanpe Catalán 13ce7426dd Update validations.yml 2021-01-31 13:36:38 +01:00
Juanpe Catalán 7d5039536c Update validations.yml 2021-01-31 13:28:12 +01:00
Juanpe Catalán b7a7731784 Update validations.yml 2021-01-31 13:22:01 +01:00
Juanpe Catalán 07f92d098a Update validations.yml 2021-01-31 13:06:33 +01:00
Juanpe Catalán f45405c9d5 Update validations.yml 2021-01-31 12:58:44 +01:00
Juanpe Catalán 768354ca35 Update validations.yml 2021-01-31 12:27:12 +01:00
Juanpe Catalán d5819763a1 Update validations.yml 2021-01-31 12:26:05 +01:00
Juanpe Catalán a73fc993aa Update validations.yml 2021-01-31 12:07:18 +01:00
Juanpe Catalán 0d027b5927 Update validations.yml 2021-01-31 11:50:44 +01:00
Juanpe Catalán bc482f58b3 Update and rename Validations.yml to validations.yml 2021-01-31 11:11:17 +01:00
Juanpe Catalán 78e941e01c Update and rename PR.yml to Validations.yml 2021-01-30 21:25:25 +01:00
Juanpe Catalán 7282008606 Update PR.yml 2021-01-28 10:40:24 +01:00
Juanpe Catalán 52d657faa0 Update PR.yml 2021-01-28 09:50:52 +01:00
Juanpe Catalán cba096becf Update PR.yml 2021-01-28 09:46:17 +01:00
Juanpe Catalán c095f49028 Update PR.yml 2021-01-28 09:34:44 +01:00
Juanpe Catalán 89e292c11b fix: broken workflow link 2021-01-27 17:29:40 +01:00
Juanpe Catalán 5089295771 feat: update CI badge in README files 2021-01-27 17:27:10 +01:00
Juanpe Catalán 39971af22d feat: update Github actions 2021-01-27 17:25:23 +01:00
Juanpe Catalán 81d182259d feat: refactor CI workflows 2021-01-27 17:24:16 +01:00
Juanpe Catalán 1d82545a3d Merge pull request #360 from Juanpe/test_action 2021-01-26 18:06:59 +01:00
Juanpe Catalán 9086d7e874 use GITHUB TOKEN 2021-01-26 18:02:43 +01:00
Juanpe Catalán 666ebdf472 fix syntax error 2021-01-26 17:56:53 +01:00
Juanpe Catalán 5a5d7b66e7 update action trigger 2021-01-26 17:54:50 +01:00
Juanpe Catalán 78f2bbe9f1 udpate danger action 2021-01-26 16:59:22 +01:00
Juanpe Catalán c7133a6711 Merge pull request #357 from keshavamurthy1/fix/refactored_removed_unused_code
Removed duplicate code in SkeletonCollectionDelegate
2021-01-22 14:26:54 +01:00
Juanpe Catalán aee5cdfd8f Merge pull request #359 from keshavamurthy1/fix/skeletonview_respecting_font_height_than_view_height
Fixed: SkeletonView respecting Font's height, rather than the `UIView…
2021-01-22 14:23:12 +01:00
Juanpe Catalán 638c535767 Update checks.yml 2021-01-22 13:36:26 +01:00
Juanpe Catalán 782dd45b33 Update checks.yml 2021-01-22 13:33:38 +01:00
Keshavamurthy GN 073baa6483 Update UIView+Frame.swift 2021-01-22 17:45:36 +05:30
Keshavamurthy GN a26dbf7c89 Reverted the iOS 10 check as per the review comment 2021-01-22 17:28:32 +05:30
Juanpe Catalán 7ebde2b030 Update checks.yml 2021-01-22 12:51:51 +01:00
Keshavamurthy GN 4009ed2b1e Fixed: SkeletonView respecting Font's height, rather than the UIView actual height #353
Using Label height from the HeightConstraint if there is any instead of the Label Font line height
if no HeightConstraint set, will be using SkeletonAppearance.default.multilineHeight as it was before
2021-01-21 12:52:17 +05:30
Keshavamurthy GN a246c16cfe Removed duplicate code in SkeletonCollectionDelegate
Removed check for older versions in UIView+Frame
Removed return on single lines (Implicit Returns)
2021-01-18 18:41:23 +05:30
Juanpe Catalán ef8e4578d7 Update CHANGELOG.md 2020-10-29 14:27:42 +01:00
Juanpe Catalán 46e2180c4b docs: bump version 1.11.0 and update CHANGELOG file 2020-10-29 14:20:20 +01:00
Juanpe Catalán f32c420165 Merge pull request #344 from Juanpe/feature/resize_labels_based_on_number_of_lines
Feature/resize labels based on number of lines
2020-10-29 14:17:57 +01:00
Juanpe Catalán 0ca38d8ea1 doc: update CHANGELOG file 2020-10-29 14:13:16 +01:00
Juanpe Catalán 9ed337ba53 Merge branch 'develop' of https://github.com/Juanpe/SkeletonView into feature/resize_labels_based_on_number_of_lines 2020-10-29 14:12:09 +01:00
Juanpe Catalán 932a1f6e6e Merge pull request #340 from yzhao198/fixMultiLineAndPadding
Fix incorrect padding and multiline layer frame calculation
2020-10-26 08:11:37 +01:00
Yang Zhao 5cd08fb77c Updated CHANGELOG.md. 2020-10-25 18:40:02 -06:00
Yang Zhao f7cb021a93 Fixed incorrect padding, and incorrect multiline layer frame calculation. 2020-10-25 18:32:31 -06:00
Juanpe Catalán 4fbfbeca55 feat: update layout to desired height 2020-10-22 00:48:23 +02:00
Juanpe Catalán c92461ae5c fix: shows at least one line 2020-10-21 14:35:48 +02:00
Juanpe Catalán efed2e7f32 Merge pull request #341 from Juanpe/feature/animation_autoreverses
Support autoreverses in gradient animations
2020-10-19 11:52:16 +02:00
Juanpe Catalán 52cbd3ae2c doc: Include PR #341 in the CHANGELOG file 2020-10-19 11:49:08 +02:00
Juanpe Catalán a349f7174c feat: support autoreverses animations for gradients 2020-10-19 11:41:57 +02:00
Juanpe Catalán a58c97eb1a Update CHANGELOG.md 2020-10-19 10:36:48 +02:00
Juanpe Catalán 8e6fea2de3 Update CHANGELOG.md 2020-10-19 10:36:33 +02:00
Juanpe Catalán bf417d6bf8 Update CHANGELOG.md 2020-10-19 10:36:16 +02:00
Juanpe Catalán c3295531be Merge pull request #339 from mohn93/develop
Add  hiddenWhenSkeletonIsActive property
2020-10-19 10:34:43 +02:00
Mohanned Binmiskeen a87f7302c0 Documentation for isHiddenWhenSkeletonIsActive 2020-10-16 22:46:20 +02:00
Juanpe Catalán 5e22f38454 Upgrade Danger version 3.5.0 2020-10-07 13:07:29 +02:00
Mohanned Binmiskeen 0dbdb9064d Add hiddenWhenSkeletonIsActive property which will hide the view when the skeleton animation starts 2020-10-06 16:03:55 +02:00
Juanpe Catalán c8efc4ccb1 doc: Update CHANGELOG 2020-10-02 17:33:48 +02:00
Juanpe Catalán 01733b358c bump version 1.10.0 2020-10-02 17:15:47 +02:00
Juanpe Catalán 027143499c Merge pull request #337 from Juanpe/feature/support_RTL
RTL support
2020-10-02 17:14:24 +02:00
Juanpe Catalán ae1b5ee790 fix: add condition for tvOS 10.0 2020-10-02 17:08:25 +02:00
Juanpe Catalán 0c0a0ea451 doc: Update CHANGELOG file 2020-10-02 17:01:40 +02:00
Juanpe Catalán 8d090904b4 feat: support RTL 2020-10-02 16:47:00 +02:00
Juanpe Catalán 8d00d5fa16 Merge pull request #336 from Juanpe/fix/replacing_text_wrongly_after_hide
Not replace text when the skeleton disappears
2020-10-02 14:00:28 +02:00
Juanpe Catalán f2bc1cab27 doc: update CHANGELOG file 2020-10-02 13:39:20 +02:00
Juanpe Catalán 83b99f16b1 fix: modified how the skeleton save and restore the original view state of the elements 2020-10-02 13:23:26 +02:00
Juanpe Catalán 7a2cc5d51d Update .swiftlint.yml 2020-09-15 12:28:53 +02:00
Juanpe Catalán c50547ef5f Update README.md 2020-09-15 10:19:36 +02:00
Juanpe Catalán 0a7f80e6d0 Update README.md 2020-09-15 10:17:02 +02:00
Juanpe Catalán 29f0726397 Update README_es.md 2020-09-13 21:02:25 +02:00
Juanpe Catalán 6db57ee5fb Update README_es.md 2020-09-13 21:02:05 +02:00
Juanpe Catalán 709dec5fa0 Update README_es.md 2020-09-13 21:01:22 +02:00
Juanpe Catalán 3796d96039 Update README.md 2020-09-13 20:59:30 +02:00
Juanpe Catalán fab5e2e36b Update README.md 2020-09-13 20:45:08 +02:00
Juanpe Catalán a6a6dc2440 Merge pull request #329 from Juanpe/feature/create_spanish_README
Add Spanish README 🇪🇸
2020-09-13 20:39:10 +02:00
Juanpe Catalán 58e9ace96d doc: Add PR in CHANGELOG file 2020-09-13 20:36:48 +02:00
Juanpe Catalán 030da2437c doc: Add spanish README 2020-09-13 20:19:31 +02:00
Juanpe Catalán 95b1b7d512 Merge branch 'develop' into feature/create_spanish_README 2020-09-13 17:47:04 +02:00
Juanpe Catalán 2060d1a4a5 Update README.md 2020-09-13 16:22:40 +02:00
Juanpe Catalán 4874e7c95c Update README.md 2020-09-13 16:15:30 +02:00
Juanpe Catalán f42ce31a7d Update README.md 2020-09-11 13:16:44 +02:00
Juanpe Catalán 805d3bc12a Update README.md 2020-09-11 13:13:43 +02:00
Juanpe Catalán a8c61c8ed2 Update README.md 2020-09-11 13:10:27 +02:00
Juanpe Catalán 90bb2cb22a Update README.md 2020-09-11 13:04:42 +02:00
Juanpe Catalán 8fddc20ed3 Update README.md 2020-09-11 13:02:27 +02:00
Juanpe Catalán a7137ac29d Update README.md 2020-09-11 12:39:56 +02:00
Juanpe Catalán a72acbae5b Update README.md 2020-09-11 12:37:53 +02:00
Juanpe Catalán bb5bdf2d0d Update README.md 2020-09-11 12:33:08 +02:00
Juanpe Catalán beeb303db8 doc: refactor README file 2020-09-11 12:27:01 +02:00
Juanpe Catalán 4ea81526b6 Update swiftlint.yml 2020-09-11 02:10:17 +02:00
Juanpe Catalán 3b8c0114de Update swiftlint.yml 2020-09-11 02:05:50 +02:00
Juanpe Catalán e1a74ad0b8 Update swiftlint.yml 2020-09-11 02:01:54 +02:00
Juanpe Catalán 39d7af9980 Update swiftlint.yml 2020-09-11 01:54:29 +02:00
Juanpe Catalán 796702671b Update swiftlint.yml 2020-09-11 01:47:31 +02:00
Juanpe Catalán df5fbb4faa Update swiftlint.yml 2020-09-11 01:45:12 +02:00
Juanpe Catalán 072f085da4 Rename .github/swiftlint.yml to .github/workflows/swiftlint.yml 2020-09-11 01:36:25 +02:00
Juanpe Catalán 88521db1a1 Create swiftlint.yml 2020-09-11 01:31:01 +02:00
Juanpe Catalán ffac0dd0e4 Merge pull request #327 from Juanpe/feature/swiftlint
Add SwiftLint
2020-09-11 01:16:47 +02:00
Juanpe Catalán d8ccc8ec7a doc: Add PR to CHANGELOG file 2020-09-11 01:16:10 +02:00
Juanpe Catalán 3dcfebda82 refactor: swiftlint changes 2020-09-11 01:10:04 +02:00
Juanpe Catalán e2afb6aba7 feat: add swiftlint.yml file 2020-09-11 01:09:43 +02:00
Juanpe Catalán b267a2c675 Merge pull request #326 from Juanpe/master
Merge branch 'develop'
2020-09-10 20:49:02 +02:00
Juanpe Catalán ced07a1ca1 Update CONTRIBUTING.md 2020-09-10 20:48:17 +02:00
Juanpe Catalán 8d09e6646a Merge branch 'develop' 2020-09-10 20:47:01 +02:00
Juanpe Catalán 7d710bbd74 doc: Update README file including contributing guidelines link 2020-09-10 20:46:50 +02:00
Juanpe Catalán 4970073190 doc: Add CONTRIBUTING file 2020-09-10 20:46:29 +02:00
Juanpe Catalán 4ecfa226b6 doc: add Pull Request template 2020-09-10 20:46:19 +02:00
Juanpe Catalán a256001f61 doc: Update Issue template 2020-09-10 20:46:11 +02:00
Juanpe Catalán 8b3b8c1d71 doc: Add CODE_OF_CONDUCT file 2020-09-10 20:15:48 +02:00
Juanpe Catalán 4e605d2fd4 Merge pull request #324 from Juanpe/master
Merge branch 'develop'
2020-09-10 11:12:05 +02:00
Juanpe Catalán 6feffdb41b Merge branch 'develop' 2020-09-10 11:08:18 +02:00
Juanpe Catalán 0adc9683ee docs: bump and update CHANGELOG file 2020-09-10 10:59:04 +02:00
Juanpe Catalán 0521be6d6e Merge pull request #323 from Juanpe/fix/save_and_restore_button_view_state
Save and restore view state for UIButton
2020-09-09 17:35:16 +02:00
Juanpe Catalán 4167579d8a add PR in the CHANGELOG file 2020-09-09 17:31:34 +02:00
Juanpe Catalán 1bd4d3d960 feat: save and restore button view state 2020-09-09 16:49:40 +02:00
Juanpe Catalán b79219ac88 Update stale.yml 2020-09-08 14:03:07 +02:00
Juanpe Catalán 39ad7aa264 Update CHANGELOG.md 2020-09-07 13:50:13 +02:00
Juanpe Catalán 997c62b7d1 Merge pull request #319 from xpereta/fix-bottom-edge-inset
Fix to consider the top and bottom edge insets when updating the skeleton layer height
2020-09-07 13:49:40 +02:00
Xavier Pereta d4aa1743e6 Update CHANGELOG.md 2020-09-03 23:07:48 +02:00
Xavier Pereta 770be4fc06 fix: Consider the bottom and top edge insets when updating the height of the skeleton layer. 2020-09-03 23:00:42 +02:00
Juanpe Catalán cdd30bd623 Update CHANGELOG.md 2020-09-01 20:30:54 +02:00
Juanpe Catalán 0c500a943c Merge pull request #320 from Juanpe/fix_labels_single_line_appearance
Fix Single line customisation
2020-09-01 20:29:40 +02:00
Juanpe Catalán 8258b73b35 Include the PR in the CHANGELOG file 2020-09-01 20:24:42 +02:00
Juanpe Catalán 3d9e9063c5 Update Dangerfile.swift 2020-09-01 20:23:21 +02:00
Juanpe Catalán b443dcc17c use multiline height when text is a single line 2020-09-01 20:18:24 +02:00
Juanpe Catalán 13b07d9edd Update checks.yml 2020-09-01 18:50:25 +02:00
Juanpe Catalán 5a27b37e81 Merge branch 'master' into develop 2020-08-27 11:43:20 +02:00
Juanpe Catalán b93bae7b49 bump version and changelog 2020-08-27 11:20:04 +02:00
Juanpe Catalán 013cc025a1 Merge branch 'develop' 2020-08-27 11:17:38 +02:00
Juanpe Catalán cc0cdf548e Add videos in README file 2020-08-24 19:11:23 +02:00
Juanpe Catalán 20d171f0db Update README.md 2020-08-21 10:18:53 +02:00
Juanpe Catalán ed563a29d7 Update README.md 2020-08-21 10:17:40 +02:00
Juanpe Catalán 38f9379aa5 Merge pull request #307 from BurhanDewantara/1.8.7-custom
Prevent incorrect skeletonLayer to be added when updating skeleton
2020-08-06 13:42:49 +02:00
William Salim d94517939a Merge branch 'develop' into 1.8.7-custom 2020-08-06 18:19:55 +07:00
Juanpe Catalán 65e86056cf Merge pull request #314 from 0xLeif/develop
Update README.md removed "he"
2020-08-06 10:52:01 +02:00
Zach Eriksen a0b01915fb Update README.md 2020-08-05 09:11:12 -05:00
Juanpe Catalán f16f4044d7 Merge pull request #313 from Juanpe/master
Master
2020-08-04 14:31:59 +02:00
Juanpe Catalán ad28803221 Merge branch 'develop' 2020-08-04 14:31:07 +02:00
Juanpe Catalán a6a988d169 Merge pull request #312 from miguelangel-dev/ipad_badge
Add try-with-ipad badge
2020-08-04 14:27:09 +02:00
Juanpe Catalán 3b17dbe7f2 Update CHANGELOG.md 2020-08-04 12:48:54 +02:00
Juanpe Catalán 06002ac2e2 Update CHANGELOG.md 2020-08-04 12:44:37 +02:00
Miguel Ángel Díaz 060c66ecf9 add try-in-ipad badge
update translations-section contributions

add PayPal button

update nef-badge in README FR

update contributions in translations section
2020-08-04 12:03:02 +02:00
Juanpe Catalán b3c25674ed Merge pull request #304 from OmarJalil/develop
French Readme
2020-08-04 11:28:33 +02:00
Juanpe Catalán 7585d068f4 Merge pull request #311 from Juanpe/dependabot/bundler/json-2.3.1
Bump json from 2.2.0 to 2.3.1
2020-07-29 09:09:43 +02:00
dependabot[bot] 29c4ab8351 Bump json from 2.2.0 to 2.3.1
Bumps [json](https://github.com/flori/json) from 2.2.0 to 2.3.1.
- [Release notes](https://github.com/flori/json/releases)
- [Changelog](https://github.com/flori/json/blob/master/CHANGES.md)
- [Commits](https://github.com/flori/json/compare/v2.2.0...v2.3.1)

Signed-off-by: dependabot[bot] <support@github.com>
2020-07-28 04:19:32 +00:00
Juanpe Catalán 90b423c893 Merge pull request #308 from toshi0383/ts-fix-example
fix example backgroundColor in DarkMode
2020-07-23 12:03:58 +02:00
toshi0383 1184453782 fix example backgroundColor 2020-07-23 11:51:48 +09:00
William Salim 33108b2a87 Update CHANGELOG 2020-07-20 19:25:56 +07:00
William Salim e4cde53d73 Prevent incorrect skeletonLayer to be added when updating skeleton 2020-07-20 19:08:23 +07:00
Jalil 7a35023c2d Update README_fr.md 2020-07-15 13:00:21 -06:00
Jalil d66c8c3f4d Update README_fr.md 2020-07-15 12:58:26 -06:00
Jalil fe195036cc Update README_fr.md 2020-07-15 12:56:51 -06:00
Jalil ac5c7b65f4 Update README_fr.md 2020-07-15 12:55:53 -06:00
Jalil 828a3a9655 Update README_fr.md 2020-07-15 12:51:02 -06:00
Jalil 8b9c1e387f Update README_fr.md 2020-07-15 12:44:46 -06:00
Jalil 88d7d7ea18 Update README_fr.md 2020-07-15 12:42:31 -06:00
Jalil d5639c6195 Update README_fr.md 2020-07-15 12:35:42 -06:00
Jalil c473f0c499 Create README_fr.md
1st part
2020-07-09 16:39:34 -06:00
Juanpe Catalán a7c884771b Merge pull request #292 from marisalaneous/develop
Add public headers back for Carthage IBInspectable support
2020-05-19 13:50:21 +02:00
marisalaneous e291ab5da1 Update CHANGELOG 2020-05-19 07:39:33 -04:00
marisalaneous e1a99a7ec1 fix: add public headers for Carthage IBInspectable support 2020-05-18 20:43:56 -04:00
Juanpe Catalán 0b5d6189b1 Merge pull request #286 from paulanatoleclaudot-betclic/develop
[BugFix] Fix issue on WKWebView/UIWebView
2020-04-27 13:10:49 +02:00
Paul-Anatole CLAUDOT 47a15e4c6d [BugFix] Add changelog 2020-04-17 13:06:00 +02:00
Paul-Anatole CLAUDOT 1f81365096 [BugFix] Fix issue when WKWebView calls skeletonLayoutSubviews not on the main thread 2020-04-17 13:03:15 +02:00
Juanpe Catalán 8e49eb305d Merge branch 'develop' 2020-03-31 09:38:09 +02:00
Juanpe Catalán d09a5d75ee bump version and update CHANGELOG file 2020-03-31 09:34:04 +02:00
Juanpe Catalán 8ab04f8108 Merge pull request #271 from paulanatoleclaudot-betclic/feature/CornerRadiusView
Add corner radius for skeletonView as IBInspectable (CGFloat) default is 0.0
2020-03-19 16:57:31 +01:00
Paul-Anatole CLAUDOT f5d0620a57 [CornerRadiusView] Fill correct changeLog with nextVersion 2020-03-19 15:47:58 +01:00
Paul-Anatole CLAUDOT 8ddd4ccd27 [CornerRadiusView] Modify changeLog according to PR 2020-03-19 09:30:14 +01:00
Juanpe Catalán 57aa984a01 Merge pull request #273 from koooootake/fix_stack_view_alignment_center
FIX: in vertical stack view with center alignment
2020-03-13 16:35:02 +01:00
koooootake 7a0c45a47e Update CHANGELOG.md 2020-03-14 00:22:39 +09:00
koooootake 30fd5aa762 Merge branch 'develop' into fix_stack_view_alignment_center 2020-03-14 00:19:51 +09:00
Juanpe Catalán 14b0248612 Update CHANGELOG.md 2020-03-13 12:18:44 +01:00
Juanpe Catalán 6b914ba1d5 Update CHANGELOG.md 2020-03-13 12:18:15 +01:00
Juanpe Catalán 3dac6c7f2f Merge pull request #274 from darkside999/develop
Fix hiding skeleton when some of views will not hide
2020-03-13 12:17:22 +01:00
Индир 1a6ab34e7b Update CHANGELOG.md 2020-03-13 14:06:45 +03:00
voltmor 601dc7a4e0 Merge branch 'develop' of https://github.com/Juanpe/SkeletonView into develop 2020-03-13 13:56:08 +03:00
Juanpe Catalán ec3398bda0 Merge pull request #275 from BurhanDewantara/259
Fix Issue #259: Prevent isSkeletonActive to be called when isSkeletonable is false
2020-03-13 11:23:24 +01:00
William Salim 5a75e00604 add PR #259 in the CHANGELOG file 2020-03-13 15:21:15 +07:00
voltmor 906c1845d3 Fix hiding skeleton when some of views will not hide 2020-03-11 16:59:22 +03:00
William Salim 8a2a512bbb Prevent isSkeletonActive to be called when isSkeletonable is false 2020-03-11 18:32:23 +07:00
koooootake e6eb35e139 delete case .center 2020-03-09 23:56:56 +09:00
Paul-Anatole CLAUDOT 9c66a4b74c Add corner radius for skeletonView as IBInspectable (CGFloat) default is 0.0 2020-03-03 13:47:08 +01:00
Juanpe Catalán 0d5c0a228b Merge pull request #267 from Juanpe/develop
v1.8.6
2020-02-21 11:00:33 +01:00
Juanpe Catalán 440e5ba022 Merge pull request #266 from Juanpe/release_1.8.6
bump version 1.8.6
2020-02-21 10:58:15 +01:00
Juanpe Catalán 26191ceb46 bump version 1.8.6 2020-02-21 10:57:34 +01:00
Juanpe Catalán 147ebd0365 Merge pull request #265 from Juanpe/fix_problem_swizzling_method
call original traitCollectionDidChange method
2020-02-21 10:52:26 +01:00
Juanpe Catalán cd07ce7314 add PR #265 in the CHANGELOG file 2020-02-21 10:49:32 +01:00
Juanpe Catalán 51ceb81f29 call original traitCollectionDidChange method 2020-02-21 10:07:56 +01:00
Juanpe Catalán 9d4e7688a3 Merge pull request #264 from Juanpe/disable-datasource-during-test-execution
not replace original datasource is running XCTests
2020-02-20 21:46:48 +01:00
Juanpe Catalán 6fc98f08d1 add 264 PR to CHANGELOG file 2020-02-20 21:43:54 +01:00
Juanpe Catalán 64cf3b07a2 not replace original datasource is running XCTests 2020-02-20 21:40:52 +01:00
Juanpe Catalán ba889f68c9 Update CHANGELOG.md 2020-02-20 16:11:26 +01:00
Juanpe Catalán e0134c3ee1 Update CHANGELOG.md 2020-02-20 16:09:04 +01:00
Juanpe Catalán f393954a96 Update CHANGELOG.md 2020-02-20 16:08:41 +01:00
Juanpe Catalán eff72e6a93 Update CHANGELOG.md 2020-02-20 16:06:56 +01:00
Juanpe Catalán f60982bb0e Update CHANGELOG.md 2020-02-20 15:56:40 +01:00
Juanpe Catalán 194e2ddaaf Merge pull request #263 from Juanpe/feature/set-cross-dissolve-transitions-as-default
Feature/set cross dissolve transitions as default
2020-02-20 15:55:02 +01:00
Juanpe Catalán 62401d502f add PR to CHANGELOG file 2020-02-20 15:49:19 +01:00
Juanpe Catalán e54d458433 Merge branch 'develop' into feature/set-cross-dissolve-transitions-as-default 2020-02-20 13:13:47 +01:00
Juanpe Catalán 06085089fb set the cross dissolve transition as default 2020-02-20 13:13:19 +01:00
Juanpe Catalán fd7ce7320e Merge pull request #261 from darkside999/develop
Fixes removing skeleton layers from table header footer sections
2020-02-20 12:04:18 +01:00
Индир 2538a62c03 Merge branch 'develop' into develop 2020-02-20 13:50:49 +03:00
Индир d0eeb5f42f Update CHANGELOG.md 2020-02-20 13:43:13 +03:00
Juanpe Catalán db1d8d7f4e Update CHANGELOG.md 2020-02-20 11:17:03 +01:00
Juanpe Catalán 43b64f8b30 Update README.md 2020-02-20 11:04:32 +01:00
Juanpe Catalán 5925d86d3f Update build.yml 2020-02-20 11:02:54 +01:00
Juanpe Catalán 3a234048d4 Update build.yml 2020-02-20 10:55:24 +01:00
Juanpe Catalán bea8fe7174 Merge pull request #262 from Juanpe/master
given changes from master branch
2020-02-20 10:22:15 +01:00
Juanpe Catalán b87a6e1d3c Update build.yml 2020-02-20 10:20:44 +01:00
Juanpe Catalán c51f495410 Create build.yml 2020-02-20 10:19:07 +01:00
Juanpe Catalán b279b8978a Delete greetings.yml 2020-02-19 13:11:58 +01:00
Juanpe Catalán 58dfa91ae6 Update checks.yml 2020-02-19 13:10:48 +01:00
voltmor 42095e776b Fix remove skeleton layers from table header footer sections 2020-02-19 13:23:16 +03:00
Juanpe Catalán 255479098f Delete .travis.yml 2020-02-17 10:28:58 +01:00
Juanpe Catalán 3a722b8a41 Update CHANGELOG.md 2020-02-17 10:27:48 +01:00
Juanpe Catalán 3ac931e15d Update CHANGELOG.md 2020-02-17 10:22:50 +01:00
Juanpe Catalán dfb538e233 Merge pull request #242 from Cacodemon/master
Offscreen table view layout issue fixed
2020-02-17 09:58:49 +01:00
Juanpe Catalán 27fab8f9e4 Merge branch 'master' into develop 2020-02-13 18:04:02 +01:00
Juanpe Catalán 3ff87e0378 Update checks.yml 2020-02-13 18:03:27 +01:00
Juanpe Catalán ce83751152 Merge branch 'master' into develop 2020-02-13 17:47:05 +01:00
Juanpe Catalán ecc90853e5 fix uncomment comment in Dangerfile 2020-02-13 17:37:44 +01:00
Juanpe Catalán 0799437dd7 Merge branch 'develop' 2020-02-13 17:27:32 +01:00
Juanpe Catalán 89a098ea44 Update checks.yml 2020-02-13 17:22:55 +01:00
Juanpe Catalán 5a59fe1ed1 Merge branch 'develop' 2020-02-13 17:05:12 +01:00
Juanpe Catalán c7bf9fdc10 update Dangerfile.swift 2020-02-13 16:58:43 +01:00
Juanpe Catalán ec15de8ec7 update dangerfile 2020-02-13 15:21:55 +01:00
Juanpe Catalán dd6d5b0e7d update dangerfile 2020-02-13 15:20:40 +01:00
Juanpe Catalán d5165fe013 change lines of code 2020-02-13 15:14:48 +01:00
Juanpe Catalán 544f1ad66f add swiftlint 2020-02-13 15:13:49 +01:00
Juanpe Catalán 744098d641 update dangerfile 2020-02-13 15:13:17 +01:00
Juanpe Catalán 1fd952ced8 Merge branch 'master' into develop 2020-02-13 15:11:00 +01:00
Juanpe Catalán 3840dc6cb5 create dangerfile swift 2020-02-13 15:10:31 +01:00
Juanpe Catalán 23a77fd90f update Dangerfile 2020-02-13 12:40:34 +01:00
Juanpe Catalán 8d19f844f7 Update checks.yml 2020-02-13 12:29:48 +01:00
Juanpe Catalán 89858a4e25 update dangerfile 2020-02-13 12:28:09 +01:00
Juanpe Catalán d32ea14495 Update checks.yml 2020-02-13 12:19:08 +01:00
Juanpe Catalán 815f17145c feat: update Dangerfile, fix merge conflicts label 2020-02-13 12:05:09 +01:00
Juanpe Catalán 86cbaa2d72 Update checks.yml 2020-02-13 12:00:25 +01:00
Juanpe Catalán c206e48732 update Dangerfile 2020-02-13 11:54:37 +01:00
Juanpe Catalán fb835a438b update Dangerfile 2020-02-13 11:54:24 +01:00
Juanpe Catalán 9f73a137c6 Merge branch 'master' into develop 2020-02-13 11:46:05 +01:00
Juanpe Catalán 83ecd7110d Delete danger.yml 2020-02-13 11:44:36 +01:00
Juanpe Catalán 2dbc82ccc9 Create checks.yml 2020-02-13 11:44:25 +01:00
Juanpe Catalán 2e40eec3b3 Create danger.yml 2020-02-13 11:13:26 +01:00
Juanpe Catalán 3fe5629ca3 Merge branch 'master' into develop 2020-02-13 11:07:56 +01:00
Juanpe Catalán bde2452bc9 feat: create Dangerfile 2020-02-13 11:07:36 +01:00
Juanpe Catalán d030c80b05 Update stale.yml 2020-02-12 11:36:05 +01:00
Juanpe Catalán f082bfbcc3 Update stale.yml 2020-02-12 02:43:00 +01:00
Juanpe Catalán 0d8313cd7e Merge branch 'master' into develop 2020-02-12 02:27:14 +01:00
Juanpe Catalán a338ffa9ae Merge pull request #238 from qclmnt/fix/tableview_row_height_when_remove_skeleton
Skeleton Data Source, in TableView : fix restore row height to add back the original row height
2020-02-12 02:26:57 +01:00
Juanpe Catalán 809dc4a9ba Merge branch 'master' into fix/tableview_row_height_when_remove_skeleton 2020-02-12 02:24:32 +01:00
Juanpe Catalán b040f4771c bump version 1.8.5 2020-02-12 01:49:08 +01:00
Juanpe Catalán b938eddb87 fix: remove duplicate import UIKit 2020-02-12 01:48:59 +01:00
Juanpe Catalán 01fe85b95c Merge pull request #227 from diogot/notifications
Post show/update/hide notifications
2020-02-12 01:39:11 +01:00
Juanpe Catalán f538673b53 Update greetings.yml 2020-02-12 01:37:14 +01:00
Juanpe Catalán 898f7e4de4 Delete auto-comment.yml 2020-02-12 01:36:17 +01:00
Juanpe Catalán 570f059615 Update stale.yml 2020-02-12 01:35:52 +01:00
Juanpe Catalán 9a106d1af2 Merge pull request #254 from Juanpe/develop
Merge changes for version 1.8.4
2020-02-12 01:16:35 +01:00
Juanpe Catalán 5544acc63e bump version 1.8.4 2020-02-12 01:14:17 +01:00
Juanpe Catalán 65299378c4 fix: problem with text views that only have one line 2020-02-12 01:13:21 +01:00
Juanpe Catalán d8f1b4c53b Merge pull request #195 from esme-putt/Customise-Single-Line
Customise Single Line
2020-02-12 00:13:39 +01:00
Juanpe Catalán d2d8c1f5db Merge branch 'develop' into Customise-Single-Line 2020-02-12 00:11:28 +01:00
Juanpe Catalán ab385e5afb Merge pull request #234 from AnatoliBenke-Helsana/master
Update SkeletonView.swift
2020-02-12 00:05:32 +01:00
Juanpe Catalán 5d8cd9432e Merge branch 'master' into develop 2020-02-11 14:53:59 +01:00
Juanpe Catalán fbaf2e7b4b Update greetings.yml 2020-02-11 11:38:45 +01:00
Juanpe Catalán 97d83c7038 Create greetings.yml 2020-02-11 11:36:24 +01:00
Juanpe Catalán ce83713240 update staling issues
just stale issues with state equal to awaiting user input
2020-02-11 11:13:32 +01:00
Juanpe Catalán 56d3156f8e Merge branch 'master' into develop 2020-02-11 10:52:04 +01:00
Juanpe Catalán aeb9dcf2c7 Create auto-comment.yml 2020-02-11 10:43:30 +01:00
Juanpe Catalán 9914be0f5b Merge pull request #240 from damien-danglard/master
[fix] Use UIFont.lineHeight for calculate the number of CALayer used in …
2020-02-11 10:33:28 +01:00
Juanpe Catalán 7d0609098c update stale.yml to not stale assigned issues 2020-02-10 00:29:24 +01:00
Diogo Tridapalli ec7a9973c5 Post show/update/hide notifications
Signed-off-by: Diogo Tridapalli <diogot@users.noreply.github.com>
2020-02-03 13:44:59 -03:00
Dmitry Rykun 06a9fb769e original delegate call added 2020-02-02 23:13:57 +02:00
Dmitry Rykun d2797238f2 offscreen table view layout fixed 2020-02-02 22:57:06 +02:00
Juanpe Catalán b431aabddb increase pod version 2020-01-31 15:22:54 +01:00
Juanpe Catalán 0091ffc08b Merge branch 'develop' 2020-01-31 14:45:07 +01:00
Juanpe Catalán e948e313a1 Merge pull request #216 from MikeGlotov/fix/preserve-user-interactions-state
Added "isUserInteractionsEnabled" state preservation to UITextView an…
2020-01-30 11:17:43 +01:00
Damien Danglard a7ae5f0f9f [fix] resolve issues from codebeat 2020-01-27 17:11:23 +01:00
Damien Danglard 85cce0cd7c [fix] Use font lineHeight for calculate the number of CALayer used in multiline Skeleton UILabel
close #239
2020-01-24 15:35:29 +01:00
Juanpe Catalán 3afe7286a2 Merge pull request #152 from eduardbosch/feature/fix_skeleton_hierarchy
Fix skeleton hierarchy
2020-01-23 20:38:19 +01:00
Quentin CLEMENT 3d8612ec0e Skeleton Data Source, in TableView : fix restore row height to add back the original row height
(otherwise it just add back the calculateRowHeight, previously based on the estimated row height)

Avoid to change the row height in  calculateRowHeight(), because the name of the method doesn't say that, and then it juste broke the utilisation of the rowHeight
2020-01-23 11:41:49 +01:00
AnatoliBenke-Helsana 6f1db7e303 Update SkeletonView.swift
- Fixes for Issue #202 UIView.layoutSubviews swizzle is messing with standard controls
- Due to Swizzling, LayoutSubviews is not called. This fixes the issue.
2020-01-07 13:39:32 +01:00
Juanpe Catalán c1815642db Merge pull request #209 from nikitskynikita/master
Add support skeletonable headers and footers of UITableView and UICollectionView
2019-12-30 20:12:00 +01:00
Juanpe Catalán a6a168a919 Merge pull request #225 from Juanpe/dependabot/bundler/excon-0.71.0
build(deps): bump excon from 0.65.0 to 0.71.0
2019-12-30 20:10:58 +01:00
dependabot[bot] d0dbd1e004 build(deps): bump excon from 0.65.0 to 0.71.0
Bumps [excon](https://github.com/excon/excon) from 0.65.0 to 0.71.0.
- [Release notes](https://github.com/excon/excon/releases)
- [Changelog](https://github.com/excon/excon/blob/master/changelog.txt)
- [Commits](https://github.com/excon/excon/compare/v0.65.0...v0.71.0)

Signed-off-by: dependabot[bot] <support@github.com>
2019-12-16 22:14:49 +00:00
Juanpe Catalán 4ade8f8797 Update FUNDING.yml 2019-12-10 17:37:49 +01:00
Nikita Nikitsky 264195bf16 Add support skeletonable headers and footers of UITableView and UICollectionView 2019-12-01 14:37:37 +04:00
Mikhail Glotov 11cc9a3ff7 Added "isUserInteractionsEnabled" state preservation to UITextView and UILabel 2019-11-19 14:26:22 +03:00
Nikita Nikitsky 37ac7d6e5d Fix attributes for tvOS 2019-11-05 14:37:55 +04:00
Juanpe Catalán a1e183a5e1 Merge pull request #199 from Wilsonator5000/feature/dark-mode
Support dark mode
2019-11-04 11:57:38 +01:00
Juanpe Catalán 420785502b Merge pull request #208 from Juanpe/dependabot/bundler/rubyzip-1.3.0
build(deps): bump rubyzip from 1.2.3 to 1.3.0
2019-11-04 11:57:07 +01:00
dependabot[bot] eed18e5372 build(deps): bump rubyzip from 1.2.3 to 1.3.0
Bumps [rubyzip](https://github.com/rubyzip/rubyzip) from 1.2.3 to 1.3.0.
- [Release notes](https://github.com/rubyzip/rubyzip/releases)
- [Changelog](https://github.com/rubyzip/rubyzip/blob/master/Changelog.md)
- [Commits](https://github.com/rubyzip/rubyzip/compare/v1.2.3...v1.3.0)

Signed-off-by: dependabot[bot] <support@github.com>
2019-11-03 14:00:59 +00:00
Wilson Gramer 0a86ac4a9c Merge branch 'master' into feature/dark-mode 2019-10-22 12:53:16 -04:00
Wilson Gramer 264b0a70c2 Update CHANGELOG 2019-10-22 12:51:26 -04:00
Juanpe Catalán 01d68190ab Merge pull request #196 from ashleyng/FixCellDataRefresh
Update tableview cells after hiding skeleton
2019-10-17 09:12:32 +02:00
Juanpe Catalán 2d57efd9cb Update CHANGELOG.md 2019-10-17 09:07:47 +02:00
Wilson Gramer da51a6f673 Update English README 2019-10-13 21:04:45 -04:00
Wilson Gramer f6d4343cc6 Update example to support dark mode 2019-10-13 20:55:53 -04:00
Wilson Gramer c6e20aa1a0 Swizzle traitCollectionDidChange(_:) method in skeleton views
Make skeleton views respond to changes in system appearance by
updating the skeleton view whenever the trait collection changes,
so the colors change automatically with dark mode.
2019-10-13 20:47:03 -04:00
Wilson Gramer 809544066f Make skeleton colors dynamic
If on iOS 13 or higher, returns a UIColor using the
`init(dynamicProvider:)` initializer so it automatically adjusts to
dark mode. Also switches out the `clouds` default color with the
dynamic `skeletonDefault` color.
2019-10-13 20:45:53 -04:00
Ashley Ng 9406e3ef62 refresh tableview after removing skeleton views 2019-10-05 20:49:20 -05:00
Esme Putt 6d4c7d76c3 Added flipper for custom options 2019-10-04 13:28:21 +13:00
Esme Putt f580fdaac2 Changed update function 2019-10-04 13:11:45 +13:00
Esme Putt 4be93db383 Added spacing 2019-10-04 11:52:38 +13:00
Esme Putt ae4ecfa760 Added comments 2019-10-04 11:28:17 +13:00
Esme Putt f60e5cd7ae Add-custom-options-for-single-line 2019-10-04 11:06:30 +13:00
Juanpe Catalán e097385de9 Merge pull request #174 from superhuman/master
Add ability to customize line spacing per label
2019-09-15 10:40:10 +02:00
gshahbazian 84d8971aa2 Add ability to customize line spacing per label
Also customizability of edge insets for skeleton rows
2019-09-13 09:59:17 -07:00
Juanpe Catalán 5384fd34dd Merge branch 'develop' 2019-09-13 10:51:56 +02:00
Juanpe Catalán 53d965e151 feat: update pod version 2019-09-13 10:51:39 +02:00
Juanpe Catalán 04678fc772 feat: change some signature of methods 2019-09-13 10:50:06 +02:00
Juanpe Catalán 46da5ab6fa Merge branch 'master' into develop 2019-09-13 10:42:13 +02:00
Juanpe Catalán 45871be409 Merge pull request #186 from AhmedOS/master
Fixed animation stopping issue after view controller disappears
2019-09-13 10:41:02 +02:00
Juanpe Catalán 93f54dcc4d Merge pull request #182 from yangzhiquan/fix-spelling-error
fix spelling error
2019-09-10 08:31:25 +02:00
yvan 3bf3038941 fix spelling error 2019-09-10 11:27:29 +08:00
Ahmed Osama df1454c749 Improved example project 2019-09-08 05:48:30 +02:00
Ahmed Osama 8212fc1a0b Fixed animation stopping issue after switching tabs 2019-09-08 05:48:30 +02:00
Juanpe Catalán e4b9416667 Merge pull request #167 from Bilue/fix-single-line-labels
Adjust multiline behaviour to properly handle single lines
2019-09-02 17:52:19 +02:00
Juanpe Catalán f6f001068d Update README.md 2019-08-31 14:00:02 +02:00
Juanpe Catalán cb4ddd487a Update README.md 2019-08-31 13:59:37 +02:00
Juanpe Catalán 18cd0f9aba feat: update stale.yml setting stale label 2019-08-27 23:29:03 +02:00
Eduard Bosch Bertran 731509a46f fix: Update examples to show skeletons 2019-08-27 21:17:47 +02:00
Eduard Bosch Bertran 7833c94f2e fix: Stop showing skeleton views when a view is not skeletonable 2019-08-27 21:17:33 +02:00
Juanpe Catalán 71d3e72eec feat: create stale file 2019-08-27 20:21:43 +02:00
Juanpe Catalán a0a2ae760b fix: problem calling layout subviews 2019-08-27 20:04:42 +02:00
Juanpe Catalán 71d40d24b2 feat: update assets 2019-08-27 02:31:59 +02:00
Juanpe Catalán 4236e9d424 feat: update README, include more examples in Hierarchy section 2019-08-27 02:28:19 +02:00
Juanpe Catalán 19b88fce3e feat: update example 2019-08-26 23:27:41 +02:00
Juanpe Catalán b200a1ff3a Merge branch 'master' of https://github.com/Juanpe/SkeletonView 2019-08-26 23:01:10 +02:00
Juanpe Catalán d9408d59b4 feat: update cocoaspec 2019-08-26 23:00:54 +02:00
Juanpe Catalán 5a0f6e2314 Update README.md 2019-08-26 23:00:07 +02:00
Juanpe Catalán 3f7505bed9 Merge branch 'master' of https://github.com/Juanpe/SkeletonView 2019-08-26 22:39:28 +02:00
Juanpe Catalán 5436e44f15 fix: property name 2019-08-26 22:37:11 +02:00
Juanpe Catalán 2f2e542d51 fix: bug #149 animation stopped when modal is presented 2019-08-26 22:34:56 +02:00
Juanpe Catalán 15764debf0 feat: rename alias of delegate 2019-08-26 19:11:28 +02:00
Juanpe Catalán bcd0fa7983 feat: user interaction enabled false 2019-08-26 19:10:44 +02:00
Juanpe Catalán 4cdc5935fc Update CHANGELOG.md 2019-08-25 11:08:42 +02:00
Juanpe Catalán 93769902a3 Merge branch 'master' into develop 2019-08-24 11:46:50 +02:00
Juanpe Catalán a1d54a448d Merge pull request #178 from aadudyrev/completionOnNoneTransition
Fix completion call in .none transition style.
2019-08-23 15:57:20 +02:00
dudyrev cc8d21e7af Fix completion call in .none transition style. 2019-08-23 16:24:47 +03:00
Juanpe Catalán 69a0c8319d Update README.md 2019-08-23 12:58:21 +02:00
Juanpe Catalán 3c173c0a23 Merge branch 'master' into develop 2019-08-22 16:51:16 +02:00
Juanpe Catalán dce910d6d0 feat: update transition gifs 2019-08-22 16:51:04 +02:00
Juanpe Catalán 2f751b9036 Merge branch 'master' into develop 2019-08-22 15:17:28 +02:00
Juanpe Catalán fdd17dd4e9 fix: missing UIView+IBInspectable 2019-08-22 15:16:37 +02:00
Juanpe Catalán 978fd553e1 Merge branch 'master' into develop 2019-08-22 15:11:15 +02:00
Juanpe Catalán 14ef5012f3 feat: refactor Swift format 2019-08-22 15:11:01 +02:00
Juanpe Catalán e62c7d8c0e Merge branch 'develop'
# Conflicts:
#	.codebeatsettings
2019-08-22 12:07:41 +02:00
Juanpe Catalán e7aa9da5ae feat: BUMP cocoapods version 2019-08-22 12:04:29 +02:00
Juanpe Catalán 09a30d36b8 feat: remove whitespaces 2019-08-22 09:34:56 +02:00
Juanpe Catalán d5656b9715 feat: change some methods about animate transition 2019-08-22 03:00:09 +02:00
Juanpe Catalán 66dc7e89c5 fix: SPM install instructions 2019-08-21 13:03:56 +02:00
Juanpe Catalán 5c815d7647 feat: add new rule for codebeat 2019-08-21 13:01:47 +02:00
Juanpe Catalán aa60f82c81 feat: create codebeat settings 2019-08-21 12:12:03 +02:00
Juanpe Catalán 6676760860 feat: config number of functions allowed. Codebeat file 2019-08-21 12:08:52 +02:00
Juanpe Catalán b571988fad update README 2019-08-21 10:04:14 +02:00
Juanpe Catalán abd9130ff6 Merge branch 'master' into develop 2019-08-21 10:02:41 +02:00
Juanpe Catalán fc9dca1730 revert README.md 2019-08-21 10:01:56 +02:00
Juanpe Catalán 46a95eecb4 Merge pull request #170 from pontusjacobsson/master
Fade in and fade out animations of the skeletonViews
2019-08-21 09:57:47 +02:00
Pontus Jacobsson e08e563ec0 Fixed typo 2019-08-21 09:23:54 +02:00
Pontus Jacobsson 1c24785ed6 Merge branch 'master' of https://github.com/pontusjacobsson/SkeletonView
# Conflicts:
#	README.md
2019-08-20 17:17:29 +02:00
Pontus Jacobsson bbcaeedd19 Added hide transition to readme 2019-08-20 17:16:13 +02:00
Pontus Jacobsson 6fc8f5caea Added hide transition to readme 2019-08-20 17:15:06 +02:00
Pontus Jacobsson ab6efd1504 Updated readme 2019-08-20 17:08:18 +02:00
Pontus Jacobsson 6632f5d91e Cleaned up code 2019-08-05 15:52:03 +02:00
Pontus Jacobsson c1a47f098b Cleaned up code 2019-08-02 13:35:41 +02:00
Pontus Jacobsson 02be363c95 Updated tableView tutorial and also added custom transitions on "hideSkeleton()" 2019-08-02 13:11:11 +02:00
Pontus Jacobsson cb0e4c63cf Added fading testing for the collection view example 2019-08-01 22:42:27 +02:00
Pontus Jacobsson 26d839387d Fixed background color bug when showing skeleton without transition 2019-07-31 10:41:20 +02:00
Pontus Jacobsson e05d013af8 Cleaned up some code and aded extra viewState keys 2019-07-31 09:50:13 +02:00
Pontus Jacobsson d8a5df75ee Cleaned up code and changed recoverableStates to structs 2019-07-30 21:51:40 +02:00
Pontus Jacobsson f7eb048317 Changed code to Eduard Bosch's tips with minor adjustments 2019-07-30 19:55:27 +02:00
Pontus Jacobsson 4497e5cdb9 Cleaned up some code 2019-07-30 10:35:54 +02:00
Pontus Jacobsson e83ab2e033 Cleaned up code 2019-07-29 13:44:50 +02:00
Pontus Jacobsson d40a877c42 Handled access level on transitions 2019-07-29 12:56:43 +02:00
Pontus Jacobsson 3b6c61cfcb Cleaned up some code 2019-07-29 11:53:09 +02:00
Pontus Jacobsson f42b77fd4d Removed lost file 2019-07-29 11:48:39 +02:00
Pontus Jacobsson c75df015d8 Added missing compilation file 2019-07-29 11:43:01 +02:00
Pontus Jacobsson 0393c04aa8 Moved some functions 2019-07-29 11:41:02 +02:00
Pontus Jacobsson c3df0bc5df Fixed a file bug in xcode prov 2019-07-29 11:35:57 +02:00
Pontus Jacobsson 0f0bb220f2 Cleaned up some code 2019-07-29 11:33:35 +02:00
Pontus Jacobsson a299c8c0c8 Added support for multiple transitions instead of just one 2019-07-29 11:32:31 +02:00
Pontus Jacobsson aea2ae6793 Added missing fade in call 2019-07-29 09:36:17 +02:00
Pontus Jacobsson a3ed33f53b Added fade in/out duration to config and text color to recoveryState 2019-07-26 17:04:52 +02:00
Pontus Jacobsson 6cf19ca50d Added support to start fade from all "showSkeleton" functions 2019-07-26 16:36:13 +02:00
Pontus Jacobsson ca0b295a80 Added support for fade in and fade out animations of the skeleton load 2019-07-26 16:28:30 +02:00
Juanpe Catalán 60c387b250 feat: update gemfile 2019-07-23 10:54:52 +02:00
Tom Izaks 5b3bc204bf Adjust multiline behaviour to properly handle single lines 2019-07-09 14:00:48 +10:00
Juanpe Catalán 1eece8e013 feat: update gemfile 2019-07-06 11:42:03 +02:00
Juanpe Catalán d665d01469 Merge pull request #160 from techinpark/master
[Feature] Add korean README.md
2019-06-30 12:59:57 +02:00
Eduard Bosch Bertran 623b326e7b Merge pull request #158 from eduardbosch/feature/allow_updating_skeleton_layers
Update skeleton layout and configuration
2019-06-25 23:32:16 +02:00
Fernando 3a4bbadcbe feat: add translator of korean documents 2019-06-21 21:19:51 +09:00
Fernando dc92e652cb feat: update document korean 2019-06-21 21:17:56 +09:00
Fernando e3f38fdd25 feat: update korean docs for custom animations 2019-06-21 18:47:01 +09:00
Fernando 6c1c4dda42 feat: update korean document. 2019-06-21 18:36:15 +09:00
Fernando 39c60b6da2 feat: update korean documents 2019-06-21 13:05:39 +09:00
Fernando c75d34e7de Merge pull request #1 from techinpark/feature/korean-docs
[Feature] Docs: add Korean document
2019-06-21 11:30:34 +09:00
Fernando c5a0bc0050 feat: update korean document 2019-06-20 20:20:09 +09:00
Fernando be74f093f3 feat: add korean document 2019-06-20 20:18:07 +09:00
Fernando 0f90edfc8e feat: update korean documents 2019-06-20 20:07:43 +09:00
Fernando 67daffd7c9 feat: translate for korean document 2019-06-20 18:41:52 +09:00
Fernando 961c731888 feat: add korean documentation 2019-06-20 10:54:47 +09:00
Eduard Bosch Bertran 39fa679ddc doc: Add new functionality to documentation 2019-06-19 23:59:29 +02:00
Eduard Bosch Bertran 40c107af23 doc: Update version 2019-06-19 23:49:54 +02:00
Eduard Bosch Bertran 0781fceab7 doc: Update changelog 2019-06-19 23:49:35 +02:00
Juanpe Catalán eef7a87eb6 Merge pull request #156 from gorillatech/master
fix - support UICollectionView's headers and footers (UICollectionReusableView)
2019-06-19 09:51:04 +02:00
Eduard Bosch Bertran be25db821b config: Add colletion view example scheme 2019-06-18 23:21:54 +02:00
Eduard Bosch Bertran 9e014dab0e refactor: Reorder methods 2019-06-18 23:21:54 +02:00
Eduard Bosch Bertran f53b722b52 refactor: Use SkeletonConfig to show and update skeleton views 2019-06-18 23:21:54 +02:00
Eduard Bosch Bertran bd02497124 fix: Skeleton new cells if container is skeletoned 2019-06-18 23:21:54 +02:00
Eduard Bosch Bertran 1802e76da9 fix: Avoid showing non skeletoned views on sample app 2019-06-18 23:21:53 +02:00
Eduard Bosch Bertran 318b2546c6 feat: Add method to layout skeleton view if needed 2019-06-18 23:21:53 +02:00
Eduard Bosch Bertran 37df94b09f style: Add space 2019-06-18 23:21:53 +02:00
Eduard Bosch Bertran 81599f2980 refactor: Rename showSkeletonLeafBlock and do not return a block 2019-06-18 23:21:53 +02:00
Eduard Bosch Bertran b28358663b refactor: showOrUpdate is now update and only updates skeleton properties 2019-06-18 23:21:53 +02:00
Juanpe Catalán b364218213 feat: Add SkeletonConfig documentation 2019-06-18 23:21:53 +02:00
Juanpe Catalán 18048c9bcd feat: Create SkeletonConfig to save the config of skeleton active 2019-06-18 23:21:53 +02:00
Juanpe Catalán 510fe34476 feat: REAMD zh 2019-06-18 23:21:53 +02:00
Eduard Bosch Bertran 932579edc0 doc: Add missing dot 2019-06-18 23:21:53 +02:00
Eduard Bosch Bertran 96673df005 doc: Add feature to changelog file 2019-06-18 23:21:53 +02:00
Eduard Bosch Bertran 43c1f2e5ac refactor: Rename update methods to showOrUpdate 2019-06-18 23:21:53 +02:00
Eduard Bosch Bertran 37f6205421 refactor: Rename layer to skeletonLayer to match the other methods 2019-06-18 23:21:53 +02:00
Eduard Bosch Bertran 3471288307 refactor: Wrap layer with guard 2019-06-18 23:21:53 +02:00
Eduard Bosch Bertran b77edf84b2 config: Ignore .idea folder 2019-06-18 23:21:53 +02:00
Eduard Bosch Bertran 3e87293a84 fix: Request layout if needed befor updating skeleton views 2019-06-18 23:21:53 +02:00
Eduard Bosch Bertran f637c20ea9 fix: Update multiline skeleton layers on skeleton layer update 2019-06-18 23:21:53 +02:00
Eduard Bosch Bertran 1737536057 refactor: Use update instead of show when updating skeleton views 2019-06-18 23:21:53 +02:00
Eduard Bosch Bertran 31fe04b92e refactor: Reuse show skeleton 2019-06-18 23:21:53 +02:00
Eduard Bosch Bertran f7d577c269 feat: Add begin updating notification 2019-06-18 23:21:53 +02:00
Eduard Bosch Bertran 3a7be98057 fix: Update table / collection skeleton views 2019-06-18 23:21:53 +02:00
Eduard Bosch Bertran dab24e40a7 fix: Only create flowDelegate if update is called before show 2019-06-18 23:21:53 +02:00
Eduard Bosch Bertran c729dec667 test: Update skeleton views in controller bounds update 2019-06-18 23:21:53 +02:00
Eduard Bosch Bertran f6f0a11968 feat: Update skeleton layer bounds and color 2019-06-18 23:21:53 +02:00
Guglielmo Faglioni 6784de9597 fix - support UICollectionView's headers and footers (UICollectionReusableView) 2019-06-18 17:44:50 +02:00
Juanpe Catalán 6e91b3fa71 Merge branch 'master' into develop 2019-06-04 19:01:14 +02:00
Juanpe Catalán 4b6f55cf66 fix: readme 2019-06-04 19:01:01 +02:00
Juanpe Catalán beaf22d696 Merge branch 'master' of https://github.com/Juanpe/SkeletonView 2019-06-04 18:57:16 +02:00
Juanpe Catalán c62586ccff Merge branch 'develop' 2019-06-04 18:57:02 +02:00
Juanpe Catalán 55cb95e3fa Merge branch 'swift_package_manager' into develop 2019-06-04 18:56:49 +02:00
Juanpe Catalán d72b28dc53 feat: Update readme file 2019-06-04 18:56:35 +02:00
Juanpe Catalán b742179fec Create FUNDING.yml 2019-06-04 18:47:15 +02:00
Juanpe Catalán f2b0329db9 upload Package.swift 2019-06-04 18:02:44 +02:00
Juanpe Catalán 8271110682 feat: update scheme 2019-04-26 09:52:58 +02:00
Juanpe Catalán 096099e2a0 feat: Update travis file 2019-04-23 22:00:57 +02:00
Juanpe Catalán 4d4fda2177 Merge branch 'develop' 2019-04-23 21:36:50 +02:00
Juanpe Catalán 4296d1cb04 feat: Update gemfile 2019-04-23 21:36:32 +02:00
Juanpe Catalán db19eae968 feat: Update swift-version 2019-04-23 20:44:39 +02:00
Juanpe Catalán 1d2256b4e6 feat: Update podspec 2019-04-23 20:43:21 +02:00
Juanpe Catalán 4e5c8627dd feat: Update Gemfile 2019-04-23 20:42:05 +02:00
Juanpe Catalán 6012b0c84b Merge pull request #148 from Juanpe/develop
feat: Migrate to Swift 5
2019-04-23 20:39:37 +02:00
Juanpe Catalán 09e1fe31e0 feat: Migrate to Swift 5 2019-04-23 20:38:03 +02:00
Juanpe Catalán 4fb8020c83 Merge pull request #144 from Juanpe/develop
Add tableview illustration
2019-04-03 16:43:57 +02:00
Juanpe Catalán 303ae5aeb8 feat: Update readme 2019-04-03 16:40:35 +02:00
Juanpe Catalán 4649c7e61f feat: Added tableview illustration 2019-04-03 16:39:00 +02:00
Juanpe Catalán 1671af6d28 Update README file 2019-02-28 15:24:00 +01:00
Juanpe Catalán 83e7e48caa feat: Bump cocoapod version 2019-02-26 17:54:53 +01:00
Juanpe Catalán c03af15070 Merge branch 'master' into develop 2019-02-02 10:30:30 +01:00
Juanpe Catalán ed82f74ba8 Merge pull request #131 from grifas/hotfix/reloadDataAfter
🐛 Fix  removeDummyDataSourceIfNeeded passing the reload parameter
2019-02-02 10:27:18 +01:00
Juanpe Catalán 01aba0b3ff Merge pull request #128 from jehlert-trip/feature/podspec_swift_version
Include swift_version in podspec
2019-02-02 10:24:14 +01:00
Aurélien Grifasi 6352030012 🐛 Fix removeDummyDataSourceIfNeeded passing the reload parameter 2019-01-15 11:53:45 +01:00
Justin Ehlert 4b06c30b9d Include swift_version in podspec 2019-01-10 14:33:15 -05:00
Juanpe Catalán 3dcde46fe9 feat: Update gitignore 2018-12-18 11:48:58 +01:00
Juanpe Catalán c9de28eb37 feat: update README file 2018-12-13 10:23:09 +01:00
Juanpe Catalán 915e838994 Merge branch 'develop'
# Conflicts:
#	README.md
2018-12-13 10:17:38 +01:00
Juanpe Catalán 74b44264ec Merge pull request #117 from Juanpe/feature/codebeat_refactor
Feature/codebeat refactor
2018-12-13 10:17:03 +01:00
Juanpe Catalán a9ad72aa0c feat: Update README file 2018-12-13 10:16:28 +01:00
Juanpe Catalán d535529be8 feat: Mute gradient switch 2018-12-13 10:03:13 +01:00
Juanpe Catalán a6bff05ca4 feat: Split line into two 2018-12-13 09:48:35 +01:00
Juanpe Catalán bc98cd600e feat: Refactor associated keys 2018-12-13 09:42:44 +01:00
Juanpe Catalán 8f1cfc0045 feat: Mute associated keys many instance variables 2018-12-13 08:51:35 +01:00
Juanpe Catalán 432ec6caa2 feat: Split associated keys 2018-12-12 18:59:34 +01:00
Juanpe Catalán e18aedbbf8 feat: Move examples files 2018-12-12 18:32:52 +01:00
Juanpe Catalán 4dc67ac3d7 feat: Refactor some classes 2018-12-12 18:28:42 +01:00
Juanpe Catalán aa29cd3d6b feat: Mute too many instance variables 2018-12-12 18:02:54 +01:00
Juanpe Catalán a2def55880 feat: Reorder section in README file 2018-12-12 16:01:44 +01:00
Juanpe Catalán 97f5e3e2e1 feat: Update README file 2018-12-12 15:59:40 +01:00
Juanpe Catalán 420cc7a669 Merge branch 'develop' 2018-12-12 09:11:09 +01:00
Juanpe Catalán b9601f56c3 Merge pull request #115 from Juanpe/feature/configure_fastlane
Feature/configure fastlane
2018-12-12 09:09:59 +01:00
Juanpe Catalán fbca1092c3 feat: Remove Appfile 2018-12-12 09:05:50 +01:00
Juanpe Catalán eb90faf413 fix: URL of bitrise badge 2018-12-11 11:21:57 +01:00
Juanpe Catalán f0cc7125ef feat: update readme 2018-12-11 11:20:44 +01:00
Juanpe Catalán f5b493d6f0 feat: Add bitrise in README file 2018-12-11 11:05:08 +01:00
Juanpe Catalán 48bc217413 feat: Update lane to create new version 2018-12-11 10:56:45 +01:00
Juanpe Catalán 516fcecce2 testing bitrise trigger 2018-12-11 10:41:51 +01:00
Juanpe Catalán 9052d5d806 feat: test bitrise 2018-12-11 09:44:15 +01:00
Juanpe Catalán 12dff52238 feat: remove useless code 2018-12-11 09:43:03 +01:00
Juanpe Catalán f0b4575de6 feat: Create fastfile 2018-12-11 09:42:09 +01:00
Juanpe Catalán 7be8ddd70a Merge pull request #114 from Juanpe/refactor_builder
feat: Create SkeletonLayerBuilder and SkeletonMultilineLayerBuilder
2018-12-10 20:48:49 +01:00
Juanpe Catalán a9628c0de8 feat: Create SkeletonLayerBuilder and SkeletonMultilineLayerBuilder 2018-12-10 20:04:07 +01:00
Juanpe Catalán 339191f016 feat: update changelog file 2018-12-10 19:34:33 +01:00
Juanpe Catalán 7022942d92 feat: Update Changelog file 2018-12-10 19:33:02 +01:00
Juanpe Catalán 03cf1bfea8 Merge pull request #113 from osterbergmarcus/patch-1
Adding swift news to mentioned section
2018-12-10 18:13:46 +01:00
Marcus Osterberg 9f46e7a647 Adding swift news to mentioned section 2018-12-06 19:31:12 +01:00
Juanpe Catalán 674cd1aa9f feat: Update README file to include swift 4.2 2018-10-04 16:15:40 +02:00
Juanpe Catalán 36a863b557 feat: Bump cocoapod version 2018-10-02 11:37:25 +02:00
Juanpe Catalán 3b83b85249 feat: Upgrade swift version 2018-10-02 11:33:55 +02:00
Juanpe Catalán afbb10d785 Update .travis.yml 2018-10-02 11:25:06 +02:00
Juanpe Catalán 99ccd1e640 Update .travis.yml 2018-10-02 11:15:02 +02:00
Juanpe Catalán e6834d1296 Merge pull request #99 from mohpor/master
Updated to Swift 4.2
2018-10-02 11:12:14 +02:00
Mohammad Porooshani 89cb6f4116 Updated to Swift 4.2
Signed-off-by: Mohammad Porooshani <porooshani@gmail.com>
2018-09-15 11:36:30 +04:30
Juanpe Catalán b74592e6be feat: Change guide image 2018-09-04 09:16:10 +02:00
Juanpe Catalán 5f79708f03 feat: Update thumbnail guide 2018-09-04 02:49:10 +02:00
Juanpe Catalán a83e1a00bf feat: Add guides section in README file 2018-09-04 00:52:14 +02:00
Juanpe Catalán 61e98b26ad Merge pull request #95 from arn00s/fix/demoProjectSettings
Fix/demo project settings
2018-08-20 23:48:30 +02:00
Arnaud 0ec754dfc5 use safe area for iPhone X 2018-08-20 17:22:09 +02:00
Arnaud 78b4b7b31c fix info.plist path 2018-08-20 17:17:51 +02:00
Juanpe Catalán e3ddc4fe98 Merge pull request #89 from brunomunizaf/translate-readme-brazil-portuguese
Translate readme file to Brazilian Portuguese
2018-08-13 11:23:34 +02:00
Bruno Muniz 13485e61f7 Translate readme file to Brazilian Portuguese 2018-08-13 11:11:23 +02:00
Juanpe Catalán 8f5d409304 feat: revert last changes in README file 2018-08-10 17:43:15 +02:00
Juanpe Catalán bc3258b8a2 feat: update README 2018-08-10 17:42:24 +02:00
Juanpe Catalán fd4683f555 Merge pull request #90 from Juanpe/debug_system
Debug system
2018-08-10 17:40:11 +02:00
Juanpe Catalán 97ebbcc917 feat: update README 2018-08-10 17:36:49 +02:00
Juanpe Catalán a02922dba6 feat: Update README file 2018-08-10 17:30:43 +02:00
Juanpe Catalán 4ac1abe50e feat: BUMP version 1.4 2018-08-10 17:28:31 +02:00
Juanpe Catalán 25e313850e feat: Update CHANGELOG file 2018-08-10 17:28:12 +02:00
Juanpe Catalán 88914f7816 feat: Update README file explaining debug mode 2018-08-10 17:10:49 +02:00
Juanpe Catalán 14ab00d13a feat: update README file 2018-08-10 14:23:48 +02:00
Juanpe Catalán 90b993a16b feat: Create skeletonHierarchy 2018-08-10 14:17:30 +02:00
Juanpe Catalán 413867718e feat: Improve recursive protocol 2018-08-10 13:23:24 +02:00
Juanpe Catalán e43b3f3750 feat: Add skeleton hierarchy 2018-08-10 08:27:51 +02:00
Juanpe Catalán b9b368b7e8 feat: Create Environment variable 2018-08-09 18:45:03 +02:00
Juanpe Catalán fc22d58f89 Merge pull request #87 from reececomo/alternate-user-interaction
#86 disableUserInteraction() on UIScrollView just to prevent scroll
2018-08-06 10:24:18 +02:00
Reece Como 8988b22784 style consistency 2018-08-06 11:09:20 +08:00
Reece Como 3cb1602e11 Merge https://github.com/Juanpe/SkeletonView into alternate-user-interaction 2018-08-06 11:08:31 +08:00
Reece Como 649672182e allow UIScrollViews to accept button taps 2018-08-06 10:58:10 +08:00
Juanpe Catalán 3c16416dbb feat: update README 2018-08-02 17:55:14 +02:00
Juanpe Catalán b90e97592a feat: BUMP version 1.3 2018-08-02 17:32:31 +02:00
Juanpe Catalán 9fbaaa02f5 feat: Update README and CHANGELOG file 2018-08-02 17:32:23 +02:00
Juanpe Catalán 3f7f2ec95c feat: Remove useless code 2018-08-02 16:33:20 +02:00
Juanpe Catalán 26da7e3fc0 feat: Rename SkeletonAppearance 2018-08-02 16:32:57 +02:00
Juanpe Catalán 804390e98a feat: Create SkeletonViewAppearance 2018-08-02 16:18:41 +02:00
Juanpe Catalán 3bf613da0d Merge pull request #84 from reececomo/83-Customisable-Defaults
#83 Customisable Defaults
2018-08-02 15:41:40 +02:00
Reece Como 0eff052314 Merge pull request #1 from reececomo/83-Customisable-Defaults
#83 Customisable Defaults
2018-08-02 16:32:39 +08:00
Reece Como af91af3716 #83 Customisable Defaults 2018-08-02 16:08:31 +08:00
Juanpe Catalán 2fe2323cc1 Merge pull request #42 from kjoneandrei/feature/fix_skeleton_collectionView
Fix: Skeleton loading for UICollectionView
2018-07-31 09:54:00 +02:00
anho 024171a993 fixed collectionview xib and skeleton 2018-07-27 15:28:59 +02:00
Juanpe Catalán 726817cfe5 feat: Add credits 2018-07-27 13:05:14 +02:00
Juanpe Catalán 9684817956 feat: Change README path 2018-07-27 13:00:36 +02:00
Juanpe Catalán 3a847ece3d fix: Link to Chinese README file 2018-07-27 12:43:11 +02:00
Juanpe Catalán a0fb735c3e feat: Add Chinese README file 2018-07-27 12:38:16 +02:00
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
149 changed files with 8572 additions and 1208 deletions
+6
View File
@@ -0,0 +1,6 @@
{
"SWIFT": {
"TOO_MANY_FUNCTIONS": [50, 100, 150, 200],
"TOTAL_LOC": [200, 400, 500, 600]
}
}
+1
View File
@@ -0,0 +1 @@
github: [juanpe]
+56
View File
@@ -0,0 +1,56 @@
---
name: "\U0001F41B Bug report"
about: Report a bug or unexpected behavior while using SkeletonView
title: ''
labels: bug
assignees: ''
---
### Description
Describe your issue here.
### What type of issue is this? (place an `x` in one of the `[ ]`)
- [ ] bug
- [ ] enhancement (feature request)
- [ ] question
- [ ] documentation related
- [ ] discussion
### Requirements (place an `x` in each of the `[ ]`)
* [ ] I've read and understood the [Contributing guidelines](https://github.com/Juanpe/SkeletonView/blob/main/CONTRIBUTING.md) and have done my best effort to follow them.
* [ ] I've read and agree to the [Code of Conduct](https://github.com/Juanpe/SkeletonView/blob/main/CODE_OF_CONDUCT.md).
* [ ] I've searched for any related issues and avoided creating a duplicate issue.
---
### Bug Report
Filling out the following details about bugs will help us solve your issue sooner.
### SkeletonView Environment:
**SkeletonView version:**
**Xcode version:**
**Swift version:**
#### Steps to reproduce:
*Please replace this with the steps to reproduce the behavior.*
1.
2.
3.
#### Expected result:
*Please replace this with what you expected to happen.*
#### Actual result:
*Please replace this with of what happened instead.*
#### Attachments:
Logs, screenshots, sample project, funny gif, etc.
+28
View File
@@ -0,0 +1,28 @@
---
name: "\U0001F4E3 Feedback"
about: Give us general feedback about the SkeletonView
title: ''
labels: feedback
assignees: ''
---
# SkeletonView Feedback
You can use this template to give us structured feedback or just wipe it and leave us a note. Thank you!
## What have you loved?
_eg "the nice colors"_
## What was confusing or gave you pause?
_eg "it did something unexpected"_
## Are there features you'd like to see added?
_eg "SkeletonView should be compatible with SwiftUI"_
## Anything else?
_eg "have a nice day"_
@@ -0,0 +1,20 @@
---
name: "⭐ Submit a request"
about: Surface a feature or problem that you think should be solved
title: ''
labels: enhancement
assignees: ''
---
### Describe the feature or problem youd like to solve
A clear and concise description of what the feature or problem is.
### Proposed solution
How will it benefit SkeletonView and its users?
### Additional context
Add any other context like screenshots or mockups are helpful, if applicable.
-23
View File
@@ -1,23 +0,0 @@
⚠️ Please fill out this template when filing an issue.
### What did you do?
*Please replace this with what you did.*
### What did you expect to happen?
*Please replace this with what you expected to happen.*
### What happened instead?
*Please replace this with of what happened instead.*
### Steps to reproduce the behavior
*Please replace this with the steps to reproduce the behavior.*
### SkeletonView Environment
**SkeletonView version:**
**Xcode version:**
**Swift version:**
+7
View File
@@ -0,0 +1,7 @@
### Summary
Describe the goal of this PR. Mention any related Issue numbers.
### Requirements (place an `x` in each of the `[ ]`)
* [ ] I've read and understood the [Contributing guidelines](https://github.com/Juanpe/SkeletonView/blob/main/CONTRIBUTING.md) and have done my best effort to follow them.
* [ ] I've read and agree to the [Code of Conduct](https://github.com/Juanpe/SkeletonView/blob/main/CODE_OF_CONDUCT.md).
+39
View File
@@ -0,0 +1,39 @@
name-template: '📦 $RESOLVED_VERSION'
tag-template: '$RESOLVED_VERSION'
category-template: '#### $TITLE'
change-template: '- **#$NUMBER**: $TITLE - @$AUTHOR'
template: |
$CHANGES
categories:
- title: '🚨 Breaking'
label: 'breaking'
- title: '🔬Improvements'
label: '💡 enhancement'
- title: '🙌 New'
label: 'feature'
- title: '🩹 Bug fixes'
label: '🐞 bug'
- title: '⚙️ Maintenance'
label: '⚙️ maintenance'
- title: '📚 Documentation'
label: '📚 docs'
- title: '💾 Dependency Updates'
label: 'dependencies'
version-resolver:
major:
labels:
- 'breaking'
minor:
labels:
- '💡 enhancement'
- 'feature'
patch:
labels:
- '🐞 bug'
- '⚙️ maintenance'
- '📚 docs'
- 'dependencies'
exclude-labels:
- 'skip-changelog'
+10
View File
@@ -0,0 +1,10 @@
daysUntilStale: 7
daysUntilClose: 7
onlyLabels:
- awaiting user input
staleLabel: given up
markComment: >
🤖 This issue has been automatically marked as stale because it has not had
recent activity. It will be closed if no further activity occurs. Thank you
for your contributions 🙂
closeComment: false
+64
View File
@@ -0,0 +1,64 @@
name: CD
on:
pull_request:
branches: [main]
types: [closed]
jobs:
release_version:
if: github.event.pull_request.milestone == null && github.event.pull_request.merged == true
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Setup fastlane
run: brew install fastlane
- name: Publish release
id: publish_release
uses: release-drafter/release-drafter@v5
with:
publish: true
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Update podspec
run: fastlane bump_version next_version:${{ steps.publish_release.outputs.tag_name }}
- name: Commit changes
uses: stefanzweifel/git-auto-commit-action@v4
with:
branch: 'main'
commit_message: 'Bump version ${{ steps.publish_release.outputs.tag_name }}'
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Deploy to Cocoapods
env:
COCOAPODS_TRUNK_TOKEN: ${{ secrets.COCOAPODS_TRUNK_TOKEN }}
run: |
set -eo pipefail
pod lib lint --allow-warnings
pod trunk push --allow-warnings
- name: Communicate on PR released
uses: unsplash/comment-on-pr@master
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
msg: |
Congratulations! 🎉 This was released as part of [SkeletonView ${{ steps.publish_release.outputs.tag_name }}](${{ steps.publish_release.outputs.html_url }}) 🚀
- name: Tweet the release
uses: ethomson/send-tweet-action@v1
with:
consumer-key: ${{ secrets.TWITTER_CONSUMER_API_KEY }}
consumer-secret: ${{ secrets.TWITTER_CONSUMER_API_SECRET }}
access-token: ${{ secrets.TWITTER_ACCESS_TOKEN }}
access-token-secret: ${{ secrets.TWITTER_ACCESS_TOKEN_SECRET }}
status: |
🎉 New release ${{ steps.publish_release.outputs.tag_name }} is out 🚀
Check out all the changes here:
${{ steps.publish_release.outputs.html_url }}
+19
View File
@@ -0,0 +1,19 @@
name: CI
on:
pull_request:
branches: [main]
jobs:
build:
runs-on: macos-latest
strategy:
matrix:
build-config:
- { target: 'SkeletonView-iOS', destination: 'platform=iOS Simulator,name=iPhone 8', sdk: 'iphonesimulator' }
- { target: 'SkeletonView-tvOS', destination: 'platform=tvOS Simulator,name=Apple TV', sdk: 'appletvsimulator' }
- { target: 'SkeletonViewExample', destination: 'platform=iOS Simulator,name=iPhone 8', sdk: 'iphonesimulator' }
steps:
- uses: actions/checkout@v2
- name: Build
run: xcodebuild clean build -target '${{ matrix.build-config['target'] }}' -sdk '${{ matrix.build-config['sdk'] }}' -destination '${{ matrix.build-config['destination'] }}'
+14
View File
@@ -0,0 +1,14 @@
name: Pod lint
on: [workflow_dispatch]
jobs:
pod_lib_lint:
runs-on: macOS-latest
steps:
- uses: actions/checkout@v2
- env:
COCOAPODS_TRUNK_TOKEN: ${{ secrets.COCOAPODS_TRUNK_TOKEN }}
run: |
set -eo pipefail
pod lib lint --allow-warnings
+38
View File
@@ -0,0 +1,38 @@
name: Release
on: [workflow_dispatch]
jobs:
release_version:
runs-on: macOS-latest
steps:
- uses: actions/checkout@v2
- name: Setup fastlane
run: brew install fastlane
- name: Publish release
id: publish_release
uses: release-drafter/release-drafter@v5
with:
publish: true
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Update podspec
run: fastlane bump_version next_version:${{ steps.publish_release.outputs.tag_name }}
- name: Commit changes
uses: stefanzweifel/git-auto-commit-action@v4
with:
branch: 'main'
commit_message: 'Bump version ${{ steps.publish_release.outputs.tag_name }}'
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Deploy to Cocoapods
env:
COCOAPODS_TRUNK_TOKEN: ${{ secrets.COCOAPODS_TRUNK_TOKEN }}
run: |
set -eo pipefail
pod lib lint --allow-warnings
pod trunk push --allow-warnings
+14
View File
@@ -0,0 +1,14 @@
name: Release Notes
on:
push:
branches:
- main
jobs:
update_release_notes:
runs-on: ubuntu-latest
steps:
- uses: release-drafter/release-drafter@master
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+34
View File
@@ -0,0 +1,34 @@
name: Validations
on:
pull_request_target:
branches: [main]
types: [opened, reoneped, edited, synchronized]
# workflow_dispatch:
# inputs:
# commit hash:
# description: "Commit hash"
# required: true
# default: ""
jobs:
lint:
runs-on: macos-latest
steps:
- uses: actions/checkout@v2
- name: Run SwiftLint
run: swiftlint lint --reporter github-actions-logging
danger:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Danger
uses: docker://frmeloni/danger-swift-with-swiftlint:1.3.1
with:
args: --failOnErrors --verbose
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+6 -1
View File
@@ -21,6 +21,7 @@ xcuserdata/
*.moved-aside
*.xccheckout
*.xcscmblueprint
.DS_Store
## Obj-C/Swift specific
*.hmap
@@ -45,7 +46,7 @@ playground.xcworkspace
# you should judge for yourself, the pros and cons are mentioned at:
# https://guides.cocoapods.org/using/using-cocoapods.html#should-i-check-the-pods-directory-into-source-control
#
# Pods/
Pods/
# Carthage
#
@@ -65,3 +66,7 @@ fastlane/report.xml
fastlane/Preview.html
fastlane/screenshots
fastlane/test_output
# JetBrains
.idea
+1 -1
View File
@@ -1 +1 @@
4.0
5.0
Executable
+69
View File
@@ -0,0 +1,69 @@
included:
- Sources
disabled_rules:
- trailing_whitespace
- line_length
- type_body_length
- identifier_name
- multiple_closures_with_trailing_closure
- class_delegate_protocol
- force_unwrapping
- force_try
- force_cast
- function_parameter_count
- discouraged_optional_collection
- shorthand_operator
- reduce_boolean
- weak_delegate
- nesting
- closure_end_indentation
- function_default_parameter_at_end
- unowned_variable_capture
- legacy_constructor
opt_in_rules:
- multiline_arguments
- multiline_parameters
- closure_spacing
- closure_body_length
- collection_alignment
- contains_over_filter_is_empty
- contains_over_filter_count
- contains_over_first_not_nil
- contains_over_range_nil_comparison
- convenience_type
- discouraged_object_literal
- discouraged_optional_boolean
- empty_count
- empty_string
- fallthrough
- file_name_no_space
- first_where
- flatmap_over_map_reduce
- implicitly_unwrapped_optional
- joined_default_parameter
- last_where
- literal_expression_end_indentation
- multiline_function_chains
- operator_usage_whitespace
- private_action
- private_outlet
- redundant_optional_initialization
- redundant_set_access_control
- redundant_type_annotation
- sorted_first_last
- switch_case_on_newline
- unneeded_parentheses_in_closure_argument
- unused_declaration
- unused_import
- vertical_whitespace_opening_braces
- discouraged_optional_collection
- enum_case_associated_values_counts
- legacy_multiple
- legacy_random
indentation: 2
file_length:
- 2500
- 3000
large_tuple:
- 5
- 6
-6
View File
@@ -1,6 +0,0 @@
language: objective-c
osx_image: xcode9
script:
- xcodebuild -project SkeletonView.xcodeproj -target SkeletonView-iOS -sdk iphonesimulator -destination 'platform=iOS Simulator,name=iPhone 7,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: 21 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 34 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.5 KiB

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 34 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 34 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.2 KiB

After

Width:  |  Height:  |  Size: 9.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 38 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 222 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 54 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 388 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.

After

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 34 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 17 KiB

After

Width:  |  Height:  |  Size: 44 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 228 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 108 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 32 KiB

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 27 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 267 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 30 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 29 KiB

+212 -17
View File
@@ -1,50 +1,245 @@
# 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)
### Next version
### New
#### 🙌 New
#### 🔬 Improvements
* [**369**](https://github.com/Juanpe/SkeletonView/pull/369): remove useless corner radius constraint - [@Juanpe](https://github.com/Juanpe)
* [**357**](https://github.com/Juanpe/SkeletonView/pull/357): Removed duplicate code in SkeletonCollectionDelegate. - [@keshavamurthy1](https://github.com/keshavamurthy1)
#### 🩹 Bug fixes
* [**359**](https://github.com/Juanpe/SkeletonView/pull/359): SkeletonView respecting Font's height, rather than the `UIView` actual height. - [@keshavamurthy1](https://github.com/keshavamurthy1)
## 📦 [1.11.0](https://github.com/Juanpe/SkeletonView/releases/tag/1.11.0)
#### 🙌 New
* [**339**](https://github.com/Juanpe/SkeletonView/pull/339): Add `hiddenWhenSkeletonIsActive` property - [@mohn93](https://github.com/mohn93)
* [**341**](https://github.com/Juanpe/SkeletonView/pull/341): Support autoreverses in gradient animations - [@Juanpe](https://github.com/Juanpe)
#### 🔬Improvements
* [**344**](https://github.com/Juanpe/SkeletonView/pull/344): Resize labels based on number of lines - [@Juanpe](https://github.com/Juanpe)
#### 🩹 Bug fixes
* [**340**](https://github.com/Juanpe/SkeletonView/pull/340): Fixed incorrect padding, and incorrect multiline layer frame calculation - [@yzhao198](https://github.com/yzhao198)
## 📦 [1.10.0](https://github.com/Juanpe/SkeletonView/releases/tag/1.10.0)
#### 🙌 New
* [**327**](https://github.com/Juanpe/SkeletonView/pull/327): Add SwiftLint - [@Juanpe](https://github.com/Juanpe)
* [**329**](https://github.com/Juanpe/SkeletonView/pull/329): Spanish README 🇪🇸 - [@Juanpe](https://github.com/Juanpe)
#### 🩹 Bug fixes
* [**336**](https://github.com/Juanpe/SkeletonView/pull/336): Not replace text when the skeleton disappears. Solved issues: [#296](https://github.com/Juanpe/SkeletonView/issues/296), [#330](https://github.com/Juanpe/SkeletonView/issues/330) - [@Juanpe](https://github.com/Juanpe)
* [**337**](https://github.com/Juanpe/SkeletonView/pull/337): RTL support. Solved issues: [#143](https://github.com/Juanpe/SkeletonView/issues/143) - [@Juanpe](https://github.com/Juanpe)
## 📦 [1.9](https://github.com/Juanpe/SkeletonView/releases/tag/1.9)
#### 🩹 Bug fixes
* [**319**](https://github.com/Juanpe/SkeletonView/pull/319): Fix to consider the top and bottom edge insets when updating the skeleton layer height - [@xpereta](https://github.com/xpereta)
* [**320**](https://github.com/Juanpe/SkeletonView/pull/320): Fix Single line customisation - [@Juanpe](https://github.com/juanpe)
* [**323**](https://github.com/Juanpe/SkeletonView/pull/323): Save and restore view state for UIButton - [@Juanpe](https://github.com/juanpe)
## 📦 [1.8.8](https://github.com/Juanpe/SkeletonView/releases/tag/1.8.8)
#### 🙌 New
* [**304**](https://github.com/Juanpe/SkeletonView/pull/304): French README 🇫🇷 - [@OmarJalil](https://github.com/OmarJalil)
#### 🔬Improvements
* [**311**](https://github.com/Juanpe/SkeletonView/pull/311): Bump json from 2.2.0 to 2.3.1 - [@dependabot](https://github.com/dependabot)
#### 🩹 Bug fixes
* [**286**](https://github.com/Juanpe/SkeletonView/pull/286): Fix issue when WKWebView calls skeletonLayoutSubviews not on the main thread - [@paulanatoleclaudot-betclic](https://github.com/paulanatoleclaudot-betclic)
* [**292**](https://github.com/Juanpe/SkeletonView/pull/292): Fix IBInspectable support when using Carthage - [@marisalaneous](https://github.com/marisalaneous)
* [**308**](https://github.com/Juanpe/SkeletonView/pull/308): Fix example backgroundColor in DarkMode - [@toshi0383](https://github.com/toshi0383)
* [**307**](https://github.com/Juanpe/SkeletonView/pull/307): Prevent incorrect skeletonLayer to be added when updating skeleton - [@wsalim1610](https://github.com/wsalim1610)
## 📦 [1.8.7](https://github.com/Juanpe/SkeletonView/releases/tag/1.8.7)
#### 🔬Improvements
* [**271**](https://github.com/Juanpe/SkeletonView/pull/271): Add corner radius for skeletonView as IBInspectable (CGFloat) default is 0.0 - [@paulanatoleclaudot-betclic](https://github.com/paulanatoleclaudot-betclic)
#### 🩹 Bug fixes
* [**259**](https://github.com/Juanpe/SkeletonView/issues/259): Prevent isSkeletonActive to be called when isSkeletonable is false - [@wsalim1610](https://github.com/wsalim1610)
* [**274**](https://github.com/Juanpe/SkeletonView/pull/274): Fix: hiding skeleton when header and footer views of section would not hide it - [@darkside999](https://github.com/darkside999)
* [**273**](https://github.com/Juanpe/SkeletonView/pull/273): Fix: in vertical stack view with center alignment show incorrect position - [@koooootake](https://github.com/koooootake)
## 📦 [1.8.6](https://github.com/Juanpe/SkeletonView/releases/tag/1.8.6)
#### 🔬Improvements
* [**242**](https://github.com/Juanpe/SkeletonView/pull/242): Offscreen table view layout issue fixed - [@Cacodemon](https://github.com/Cacodemon)
* [**261**](https://github.com/Juanpe/SkeletonView/pull/261): Fixes removing skeleton layers from table header footer sections - [@darkside999](https://github.com/darkside999)
* [**263**](https://github.com/Juanpe/SkeletonView/pull/263): Feature/set cross dissolve transitions as default - [@Juanpe](https://github.com/Juanpe)
* [**264**](https://github.com/Juanpe/SkeletonView/pull/264): not replace original datasource is running XCTests - [@Juanpe](https://github.com/Juanpe)
* [**265**](https://github.com/Juanpe/SkeletonView/pull/265): call original traitCollectionDidChange method - [@Juanpe](https://github.com/Juanpe)
#### 🩹 Bug fixes
* [**260**](https://github.com/Juanpe/SkeletonView/issues/260): Don't hide skeleton layers on TableViewHeaderFooterView
* [**257**](https://github.com/Juanpe/SkeletonView/issues/257): Unit test problem when using SkeletonView
## 📦 [1.8.3](https://github.com/Juanpe/SkeletonView/releases/tag/1.8.3)
- Support for iOS 13 dark mode. (thanks @Wilsonator5000)
## 📦 [1.8.2](https://github.com/Juanpe/SkeletonView/releases/tag/1.8.2)
#### 🙌 New
- Add ability to customize line spacing per label. (thanks @gshahbazian)
## 📦 [LayoutSkeleton (1.8.1)](https://github.com/Juanpe/SkeletonView/releases/tag/1.8.1)
#### 🔬Improvements
- Fix completion call in .none transition style while hide skeletons. (thanks @aadudyrev)
#### 🙌 New
- Swizzle `layoutSubviews` method.
#### 🔬Improvements
- Fix completion call in .none transition style while hiding skeletons. (thanks @aadudyrev)
- Swift format.
#### 🩹 Bug fixes
- Update layout subviews when the original method is called.
- Issues: [#88, #149]
## 📦 [Transitions (1.8)](https://github.com/Juanpe/SkeletonView/releases/tag/1.8)
#### 🙌 New
- Adding swift news to mentioned section (thanks @osterbergmarcus).
- Create `SkeletonTransitionStyle`. Now, you can animate transition when you show or hide skeletons. (thanks @pontusjacobsson)
#### 🔬Improvements
- Refactor some methods.
#### 🩹 Bug fixes
- Solved issues.
[#175](https://github.com/Juanpe/SkeletonView/issues/175) Swift Package Manager version format
## 📦 [Layout update (1.7)](https://github.com/Juanpe/SkeletonView/releases/tag/1.7)
#### 🙌 New
- Allow updating skeleton layout to recalculate skeleton bounds: `layoutSkeletonIfNeeded`. See the examples to know how to use it. (thanks @eduardbosch)
#### 🔬Improvements
- Allow updating skeleton layers without recreating them: `updateSkeleton`, `updateGradientSkeleton`, `updateAnimatedSkeleton`, `updateAnimatedGradientSkeleton`. (thanks @eduardbosch)
## 📦 [Debug (1.4)](https://github.com/Juanpe/SkeletonView/releases/tag/1.4)
#### 🙌 New
- Create `skeletonDescription` print a skeleton representation of the view.
- Create `SKELETON_DEBUG` environment variable, in order to print the view hierarchy when the skeleton appears.
#### 🔬Improvements
- Add two new methods to `SkeletonFlowDelegate` protocol. Now you can know when the skeleton did show and when it did hide.
- `Recursive` protocol
#### 🩹 Bug fixes
- Solved issue [#86](https://github.com/Juanpe/SkeletonView/issues/86) (thanks @reececomo)
## 📦 [Custom defaults (1.3)](https://github.com/Juanpe/SkeletonView/releases/tag/1.3)
#### 🙌 New
- Default values customizables. Now you can set the default values of Skeleton appearance.(thanks @reececomo)
- issues: [[#50](https://github.com/Juanpe/SkeletonView/issues/50), [#83](https://github.com/Juanpe/SkeletonView/issues/83)]
#### 🩹 Bug fixes
- Solved issue [#41](https://github.com/Juanpe/SkeletonView/issues/41). Now, Skeleton works if UICollectionView cell's Nib is registered in code. (thanks @kjoneandrei)
## 📦 [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.
#### 🩹 Bug fixes
- 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)
## 📦 [Resizable (1.0.5)](https://github.com/Juanpe/SkeletonView/releases/tag/1.0.5)
### New
#### 🙌 New
- Now you can use table views with resizable cells.
### Bug fixes
#### 🩹 Bug fixes
- Solved issues.
[#17](https://github.com/Juanpe/SkeletonView/issues/17),
[#30](https://github.com/Juanpe/SkeletonView/issues/30),
[#34](https://github.com/Juanpe/SkeletonView/issues/34).
## [Filled or not (1.0.4)](https://github.com/Juanpe/SkeletonView/releases/tag/1.0.4)
## 📦 [Filled or not (1.0.4)](https://github.com/Juanpe/SkeletonView/releases/tag/1.0.4)
### New
#### 🙌 New
- You can set the filling percent of the last line in multiline elements (thanks @jontelang!)
### Bug fixes
#### 🩹 Bug fixes
- Solved issue [#14](https://github.com/Juanpe/SkeletonView/issues/14). You could edit text views with skeleton active.
## [In all directions (1.0.3)](https://github.com/Juanpe/SkeletonView/releases/tag/1.0.3)
## 📦 [In all directions (1.0.3)](https://github.com/Juanpe/SkeletonView/releases/tag/1.0.3)
### New
#### 🙌 New
- Create ```SkeletonAnimationBuilder```, to facilitate the creation of layer animations.
```GradientDirection``` enum.
## [Retro (1.0.2)](https://github.com/Juanpe/SkeletonView/releases/tag/1.0.2)
## 📦 [Retro (1.0.2)](https://github.com/Juanpe/SkeletonView/releases/tag/1.0.2)
### New
#### 🙌 New
- Change some private keywords, to be Swift 3 compatible
## [Early bird bug (1.0.1)](https://github.com/Juanpe/SkeletonView/releases/tag/1.0.2)
## 📦 [Early bird bug (1.0.1)](https://github.com/Juanpe/SkeletonView/releases/tag/1.0.2)
### Bug fixes
#### 🩹 Bug fixes
- It was not removing the skeleton layer
## [Starter (1.0)](https://github.com/Juanpe/SkeletonView/releases/tag/1.0)
## 📦 [Starter (1.0)](https://github.com/Juanpe/SkeletonView/releases/tag/1.0)
- First release
+52
View File
@@ -0,0 +1,52 @@
# Code of Conduct
The Code of Conduct governs how we behave in public or in private
whenever the project will be judged by our actions.
We expect it to be honored by everyone who represents the project
officially or informally,
claims affiliation with the project,
or participates directly.
We strive to:
* **Be open**: We invite anybody to participate in any aspect of our projects.
Our community is open, and any responsibility can be carried
by any contributor who demonstrates the required capacity and competence.
* **Be empathetic**: We work together to resolve conflict,
assume good intentions,
and do our best to act in an empathic fashion.
By understanding that humanity drops a few packets in online interactions,
and adjusting accordingly,
we can create a comfortable environment for everyone to share their ideas.
* **Be collaborative**: We prefer to work transparently
and to involve interested parties early on in the process.
Wherever possible, we work closely with others in the open source community
to coordinate our efforts.
* **Be decisive**: We expect participants in the project to resolve disagreements constructively.
When they cannot, we escalate the matter to structures
with designated leaders to arbitrate and provide clarity and direction.
* **Be responsible**: We hold ourselves accountable for our actions.
When we make mistakes, we take responsibility for them.
When we need help, we reach out to others.
When it comes time to move on from a project,
we take the proper steps to ensure that others can pick up where we left off.
This code is not exhaustive or complete.
It serves to distill our common understanding of a
collaborative, shared environment and goals.
We expect it to be followed in spirit as much as in the letter.
---
The **SkeletonView** Code of Conduct is adapted from the [Contributor Covenant][homepage],
version 2.0, available at
https://www.contributor-covenant.org/version/2/0/code_of_conduct.html.
Community Impact Guidelines were inspired by [Mozilla's code of conduct
enforcement ladder](https://github.com/mozilla/diversity).
[homepage]: https://www.contributor-covenant.org
For answers to common questions about this code of conduct, see the FAQ at
https://www.contributor-covenant.org/faq. Translations are available at
https://www.contributor-covenant.org/translations.
+77
View File
@@ -0,0 +1,77 @@
# Contributors Guide
Interested in contributing? Awesome! Before you do though, please read our
[Code of Conduct](https://github.com/Juanpe/SkeletonView/blob/main/CODE_OF_CONDUCT.md). We take it very seriously, and expect that you will as
well.
There are many ways you can contribute! :heart:
### Bug Reports and Fixes :bug:
- If you find a bug, please search for it in the [Issues](https://github.com/Juanpe/SkeletonView/issues), and if it isn't already tracked,
[create a new issue](https://github.com/slackhq/PanModal/issues/new). Fill out the "Bug Report" section of the issue template. Even if an Issue is closed, feel free to comment and add details, it will still
be reviewed.
- Issues that have already been identified as a bug (note: able to reproduce) will be labelled `🐞 Bug`.
- If you'd like to submit a fix for a bug, [send a Pull Request](#creating_a_pull_request) and mention the Issue number.
### New Features :bulb:
- If you'd like to add new functionality to this project, describe the problem you want to solve in a [new Issue](https://github.com/Juanpe/SkeletonView/issues/new).
- Issues that have been identified as a feature request will be labelled `💡 Enhancement`.
- If you'd like to implement the new feature, please wait for feedback from the project
maintainers before spending too much time writing the code. In some cases, `💡 Enhancement`s may
not align well with the project objectives at the time.
### Miscellaneous :sparkles:
- If you have an alternative implementation of something that may have advantages over the way its currently
done, or you have any other change, we would be happy to hear about it!
- If its a trivial change, go ahead and [send a Pull Request](#creating_a_pull_request) with the changes you have in mind.
- If not, [open an Issue](https://github.com/Juanpe/SkeletonView/issues/new) to discuss the idea first.
If you're new to our project and looking for some way to make your first contribution, look for
Issues labelled `good first issue`.
## Requirements
For your contribution to be accepted:
- [x] The changes must be approved by code review.
- [x] Commits should be atomic and messages must be descriptive. Related issues should be mentioned by Issue number.
If the contribution doesn't meet the above criteria, you may fail our automated checks or a maintainer will discuss it with you. You can continue to improve a Pull Request by adding commits to the branch from which the PR was created.
## Creating a Pull Request
1. :fork_and_knife: Fork the repository on GitHub.
2. :runner: Clone/fetch your fork to your local development machine.
3. :herb: Create a new branch and check it out.
4. :crystal_ball: Make your changes and commit them locally.
5. :arrow_heading_up: Push your new branch to your fork. (e.g. `git push username fix-issue-300`).
6. :inbox_tray: Open a Pull Request on github.com from your new branch on your fork to `main` in this
repository.
## Developer's Certificate of Origin 1.1
By making a contribution to this project, I certify that:
- (a) The contribution was created in whole or in part by me and I
have the right to submit it under the open source license
indicated in the file; or
- (b) The contribution is based upon previous work that, to the best
of my knowledge, is covered under an appropriate open source
license and I have the right under that license to submit that
work with modifications, whether created in whole or in part
by me, under the same open source license (unless I am
permitted to submit under a different license), as indicated
in the file; or
- (c) The contribution was provided directly to me by some other
person who certified (a), (b) or (c) and I have not modified
it.
- (d) I understand and agree that this project and the contribution
are public and that a record of the contribution (including all
personal information I submit with it, including my sign-off) is
maintained indefinitely and may be redistributed consistent with
this project or the open source license(s) involved.
*Wording of statement copied from [elinux.org](http://elinux.org/Developer_Certificate_Of_Origin)*
@@ -15,7 +15,7 @@
<key>CFBundlePackageType</key>
<string>FMWK</string>
<key>CFBundleShortVersionString</key>
<string>1.0.5</string>
<string>1.3</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>
@@ -0,0 +1,45 @@
<?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>APPL</string>
<key>CFBundleShortVersionString</key>
<string>1.0</string>
<key>CFBundleVersion</key>
<string>1</string>
<key>LSRequiresIPhoneOS</key>
<true/>
<key>UILaunchStoryboardName</key>
<string>LaunchScreen</string>
<key>UIMainStoryboardFile</key>
<string>Main</string>
<key>UIRequiredDeviceCapabilities</key>
<array>
<string>armv7</string>
</array>
<key>UISupportedInterfaceOrientations</key>
<array>
<string>UIInterfaceOrientationPortrait</string>
<string>UIInterfaceOrientationLandscapeLeft</string>
<string>UIInterfaceOrientationLandscapeRight</string>
</array>
<key>UISupportedInterfaceOrientations~ipad</key>
<array>
<string>UIInterfaceOrientationPortrait</string>
<string>UIInterfaceOrientationPortraitUpsideDown</string>
<string>UIInterfaceOrientationLandscapeLeft</string>
<string>UIInterfaceOrientationLandscapeRight</string>
</array>
</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.3</string>
<key>CFBundleVersion</key>
<string>1</string>
<key>LSRequiresIPhoneOS</key>
+34
View File
@@ -0,0 +1,34 @@
import Danger
let danger = Danger()
let github = danger.github
// Make it more obvious that a PR is a work in progress and shouldn't be merged yet
if danger.github.pullRequest.title.contains("WIP") {
warn("PR is classed as Work in Progress")
}
// Warn, asking to update all README files if only English README are updated
let enReameModified = danger.git.modifiedFiles.contains { $0.contains("README.md") }
let zhReameModified = danger.git.modifiedFiles.contains { $0.contains("README_zh.md") }
let koReameModified = danger.git.modifiedFiles.contains { $0.contains("README_ko.md") }
let ptBrReameModified = danger.git.modifiedFiles.contains { $0.contains("README_pt-br.md") }
let otherLanguagesReadmeHaveBeenModified = zhReameModified && koReameModified && ptBrReameModified
if (enReameModified && !otherLanguagesReadmeHaveBeenModified) {
warn("Consider **also** updating the README for other languages.")
}
// Warn when there is a big PR
if (danger.github.pullRequest.additions ?? 0) > 500 {
warn("Big PR, try to keep changes smaller if you can")
}
// Added (or removed) library files need to be added (or removed) from the
// Xcode project to avoid breaking things.
let addedSwiftLibraryFiles = danger.git.createdFiles.contains { $0.fileType == .swift && $0.hasPrefix("Sources") }
let deletedSwiftLibraryFiles = danger.git.deletedFiles.contains { $0.fileType == .swift && $0.hasPrefix("Sources") }
let modifiedXcodeProject = danger.git.modifiedFiles.contains { $0.contains(".xcodeproj") }
if (addedSwiftLibraryFiles || deletedSwiftLibraryFiles) && !modifiedXcodeProject {
fail("Added or removed files require the Xcode project to be updated.")
}
-216
View File
@@ -1,216 +0,0 @@
<?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">
<device id="retina4_7" orientation="portrait">
<adaptation id="fullscreen"/>
</device>
<dependencies>
<deployment identifier="iOS"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="13772"/>
<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"/>
</dependencies>
<scenes>
<!--View Controller-->
<scene sceneID="tne-QT-ifu">
<objects>
<viewController id="BYZ-38-t0r" customClass="ViewController" customModule="SkeletonViewExample" customModuleProvider="target" sceneMemberID="viewController">
<view key="view" contentMode="scaleToFill" id="8bC-Xf-vdC">
<rect key="frame" x="0.0" y="0.0" width="375" height="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">
<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"/>
<prototypes>
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" preservesSuperviewLayoutMargins="YES" selectionStyle="default" indentationWidth="10" reuseIdentifier="CellIdentifier" rowHeight="120" id="2dN-Bd-tdy" customClass="Cell" customModule="SkeletonViewExample" customModuleProvider="target">
<rect key="frame" x="0.0" y="28" width="375" height="120"/>
<autoresizingMask key="autoresizingMask"/>
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" preservesSuperviewLayoutMargins="YES" insetsLayoutMarginsFromSafeArea="NO" tableViewCell="2dN-Bd-tdy" id="7IN-F3-Mr6">
<rect key="frame" x="0.0" y="0.0" width="375" height="120"/>
<autoresizingMask key="autoresizingMask"/>
<subviews>
<imageView userInteractionEnabled="NO" contentMode="scaleToFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" 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>
<constraint firstAttribute="width" constant="82" id="4j0-PU-CmN"/>
<constraint firstAttribute="height" constant="82" id="iqE-Lc-FOj"/>
</constraints>
<userDefinedRuntimeAttributes>
<userDefinedRuntimeAttribute type="boolean" keyPath="isSkeletonable" value="YES"/>
</userDefinedRuntimeAttributes>
</imageView>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Label" textAlignment="natural" lineBreakMode="tailTruncation" numberOfLines="15" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="VhU-1t-AaI">
<rect key="frame" x="118" y="29" width="237" height="20.5"/>
<constraints>
<constraint firstAttribute="height" relation="lessThanOrEqual" constant="71" id="HRL-cI-ieC"/>
</constraints>
<fontDescription key="fontDescription" type="system" pointSize="17"/>
<nil key="textColor"/>
<nil key="highlightedColor"/>
<userDefinedRuntimeAttributes>
<userDefinedRuntimeAttribute type="boolean" keyPath="isSkeletonable" value="YES"/>
</userDefinedRuntimeAttributes>
</label>
</subviews>
<constraints>
<constraint firstItem="oiE-tt-nc2" firstAttribute="leading" secondItem="7IN-F3-Mr6" secondAttribute="leadingMargin" id="1be-ak-AH1"/>
<constraint firstItem="oiE-tt-nc2" firstAttribute="top" secondItem="7IN-F3-Mr6" secondAttribute="topMargin" constant="7" id="EKn-ST-LDX"/>
<constraint firstAttribute="trailingMargin" secondItem="VhU-1t-AaI" secondAttribute="trailing" constant="5" id="I7C-Bq-mfK"/>
<constraint firstItem="VhU-1t-AaI" firstAttribute="leading" secondItem="oiE-tt-nc2" secondAttribute="trailing" constant="21" id="Ojr-Kz-1k6"/>
<constraint firstItem="VhU-1t-AaI" firstAttribute="top" secondItem="7IN-F3-Mr6" secondAttribute="topMargin" constant="18" id="ZW6-JY-S4c"/>
</constraints>
<userDefinedRuntimeAttributes>
<userDefinedRuntimeAttribute type="boolean" keyPath="isSkeletonable" value="YES"/>
</userDefinedRuntimeAttributes>
</tableViewCellContentView>
<userDefinedRuntimeAttributes>
<userDefinedRuntimeAttribute type="boolean" keyPath="isSkeletonable" value="YES"/>
</userDefinedRuntimeAttributes>
<connections>
<outlet property="avatar" destination="oiE-tt-nc2" id="Dkh-R5-Qhu"/>
<outlet property="label1" destination="VhU-1t-AaI" id="kUW-HV-KrD"/>
</connections>
</tableViewCell>
</prototypes>
<userDefinedRuntimeAttributes>
<userDefinedRuntimeAttribute type="boolean" keyPath="isSkeletonable" value="YES"/>
</userDefinedRuntimeAttributes>
<connections>
<outlet property="dataSource" destination="BYZ-38-t0r" id="Hxi-nC-gbY"/>
</connections>
</tableView>
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="F9K-jU-100">
<rect key="frame" x="0.0" y="20" width="375" height="243"/>
<subviews>
<textView clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="scaleToFill" textAlignment="natural" translatesAutoresizingMaskIntoConstraints="NO" id="e9V-mk-xH0">
<rect key="frame" x="45" y="142" width="287" height="78"/>
<color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
<constraints>
<constraint firstAttribute="height" constant="78" id="gF5-G1-lKI"/>
</constraints>
<string key="text">Lorem ipsum dolor sit er elit lamet, consectetaur cillium adipisicing pecu, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. </string>
<fontDescription key="fontDescription" type="system" pointSize="14"/>
<textInputTraits key="textInputTraits" autocapitalizationType="sentences"/>
<userDefinedRuntimeAttributes>
<userDefinedRuntimeAttribute type="boolean" keyPath="isSkeletonable" value="YES"/>
<userDefinedRuntimeAttribute type="number" keyPath="lastLineFillPercent">
<integer key="value" value="40"/>
</userDefinedRuntimeAttribute>
</userDefinedRuntimeAttributes>
</textView>
<imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="avatar" translatesAutoresizingMaskIntoConstraints="NO" id="nMj-pU-5wJ">
<rect key="frame" x="141" y="20" width="93" height="93"/>
<color key="backgroundColor" red="0.56078431370000004" green="0.59607843140000005" blue="0.7843137255" alpha="0.90709546230000004" colorSpace="calibratedRGB"/>
<constraints>
<constraint firstAttribute="height" constant="93" id="gw9-nu-cKo"/>
<constraint firstAttribute="width" constant="93" id="zB6-Lp-IUt"/>
</constraints>
<userDefinedRuntimeAttributes>
<userDefinedRuntimeAttribute type="boolean" keyPath="isSkeletonable" value="YES"/>
</userDefinedRuntimeAttributes>
</imageView>
</subviews>
<color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
<constraints>
<constraint firstItem="nMj-pU-5wJ" firstAttribute="centerX" secondItem="F9K-jU-100" secondAttribute="centerX" id="9X4-2r-AKx"/>
<constraint firstItem="e9V-mk-xH0" firstAttribute="leading" secondItem="F9K-jU-100" secondAttribute="leading" constant="45" id="HvQ-HY-zYU"/>
<constraint firstItem="e9V-mk-xH0" firstAttribute="centerX" secondItem="F9K-jU-100" secondAttribute="centerX" constant="1" id="KcB-tG-NXa"/>
<constraint firstAttribute="height" constant="243" id="MIj-xq-gr1"/>
<constraint firstItem="e9V-mk-xH0" firstAttribute="top" secondItem="F9K-jU-100" secondAttribute="top" constant="142" id="Wcx-nZ-1lR"/>
<constraint firstAttribute="trailing" secondItem="e9V-mk-xH0" secondAttribute="trailing" constant="43" id="XbU-Og-rht"/>
<constraint firstItem="nMj-pU-5wJ" firstAttribute="top" secondItem="F9K-jU-100" secondAttribute="top" constant="20" id="hQL-cr-MaN"/>
</constraints>
<userDefinedRuntimeAttributes>
<userDefinedRuntimeAttribute type="boolean" keyPath="isSkeletonable" value="YES"/>
</userDefinedRuntimeAttributes>
</view>
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="XgY-1a-UGc">
<rect key="frame" x="0.0" y="527" width="375" height="140"/>
<subviews>
<segmentedControl opaque="NO" contentMode="scaleToFill" fixedFrame="YES" contentHorizontalAlignment="left" contentVerticalAlignment="top" segmentControlStyle="plain" selectedSegmentIndex="0" translatesAutoresizingMaskIntoConstraints="NO" id="xOL-Sq-r4i">
<rect key="frame" x="20" y="23" width="140" height="29"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
<segments>
<segment title="Solid"/>
<segment title="Gradient"/>
</segments>
<connections>
<action selector="changeSkeletonType:" destination="BYZ-38-t0r" eventType="valueChanged" id="iAS-ab-0jP"/>
</connections>
</segmentedControl>
<switch opaque="NO" contentMode="scaleToFill" horizontalHuggingPriority="750" verticalHuggingPriority="750" fixedFrame="YES" contentHorizontalAlignment="center" contentVerticalAlignment="center" on="YES" translatesAutoresizingMaskIntoConstraints="NO" id="vz0-qg-GcZ">
<rect key="frame" x="310" y="21" width="49" height="31"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
<connections>
<action selector="changeAnimated:" destination="BYZ-38-t0r" eventType="valueChanged" id="w1G-gZ-RE0"/>
</connections>
</switch>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" fixedFrame="YES" text="Animated" textAlignment="right" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="WHN-wR-TKt">
<rect key="frame" x="211" y="28" width="91" height="21"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
<fontDescription key="fontDescription" type="system" pointSize="17"/>
<nil key="textColor"/>
<nil key="highlightedColor"/>
</label>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" fixedFrame="YES" text="Color" textAlignment="right" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="7CF-rV-pK2">
<rect key="frame" x="32" y="89" width="52" height="21"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
<fontDescription key="fontDescription" type="system" pointSize="17"/>
<nil key="textColor"/>
<nil key="highlightedColor"/>
</label>
<view contentMode="scaleToFill" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="iGp-rp-t1d">
<rect key="frame" x="92" y="84" width="30" height="30"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
<color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
</view>
<button opaque="NO" contentMode="scaleToFill" fixedFrame="YES" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="Mde-Cm-CoS">
<rect key="frame" x="20" y="74" width="140" height="52"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
<connections>
<action selector="btnChangeColorTouchUpInside:" destination="BYZ-38-t0r" eventType="touchUpInside" id="cB8-Ik-LIJ"/>
</connections>
</button>
</subviews>
<color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
<constraints>
<constraint firstAttribute="height" constant="140" id="OH5-ja-ZlB"/>
</constraints>
</view>
</subviews>
<color key="backgroundColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<constraints>
<constraint firstItem="F9K-jU-100" firstAttribute="trailing" secondItem="6Tk-OE-BBY" secondAttribute="trailing" id="1es-nY-bd3"/>
<constraint firstItem="F9K-jU-100" firstAttribute="leading" secondItem="6Tk-OE-BBY" secondAttribute="leading" id="A3E-iv-1qp"/>
<constraint firstItem="XgY-1a-UGc" firstAttribute="trailing" secondItem="6Tk-OE-BBY" secondAttribute="trailing" id="Luk-cg-4Ez"/>
<constraint firstItem="UCB-SP-lQk" firstAttribute="leading" secondItem="6Tk-OE-BBY" secondAttribute="leading" id="Qbw-Rq-Rhw"/>
<constraint firstItem="F9K-jU-100" firstAttribute="top" secondItem="6Tk-OE-BBY" secondAttribute="top" id="VLb-cX-ZHC"/>
<constraint firstItem="XgY-1a-UGc" firstAttribute="leading" secondItem="6Tk-OE-BBY" secondAttribute="leading" id="Y8A-sq-fmq"/>
<constraint firstItem="XgY-1a-UGc" firstAttribute="top" secondItem="UCB-SP-lQk" secondAttribute="bottom" id="eof-MM-DrW"/>
<constraint firstItem="UCB-SP-lQk" firstAttribute="top" secondItem="F9K-jU-100" secondAttribute="bottom" id="hwL-ec-fKo"/>
<constraint firstItem="UCB-SP-lQk" firstAttribute="trailing" secondItem="6Tk-OE-BBY" secondAttribute="trailing" id="o6z-Dj-ppC"/>
<constraint firstItem="XgY-1a-UGc" firstAttribute="bottom" secondItem="6Tk-OE-BBY" secondAttribute="bottom" id="vnZ-9k-MfI"/>
</constraints>
<viewLayoutGuide key="safeArea" id="6Tk-OE-BBY"/>
</view>
<navigationItem key="navigationItem" id="BEI-dU-kr2"/>
<connections>
<outlet property="avatarImage" destination="nMj-pU-5wJ" id="9fa-Z7-vYi"/>
<outlet property="colorSelectedView" destination="iGp-rp-t1d" id="0Zm-9d-jRU"/>
<outlet property="skeletonTypeSelector" destination="xOL-Sq-r4i" id="yTr-8L-I4Y"/>
<outlet property="switchAnimated" destination="vz0-qg-GcZ" id="d2R-8x-lRb"/>
<outlet property="tableview" destination="UCB-SP-lQk" id="XV0-KX-lAN"/>
</connections>
</viewController>
<placeholder placeholderIdentifier="IBFirstResponder" id="dkx-z0-nzr" sceneMemberID="firstResponder"/>
</objects>
<point key="canvasLocation" x="-482" y="-6"/>
</scene>
</scenes>
<resources>
<image name="avatar" width="215" height="211"/>
</resources>
</document>
-19
View File
@@ -1,19 +0,0 @@
//
// Cell.swift
// SkeletonViewExample
//
// Created by Juanpe Catalán on 03/11/2017.
// Copyright © 2017 SkeletonView. All rights reserved.
//
import UIKit
class Cell: UITableViewCell {
@IBOutlet weak var avatar: UIImageView!
@IBOutlet weak var label1: UILabel!
override func awakeFromNib() {
super.awakeFromNib()
}
}
+40
View File
@@ -0,0 +1,40 @@
// Copyright © 2018 SkeletonView. All rights reserved.
import UIKit
@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {
var window: UIWindow?
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
// Override point for customization after application launch.
return true
}
func applicationWillResignActive(_ application: UIApplication) {
// Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
// Use this method to pause ongoing tasks, disable timers, and invalidate graphics rendering callbacks. Games should use this method to pause the game.
}
func applicationDidEnterBackground(_ application: UIApplication) {
// Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.
// If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
}
func applicationWillEnterForeground(_ application: UIApplication) {
// Called as part of the transition from the background to the active state; here you can undo many of the changes made on entering the background.
}
func applicationDidBecomeActive(_ application: UIApplication) {
// Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
}
func applicationWillTerminate(_ application: UIApplication) {
// Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
}
}

Before

Width:  |  Height:  |  Size: 933 B

After

Width:  |  Height:  |  Size: 933 B

@@ -0,0 +1,21 @@
{
"images" : [
{
"idiom" : "universal",
"filename" : "picture.png",
"scale" : "1x"
},
{
"idiom" : "universal",
"scale" : "2x"
},
{
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"version" : 1,
"author" : "xcode"
}
}
Binary file not shown.

After

Width:  |  Height:  |  Size: 8.0 KiB

@@ -0,0 +1,55 @@
// Copyright © 2018 SkeletonView. All rights reserved.
import UIKit
import SkeletonView
class CollectionViewCell: UICollectionViewCell {
var label: UILabel!
var imageView: UIImageView!
override init(frame: CGRect) {
super.init(frame: frame)
isSkeletonable = true
createLabel()
createImageView()
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
private func createImageView() {
imageView = UIImageView(image: UIImage(named: "picture"))
imageView.isSkeletonable = true
imageView.translatesAutoresizingMaskIntoConstraints = false
imageView.contentMode = .scaleAspectFit
addSubview(imageView)
NSLayoutConstraint.activate([
imageView.centerXAnchor.constraint(equalTo: centerXAnchor),
imageView.topAnchor.constraint(equalTo: topAnchor),
imageView.heightAnchor.constraint(equalTo: heightAnchor, multiplier: 0.75),
imageView.widthAnchor.constraint(equalTo: widthAnchor, multiplier: 0.75)
])
}
private func createLabel() {
label = UILabel()
label.isSkeletonable = true
label.text = "Lorem ipsum"
label.textAlignment = .center
label.translatesAutoresizingMaskIntoConstraints = false
addSubview(label)
NSLayoutConstraint.activate([
label.centerXAnchor.constraint(equalTo: centerXAnchor),
label.bottomAnchor.constraint(equalTo: bottomAnchor),
label.heightAnchor.constraint(equalToConstant: 40),
label.widthAnchor.constraint(equalToConstant: frame.width)
])
}
}
+212
View File
@@ -0,0 +1,212 @@
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="15702" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES" initialViewController="irH-dz-xqL">
<device id="retina4_7" orientation="portrait" appearance="light"/>
<dependencies>
<deployment identifier="iOS"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="15704"/>
<capability name="Safe area layout guides" minToolsVersion="9.0"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>
<scenes>
<!--View Controller-->
<scene sceneID="qda-qV-vJk">
<objects>
<viewController id="irH-dz-xqL" customClass="ViewController" customModule="SkeletonViewExampleUICollectionView" sceneMemberID="viewController">
<view key="view" contentMode="scaleToFill" id="Fso-nq-n6t">
<rect key="frame" x="0.0" y="0.0" width="375" height="667"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="eHI-ka-8vS">
<rect key="frame" x="0.0" y="0.0" width="375" height="243"/>
<subviews>
<textView clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="scaleToFill" textAlignment="natural" translatesAutoresizingMaskIntoConstraints="NO" id="obr-b6-dib">
<rect key="frame" x="45" y="142" width="287" height="78"/>
<color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
<constraints>
<constraint firstAttribute="height" constant="78" id="jx6-c1-U0j"/>
</constraints>
<string key="text">Lorem ipsum dolor sit er elit lamet, consectetaur cillium adipisicing pecu, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. </string>
<fontDescription key="fontDescription" type="system" pointSize="14"/>
<textInputTraits key="textInputTraits" autocapitalizationType="sentences"/>
<userDefinedRuntimeAttributes>
<userDefinedRuntimeAttribute type="boolean" keyPath="isSkeletonable" value="YES"/>
<userDefinedRuntimeAttribute type="number" keyPath="lastLineFillPercent">
<integer key="value" value="40"/>
</userDefinedRuntimeAttribute>
</userDefinedRuntimeAttributes>
</textView>
<imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="avatar" translatesAutoresizingMaskIntoConstraints="NO" id="Ql9-Jy-aWM">
<rect key="frame" x="141" y="20" width="93" height="93"/>
<color key="backgroundColor" red="0.56078431370000004" green="0.59607843140000005" blue="0.7843137255" alpha="0.90709546230000004" colorSpace="calibratedRGB"/>
<constraints>
<constraint firstAttribute="height" constant="93" id="jlG-7K-wMd"/>
<constraint firstAttribute="width" constant="93" id="xHX-Y1-dvi"/>
</constraints>
<userDefinedRuntimeAttributes>
<userDefinedRuntimeAttribute type="boolean" keyPath="isSkeletonable" value="YES"/>
</userDefinedRuntimeAttributes>
</imageView>
</subviews>
<color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
<constraints>
<constraint firstAttribute="height" relation="greaterThanOrEqual" constant="243" id="0g6-3g-uII"/>
<constraint firstAttribute="trailing" secondItem="obr-b6-dib" secondAttribute="trailing" constant="43" id="3ms-Wk-qcn"/>
<constraint firstItem="obr-b6-dib" firstAttribute="centerX" secondItem="eHI-ka-8vS" secondAttribute="centerX" constant="1" id="B5s-DM-eR8"/>
<constraint firstAttribute="height" constant="243" id="GX5-3W-tUt"/>
<constraint firstItem="Ql9-Jy-aWM" firstAttribute="centerX" secondItem="eHI-ka-8vS" secondAttribute="centerX" id="HsA-ID-oSK"/>
<constraint firstItem="Ql9-Jy-aWM" firstAttribute="top" secondItem="eHI-ka-8vS" secondAttribute="top" constant="20" id="Hxu-ae-hXQ"/>
<constraint firstItem="obr-b6-dib" firstAttribute="leading" secondItem="eHI-ka-8vS" secondAttribute="leading" constant="45" id="eop-Gq-7mO"/>
<constraint firstItem="obr-b6-dib" firstAttribute="top" secondItem="eHI-ka-8vS" secondAttribute="top" constant="142" id="inJ-75-hGX"/>
</constraints>
<viewLayoutGuide key="safeArea" id="36i-gK-pIa"/>
<userDefinedRuntimeAttributes>
<userDefinedRuntimeAttribute type="boolean" keyPath="isSkeletonable" value="YES"/>
</userDefinedRuntimeAttributes>
</view>
<collectionView clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="scaleToFill" dataMode="prototypes" translatesAutoresizingMaskIntoConstraints="NO" id="HKL-L0-T2w">
<rect key="frame" x="0.0" y="243" width="375" height="264"/>
<color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
<collectionViewFlowLayout key="collectionViewLayout" minimumLineSpacing="10" minimumInteritemSpacing="10" id="mGU-kn-rfE">
<size key="itemSize" width="50" height="50"/>
<size key="headerReferenceSize" width="0.0" height="0.0"/>
<size key="footerReferenceSize" width="0.0" height="0.0"/>
<inset key="sectionInset" minX="0.0" minY="0.0" maxX="0.0" maxY="0.0"/>
</collectionViewFlowLayout>
<cells/>
<connections>
<outlet property="dataSource" destination="irH-dz-xqL" id="wya-hE-ovQ"/>
</connections>
</collectionView>
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="JjA-MK-YzZ">
<rect key="frame" x="0.0" y="507" width="375" height="160"/>
<subviews>
<segmentedControl opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="left" contentVerticalAlignment="top" segmentControlStyle="plain" selectedSegmentIndex="0" translatesAutoresizingMaskIntoConstraints="NO" id="fMR-vj-7de">
<rect key="frame" x="20" y="21" width="145" height="32"/>
<segments>
<segment title="Solid"/>
<segment title="Gradient"/>
</segments>
<connections>
<action selector="changeSkeletonType:" destination="irH-dz-xqL" eventType="valueChanged" id="lfR-JV-DU4"/>
</connections>
</segmentedControl>
<switch opaque="NO" contentMode="scaleToFill" horizontalHuggingPriority="750" verticalHuggingPriority="750" contentHorizontalAlignment="center" contentVerticalAlignment="center" on="YES" translatesAutoresizingMaskIntoConstraints="NO" id="KBe-RM-BG8">
<rect key="frame" x="308" y="21" width="51" height="31"/>
<connections>
<action selector="changeAnimated:" destination="irH-dz-xqL" eventType="valueChanged" id="dlH-KK-iee"/>
</connections>
</switch>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Animated" textAlignment="right" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="GSj-Ze-UIK">
<rect key="frame" x="229" y="26" width="73" height="21"/>
<fontDescription key="fontDescription" type="system" pointSize="17"/>
<nil key="textColor"/>
<nil key="highlightedColor"/>
</label>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Color" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="4Hm-fj-45V">
<rect key="frame" x="20" y="61" width="41.5" height="52"/>
<fontDescription key="fontDescription" type="system" pointSize="17"/>
<nil key="textColor"/>
<nil key="highlightedColor"/>
</label>
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="HBJ-nh-56V">
<rect key="frame" x="69.5" y="72" width="30" height="30"/>
<color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
<constraints>
<constraint firstAttribute="width" constant="30" id="DVW-Tc-XEQ"/>
<constraint firstAttribute="height" constant="30" id="JfP-3b-yqX"/>
</constraints>
</view>
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="aUR-Qo-gHK">
<rect key="frame" x="20" y="61" width="100" height="52"/>
<constraints>
<constraint firstAttribute="width" constant="100" id="GvX-hq-2Qn"/>
<constraint firstAttribute="height" constant="52" id="UQe-Cf-riE"/>
</constraints>
<connections>
<action selector="btnChangeColorTouchUpInside:" destination="irH-dz-xqL" eventType="touchUpInside" id="Xca-QC-htl"/>
</connections>
</button>
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="nPs-17-vfs">
<rect key="frame" x="263" y="72" width="94" height="30"/>
<state key="normal" title="Hide skeleton"/>
<connections>
<action selector="showOrHideSkeleton:" destination="irH-dz-xqL" eventType="touchUpInside" id="lHc-k2-OgV"/>
</connections>
</button>
<stepper opaque="NO" contentMode="scaleToFill" horizontalHuggingPriority="750" verticalHuggingPriority="750" contentHorizontalAlignment="center" contentVerticalAlignment="center" value="0.25" maximumValue="5" stepValue="0.25" translatesAutoresizingMaskIntoConstraints="NO" id="3mz-9M-e7Q">
<rect key="frame" x="263" y="123" width="94" height="32"/>
<connections>
<action selector="transitionDurationStepperAction:" destination="irH-dz-xqL" eventType="valueChanged" id="Ll0-Pr-d0V"/>
</connections>
</stepper>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Fade Duration: 0.25 sec" textAlignment="right" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="5gN-Jz-44y">
<rect key="frame" x="92.5" y="130" width="162.5" height="18"/>
<fontDescription key="fontDescription" type="system" pointSize="15"/>
<nil key="textColor"/>
<nil key="highlightedColor"/>
</label>
</subviews>
<color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
<constraints>
<constraint firstItem="3mz-9M-e7Q" firstAttribute="leading" secondItem="5gN-Jz-44y" secondAttribute="trailing" constant="8" id="65e-Nj-bKG"/>
<constraint firstItem="HBJ-nh-56V" firstAttribute="centerY" secondItem="aUR-Qo-gHK" secondAttribute="centerY" id="81M-Wq-Avl"/>
<constraint firstItem="fMR-vj-7de" firstAttribute="leading" secondItem="JjA-MK-YzZ" secondAttribute="leading" constant="20" id="AyG-hI-tte"/>
<constraint firstItem="aUR-Qo-gHK" firstAttribute="leading" secondItem="fMR-vj-7de" secondAttribute="leading" id="C1b-Hl-jEg"/>
<constraint firstItem="3mz-9M-e7Q" firstAttribute="trailing" secondItem="nPs-17-vfs" secondAttribute="trailing" id="KuK-fc-jOQ"/>
<constraint firstItem="nPs-17-vfs" firstAttribute="centerY" secondItem="aUR-Qo-gHK" secondAttribute="centerY" id="MQX-E5-IDE"/>
<constraint firstItem="HBJ-nh-56V" firstAttribute="leading" secondItem="4Hm-fj-45V" secondAttribute="trailing" constant="8" id="MhM-jY-LIA"/>
<constraint firstItem="4Hm-fj-45V" firstAttribute="height" secondItem="aUR-Qo-gHK" secondAttribute="height" id="OSn-RA-wQL"/>
<constraint firstItem="4Hm-fj-45V" firstAttribute="leading" secondItem="aUR-Qo-gHK" secondAttribute="leading" id="PwQ-UR-iMq"/>
<constraint firstAttribute="height" constant="160" id="QDV-wu-e3I"/>
<constraint firstItem="5gN-Jz-44y" firstAttribute="centerY" secondItem="3mz-9M-e7Q" secondAttribute="centerY" id="TGP-Ep-0ob"/>
<constraint firstItem="nPs-17-vfs" firstAttribute="top" secondItem="KBe-RM-BG8" secondAttribute="bottom" constant="20" id="TPg-wY-9bc"/>
<constraint firstItem="4Hm-fj-45V" firstAttribute="centerY" secondItem="aUR-Qo-gHK" secondAttribute="centerY" id="V4i-bF-Jed"/>
<constraint firstItem="KBe-RM-BG8" firstAttribute="leading" secondItem="GSj-Ze-UIK" secondAttribute="trailing" constant="6" id="ehg-tW-7kq"/>
<constraint firstItem="GSj-Ze-UIK" firstAttribute="centerY" secondItem="KBe-RM-BG8" secondAttribute="centerY" id="esk-GV-DBS"/>
<constraint firstAttribute="trailing" secondItem="KBe-RM-BG8" secondAttribute="trailing" constant="18" id="hhE-rV-dV7"/>
<constraint firstItem="KBe-RM-BG8" firstAttribute="top" secondItem="JjA-MK-YzZ" secondAttribute="top" constant="21" id="pBQ-H8-xTK"/>
<constraint firstAttribute="bottom" secondItem="3mz-9M-e7Q" secondAttribute="bottom" constant="5" id="pQ9-a6-hM4"/>
<constraint firstItem="fMR-vj-7de" firstAttribute="centerY" secondItem="GSj-Ze-UIK" secondAttribute="centerY" id="q2v-t1-Zu0"/>
<constraint firstAttribute="height" relation="greaterThanOrEqual" constant="160" id="qR5-cz-YAm"/>
<constraint firstItem="nPs-17-vfs" firstAttribute="trailing" secondItem="KBe-RM-BG8" secondAttribute="trailing" id="yls-k6-ZfC"/>
</constraints>
</view>
</subviews>
<color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
<constraints>
<constraint firstItem="eHI-ka-8vS" firstAttribute="trailing" secondItem="2Gq-Y8-1TU" secondAttribute="trailing" id="0dc-Vd-yJY"/>
<constraint firstItem="JjA-MK-YzZ" firstAttribute="leading" secondItem="2Gq-Y8-1TU" secondAttribute="leading" id="57i-UV-Wqd"/>
<constraint firstItem="eHI-ka-8vS" firstAttribute="leading" secondItem="2Gq-Y8-1TU" secondAttribute="leading" id="5tt-Ne-67Y"/>
<constraint firstItem="JjA-MK-YzZ" firstAttribute="bottom" secondItem="2Gq-Y8-1TU" secondAttribute="bottom" id="AAr-ke-R7M"/>
<constraint firstItem="JjA-MK-YzZ" firstAttribute="trailing" secondItem="2Gq-Y8-1TU" secondAttribute="trailing" id="DtS-9c-zBC"/>
<constraint firstItem="HKL-L0-T2w" firstAttribute="top" secondItem="eHI-ka-8vS" secondAttribute="bottom" id="Jgf-jS-PLT"/>
<constraint firstItem="eHI-ka-8vS" firstAttribute="top" secondItem="2Gq-Y8-1TU" secondAttribute="top" id="Ux2-GF-HLK"/>
<constraint firstItem="JjA-MK-YzZ" firstAttribute="top" secondItem="HKL-L0-T2w" secondAttribute="bottom" id="XEd-Gf-KFI"/>
<constraint firstItem="2Gq-Y8-1TU" firstAttribute="trailing" secondItem="HKL-L0-T2w" secondAttribute="trailing" id="bNo-98-pE4"/>
<constraint firstItem="HKL-L0-T2w" firstAttribute="leading" secondItem="2Gq-Y8-1TU" secondAttribute="leading" id="iIq-cx-paX"/>
</constraints>
<viewLayoutGuide key="safeArea" id="2Gq-Y8-1TU"/>
<userDefinedRuntimeAttributes>
<userDefinedRuntimeAttribute type="boolean" keyPath="isSkeletonable" value="YES"/>
</userDefinedRuntimeAttributes>
</view>
<connections>
<outlet property="avatarImage" destination="Ql9-Jy-aWM" id="VoL-by-ygR"/>
<outlet property="collectionView" destination="HKL-L0-T2w" id="HSe-j0-S5d"/>
<outlet property="colorSelectedView" destination="HBJ-nh-56V" id="Iiq-iY-Glj"/>
<outlet property="showOrHideSkeletonButton" destination="nPs-17-vfs" id="vw4-fW-QoD"/>
<outlet property="skeletonTypeSelector" destination="fMR-vj-7de" id="CgX-3A-weo"/>
<outlet property="switchAnimated" destination="KBe-RM-BG8" id="emU-g9-NHT"/>
<outlet property="transitionDurationLabel" destination="5gN-Jz-44y" id="69y-iR-mbi"/>
<outlet property="transitionDurationStepper" destination="3mz-9M-e7Q" id="tzK-W7-A4D"/>
</connections>
</viewController>
<placeholder placeholderIdentifier="IBFirstResponder" id="PkM-Y0-M5i" userLabel="First Responder" sceneMemberID="firstResponder"/>
</objects>
<point key="canvasLocation" x="-972" y="-209.14542728635683"/>
</scene>
</scenes>
<resources>
<image name="avatar" width="215" height="211"/>
</resources>
</document>
+199
View File
@@ -0,0 +1,199 @@
// Copyright © 2018 SkeletonView. All rights reserved.
import UIKit
import SkeletonView
class ViewController: UIViewController {
@IBOutlet weak var collectionView: UICollectionView! {
didSet {
collectionView.isSkeletonable = true
collectionView.backgroundColor = .clear
collectionView.showsHorizontalScrollIndicator = false
collectionView.showsVerticalScrollIndicator = false
collectionView.dataSource = self
collectionView.delegate = self
collectionView.register(CollectionViewCell.self, forCellWithReuseIdentifier: "CollectionViewCell")
}
}
@IBOutlet weak var avatarImage: UIImageView! {
didSet {
avatarImage.layer.cornerRadius = avatarImage.frame.width/2
avatarImage.layer.masksToBounds = true
}
}
@IBOutlet weak var colorSelectedView: UIView! {
didSet {
colorSelectedView.layer.cornerRadius = 5
colorSelectedView.layer.masksToBounds = true
colorSelectedView.backgroundColor = SkeletonAppearance.default.tintColor
}
}
@IBOutlet weak var switchAnimated: UISwitch!
@IBOutlet weak var skeletonTypeSelector: UISegmentedControl!
@IBOutlet weak var showOrHideSkeletonButton: UIButton!
@IBOutlet weak var transitionDurationLabel: UILabel!
@IBOutlet weak var transitionDurationStepper: UIStepper!
var type: SkeletonType {
return skeletonTypeSelector.selectedSegmentIndex == 0 ? .solid : .gradient
}
override func viewDidLoad() {
super.viewDidLoad()
transitionDurationStepper.value = 0.25
collectionView.prepareSkeleton(completion: { done in
self.view.showAnimatedSkeleton()
})
}
@IBAction func changeAnimated(_ sender: Any) {
if switchAnimated.isOn {
view.startSkeletonAnimation()
} else {
view.stopSkeletonAnimation()
}
}
@IBAction func changeSkeletonType(_ sender: Any) {
refreshSkeleton()
}
@IBAction func btnChangeColorTouchUpInside(_ sender: Any) {
showAlertPicker()
}
@IBAction func showOrHideSkeleton(_ sender: Any) {
showOrHideSkeletonButton.setTitle((view.isSkeletonActive ? "Show skeleton" : "Hide skeleton"), for: .normal)
view.isSkeletonActive ? hideSkeleton() : showSkeleton()
}
@IBAction func transitionDurationStepperAction(_ sender: Any) {
transitionDurationLabel.text = "transition duration: \(transitionDurationStepper.value) sec"
}
func showSkeleton() {
refreshSkeleton()
}
func hideSkeleton() {
view.hideSkeleton(transition: .crossDissolve(transitionDurationStepper.value))
}
func refreshSkeleton() {
self.view.hideSkeleton()
if type == .gradient { showGradientSkeleton() }
else { showSolidSkeleton() }
}
func showSolidSkeleton() {
if switchAnimated.isOn {
view.showAnimatedSkeleton(usingColor: colorSelectedView.backgroundColor!, transition: .crossDissolve(transitionDurationStepper.value))
} else {
view.showSkeleton(usingColor: colorSelectedView.backgroundColor!, transition: .crossDissolve(transitionDurationStepper.value))
}
}
func showGradientSkeleton() {
let gradient = SkeletonGradient(baseColor: colorSelectedView.backgroundColor!)
if switchAnimated.isOn {
view.showAnimatedGradientSkeleton(usingGradient: gradient, transition: .crossDissolve(transitionDurationStepper.value))
} else {
view.showGradientSkeleton(usingGradient: gradient, transition: .crossDissolve(transitionDurationStepper.value))
}
}
func showAlertPicker() {
let alertView = UIAlertController(title: "Select color", message: "\n\n\n\n\n\n", preferredStyle: .alert)
let pickerView = UIPickerView(frame: CGRect(x: 0, y: 50, width: 260, height: 115))
pickerView.dataSource = self
pickerView.delegate = self
alertView.view.addSubview(pickerView)
let action = UIAlertAction(title: "OK", style: .default) { [unowned pickerView, unowned self] _ in
let row = pickerView.selectedRow(inComponent: 0)
self.colorSelectedView.backgroundColor = colors[row].0
self.refreshSkeleton()
}
alertView.addAction(action)
let cancelAction = UIAlertAction(title: "Cancel", style: .cancel, handler: nil)
alertView.addAction(cancelAction)
present(alertView, animated: false, completion: {
pickerView.frame.size.width = alertView.view.frame.size.width
})
}
}
// MARK: - UIPickerViewDelegate, UIPickerViewDataSource
extension ViewController: UIPickerViewDelegate, UIPickerViewDataSource {
func numberOfComponents(in pickerView: UIPickerView) -> Int {
return 1
}
func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
return colors.count
}
func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? {
return colors[row].1
}
}
// MARK: - UICollectionViewDelegateFlowLayout
extension ViewController: UICollectionViewDelegateFlowLayout {
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
return CGSize(width: view.frame.width/3 - 10, height: view.frame.width/3 - 10)
}
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumInteritemSpacingForSectionAt section: Int) -> CGFloat {
return 5
}
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumLineSpacingForSectionAt section: Int) -> CGFloat {
return 5
}
}
// MARK: - SkeletonCollectionViewDataSource
extension ViewController: SkeletonCollectionViewDataSource {
func collectionSkeletonView(_ skeletonView: UICollectionView, cellIdentifierForItemAt indexPath: IndexPath) -> ReusableCellIdentifier {
return "CollectionViewCell"
}
func collectionSkeletonView(_ skeletonView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return 10
}
func collectionSkeletonView(_ skeletonView: UICollectionView, skeletonCellForItemAt indexPath: IndexPath) -> UICollectionViewCell? {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "CollectionViewCell", for: indexPath) as? CollectionViewCell
cell?.isSkeletonable = indexPath.row != 0
return cell
}
// MARK: - UICollectionViewDataSource
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return 10
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "CollectionViewCell", for: indexPath) as! CollectionViewCell
return cell
}
func collectionSkeletonView(_ skeletonView: UICollectionView, prepareCellForSkeleton cell: UICollectionViewCell, at indexPath: IndexPath) {
let cell = cell as? CollectionViewCell
cell?.isSkeletonable = indexPath.row != 0
}
}
-11
View File
@@ -1,11 +0,0 @@
//
// Constants.swift
// SkeletonView-iOS
//
// Created by Renato Mendes on 28/11/2017.
// Copyright © 2017 SkeletonView. All rights reserved.
//
import UIKit
let colors = [(UIColor.turquoise,"turquoise"), (UIColor.emerald,"emerald"), (UIColor.peterRiver,"peterRiver"), (UIColor.amethyst,"amethyst"),(UIColor.wetAsphalt,"wetAsphalt"), (UIColor.nephritis,"nephritis"), (UIColor.belizeHole,"belizeHole"), (UIColor.wisteria,"wisteria"), (UIColor.midnightBlue,"midnightBlue"), (UIColor.sunFlower,"sunFlower"), (UIColor.carrot,"carrot"), (UIColor.alizarin,"alizarin"),(UIColor.clouds,"clouds"), (UIColor.concrete,"concrete"), (UIColor.flatOrange,"flatOrange"), (UIColor.pumpkin,"pumpkin"), (UIColor.pomegranate,"pomegranate"), (UIColor.silver,"silver"), (UIColor.asbestos,"asbestos")]
@@ -14,7 +14,7 @@ class AppDelegate: UIResponder, UIApplicationDelegate {
var window: UIWindow?
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
// Override point for customization after application launch.
return true
}
@@ -0,0 +1,98 @@
{
"images" : [
{
"idiom" : "iphone",
"size" : "20x20",
"scale" : "2x"
},
{
"idiom" : "iphone",
"size" : "20x20",
"scale" : "3x"
},
{
"idiom" : "iphone",
"size" : "29x29",
"scale" : "2x"
},
{
"idiom" : "iphone",
"size" : "29x29",
"scale" : "3x"
},
{
"idiom" : "iphone",
"size" : "40x40",
"scale" : "2x"
},
{
"idiom" : "iphone",
"size" : "40x40",
"scale" : "3x"
},
{
"idiom" : "iphone",
"size" : "60x60",
"scale" : "2x"
},
{
"idiom" : "iphone",
"size" : "60x60",
"scale" : "3x"
},
{
"idiom" : "ipad",
"size" : "20x20",
"scale" : "1x"
},
{
"idiom" : "ipad",
"size" : "20x20",
"scale" : "2x"
},
{
"idiom" : "ipad",
"size" : "29x29",
"scale" : "1x"
},
{
"idiom" : "ipad",
"size" : "29x29",
"scale" : "2x"
},
{
"idiom" : "ipad",
"size" : "40x40",
"scale" : "1x"
},
{
"idiom" : "ipad",
"size" : "40x40",
"scale" : "2x"
},
{
"idiom" : "ipad",
"size" : "76x76",
"scale" : "1x"
},
{
"idiom" : "ipad",
"size" : "76x76",
"scale" : "2x"
},
{
"idiom" : "ipad",
"size" : "83.5x83.5",
"scale" : "2x"
},
{
"idiom" : "ios-marketing",
"size" : "1024x1024",
"scale" : "1x"
}
],
"info" : {
"version" : 1,
"author" : "xcode"
}
}
@@ -0,0 +1,6 @@
{
"info" : {
"version" : 1,
"author" : "xcode"
}
}
@@ -0,0 +1,21 @@
{
"images" : [
{
"idiom" : "universal",
"filename" : "avatar.png",
"scale" : "1x"
},
{
"idiom" : "universal",
"scale" : "2x"
},
{
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"version" : 1,
"author" : "xcode"
}
}
Binary file not shown.

After

Width:  |  Height:  |  Size: 933 B

@@ -0,0 +1,25 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="13122.16" systemVersion="17A277" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" launchScreen="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES" initialViewController="01J-lp-oVM">
<dependencies>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="13104.12"/>
<capability name="Safe area layout guides" minToolsVersion="9.0"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>
<scenes>
<!--View Controller-->
<scene sceneID="EHf-IW-A2E">
<objects>
<viewController id="01J-lp-oVM" sceneMemberID="viewController">
<view key="view" contentMode="scaleToFill" id="Ze5-6b-2t3">
<rect key="frame" x="0.0" y="0.0" width="375" height="667"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<color key="backgroundColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<viewLayoutGuide key="safeArea" id="6Tk-OE-BBY"/>
</view>
</viewController>
<placeholder placeholderIdentifier="IBFirstResponder" id="iYj-Kq-Ea1" userLabel="First Responder" sceneMemberID="firstResponder"/>
</objects>
<point key="canvasLocation" x="53" y="375"/>
</scene>
</scenes>
</document>
@@ -0,0 +1,344 @@
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="17701" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES" initialViewController="Va7-1y-Tel">
<device id="retina5_9" orientation="portrait" appearance="light"/>
<dependencies>
<deployment identifier="iOS"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="17703"/>
<capability name="Safe area layout guides" minToolsVersion="9.0"/>
<capability name="System colors in document resources" minToolsVersion="11.0"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>
<scenes>
<!--Item-->
<scene sceneID="tne-QT-ifu">
<objects>
<viewController id="BYZ-38-t0r" customClass="ViewController" customModule="SkeletonViewExample" customModuleProvider="target" sceneMemberID="viewController">
<view key="view" contentMode="scaleToFill" id="8bC-Xf-vdC">
<rect key="frame" x="0.0" y="0.0" width="375" height="812"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="F9K-jU-100" userLabel="ContainerView">
<rect key="frame" x="0.0" y="44" width="375" height="243"/>
<subviews>
<textView clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="scaleToFill" textAlignment="natural" translatesAutoresizingMaskIntoConstraints="NO" id="e9V-mk-xH0">
<rect key="frame" x="45" y="142" width="287" height="78"/>
<constraints>
<constraint firstAttribute="height" constant="78" id="gF5-G1-lKI"/>
</constraints>
<string key="text">Lorem ipsum dolor sit er elit lamet, consectetaur cillium adipisicing pecu, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. </string>
<color key="textColor" systemColor="labelColor"/>
<fontDescription key="fontDescription" type="system" pointSize="14"/>
<textInputTraits key="textInputTraits" autocapitalizationType="sentences"/>
<userDefinedRuntimeAttributes>
<userDefinedRuntimeAttribute type="boolean" keyPath="isSkeletonable" value="YES"/>
<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="scaleAspectFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="avatar" translatesAutoresizingMaskIntoConstraints="NO" id="nMj-pU-5wJ">
<rect key="frame" x="45" y="20" width="93" height="93"/>
<color key="backgroundColor" red="0.56078431370000004" green="0.59607843140000005" blue="0.7843137255" alpha="0.90709546230000004" colorSpace="calibratedRGB"/>
<constraints>
<constraint firstAttribute="height" constant="93" id="gw9-nu-cKo"/>
<constraint firstAttribute="width" constant="93" id="zB6-Lp-IUt"/>
</constraints>
<userDefinedRuntimeAttributes>
<userDefinedRuntimeAttribute type="boolean" keyPath="isSkeletonable" value="YES"/>
</userDefinedRuntimeAttributes>
</imageView>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Label" textAlignment="natural" lineBreakMode="tailTruncation" numberOfLines="3" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="CJW-A4-Fb8">
<rect key="frame" x="166" y="27" width="166" height="12"/>
<color key="backgroundColor" red="0.92156862750000001" green="0.16862745100000001" blue="0.54901960780000003" alpha="1" colorSpace="calibratedRGB"/>
<fontDescription key="fontDescription" type="system" pointSize="10"/>
<nil key="textColor"/>
<nil key="highlightedColor"/>
<userDefinedRuntimeAttributes>
<userDefinedRuntimeAttribute type="boolean" keyPath="isSkeletonable" value="YES"/>
<userDefinedRuntimeAttribute type="number" keyPath="linesCornerRadius">
<integer key="value" value="5"/>
</userDefinedRuntimeAttribute>
<userDefinedRuntimeAttribute type="number" keyPath="skeletonLineSpacing">
<real key="value" value="8"/>
</userDefinedRuntimeAttribute>
</userDefinedRuntimeAttributes>
</label>
</subviews>
<color key="backgroundColor" systemColor="systemBackgroundColor"/>
<constraints>
<constraint firstItem="CJW-A4-Fb8" firstAttribute="leading" secondItem="nMj-pU-5wJ" secondAttribute="trailing" constant="28" id="Drg-cD-6E8"/>
<constraint firstItem="e9V-mk-xH0" firstAttribute="leading" secondItem="F9K-jU-100" secondAttribute="leading" constant="45" id="HvQ-HY-zYU"/>
<constraint firstItem="e9V-mk-xH0" firstAttribute="centerX" secondItem="F9K-jU-100" secondAttribute="centerX" constant="1" id="KcB-tG-NXa"/>
<constraint firstAttribute="height" constant="243" id="MIj-xq-gr1"/>
<constraint firstItem="nMj-pU-5wJ" firstAttribute="leading" secondItem="F9K-jU-100" secondAttribute="leading" constant="45" id="TK6-Ws-2xY"/>
<constraint firstItem="e9V-mk-xH0" firstAttribute="top" secondItem="F9K-jU-100" secondAttribute="top" constant="142" id="Wcx-nZ-1lR"/>
<constraint firstAttribute="trailing" secondItem="e9V-mk-xH0" secondAttribute="trailing" constant="43" id="XbU-Og-rht"/>
<constraint firstItem="CJW-A4-Fb8" firstAttribute="top" secondItem="F9K-jU-100" secondAttribute="top" constant="27" id="ceh-gB-7Et"/>
<constraint firstItem="nMj-pU-5wJ" firstAttribute="top" secondItem="F9K-jU-100" secondAttribute="top" constant="20" id="hQL-cr-MaN"/>
<constraint firstAttribute="trailing" secondItem="CJW-A4-Fb8" secondAttribute="trailing" constant="43" id="nfT-a5-z36"/>
</constraints>
<userDefinedRuntimeAttributes>
<userDefinedRuntimeAttribute type="boolean" keyPath="isSkeletonable" value="YES"/>
</userDefinedRuntimeAttributes>
</view>
<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="287" width="375" height="282"/>
<color key="separatorColor" red="0.1061807256" green="0.84678786989999999" blue="0.031482450150000001" alpha="1" colorSpace="custom" customColorSpace="displayP3"/>
<prototypes>
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" preservesSuperviewLayoutMargins="YES" selectionStyle="default" indentationWidth="10" reuseIdentifier="CellIdentifier" rowHeight="120" id="2dN-Bd-tdy" customClass="Cell" customModule="SkeletonViewExample" customModuleProvider="target">
<rect key="frame" x="0.0" y="28" width="375" height="120"/>
<autoresizingMask key="autoresizingMask"/>
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" preservesSuperviewLayoutMargins="YES" insetsLayoutMarginsFromSafeArea="NO" tableViewCell="2dN-Bd-tdy" id="7IN-F3-Mr6">
<rect key="frame" x="0.0" y="0.0" width="375" height="120"/>
<autoresizingMask key="autoresizingMask"/>
<subviews>
<imageView userInteractionEnabled="NO" contentMode="scaleToFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="avatar" translatesAutoresizingMaskIntoConstraints="NO" id="oiE-tt-nc2">
<rect key="frame" x="16" y="18" width="82" height="82"/>
<color key="backgroundColor" red="0.56078431370000004" green="0.59607843140000005" blue="0.7843137255" alpha="0.90709546230000004" colorSpace="calibratedRGB"/>
<constraints>
<constraint firstAttribute="width" constant="82" id="4j0-PU-CmN"/>
<constraint firstAttribute="height" constant="82" id="iqE-Lc-FOj"/>
</constraints>
<userDefinedRuntimeAttributes>
<userDefinedRuntimeAttribute type="boolean" keyPath="isSkeletonable" value="YES"/>
</userDefinedRuntimeAttributes>
</imageView>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Label" textAlignment="natural" lineBreakMode="tailTruncation" numberOfLines="2" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="VhU-1t-AaI" userLabel="Label">
<rect key="frame" x="119" y="29" width="235" height="20"/>
<color key="backgroundColor" red="0.92156862750000001" green="0.16862745100000001" blue="0.54901960780000003" alpha="1" colorSpace="calibratedRGB"/>
<constraints>
<constraint firstAttribute="height" constant="20" id="HRL-cI-ieC"/>
</constraints>
<fontDescription key="fontDescription" type="system" pointSize="15"/>
<nil key="textColor"/>
<nil key="highlightedColor"/>
<userDefinedRuntimeAttributes>
<userDefinedRuntimeAttribute type="boolean" keyPath="isSkeletonable" value="YES"/>
<userDefinedRuntimeAttribute type="number" keyPath="linesCornerRadius">
<integer key="value" value="5"/>
</userDefinedRuntimeAttribute>
<userDefinedRuntimeAttribute type="number" keyPath="lastLineFillPercent">
<integer key="value" value="20"/>
</userDefinedRuntimeAttribute>
</userDefinedRuntimeAttributes>
</label>
<textField opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="left" contentVerticalAlignment="center" borderStyle="roundedRect" placeholder="placeholder" textAlignment="natural" minimumFontSize="17" translatesAutoresizingMaskIntoConstraints="NO" id="dha-bH-Ipf">
<rect key="frame" x="119" y="57" width="235" height="34"/>
<fontDescription key="fontDescription" type="system" pointSize="14"/>
<textInputTraits key="textInputTraits"/>
<userDefinedRuntimeAttributes>
<userDefinedRuntimeAttribute type="boolean" keyPath="isSkeletonable" value="YES"/>
</userDefinedRuntimeAttributes>
</textField>
</subviews>
<constraints>
<constraint firstItem="dha-bH-Ipf" firstAttribute="top" secondItem="VhU-1t-AaI" secondAttribute="bottom" constant="8" symbolic="YES" id="1Ek-1L-ZVs"/>
<constraint firstItem="oiE-tt-nc2" firstAttribute="leading" secondItem="7IN-F3-Mr6" secondAttribute="leadingMargin" id="1be-ak-AH1"/>
<constraint firstAttribute="bottom" secondItem="oiE-tt-nc2" secondAttribute="bottom" constant="20" id="CKt-oA-eBI"/>
<constraint firstItem="oiE-tt-nc2" firstAttribute="top" secondItem="7IN-F3-Mr6" secondAttribute="topMargin" constant="7" id="EKn-ST-LDX"/>
<constraint firstAttribute="trailingMargin" secondItem="VhU-1t-AaI" secondAttribute="trailing" constant="5" id="I7C-Bq-mfK"/>
<constraint firstItem="VhU-1t-AaI" firstAttribute="leading" secondItem="oiE-tt-nc2" secondAttribute="trailing" constant="21" id="Ojr-Kz-1k6"/>
<constraint firstItem="VhU-1t-AaI" firstAttribute="top" secondItem="7IN-F3-Mr6" secondAttribute="topMargin" constant="18" id="ZW6-JY-S4c"/>
<constraint firstItem="dha-bH-Ipf" firstAttribute="trailing" secondItem="VhU-1t-AaI" secondAttribute="trailing" id="baX-Nw-8sB"/>
<constraint firstItem="dha-bH-Ipf" firstAttribute="leading" secondItem="VhU-1t-AaI" secondAttribute="leading" id="kzA-mV-IDt"/>
</constraints>
<userDefinedRuntimeAttributes>
<userDefinedRuntimeAttribute type="boolean" keyPath="isSkeletonable" value="YES"/>
</userDefinedRuntimeAttributes>
</tableViewCellContentView>
<userDefinedRuntimeAttributes>
<userDefinedRuntimeAttribute type="boolean" keyPath="isSkeletonable" value="YES"/>
</userDefinedRuntimeAttributes>
<connections>
<outlet property="avatar" destination="oiE-tt-nc2" id="Dkh-R5-Qhu"/>
<outlet property="label1" destination="VhU-1t-AaI" id="kUW-HV-KrD"/>
<outlet property="textField" destination="dha-bH-Ipf" id="OHI-6P-tuU"/>
</connections>
</tableViewCell>
</prototypes>
<userDefinedRuntimeAttributes>
<userDefinedRuntimeAttribute type="boolean" keyPath="isSkeletonable" value="NO"/>
</userDefinedRuntimeAttributes>
<connections>
<outlet property="dataSource" destination="BYZ-38-t0r" id="Hxi-nC-gbY"/>
<outlet property="delegate" destination="BYZ-38-t0r" id="Z10-Nx-iGb"/>
</connections>
</tableView>
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="XgY-1a-UGc">
<rect key="frame" x="0.0" y="569" width="375" height="160"/>
<subviews>
<segmentedControl opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="left" contentVerticalAlignment="top" segmentControlStyle="plain" selectedSegmentIndex="0" translatesAutoresizingMaskIntoConstraints="NO" id="xOL-Sq-r4i">
<rect key="frame" x="20" y="23" width="145" height="32"/>
<segments>
<segment title="Solid"/>
<segment title="Gradient"/>
</segments>
<connections>
<action selector="changeSkeletonType:" destination="BYZ-38-t0r" eventType="valueChanged" id="iAS-ab-0jP"/>
</connections>
</segmentedControl>
<switch opaque="NO" contentMode="scaleToFill" horizontalHuggingPriority="750" verticalHuggingPriority="750" contentHorizontalAlignment="center" contentVerticalAlignment="center" on="YES" translatesAutoresizingMaskIntoConstraints="NO" id="vz0-qg-GcZ">
<rect key="frame" x="308" y="21" width="51" height="31"/>
<connections>
<action selector="changeAnimated:" destination="BYZ-38-t0r" eventType="valueChanged" id="w1G-gZ-RE0"/>
</connections>
</switch>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Animated" textAlignment="right" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="WHN-wR-TKt">
<rect key="frame" x="229" y="26" width="73" height="21"/>
<fontDescription key="fontDescription" type="system" pointSize="17"/>
<nil key="textColor"/>
<nil key="highlightedColor"/>
</label>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Color" textAlignment="right" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="7CF-rV-pK2">
<rect key="frame" x="20" y="73.666666666666629" width="90" height="21"/>
<fontDescription key="fontDescription" type="system" pointSize="17"/>
<nil key="textColor"/>
<nil key="highlightedColor"/>
</label>
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="iGp-rp-t1d">
<rect key="frame" x="130" y="69" width="30" height="30"/>
<color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
<constraints>
<constraint firstAttribute="width" constant="30" id="Q3k-B1-E88"/>
<constraint firstAttribute="height" constant="30" id="xOD-RY-U4u"/>
</constraints>
</view>
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="Mde-Cm-CoS">
<rect key="frame" x="20" y="58" width="140" height="52"/>
<constraints>
<constraint firstAttribute="height" constant="52" id="3GX-2y-eQj"/>
<constraint firstAttribute="width" constant="140" id="6cC-Y1-RKs"/>
</constraints>
<connections>
<action selector="btnChangeColorTouchUpInside:" destination="BYZ-38-t0r" eventType="touchUpInside" id="cB8-Ik-LIJ"/>
</connections>
</button>
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="system" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="Tdu-YQ-saq">
<rect key="frame" x="263" y="69" width="94" height="30"/>
<state key="normal" title="Hide skeleton"/>
<connections>
<action selector="showOrHideSkeleton:" destination="BYZ-38-t0r" eventType="touchUpInside" id="Ma1-WX-Dzy"/>
</connections>
</button>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Fade Duration: 0.25 sec" textAlignment="right" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="mrw-PM-jJJ">
<rect key="frame" x="92.333333333333329" y="130" width="162.66666666666669" height="18"/>
<fontDescription key="fontDescription" type="system" pointSize="15"/>
<nil key="textColor"/>
<nil key="highlightedColor"/>
</label>
<stepper opaque="NO" contentMode="scaleToFill" horizontalHuggingPriority="750" verticalHuggingPriority="750" contentHorizontalAlignment="center" contentVerticalAlignment="center" value="0.25" maximumValue="5" stepValue="0.25" translatesAutoresizingMaskIntoConstraints="NO" id="l4N-LL-ZrJ">
<rect key="frame" x="263" y="123" width="94" height="32"/>
<connections>
<action selector="transitionDurationStepperAction:" destination="BYZ-38-t0r" eventType="valueChanged" id="jPN-df-fNs"/>
</connections>
</stepper>
</subviews>
<color key="backgroundColor" systemColor="systemBackgroundColor"/>
<constraints>
<constraint firstItem="l4N-LL-ZrJ" firstAttribute="leading" secondItem="mrw-PM-jJJ" secondAttribute="trailing" constant="8" id="5iU-dO-qVc"/>
<constraint firstItem="mrw-PM-jJJ" firstAttribute="centerY" secondItem="l4N-LL-ZrJ" secondAttribute="centerY" id="9OM-mx-4Jo"/>
<constraint firstAttribute="trailing" secondItem="Tdu-YQ-saq" secondAttribute="trailing" constant="18" id="BQ0-S0-YMp"/>
<constraint firstItem="iGp-rp-t1d" firstAttribute="trailing" secondItem="Mde-Cm-CoS" secondAttribute="trailing" id="IJ3-CC-5M7"/>
<constraint firstAttribute="height" constant="160" id="OH5-ja-ZlB"/>
<constraint firstItem="Mde-Cm-CoS" firstAttribute="leading" secondItem="XgY-1a-UGc" secondAttribute="leading" constant="20" id="Rek-hz-pDw"/>
<constraint firstItem="xOL-Sq-r4i" firstAttribute="top" secondItem="XgY-1a-UGc" secondAttribute="top" constant="23" id="Udf-0g-bZm"/>
<constraint firstItem="Tdu-YQ-saq" firstAttribute="top" secondItem="vz0-qg-GcZ" secondAttribute="bottom" constant="17" id="WiR-yP-dyv"/>
<constraint firstItem="Mde-Cm-CoS" firstAttribute="centerY" secondItem="7CF-rV-pK2" secondAttribute="centerY" id="eaN-FA-4mF"/>
<constraint firstItem="iGp-rp-t1d" firstAttribute="centerY" secondItem="7CF-rV-pK2" secondAttribute="centerY" id="hBb-mp-AjF"/>
<constraint firstItem="l4N-LL-ZrJ" firstAttribute="top" secondItem="Tdu-YQ-saq" secondAttribute="bottom" constant="24" id="iA5-RB-pW2"/>
<constraint firstItem="vz0-qg-GcZ" firstAttribute="top" secondItem="XgY-1a-UGc" secondAttribute="top" constant="21" id="iad-6N-wNf"/>
<constraint firstItem="vz0-qg-GcZ" firstAttribute="leading" secondItem="WHN-wR-TKt" secondAttribute="trailing" constant="6" id="jgu-tV-gqO"/>
<constraint firstItem="WHN-wR-TKt" firstAttribute="centerY" secondItem="vz0-qg-GcZ" secondAttribute="centerY" id="kTu-fb-Bc8"/>
<constraint firstAttribute="trailing" secondItem="vz0-qg-GcZ" secondAttribute="trailing" constant="18" id="ktq-JT-uoR"/>
<constraint firstItem="xOL-Sq-r4i" firstAttribute="leading" secondItem="XgY-1a-UGc" secondAttribute="leading" constant="20" id="pY0-qd-xmK"/>
<constraint firstItem="l4N-LL-ZrJ" firstAttribute="trailing" secondItem="Tdu-YQ-saq" secondAttribute="trailing" id="ql2-Z9-dnv"/>
<constraint firstItem="iGp-rp-t1d" firstAttribute="leading" secondItem="7CF-rV-pK2" secondAttribute="trailing" constant="20" id="vWD-0m-dMp"/>
<constraint firstItem="7CF-rV-pK2" firstAttribute="centerY" secondItem="Tdu-YQ-saq" secondAttribute="centerY" id="x0d-LB-A4q"/>
<constraint firstItem="7CF-rV-pK2" firstAttribute="leading" secondItem="xOL-Sq-r4i" secondAttribute="leading" id="yEL-Nv-z76"/>
</constraints>
</view>
</subviews>
<viewLayoutGuide key="safeArea" id="6Tk-OE-BBY"/>
<color key="backgroundColor" systemColor="systemBackgroundColor"/>
<constraints>
<constraint firstItem="F9K-jU-100" firstAttribute="trailing" secondItem="6Tk-OE-BBY" secondAttribute="trailing" id="1es-nY-bd3"/>
<constraint firstItem="F9K-jU-100" firstAttribute="leading" secondItem="6Tk-OE-BBY" secondAttribute="leading" id="A3E-iv-1qp"/>
<constraint firstItem="XgY-1a-UGc" firstAttribute="trailing" secondItem="6Tk-OE-BBY" secondAttribute="trailing" id="Luk-cg-4Ez"/>
<constraint firstItem="UCB-SP-lQk" firstAttribute="leading" secondItem="6Tk-OE-BBY" secondAttribute="leading" id="Qbw-Rq-Rhw"/>
<constraint firstItem="F9K-jU-100" firstAttribute="top" secondItem="6Tk-OE-BBY" secondAttribute="top" id="VLb-cX-ZHC"/>
<constraint firstItem="XgY-1a-UGc" firstAttribute="leading" secondItem="6Tk-OE-BBY" secondAttribute="leading" id="Y8A-sq-fmq"/>
<constraint firstItem="XgY-1a-UGc" firstAttribute="top" secondItem="UCB-SP-lQk" secondAttribute="bottom" id="eof-MM-DrW"/>
<constraint firstItem="UCB-SP-lQk" firstAttribute="top" secondItem="F9K-jU-100" secondAttribute="bottom" id="hwL-ec-fKo"/>
<constraint firstItem="UCB-SP-lQk" firstAttribute="trailing" secondItem="6Tk-OE-BBY" secondAttribute="trailing" id="o6z-Dj-ppC"/>
<constraint firstItem="XgY-1a-UGc" firstAttribute="bottom" secondItem="6Tk-OE-BBY" secondAttribute="bottom" id="vnZ-9k-MfI"/>
</constraints>
<userDefinedRuntimeAttributes>
<userDefinedRuntimeAttribute type="boolean" keyPath="isSkeletonable" value="YES"/>
</userDefinedRuntimeAttributes>
</view>
<tabBarItem key="tabBarItem" title="Item" id="wQY-ap-3n3"/>
<navigationItem key="navigationItem" id="BEI-dU-kr2"/>
<connections>
<outlet property="avatarImage" destination="nMj-pU-5wJ" id="9fa-Z7-vYi"/>
<outlet property="colorSelectedView" destination="iGp-rp-t1d" id="0Zm-9d-jRU"/>
<outlet property="showOrHideSkeletonButton" destination="Tdu-YQ-saq" id="gkm-mB-zYD"/>
<outlet property="skeletonTypeSelector" destination="xOL-Sq-r4i" id="yTr-8L-I4Y"/>
<outlet property="switchAnimated" destination="vz0-qg-GcZ" id="d2R-8x-lRb"/>
<outlet property="tableview" destination="UCB-SP-lQk" id="XV0-KX-lAN"/>
<outlet property="transitionDurationLabel" destination="mrw-PM-jJJ" id="BVK-Kl-5Q3"/>
<outlet property="transitionDurationStepper" destination="l4N-LL-ZrJ" id="OJr-Ul-7XR"/>
</connections>
</viewController>
<placeholder placeholderIdentifier="IBFirstResponder" id="dkx-z0-nzr" sceneMemberID="firstResponder"/>
</objects>
<point key="canvasLocation" x="-2682.4000000000001" y="339.90147783251234"/>
</scene>
<!--Item-->
<scene sceneID="Cfc-AT-AS1">
<objects>
<viewController id="dv8-ph-Ehg" sceneMemberID="viewController">
<view key="view" contentMode="scaleToFill" id="Jwx-gI-Qod">
<rect key="frame" x="0.0" y="0.0" width="375" height="812"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<viewLayoutGuide key="safeArea" id="Ao1-hk-zrH"/>
<color key="backgroundColor" systemColor="systemBackgroundColor"/>
</view>
<tabBarItem key="tabBarItem" title="Item" id="iKp-9S-aib"/>
</viewController>
<placeholder placeholderIdentifier="IBFirstResponder" id="M03-a6-GOC" userLabel="First Responder" sceneMemberID="firstResponder"/>
</objects>
<point key="canvasLocation" x="-1644" y="340"/>
</scene>
<!--Tab Bar Controller-->
<scene sceneID="U6k-MC-AHH">
<objects>
<tabBarController automaticallyAdjustsScrollViewInsets="NO" id="Va7-1y-Tel" sceneMemberID="viewController">
<toolbarItems/>
<tabBar key="tabBar" contentMode="scaleToFill" insetsLayoutMarginsFromSafeArea="NO" id="HSI-2O-RyO">
<rect key="frame" x="0.0" y="0.0" width="1000" height="1000"/>
<autoresizingMask key="autoresizingMask"/>
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
</tabBar>
<connections>
<segue destination="BYZ-38-t0r" kind="relationship" relationship="viewControllers" id="dL3-9L-KNU"/>
<segue destination="dv8-ph-Ehg" kind="relationship" relationship="viewControllers" id="8QB-uV-gaF"/>
</connections>
</tabBarController>
<placeholder placeholderIdentifier="IBFirstResponder" id="huq-Fh-0sW" userLabel="First Responder" sceneMemberID="firstResponder"/>
</objects>
<point key="canvasLocation" x="-2172" y="-555"/>
</scene>
</scenes>
<resources>
<image name="avatar" width="215" height="211"/>
<systemColor name="labelColor">
<color white="0.0" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
</systemColor>
<systemColor name="systemBackgroundColor">
<color white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
</systemColor>
</resources>
</document>
+33
View File
@@ -0,0 +1,33 @@
//
// Cell.swift
// SkeletonViewExample
//
// Created by Juanpe Catalán on 03/11/2017.
// Copyright © 2017 SkeletonView. All rights reserved.
//
import UIKit
class Cell: UITableViewCell {
@IBOutlet weak var avatar: UIImageView!
@IBOutlet weak var label1: UILabel!
@IBOutlet weak var textField: UITextField!
override func awakeFromNib() {
super.awakeFromNib()
setUpInputAccessoryView()
}
func setUpInputAccessoryView() {
let bar = UIToolbar()
let reset = UIBarButtonItem(title: "InputAccessoryView", style: .plain, target: self, action: #selector(resetTapped))
bar.items = [reset]
bar.sizeToFit()
textField.inputAccessoryView = bar
}
@objc func resetTapped() {
}
}
+5
View File
@@ -0,0 +1,5 @@
// Copyright © 2018 SkeletonView. All rights reserved.
import UIKit
let colors = [(UIColor.skeletonDefault,"skeletonDefault"),(UIColor.turquoise,"turquoise"), (UIColor.emerald,"emerald"), (UIColor.peterRiver,"peterRiver"), (UIColor.amethyst,"amethyst"),(UIColor.wetAsphalt,"wetAsphalt"), (UIColor.nephritis,"nephritis"), (UIColor.belizeHole,"belizeHole"), (UIColor.wisteria,"wisteria"), (UIColor.midnightBlue,"midnightBlue"), (UIColor.sunFlower,"sunFlower"), (UIColor.carrot,"carrot"), (UIColor.alizarin,"alizarin"),(UIColor.clouds,"clouds"), (UIColor.concrete,"concrete"), (UIColor.flatOrange,"flatOrange"), (UIColor.pumpkin,"pumpkin"), (UIColor.pomegranate,"pomegranate"), (UIColor.silver,"silver"), (UIColor.asbestos,"asbestos")]
@@ -0,0 +1,44 @@
// Copyright © 2020 SkeletonView. All rights reserved.
import UIKit
class HeaderFooterSection: UITableViewHeaderFooterView {
lazy var titleLabel: UILabel = {
let label = UILabel()
label.text = " "
label.isSkeletonable = true
label.linesCornerRadius = 5
return label
}()
override init(reuseIdentifier: String?) {
super.init(reuseIdentifier: reuseIdentifier)
isSkeletonable = true
contentView.addSubview(titleLabel)
titleLabel.translatesAutoresizingMaskIntoConstraints = false
NSLayoutConstraint.activate([
titleLabel.topAnchor.constraint(equalTo: contentView.topAnchor, constant: 10),
titleLabel.leadingAnchor.constraint(equalTo: contentView.leadingAnchor, constant: 10),
titleLabel.trailingAnchor.constraint(equalTo: contentView.trailingAnchor, constant: -10),
titleLabel.bottomAnchor.constraint(equalTo: contentView.bottomAnchor, constant: -10)
])
backgroundView = UIView()
if #available(iOS 13.0, *) {
backgroundView?.backgroundColor = .systemBackground
} else {
backgroundView?.backgroundColor = .white
}
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}
+221
View File
@@ -0,0 +1,221 @@
//
// ViewController.swift
// SkeletonViewExample
//
// Created by Juanpe Catalán on 02/11/2017.
// Copyright © 2017 SkeletonView. All rights reserved.
//
import UIKit
import SkeletonView
class ViewController: UIViewController {
@IBOutlet weak var tableview: UITableView! {
didSet {
tableview.rowHeight = UITableView.automaticDimension
tableview.sectionHeaderHeight = UITableView.automaticDimension
tableview.sectionFooterHeight = UITableView.automaticDimension
tableview.estimatedRowHeight = 120.0
tableview.estimatedSectionFooterHeight = 20.0
tableview.estimatedSectionHeaderHeight = 20.0
tableview.register(HeaderFooterSection.self, forHeaderFooterViewReuseIdentifier: "HeaderIdentifier")
tableview.register(HeaderFooterSection.self, forHeaderFooterViewReuseIdentifier: "FooterIdentifier")
}
}
@IBOutlet weak var avatarImage: UIImageView! {
didSet {
avatarImage.layer.cornerRadius = avatarImage.frame.width/2
avatarImage.layer.masksToBounds = true
}
}
@IBOutlet weak var colorSelectedView: UIView! {
didSet {
colorSelectedView.layer.cornerRadius = 5
colorSelectedView.layer.masksToBounds = true
colorSelectedView.backgroundColor = SkeletonAppearance.default.tintColor
}
}
@IBOutlet weak var switchAnimated: UISwitch!
@IBOutlet weak var skeletonTypeSelector: UISegmentedControl!
@IBOutlet weak var showOrHideSkeletonButton: UIButton!
@IBOutlet weak var transitionDurationLabel: UILabel!
@IBOutlet weak var transitionDurationStepper: UIStepper!
var type: SkeletonType {
return skeletonTypeSelector.selectedSegmentIndex == 0 ? .solid : .gradient
}
override func viewDidLoad() {
super.viewDidLoad()
tableview.isSkeletonable = true
transitionDurationStepper.value = 0.25
}
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
view.showAnimatedSkeleton()
}
@IBAction func changeAnimated(_ sender: Any) {
if switchAnimated.isOn {
view.startSkeletonAnimation()
} else {
view.stopSkeletonAnimation()
}
}
@IBAction func changeSkeletonType(_ sender: Any) {
refreshSkeleton()
}
@IBAction func btnChangeColorTouchUpInside(_ sender: Any) {
showAlertPicker()
}
@IBAction func showOrHideSkeleton(_ sender: Any) {
showOrHideSkeletonButton.setTitle((view.isSkeletonActive ? "Show skeleton" : "Hide skeleton"), for: .normal)
view.isSkeletonActive ? hideSkeleton() : showSkeleton()
}
@IBAction func transitionDurationStepperAction(_ sender: Any) {
transitionDurationLabel.text = "Transition duration: \(transitionDurationStepper.value) sec"
}
func showSkeleton() {
if type == .gradient {
let gradient = SkeletonGradient(baseColor: colorSelectedView.backgroundColor!)
if switchAnimated.isOn {
view.showAnimatedGradientSkeleton(usingGradient: gradient, transition: .crossDissolve(transitionDurationStepper.value))
}
else {
view.showGradientSkeleton(usingGradient: gradient, transition: .crossDissolve(transitionDurationStepper.value))
}
}
else {
if switchAnimated.isOn {
view.showAnimatedSkeleton(transition: .crossDissolve(transitionDurationStepper.value))
}
else {
view.showSkeleton(transition: .crossDissolve(transitionDurationStepper.value))
}
}
}
func hideSkeleton() {
view.hideSkeleton(transition: .crossDissolve(transitionDurationStepper.value))
}
func refreshSkeleton() {
if type == .gradient { showOrUpdateGradientSkeleton() }
else { showOrUpdatepdateSolidSkeleton() }
}
func showOrUpdatepdateSolidSkeleton() {
if switchAnimated.isOn {
view.updateAnimatedSkeleton(usingColor: colorSelectedView.backgroundColor!)
} else {
view.updateSkeleton(usingColor: colorSelectedView.backgroundColor!)
}
}
func showOrUpdateGradientSkeleton() {
let gradient = SkeletonGradient(baseColor: colorSelectedView.backgroundColor!)
if switchAnimated.isOn {
view.updateAnimatedGradientSkeleton(usingGradient: gradient)
} else {
view.updateGradientSkeleton(usingGradient: gradient)
}
}
func showAlertPicker() {
let alertView = UIAlertController(title: "Select color", message: "\n\n\n\n\n\n", preferredStyle: .alert)
let pickerView = UIPickerView(frame: CGRect(x: 0, y: 50, width: 260, height: 115))
pickerView.dataSource = self
pickerView.delegate = self
alertView.view.addSubview(pickerView)
let action = UIAlertAction(title: "OK", style: .default) { [unowned pickerView, unowned self] _ in
let row = pickerView.selectedRow(inComponent: 0)
self.colorSelectedView.backgroundColor = colors[row].0
self.refreshSkeleton()
}
alertView.addAction(action)
let cancelAction = UIAlertAction(title: "Cancel", style: .cancel, handler: nil)
alertView.addAction(cancelAction)
present(alertView, animated: false, completion: {
pickerView.frame.size.width = alertView.view.frame.size.width
})
}
}
extension ViewController: UIPickerViewDelegate, UIPickerViewDataSource {
func numberOfComponents(in pickerView: UIPickerView) -> Int {
return 1
}
func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
return colors.count
}
func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? {
return colors[row].1
}
}
extension ViewController: SkeletonTableViewDataSource {
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return 10
}
func collectionSkeletonView(_ skeletonView: UITableView, cellIdentifierForRowAt indexPath: IndexPath) -> ReusableCellIdentifier {
return "CellIdentifier"
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "CellIdentifier", for: indexPath) as! Cell
cell.label1.text = "cell -> \(indexPath.row)"
return cell
}
func collectionSkeletonView(_ skeletonView: UITableView, skeletonCellForRowAt indexPath: IndexPath) -> UITableViewCell? {
let cell = skeletonView.dequeueReusableCell(withIdentifier: "CellIdentifier", for: indexPath) as? Cell
cell?.textField.isHidden = indexPath.row == 0
return cell
}
func collectionSkeletonView(_ skeletonView: UITableView, prepareCellForSkeleton cell: UITableViewCell, at indexPath: IndexPath) {
let cell = cell as? Cell
cell?.textField.isHidden = indexPath.row == 0
}
}
extension ViewController: SkeletonTableViewDelegate {
func collectionSkeletonView(_ skeletonView: UITableView, identifierForHeaderInSection section: Int) -> ReusableHeaderFooterIdentifier? {
return "HeaderIdentifier"
}
func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
let header = tableView
.dequeueReusableHeaderFooterView(withIdentifier: "HeaderIdentifier") as! HeaderFooterSection
header.titleLabel.text = "header -> \(section)"
return header
}
func collectionSkeletonView(_ skeletonView: UITableView, identifierForFooterInSection section: Int) -> ReusableHeaderFooterIdentifier? {
return "FooterIdentifier"
}
func tableView(_ tableView: UITableView, viewForFooterInSection section: Int) -> UIView? {
let footer = tableView
.dequeueReusableHeaderFooterView(withIdentifier: "FooterIdentifier") as! HeaderFooterSection
footer.titleLabel.text = "footer -> \(section)"
return footer
}
}
-144
View File
@@ -1,144 +0,0 @@
//
// ViewController.swift
// SkeletonViewExample
//
// Created by Juanpe Catalán on 02/11/2017.
// Copyright © 2017 SkeletonView. All rights reserved.
//
import UIKit
import SkeletonView
class ViewController: UIViewController {
@IBOutlet weak var tableview: UITableView! {
didSet {
tableview.rowHeight = UITableViewAutomaticDimension
tableview.estimatedRowHeight = 120.0
}
}
@IBOutlet weak var avatarImage: UIImageView! {
didSet {
avatarImage.layer.cornerRadius = avatarImage.frame.width/2
avatarImage.layer.masksToBounds = true
}
}
@IBOutlet weak var colorSelectedView: UIView! {
didSet {
colorSelectedView.layer.cornerRadius = 5
colorSelectedView.layer.masksToBounds = true
colorSelectedView.backgroundColor = SkeletonDefaultConfig.tintColor
}
}
@IBOutlet weak var switchAnimated: UISwitch!
@IBOutlet weak var skeletonTypeSelector: UISegmentedControl!
var type: SkeletonType {
return skeletonTypeSelector.selectedSegmentIndex == 0 ? .solid : .gradient
}
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
view.showAnimatedSkeleton()
}
@IBAction func changeAnimated(_ sender: Any) {
if switchAnimated.isOn {
view.startSkeletonAnimation()
} else {
view.stopSkeletonAnimation()
}
}
@IBAction func changeSkeletonType(_ sender: Any) {
refreshSkeleton()
}
@IBAction func btnChangeColorTouchUpInside(_ sender: Any) {
showAlertPicker()
}
func refreshSkeleton() {
self.view.hideSkeleton()
if type == .gradient { showGradientSkeleton() }
else { showSolidSkeleton() }
}
func showSolidSkeleton() {
if switchAnimated.isOn {
view.showAnimatedSkeleton(usingColor: colorSelectedView.backgroundColor!)
} else {
view.showSkeleton(usingColor: colorSelectedView.backgroundColor!)
}
}
func showGradientSkeleton() {
let gradient = SkeletonGradient(baseColor: colorSelectedView.backgroundColor!)
if switchAnimated.isOn {
view.showAnimatedGradientSkeleton(usingGradient: gradient)
} else {
view.showGradientSkeleton(usingGradient: gradient)
}
}
func showAlertPicker() {
let alertView = UIAlertController(title: "Select color", message: "\n\n\n\n\n\n", preferredStyle: .alert)
let pickerView = UIPickerView(frame: CGRect(x: 0, y: 50, width: 260, height: 115))
pickerView.dataSource = self
pickerView.delegate = self
alertView.view.addSubview(pickerView)
let action = UIAlertAction(title: "OK", style: .default) { [unowned pickerView, unowned self] _ in
let row = pickerView.selectedRow(inComponent: 0)
self.colorSelectedView.backgroundColor = colors[row].0
self.refreshSkeleton()
}
alertView.addAction(action)
let cancelAction = UIAlertAction(title: "Cancel", style: .cancel, handler: nil)
alertView.addAction(cancelAction)
present(alertView, animated: false, completion: {
pickerView.frame.size.width = alertView.view.frame.size.width
})
}
}
extension ViewController: UIPickerViewDelegate, UIPickerViewDataSource {
func numberOfComponents(in pickerView: UIPickerView) -> Int {
return 1
}
func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
return colors.count
}
func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? {
return colors[row].1
}
}
extension ViewController: SkeletonTableViewDataSource {
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return 9
}
func collectionSkeletonView(_ skeletonView: UITableView, cellIdenfierForRowAt indexPath: IndexPath) -> ReusableCellIdentifier {
return "CellIdentifier"
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "CellIdentifier", for: indexPath) as! Cell
cell.label1.text = "cell => \(indexPath.row)"
return cell
}
}
+4
View File
@@ -0,0 +1,4 @@
source "https://rubygems.org"
gem "fastlane"
gem 'cocoapods', '~> 1.7.0.beta.2'
+212
View File
@@ -0,0 +1,212 @@
GEM
remote: https://rubygems.org/
specs:
CFPropertyList (3.0.0)
activesupport (4.2.11.1)
i18n (~> 0.7)
minitest (~> 5.1)
thread_safe (~> 0.3, >= 0.3.4)
tzinfo (~> 1.1)
addressable (2.6.0)
public_suffix (>= 2.0.2, < 4.0)
atomos (0.1.3)
babosa (1.0.2)
claide (1.0.2)
cocoapods (1.7.5)
activesupport (>= 4.0.2, < 5)
claide (>= 1.0.2, < 2.0)
cocoapods-core (= 1.7.5)
cocoapods-deintegrate (>= 1.0.3, < 2.0)
cocoapods-downloader (>= 1.2.2, < 2.0)
cocoapods-plugins (>= 1.0.0, < 2.0)
cocoapods-search (>= 1.0.0, < 2.0)
cocoapods-stats (>= 1.0.0, < 2.0)
cocoapods-trunk (>= 1.3.1, < 2.0)
cocoapods-try (>= 1.1.0, < 2.0)
colored2 (~> 3.1)
escape (~> 0.0.4)
fourflusher (>= 2.3.0, < 3.0)
gh_inspector (~> 1.0)
molinillo (~> 0.6.6)
nap (~> 1.0)
ruby-macho (~> 1.4)
xcodeproj (>= 1.10.0, < 2.0)
cocoapods-core (1.7.5)
activesupport (>= 4.0.2, < 6)
fuzzy_match (~> 2.0.4)
nap (~> 1.0)
cocoapods-deintegrate (1.0.4)
cocoapods-downloader (1.2.2)
cocoapods-plugins (1.0.0)
nap
cocoapods-search (1.0.0)
cocoapods-stats (1.1.0)
cocoapods-trunk (1.3.1)
nap (>= 0.8, < 2.0)
netrc (~> 0.11)
cocoapods-try (1.1.0)
colored (1.2)
colored2 (3.1.2)
commander-fastlane (4.4.6)
highline (~> 1.7.2)
concurrent-ruby (1.1.5)
declarative (0.0.10)
declarative-option (0.1.0)
digest-crc (0.4.1)
domain_name (0.5.20190701)
unf (>= 0.0.5, < 1.0.0)
dotenv (2.7.4)
emoji_regex (1.0.1)
escape (0.0.4)
excon (0.71.0)
faraday (0.15.4)
multipart-post (>= 1.2, < 3)
faraday-cookie_jar (0.0.6)
faraday (>= 0.7.4)
http-cookie (~> 1.0.0)
faraday_middleware (0.13.1)
faraday (>= 0.7.4, < 1.0)
fastimage (2.1.5)
fastlane (2.128.0)
CFPropertyList (>= 2.3, < 4.0.0)
addressable (>= 2.3, < 3.0.0)
babosa (>= 1.0.2, < 2.0.0)
bundler (>= 1.12.0, < 3.0.0)
colored
commander-fastlane (>= 4.4.6, < 5.0.0)
dotenv (>= 2.1.1, < 3.0.0)
emoji_regex (>= 0.1, < 2.0)
excon (>= 0.45.0, < 1.0.0)
faraday (~> 0.9)
faraday-cookie_jar (~> 0.0.6)
faraday_middleware (~> 0.9)
fastimage (>= 2.1.0, < 3.0.0)
gh_inspector (>= 1.1.2, < 2.0.0)
google-api-client (>= 0.21.2, < 0.24.0)
google-cloud-storage (>= 1.15.0, < 2.0.0)
highline (>= 1.7.2, < 2.0.0)
json (< 3.0.0)
jwt (~> 2.1.0)
mini_magick (>= 4.9.4, < 5.0.0)
multi_xml (~> 0.5)
multipart-post (~> 2.0.0)
plist (>= 3.1.0, < 4.0.0)
public_suffix (~> 2.0.0)
rubyzip (>= 1.2.2, < 2.0.0)
security (= 0.1.3)
simctl (~> 1.6.3)
slack-notifier (>= 2.0.0, < 3.0.0)
terminal-notifier (>= 2.0.0, < 3.0.0)
terminal-table (>= 1.4.5, < 2.0.0)
tty-screen (>= 0.6.3, < 1.0.0)
tty-spinner (>= 0.8.0, < 1.0.0)
word_wrap (~> 1.0.0)
xcodeproj (>= 1.8.1, < 2.0.0)
xcpretty (~> 0.3.0)
xcpretty-travis-formatter (>= 0.0.3)
fourflusher (2.3.1)
fuzzy_match (2.0.4)
gh_inspector (1.1.3)
google-api-client (0.23.9)
addressable (~> 2.5, >= 2.5.1)
googleauth (>= 0.5, < 0.7.0)
httpclient (>= 2.8.1, < 3.0)
mime-types (~> 3.0)
representable (~> 3.0)
retriable (>= 2.0, < 4.0)
signet (~> 0.9)
google-cloud-core (1.3.0)
google-cloud-env (~> 1.0)
google-cloud-env (1.2.0)
faraday (~> 0.11)
google-cloud-storage (1.16.0)
digest-crc (~> 0.4)
google-api-client (~> 0.23)
google-cloud-core (~> 1.2)
googleauth (>= 0.6.2, < 0.10.0)
googleauth (0.6.7)
faraday (~> 0.12)
jwt (>= 1.4, < 3.0)
memoist (~> 0.16)
multi_json (~> 1.11)
os (>= 0.9, < 2.0)
signet (~> 0.7)
highline (1.7.10)
http-cookie (1.0.3)
domain_name (~> 0.5)
httpclient (2.8.3)
i18n (0.9.5)
concurrent-ruby (~> 1.0)
json (2.3.1)
jwt (2.1.0)
memoist (0.16.0)
mime-types (3.2.2)
mime-types-data (~> 3.2015)
mime-types-data (3.2019.0331)
mini_magick (4.9.5)
minitest (5.11.3)
molinillo (0.6.6)
multi_json (1.13.1)
multi_xml (0.6.0)
multipart-post (2.0.0)
nanaimo (0.2.6)
nap (1.1.0)
naturally (2.2.0)
netrc (0.11.0)
os (1.0.1)
plist (3.5.0)
public_suffix (2.0.5)
representable (3.0.4)
declarative (< 0.1.0)
declarative-option (< 0.2.0)
uber (< 0.2.0)
retriable (3.1.2)
rouge (2.0.7)
ruby-macho (1.4.0)
rubyzip (1.3.0)
security (0.1.3)
signet (0.11.0)
addressable (~> 2.3)
faraday (~> 0.9)
jwt (>= 1.5, < 3.0)
multi_json (~> 1.10)
simctl (1.6.5)
CFPropertyList
naturally
slack-notifier (2.3.2)
terminal-notifier (2.0.0)
terminal-table (1.8.0)
unicode-display_width (~> 1.1, >= 1.1.1)
thread_safe (0.3.6)
tty-cursor (0.7.0)
tty-screen (0.7.0)
tty-spinner (0.9.1)
tty-cursor (~> 0.7)
tzinfo (1.2.5)
thread_safe (~> 0.1)
uber (0.1.0)
unf (0.1.4)
unf_ext
unf_ext (0.0.7.6)
unicode-display_width (1.6.0)
word_wrap (1.0.0)
xcodeproj (1.11.0)
CFPropertyList (>= 2.3.3, < 4.0)
atomos (~> 0.1.3)
claide (>= 1.0.2, < 2.0)
colored2 (~> 3.1)
nanaimo (~> 0.2.6)
xcpretty (0.3.0)
rouge (~> 2.0.7)
xcpretty-travis-formatter (1.0.0)
xcpretty (~> 0.2, >= 0.0.7)
PLATFORMS
ruby
DEPENDENCIES
cocoapods (~> 1.7.0.beta.2)
fastlane
BUNDLED WITH
2.0.1
+23
View File
@@ -0,0 +1,23 @@
// swift-tools-version:5.0
import PackageDescription
let package = Package(
name: "SkeletonView",
platforms: [
.iOS(.v9),
.tvOS(.v9)
],
products: [
.library(
name: "SkeletonView",
targets: ["SkeletonView"])
],
targets: [
.target(
name: "SkeletonView",
dependencies: [],
path: "Sources")
],
swiftLanguageVersions: [.v5]
)
+384 -124
View File
@@ -1,101 +1,107 @@
![](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://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://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>
<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 href="https://github.com/Juanpe/SkeletonView/actions?query=workflow%3ACI">
<img src="https://github.com/Juanpe/SkeletonView/workflows/CI/badge.svg">
</a>
<a href="https://codebeat.co/projects/github-com-juanpe-skeletonview-main"><img alt="codebeat badge" src="https://codebeat.co/badges/1f37bbab-a1c8-4a4a-94d7-f21740d461e9" /></a>
<a href="https://cocoapods.org/pods/SkeletonView"><img src="https://img.shields.io/cocoapods/v/SkeletonView.svg?style=flat"></a>
<a href="https://github.com/Carthage/Carthage/"><img src="https://img.shields.io/badge/Carthage-compatible-4BC51D.svg?style=flat"></a>
<a href="https://swift.org/package-manager/"><img src="https://img.shields.io/badge/SPM-supported-Green.svg?style=flat"></a>
<img src="https://img.shields.io/badge/platforms-iOS_tvOS-green" />
<a href="https://badge.bow-swift.io/recipe?name=SkeletonView&description=An%20elegant%20way%20to%20show%20users%20that%20something%20is%20happening%20and%20also%20prepare%20them%20to%20which%20contents%20he%20is%20waiting&url=https://github.com/juanpe/skeletonview&owner=Juanpe&avatar=https://avatars0.githubusercontent.com/u/1409041?v=4&tag=1.20.0"><img src="https://raw.githubusercontent.com/bow-swift/bow-art/master/badges/nef-playgrounds-badge.svg" alt="SkeletonView Playground" style="height:20px"></a>
</p>
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.
<p align="center">
<a href="#-features">Features</a>
• <a href="#-guides">Guides</a>
• <a href="#-installation">Installation</a>
• <a href="#-usage">Usage</a>
• <a href="#-miscellaneous">Miscellaneous</a>
• <a href="#-contributing">Contributing</a>
</p>
```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.
**🌎 README is available in other languages: [🇪🇸](https://github.com/Juanpe/SkeletonView/blob/main/README_es.md) . [🇨🇳](https://github.com/Juanpe/SkeletonView/blob/master/README_zh.md) . [🇧🇷](https://github.com/Juanpe/SkeletonView/blob/master/README_pt-br.md) . [🇰🇷](https://github.com/Juanpe/SkeletonView/blob/master/README_ko.md) . [🇫🇷](https://github.com/Juanpe/SkeletonView/blob/master/README_fr.md)**
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 for which contents are waiting.
Enjoy it! 🙂
* [Features](#-features)
* [Requirements](#-supported-os--sdk-versions)
* [Example Project](#-example)
* [Installation](#-installation)
* [Cocoapods](#using-cocoapods)
* [Carthage](#using-carthage)
* [How to use](#-how-to-use)
* [Collections](#-collections)
* [Multiline text](#-multiline-text)
* [Custom colors](#-custom-colors)
* [Custom animations](#-custom-animations)
* [Hierarchy](#-hierarchy)
* [Documentation](#-documentation)
* [Next steps](#-next-steps)
* [Contributed](#-contributed)
* [Author](#-author)
* [License](#-license)
##
- [🌟 Features](#-features)
- [🎬 Guides](#-guides)
- [📲 Installation](#-installation)
- [🐒 Usage](#-usage)
- [🌿 Collections](#-collections)
- [🔠 Texts](#-texts)
- [🦋 Appearance](#-appearance)
- [🎨 Custom colors](#-custom-colors)
- [Image captured from website https://flatuicolors.com](#image-captured-from-website-httpsflatuicolorscom)
- [🏃‍♀️ Animations](#-animations)
- [🏄 Transitions](#-transitions)
- [✨ Miscellaneous](#-miscellaneous)
- [❤️ Contributing](#-contributing)
- [📢 Mentions](#-mentions)
- [🏆 Sponsors](#-sponsors)
- [👨🏻‍💻 Author](#-author)
- [👮🏻 License](#-license)
## 🌟 Features
- [x] Easy to use
- [x] All UIViews are skeletonables
- [x] Fully customizable
- [x] Universal (iPhone & iPad)
- [x] Interface Builder friendly
- [x] Simple Swift syntax
- [x] Lightweight readable codebase
* Easy to use
* All UIViews are skeletonables
* Fully customizable
* Universal (iPhone & iPad)
* Interface Builder friendly
* Simple Swift syntax
* Lightweight readable codebase
### 📋 Supported OS & SDK Versions
* iOS 9.0+
* Swift 4
## 🎬 Guides
### 🔮 Example
| [![](https://img.youtube.com/vi/75kgOhWsPNA/maxresdefault.jpg)](https://youtu.be/75kgOhWsPNA)|[![](https://img.youtube.com/vi/MVCiM_VdxVA/maxresdefault.jpg)](https://youtu.be/MVCiM_VdxVA)|[![](https://img.youtube.com/vi/Qq3Evspeea8/maxresdefault.jpg)](https://youtu.be/Qq3Evspeea8)|[![](https://img.youtube.com/vi/ZOoPtBwDRT0/maxresdefault.jpg)](https://youtu.be/ZOoPtBwDRT0)|[![](https://img.youtube.com/vi/Zx1Pg1gPfxA/maxresdefault.jpg)](https://www.youtube.com/watch?v=Zx1Pg1gPfxA)
|:---: | :---: |:---: | :---: | :---:
|[**SkeletonView Guides - Getting started**](https://youtu.be/75kgOhWsPNA)|[**How to Create Loading View with Skeleton View in Swift 5.2**](https://youtu.be/MVCiM_VdxVA) by iKh4ever Studio|[**Create Skeleton Loading View in App (Swift 5) - Xcode 11, 2020**](https://youtu.be/Qq3Evspeea8) by iOS Academy| [**Add An Elegant Loading Animation in Swift***](https://youtu.be/ZOoPtBwDRT0) by Gary Tokman| [**Cómo crear una ANIMACIÓN de CARGA de DATOS en iOS**](https://www.youtube.com/watch?v=Zx1Pg1gPfxA) by MoureDev
To run the example project, clone the repo and run `SkeletonViewExample` target.
![](Assets/demoApp2.png)
## 📲 Installation
#### Using [CocoaPods](https://cocoapods.org)
Edit your `Podfile` and specify the dependency:
* [CocoaPods](https://guides.cocoapods.org/using/using-cocoapods.html):
```ruby
pod "SkeletonView"
pod 'SkeletonView'
```
#### Using [Carthage](https://github.com/carthage)
* [Carthage](https://github.com/Carthage/Carthage):
Edit your `Cartfile` and specify the dependency:
```bash
```ruby
github "Juanpe/SkeletonView"
```
## 🐒 How to use
* [Swift Package Manager](https://swift.org/package-manager/):
```swift
dependencies: [
.package(url: "https://github.com/Juanpe/SkeletonView.git", from: "1.7.0")
]
```
## 🐒 Usage
Only **3** steps needed to use `SkeletonView`:
**1.** Import SkeletonView in proper place.
1️⃣ Import SkeletonView in proper place.
```swift
import SkeletonView
```
**2.** Now, set which views will be `skeletonables`. You achieve this in two ways:
2️⃣ Now, set which views will be `skeletonables`. You achieve this in two ways:
**Using code:**
```swift
@@ -105,7 +111,7 @@ avatarImageView.isSkeletonable = true
![](Assets/storyboard.png)
**3.** Once you've set the views, you can show the **skeleton**. To do so, you have **4** choices:
3️⃣ Once you've set the views, you can show the **skeleton**. To do so, you have **4** choices:
```swift
(1) view.showSkeleton() // Solid
@@ -147,32 +153,35 @@ avatarImageView.isSkeletonable = true
</tr>
</table>
> **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
> 📣 **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`.
### 🌿 Collections
Now, ```SkeletonView``` is compatible with ```UITableView``` and ```UICollectionView```.
```SkeletonView``` is compatible with ```UITableView``` and ```UICollectionView```.
###### UITableView
**UITableView**
If you want to show the skeleton in a ```UITableView```, you need to conform to ```SkeletonTableViewDataSource``` protocol.
``` swift
public protocol SkeletonTableViewDataSource: UITableViewDataSource {
func numSections(in collectionSkeletonView: UITableView) -> Int
func numSections(in collectionSkeletonView: UITableView) -> Int // Default: 1
func collectionSkeletonView(_ skeletonView: UITableView, numberOfRowsInSection section: Int) -> Int
func collectionSkeletonView(_ skeletonView: UITableView, cellIdenfierForRowAt indexPath: IndexPath) -> ReusableCellIdentifier
func collectionSkeletonView(_ skeletonView: UITableView, cellIdentifierForRowAt indexPath: IndexPath) -> ReusableCellIdentifier
func collectionSkeletonView(_ skeletonView: UITableView, skeletonCellForRowAt indexPath: IndexPath) -> UITableViewCell? // Default: nil
func collectionSkeletonView(_ skeletonView: UITableView, prepareCellForSkeleton cell: UITableViewCell, at indexPath: IndexPath)
}
```
As you can see, this protocol inherits from ```UITableViewDataSource```, so you can replace this protocol with the skeleton protocol.
This protocol has a default implementation:
``` swift
func numSections(in collectionSkeletonView: UITableView) -> Int
// Default: 1
```
This protocol has a default implementation for some methods. For example, the number of rows for each section is calculated in runtime:
``` swift
func collectionSkeletonView(_ skeletonView: UITableView, numberOfRowsInSection section: Int) -> Int
@@ -180,53 +189,133 @@ func collectionSkeletonView(_ skeletonView: UITableView, numberOfRowsInSection s
// It calculates how many cells need to populate whole tableview
```
> 📣 **IMPORTANT!**
>
> If you return `UITableView.automaticNumberOfSkeletonRows` in the above method, it acts like the default behavior (i.e. it calculates how many cells needed to populate the whole tableview).
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
```
**Example**
``` swift
func collectionSkeletonView(_ skeletonView: UITableView, cellIdenfierForRowAt indexPath: IndexPath) -> ReusableCellIdentifier {
func collectionSkeletonView(_ skeletonView: UITableView, cellIdentifierForRowAt indexPath: IndexPath) -> ReusableCellIdentifier {
return "CellIdentifier"
}
```
By default, the library dequeues the cells from each indexPath, but you can also do this if you want to make some changes before the skeleton appears:
``` swift
func collectionSkeletonView(_ skeletonView: UITableView, skeletonCellForRowAt indexPath: IndexPath) -> UITableViewCell? {
let cell = skeletonView.dequeueReusableCell(withIdentifier: "CellIdentifier", for: indexPath) as? Cell
cell?.textField.isHidden = indexPath.row == 0
return cell
}
```
If you prefer to leave the deque part to the library you can configure the cell using this method:
``` swift
func collectionSkeletonView(_ skeletonView: UITableView, prepareCellForSkeleton cell: UITableViewCell, at indexPath: IndexPath) {
let cell = cell as? Cell
cell?.textField.isHidden = indexPath.row == 0
}
```
> **IMPORTANT!**
> If you are using resizable cells (`tableView.rowHeight = UITableViewAutomaticDimension` ), it's mandatory define the `estimatedRowHeight`.
Besides, you can skeletonize both the headers and footers. You need to conform to `SkeletonTableViewDelegate` protocol.
###### UICollectionView
```swift
public protocol SkeletonTableViewDelegate: UITableViewDelegate {
func collectionSkeletonView(_ skeletonView: UITableView, identifierForHeaderInSection section: Int) -> ReusableHeaderFooterIdentifier? // default: nil
func collectionSkeletonView(_ skeletonView: UITableView, identifierForFooterInSection section: Int) -> ReusableHeaderFooterIdentifier? // default: nil
}
```
For ```UICollectionView```, you need to conform to ```SkeletonCollectionViewDataSource``` protocol.
> 📣 **IMPORTANT!**
>
> 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) ❌
> ```
**UICollectionView**
For `UICollectionView`, you need to conform to `SkeletonCollectionViewDataSource` protocol.
``` swift
public protocol SkeletonCollectionViewDataSource: UICollectionViewDataSource {
func numSections(in collectionSkeletonView: UICollectionView) -> Int
func numSections(in collectionSkeletonView: UICollectionView) -> Int // default: 1
func collectionSkeletonView(_ skeletonView: UICollectionView, numberOfItemsInSection section: Int) -> Int
func collectionSkeletonView(_ skeletonView: UICollectionView, cellIdentifierForItemAt indexPath: IndexPath) -> ReusableCellIdentifier
func collectionSkeletonView(_ skeletonView: UICollectionView, supplementaryViewIdentifierOfKind: String, at indexPath: IndexPath) -> ReusableCellIdentifier? // default: nil
func collectionSkeletonView(_ skeletonView: UICollectionView, skeletonCellForItemAt indexPath: IndexPath) -> UICollectionViewCell? // default: nil
func collectionSkeletonView(_ skeletonView: UICollectionView, prepareCellForSkeleton cell: UICollectionViewCell, at indexPath: IndexPath)
}
```
The rest of the process is the same as ```UITableView```
### 📰 Multiline text
### 🔠 Texts
![](Assets/multilines2.png)
When using elements with text, ```SkeletonView``` draws lines to simulate text.
Besides, you can decide how many lines you want. If ```numberOfLines``` is set to zero, it will calculate how many lines needed to populate the whole skeleton and it will be drawn. Instead, if you set it to one, two or any number greater than zero, it will only draw this number of lines.
**NEW** Now, you can set the filling percent of the last line. **Default: 70%**
You can set some properties for multilines elements.
To modify the percent **using code**, set the property:
| 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)
### 🦋 Appearance
The skeletons have a default appearance. So, when you don't specify the color, gradient or multilines properties, `SkeletonView` uses the default values.
Default values:
- **tintColor**: UIColor
- *default: `.skeletonDefault` (same as `.clouds` but adaptive to dark mode)*
- **gradient**: SkeletonGradient
- *default: `SkeletonGradient(baseColor: .skeletonDefault)`*
- **multilineHeight**: CGFloat
- *default: 15*
- **multilineSpacing**: CGFloat
- *default: 10*
- **multilineLastLineFillPercent**: Int
- *default: 70*
- **multilineCornerRadius**: Int
- *default: 0*
- **skeletonCornerRadius**: CGFloat (IBInspectable) (Make your skeleton view with corner)
- *default: 0*
To get these default values you can use `SkeletonAppearance.default`. Using this property you can set the values as well:
```swift
SkeletonAppearance.default.multilineHeight = 20
SkeletonAppearance.default.tintColor = .green
```
You can also specifiy these line appearance properties on a per-label basis:
- **lastLineFillPercent**: Int
- **linesCornerRadius**: Int
- **skeletonLineSpacing**: CGFloat
- **skeletonPaddingInsets**: UIEdgeInsets
### 🎨 Custom colors
@@ -234,7 +323,7 @@ Or, if you prefer use **IB/Storyboard**:
You can decide which color the skeleton is tinted with. You only need to pass as a parameter the color or gradient you want.
**Using solid colors**
``` swift
```swift
view.showSkeleton(usingColor: UIColor.gray) // Solid
// or
view.showSkeleton(usingColor: UIColor(red: 25.0, green: 30.0, blue: 255.0, alpha: 1.0))
@@ -245,16 +334,17 @@ let gradient = SkeletonGradient(baseColor: UIColor.midnightBlue)
view.showGradientSkeleton(usingGradient: gradient) // Gradient
```
Besides, ```SkeletonView``` features 20 flat colors 🤙🏼
Besides, **SkeletonView** features 20 flat colors 🤙🏼
```UIColor.turquoise, UIColor.greenSea, UIColor.sunFlower, UIColor.flatOrange ...```
![](Assets/flatcolors.png)
###### Image captured from website [https://flatuicolors.com](https://flatuicolors.com)
### 🤓 Custom animations
Now, ```SkeletonView``` has two built-in animations, *pulse* for solid skeletons and *sliding* for gradients.
### 🏃‍♀️ Animations
**SkeletonView** has two built-in animations, *pulse* for solid skeletons and *sliding* for gradients.
Besides, if you want to do your own skeleton animation, it's really easy.
@@ -276,7 +366,7 @@ view.showAnimatedSkeleton { (layer) -> CAAnimation in
}
```
**NEW** It's available ```SkeletonAnimationBuilder```. It's a builder to make ```SkeletonLayerAnimation```.
It's available ```SkeletonAnimationBuilder```. It's a builder to make ```SkeletonLayerAnimation```.
Today, you can create **sliding animations** for gradients, deciding the **direction** and setting the **duration** of the animation (default = 1.5s).
@@ -288,67 +378,237 @@ view.showAnimatedGradientSkeleton(usingGradient: gradient, animation: animation)
```
```GradientDirection``` is an enum, with this cases:
```GradientDirection``` is an enum, with theses cases:
| Direction | Preview
|------- | -------
| .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)
> **😉 TRICK!**
Exist another way to create sliding animations, just using this shortcut:
>>```let animation = GradientDirection.leftToRight.slidingAnimation()```
>
> Exist another way to create sliding animations, just using this shortcut:
> ```swift
> let animation = GradientDirection.leftToRight.slidingAnimation()
> ```
### 👨‍👧‍👦 Hierarchy
### 🏄 Transitions
**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:
```swift
view.showSkeleton(transition: .crossDissolve(0.25)) //Show skeleton cross dissolve transition with 0.25 seconds fade time
view.hideSkeleton(transition: .crossDissolve(0.25)) //Hide skeleton cross dissolve transition with 0.25 seconds fade time
```
The default value is `crossDissolve(0.25)`
**Preview**
<table>
<tr>
<td width="50%">
<center>None</center>
</td>
<td width="50%">
<center>Cross dissolve</center>
</td>
</tr>
<tr>
<td width="50%">
<img src="Assets/skeleton_transition_nofade.gif"></img>
</td>
<td width="50%">
<img src="Assets/skeleton_transition_fade.gif"></img>
</td>
</tr>
</table>
## ✨ 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.
Because an image is worth a thousand words:
> ```ìsSkeletonable```= ☠️
In this example we have a `UIViewController` with a `ContainerView` and a `UITableView`. When the view is ready, we show the skeleton using this method:
```
view.showSkeleton()
```
| Configuration | Result
|------- | -------
|![](Assets/no_skeletonable.png) | ![](Assets/no_skeletonables_result.png)
|![](Assets/container_no_skeletonable.png) | ![](Assets/no_skeletonables_result.png)
|![](Assets/container_skeletonable.png) | ![](Assets/container_skeletonable_result.png)
|![](Assets/all_skeletonables.png) | ![](Assets/all_skeletonables_result.png)
> ```isSkeletonable```= ☠️
| Configuration | Result|
|:-------:|:-------:|
|<img src="Assets/no_skeletonable.jpg" width="350"/> | <img src="Assets/no_skeletonables_result.png" width="350"/>|
|<img src="Assets/container_no_skeletonable.jpg" width="350"/> | <img src="Assets/no_skeletonables_result.png" width="350"/>|
|<img src="Assets/container_skeletonable.jpg" width="350"/> | <img src="Assets/container_skeletonable_result.png" width="350"/>|
|<img src="Assets/all_skeletonables.jpg" width="350"/>| <img src="Assets/all_skeletonables_result.png" width="350"/>|
|<img src="Assets/tableview_no_skeletonable.jpg" width="350"/> | <img src="Assets/tableview_no_skeletonable_result.png" height="350"/>|
|<img src="Assets/tableview_skeletonable.jpg" width="350"/> | <img src="Assets/tableview_skeletonable_result.png" height="350"/>|
**Hierarchy in collections**
Here is an illustration that shows how you should specify which elements are skeletonables when you are using an `UITableView`:
<img src="Assets/tableview_scheme.png" width="700px">
As you can see, we have to make skeletonable the tableview, the cell and the UI elements, but we don't need to set as skeletonable the `contentView`
**Skeleton views layout**
Sometimes skeleton layout may not fit your layout because the parent view bounds have changed. ~For example, rotating the device.~
You can relayout the skeleton views like so:
```swift
override func viewDidLayoutSubviews() {
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.
### 📚 Documentation
Coming soon...😅
**Update skeleton**
## 📬 Next steps
You can change the skeleton configuration at any time like its colour, animation, etc. with the following methods:
* [x] Set the filling percent of the last line in multiline elements
* [x] Add more gradient animations
* [x] Supported resizable cells
* [x] CollectionView compatible
* [ ] Add recovery state
* [ ] Custom collections compatible
* [ ] Add animations when it shows/hides the skeletons
* [ ] MacOS and WatchOS compatible
```swift
(1) view.updateSkeleton() // Solid
(2) view.updateGradientSkeleton() // Gradient
(3) view.updateAnimatedSkeleton() // Solid animated
(4) view.updateAnimatedGradientSkeleton() // Gradient animated
```
## ❤️ Contributed
**Hiding views when the animation starts**
Sometimes you wanna hide some view when the animation starts, so there is a quick property that you can use to make this happen:
```swift
view.isHiddenWhenSkeletonIsActive = true // This works only when isSkeletonable = true
```
**Don't modify user interaction when the skeleton is active**
By default, the user interaction is disabled for skeletonized items, but if you don't want to modify the user interaction indicator when skeleton is active, you can use the `isUserInteractionDisabledWhenSkeletonIsActive` property:
```swift
view.isUserInteractionDisabledWhenSkeletonIsActive = false // The view will be active when the skeleton will be active.
```
**Delayed show skeleton**
You can delay the presentation of the skeleton if the views update quickly.
```swift
func showSkeleton(usingColor: UIColor,
animated: Bool,
delay: TimeInterval,
transition: SkeletonTransitionStyle)
```
```swift
func showGradientSkeleton(usingGradient: SkeletonGradient,
animated: Bool,
delay: TimeInterval,
transition: SkeletonTransitionStyle)
```
**Debug**
To facilitate the debug tasks when something is not working fine. **`SkeletonView`** has some new tools.
First, `UIView` has available a new property with his skeleton info:
```swift
var skeletonDescription: String
```
The skeleton representation looks like this:
![](Assets/debug_description.png)
Besides, you can activate the new **debug mode**. You just add the environment variable `SKELETON_DEBUG` and activate it.
![](Assets/debug_mode.png)
Then, when the skeleton appears, you can see the view hierarchy in the Xcode console.
<details>
<summary>Open to see an output example </summary>
<img src="Assets/hierarchy_output.png" />
</details>
**Supported OS & SDK Versions**
* iOS 9.0+
* tvOS 9.0+
* Swift 5.3
## ❤️ 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).
- Propose your own fixes, suggestions and open a pull request with the changes.
See [all contributors](https://github.com/Juanpe/SkeletonView/graphs/contributors)
###### Project generated with [SwiftPlate](https://github.com/JohnSundell/SwiftPlate)
For more information, please read the [contributing guidelines](https://github.com/Juanpe/SkeletonView/blob/main/CONTRIBUTING.md).
## 📢 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)
- [Swift News #36](https://www.youtube.com/watch?v=mAGpsQiy6so)
- [Best iOS articles, new tools & more](https://medium.com/flawless-app-stories/best-ios-articles-new-tools-more-fcbe673e10d)
## 🏆 Sponsors
Open-source projects cannot live long without your help. If you find **SkeletonView** is useful, please consider supporting this
project by becoming a sponsor.
Become a sponsor through [GitHub Sponsors](https://github.com/sponsors/Juanpe) :heart:
## 👨🏻‍💻 Author
[1.1]: http://i.imgur.com/tXSoThF.png
[1]: http://www.twitter.com/JuanpeCatalan
* Juanpe Catalán [![alt text][1.1]][1]
[Juanpe Catalán](http://www.twitter.com/JuanpeCatalan)
<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
+532
View File
@@ -0,0 +1,532 @@
![](Assets/header2.jpg)
<p align="center">
<a href="https://github.com/Juanpe/SkeletonView/actions?query=workflow%3ACI">
<img src="https://github.com/Juanpe/SkeletonView/workflows/CI/badge.svg">
</a>
<a href="https://codebeat.co/projects/github-com-juanpe-skeletonview-master"><img alt="codebeat badge" src="https://codebeat.co/badges/f854fdfd-31e5-4689-ba04-075d83653e60" /></a>
<img src="http://img.shields.io/badge/dependency%20manager-swiftpm%2Bcocoapods%2Bcarthage-green" />
<img src="https://img.shields.io/badge/platforms-ios%2Btvos-green" />
<a href="https://badge.bow-swift.io/recipe?name=SkeletonView&description=An%20elegant%20way%20to%20show%20users%20that%20something%20is%20happening%20and%20also%20prepare%20them%20to%20which%20contents%20he%20is%20waiting&url=https://github.com/juanpe/skeletonview&owner=Juanpe&avatar=https://avatars0.githubusercontent.com/u/1409041?v=4&tag=1.8.7"><img src="https://raw.githubusercontent.com/bow-swift/bow-art/master/badges/nef-playgrounds-badge.svg" alt="SkeletonView Playground" style="height:20px"></a>
</p>
<p align="center">
<a href="#-destacado">Destacado</a>
• <a href="#-instalación">Instalación</a>
• <a href="#-cómo-funciona">¿Cómo funciona?</a>
• <a href="#-miscelánea">Miscelánea</a>
• <a href="#-contribuir">Contribuir</a>
</p>
**🌎 README está disponible en estos idiomas: [🇬🇧](https://github.com/Juanpe/SkeletonView/blob/master/README.md) . [🇨🇳](https://github.com/Juanpe/SkeletonView/blob/master/README_zh.md) . [🇧🇷](https://github.com/Juanpe/SkeletonView/blob/master/README_pt-br.md) . [🇰🇷](https://github.com/Juanpe/SkeletonView/blob/master/README_ko.md) . [🇫🇷](https://github.com/Juanpe/SkeletonView/blob/master/README_fr.md)**
Hoy en día, La mayoría de las apps tiene procesos asíncronos, como peticiones a una API, procesos que tardan mucho tiempo, etc. Mientras estos procesos se están ejecutando, se suele mostrar un aburrido spinner indicando que algo está pasando.
**SkeletonView** ha sido desarrollada para cubrir esta necesidad, un elegante manera de decirle a los usarios que algo se está procesando y además prepararlos, visualmente, para el contenido que están esperando.
Enjoy it! 🙂
##
- [](#)
- [🌟 Destacado](#-destacado)
- [🎬 Videotutoriales](#-videotutoriales)
- [📲 Instalación](#-instalación)
- [🐒 ¿Cómo funciona?](#-cómo-funciona)
- [](#-1)
- [🌿 Colecciones](#-colecciones)
- [🔠 Textos](#-textos)
- [🦋 Apariencia](#-apariencia)
- [🎨 Colores](#-colores)
- [Imagen extraída de la web https://flatuicolors.com](#imagen-extraída-de-la-web-httpsflatuicolorscom)
- [🏃‍♀️ Animaciones](#-animaciones)
- [🏄 Transiciones](#-transiciones)
- [✨ Miscelánea](#-miscelánea)
- [❤️ Contributing](#-contributing)
- [📢 Menciones](#-menciones)
- [👨🏻‍💻 Autor](#-autor)
- [👮🏻 Licencia](#-licencia)
## 🌟 Destacado
* Fácil de usar
* Todas las UIViews son skeletonables
* Personalizable
* Universal (iPhone & iPad)
* Interface Builder friendly
## 🎬 Videotutoriales
| [![](https://img.youtube.com/vi/75kgOhWsPNA/maxresdefault.jpg)](https://youtu.be/75kgOhWsPNA)|[![](https://img.youtube.com/vi/MVCiM_VdxVA/maxresdefault.jpg)](https://youtu.be/MVCiM_VdxVA)|[![](https://img.youtube.com/vi/Qq3Evspeea8/maxresdefault.jpg)](https://youtu.be/Qq3Evspeea8)|[![](https://img.youtube.com/vi/ZOoPtBwDRT0/maxresdefault.jpg)](https://youtu.be/ZOoPtBwDRT0)
|:---: | :---: |:---: | :---:
|[**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
## 📲 Instalación
* [CocoaPods](https://guides.cocoapods.org/using/using-cocoapods.html):
```ruby
pod 'SkeletonView'
```
* [Carthage](https://github.com/Carthage/Carthage):
```ruby
github "Juanpe/SkeletonView"
```
* [Swift Package Manager](https://swift.org/package-manager/):
```swift
dependencies: [
.package(url: "https://github.com/Juanpe/SkeletonView.git", from: "1.7.0")
]
```
## 🐒 ¿Cómo funciona?
Solo necesitas **3** pasos para usar `SkeletonView`:
1️⃣ Importa SkeletonView en el archivo donde vayas a utilizarlo.
```swift
import SkeletonView
```
2️⃣ Ahora, debes indicar qué elementos de tu vista son `skeletonables`
**Con código:**
```swift
avatarImageView.isSkeletonable = true
```
**Con IB/Storyboards:**
![](Assets/storyboard.png)
3️⃣ Una vez indicado, solo tienes que mostrar el **skeleton**. Tienes **4** opciones:
```swift
(1) view.showSkeleton() // Sólido
(2) view.showGradientSkeleton() // Degradado
(3) view.showAnimatedSkeleton() // Sólido animado
(4) view.showAnimatedGradientSkeleton() // Degradado animado
```
**Vista previa**
<table>
<tr>
<td width="25%">
<center>Sólido</center>
</td>
<td width="25%">
<center>Degradado</center>
</td>
<td width="25%">
<center>Sólido Animado</center>
</td>
<td width="25%">
<center>Degradado Animado</center>
</td>
</tr>
<tr>
<td width="25%">
<img src="Assets/solid.png"></img>
</td>
<td width="25%">
<img src="Assets/gradient.png"></img>
</td>
<td width="25%">
<img src="Assets/solid_animated.gif"></img>
</td>
<td width="25%">
<img src="Assets/gradient_animated.gif"></img>
</td>
</tr>
</table>
> 📣 **¡IMPORTANTE!**
>
> `SkeletonView` es recursivo. Por lo que si tienes una vsita que contiene varios elementos skeletonables, solo tienes queenecu For example, with `UIViewControllers`.
##
### 🌿 Colecciones
`SkeletonView` es compatible con `UITableView` and `UICollectionView`.
**UITableView**
Si quieres mostrar el skeleton en un `UITableView`, necesitas conformar el protocolo `SkeletonTableViewDataSource`.
``` swift
public protocol SkeletonTableViewDataSource: UITableViewDataSource {
// Por defecto: 1
func numSections(in collectionSkeletonView: UITableView) -> Int
// Por defecto:
// Calcula cuantas celdas necesita para rellenar todo el frame.
func collectionSkeletonView(_ skeletonView: UITableView, numberOfRowsInSection section: Int) -> Int
func collectionSkeletonView(_ skeletonView: UITableView, cellIdentifierForRowAt indexPath: IndexPath) -> ReusableCellIdentifier
}
```
Este protocolo hereda de `UITableViewDataSource`, por lo que puedes reemplazar este protocolo por el protocolo de skeleton sin perder ninguna funcionalidad. El único método que es obligatorio implementar es `cellIdentifierForRowAt`, donde tienes que indicar el identificador de la celda.
**Ejemplo**
``` swift
func collectionSkeletonView(_ skeletonView: UITableView, cellIdentifierForRowAt indexPath: IndexPath) -> ReusableCellIdentifier {
return "CellIdentifier"
}
```
Además, tu puedes mostrar el skeleton en las headers y en los footers, conformando el protocolo `SkeletonTableViewDelegate`.
```swift
public protocol SkeletonTableViewDelegate: UITableViewDelegate {
func collectionSkeletonView(_ skeletonView: UITableView, identifierForHeaderInSection section: Int) -> ReusableHeaderFooterIdentifier? // default: nil
func collectionSkeletonView(_ skeletonView: UITableView, identifierForFooterInSection section: Int) -> ReusableHeaderFooterIdentifier? // default: nil
}
```
> 📣 **¡IMPORTANTE!**
>
> 1️⃣ Si estás usando celdas con altura dinámica (**`tableView.rowHeight = UITableViewAutomaticDimension`**), es obligatorio definir el **`estimatedRowHeight`**.
>
> 2️⃣ Cuando añades elemetos a una **`UITableViewCell`**, debes añadirlo al **`contentView`** y no a la celda directamente.
> ```swift
> cell.contentView.addSubview(titleLabel) ✅
> cell.addSubview(titleLabel) ❌
> ```
**UICollectionView**
Para los `UICollectionView`, debes conformar el protocolo `SkeletonCollectionViewDataSource`.
``` swift
public protocol SkeletonCollectionViewDataSource: UICollectionViewDataSource {
func numSections(in collectionSkeletonView: UICollectionView) -> Int // Por defecto: 1
func collectionSkeletonView(_ skeletonView: UICollectionView, numberOfItemsInSection section: Int) -> Int
func collectionSkeletonView(_ skeletonView: UICollectionView, cellIdentifierForItemAt indexPath: IndexPath) -> ReusableCellIdentifier
func collectionSkeletonView(_ skeletonView: UICollectionView, supplementaryViewIdentifierOfKind: String, at indexPath: IndexPath) -> ReusableCellIdentifier? // Por defecto: nil
}
```
El resto del proceso es exactamente igual que con las `UITableView`.
### 🔠 Textos
![](Assets/multilines2.png)
Cuando usas elementos que contienen texto,`SkeletonView` dibujo líneas para simular el texto.
Además, puedes decidir el número de líneas. Si `numberOfLines` es igual a **0**, se calculará automáticamente el número de líneas necesarias para ocupar todo el frame. Sin embargo, si es un número mayor que cero, solo se dibujarán esas líneas.
Puedes especificar algunos atributos para estos elementos:
| Atributo | Valores | Por defecto | Vista previa
| ------- | ------- |------- | -------
| **Porcentaje de relleno** de la última línea. | `0...100` | `70%` | ![](Assets/multiline_lastline.png)
| **Radio de las esquinas** de las líneas. | `0...10` | `0` | ![](Assets/multiline_corner.png)
Para modificar alguno de los valores lo puedes hacer **con código**::
```swift
descriptionTextView.lastLineFillPercent = 50
descriptionTextView.linesCornerRadius = 5
```
O usando **IB/Storyboards**:
![](Assets/multiline_customize.png)
### 🦋 Apariencia
Los skeletons tiene una apariencia por defecto. Así, cuando no especificas el color, el degradado o las propiedades para las multiíneas, `SkeletonView` usa estos valores.
Valores por defecto:
- **tintColor**: `UIColor`
- *default: `.skeletonDefault` (igual que `.clouds` pero se adapta al dark mode)*
- **gradient**: `SkeletonGradient`
- *default: `SkeletonGradient(baseColor: .skeletonDefault)`*
- **multilineHeight**: `CGFloat`
- *default: 15*
- **multilineSpacing**: `CGFloat`
- *default: 10*
- **multilineLastLineFillPercent**: `Int`
- *default: 70*
- **multilineCornerRadius**: `Int`
- *default: 0*
- **skeletonCornerRadius**: `CGFloat` (IBInspectable)
- *default: 0*
Para obtener o modificar estos valores tu puedes usar `SkeletonAppearance.default`:
```swift
SkeletonAppearance.default.multilineHeight = 20
SkeletonAppearance.default.tintColor = .green
```
### 🎨 Colores
Puedes decidir de qué color se tinta tu skeleton. Solo tienes que indicarlo pasándolo como parámetro:
**Usando colores sólidos**
```swift
view.showSkeleton(usingColor: UIColor.gray)
// o
view.showSkeleton(usingColor: UIColor(red: 25.0, green: 30.0, blue: 255.0, alpha: 1.0))
```
**Usando degradados**
``` swift
let gradient = SkeletonGradient(baseColor: UIColor.midnightBlue)
view.showGradientSkeleton(usingGradient: gradient)
```
Además, **SkeletonView** añade 20 colores flat 🤙🏼
```UIColor.turquoise, UIColor.greenSea, UIColor.sunFlower, UIColor.flatOrange ...```
![](Assets/flatcolors.png)
###### Imagen extraída de la web [https://flatuicolors.com](https://flatuicolors.com)
### 🏃‍♀️ Animaciones
**SkeletonView** tiene pre-definidas dos animaciones, *pulse* para skeleton sólidos y *sliding* para degradados.
Además, usando el método `showAnimatedSkeleton`, podemos incluir la `animation` que es de tipo `SkeletonLayerAnimation`, un bloque donde tu puedes crear tus propias animaciones:
```swift
public typealias SkeletonLayerAnimation = (CALayer) -> CAAnimation
```
Tu código quedaría así:
```swift
view.showAnimatedSkeleton { (layer) -> CAAnimation in
let animation = CAAnimation()
// Personaliza la animación aquí
return animation
}
```
`SkeletonAnimationBuilder` es un builder que permite crear `SkeletonLayerAnimation`.
Por ejemplo, tu puedes crear **sliding animations** para los degradados, decidiendo la **direction** y indicando la **duration** de la animación (default = 1.5s).
```swift
// func makeSlidingAnimation(withDirection direction: GradientDirection, duration: CFTimeInterval = 1.5) -> SkeletonLayerAnimation
let animation = SkeletonAnimationBuilder().makeSlidingAnimation(withDirection: .leftToRight)
view.showAnimatedGradientSkeleton(usingGradient: gradient, animation: animation)
```
```GradientDirection``` es un enumerado con estos `cases`:
| Dirección | Vista previa
|------- | -------
| .leftRight | ![](Assets/sliding_left_to_right.gif)
| .rightLeft | ![](Assets/sliding_right_to_left.gif)
| .topBottom | ![](Assets/sliding_top_to_bottom.gif)
| .bottomTop | ![](Assets/sliding_bottom_to_top.gif)
| .topLeftBottomRight | ![](Assets/sliding_topLeft_to_bottomRight.gif)
| .bottomRightTopLeft | ![](Assets/sliding_bottomRight_to_topLeft.gif)
> **😉 ¡Truco!**
>
> Puedes crear una animación sliding, con este shortcut:
> ```swift
> let animation = GradientDirection.leftToRight.slidingAnimation()
> ```
### 🏄 Transiciones
**SkeletonView** tiene algunas transiciones listas para usarse cuando **aparece** o se **oculta**. Puedes especificarla así:
```swift
view.showSkeleton(transition: .crossDissolve(0.25))
view.hideSkeleton(transition: .crossDissolve(0.25))
```
La transición por defecto es `crossDissolve(0.25)`
**Vista previa**
<table>
<tr>
<td width="50%">
<center>Sin transición</center>
</td>
<td width="50%">
<center>Cross dissolve</center>
</td>
</tr>
<tr>
<td width="50%">
<img src="Assets/skeleton_transition_nofade.gif"></img>
</td>
<td width="50%">
<img src="Assets/skeleton_transition_fade.gif"></img>
</td>
</tr>
</table>
## ✨ Miscelánea
**Jerarquía**
`SkeletonView` es recursivo, pero para que sea eficiente, tenemos que pararar la recursión tan pronto como sea posible. Por este motivo, el contenedor de las vistas debe ser **`skeletonable`**, porque `SkeletonView` parará de buscar vistas skeletonables cuando encuentre una que no lo sea, dentro de la jerarquía.
Como una imagen vale más que mil palabras:
En este ejemplo, tenemos un `UIViewController` con un `containerView` y una `UITableView`. Cuando la vista está lista, para mostrar el skeleton ejecutamos el método:
```
view.showSkeleton()
```
> `isSkeletonable`= ☠️
| Configuración | Resultado|
|:-------:|:-------:|
|<img src="Assets/no_skeletonable.jpg" width="350"/> | <img src="Assets/no_skeletonables_result.png" width="350"/>|
|<img src="Assets/container_no_skeletonable.jpg" width="350"/> | <img src="Assets/no_skeletonables_result.png" width="350"/>|
|<img src="Assets/container_skeletonable.jpg" width="350"/> | <img src="Assets/container_skeletonable_result.png" width="350"/>|
|<img src="Assets/all_skeletonables.jpg" width="350"/>| <img src="Assets/all_skeletonables_result.png" width="350"/>|
|<img src="Assets/tableview_no_skeletonable.jpg" width="350"/> | <img src="Assets/tableview_no_skeletonable_result.png" height="350"/>|
|<img src="Assets/tableview_skeletonable.jpg" width="350"/> | <img src="Assets/tableview_skeletonable_result.png" height="350"/>|
**Jerarquía en las colecciones**
Esta ilustración muestra como deberías específicar qué elementos son skeletonables cuando estás usando una `UITableView`:
<img src="Assets/tableview_scheme.png" width="700px">
**Actualiza el skeleton**
Puedes cambiar la configuración del skeleton, como el color, la animación, etc, con los siguientes métodos:
```swift
(1) view.updateSkeleton() // Sólido
(2) view.updateGradientSkeleton() // Degradado
(3) view.updateAnimatedSkeleton() // Sólido animado
(4) view.updateAnimatedGradientSkeleton() // Degradado animado
```
**Debug**
Para facilitar las tareas de debug cuando algo no está funcionando bien, **`SkeletonView`** tiene una nueva herramienta.
Primero, `UIView` tiene una nueva propiedad que contiene toda la info del skeleton:
```swift
var skeletonDescription: String
```
Y es representada de la siguiente manera:
![](Assets/debug_description.png)
Para activar el **modo debug**. Solo tienes que añadir una variable de entorno con esta clave `SKELETON_DEBUG` y activarla.
![](Assets/debug_mode.png)
Entonces, cuando el skeleton aparece, tu podrás ver la jerarquía de vistas en la consola de Xcode.
<details>
<summary>Abre para ver un ejemplo </summary>
<img src="Assets/hierarchy_output.png" />
</details>
**OS Soportado & Versiones SDK**
* iOS 9.0+
* tvOS 9.0+
* Swift 5
## ❤️ Contributing
Esto es un proyecto open source, siéntete libre de contribuir. ¿Cómo?
- Abre un [issue](https://github.com/Juanpe/SkeletonView/issues/new).
- Envía feedback a través del [email](mailto://juanpecatalan.com).
- Propone tus propies fixes, sugerencias y abre una Pull Request con los cambios.
Échale un vistazo a [los que ya han contribuído](https://github.com/Juanpe/SkeletonView/graphs/contributors)
Para más información, por favor, lee la [guía de contribución](https://github.com/Juanpe/SkeletonView/blob/main/CONTRIBUTING.md).
## 📢 Menciones
- [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)
- [Swift News #36](https://www.youtube.com/watch?v=mAGpsQiy6so)
- [Best iOS articles, new tools & more](https://medium.com/flawless-app-stories/best-ios-articles-new-tools-more-fcbe673e10d)
## 👨🏻‍💻 Autor
[Juanpe Catalán](http://www.twitter.com/JuanpeCatalan)
<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>
## 👮🏻 Licencia
```
MIT License
Copyright (c) 2017 Juanpe Catalán
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
```
+570
View File
@@ -0,0 +1,570 @@
![](Assets/header2.jpg)
<p align="center">
<a href="https://github.com/Juanpe/SkeletonView/actions?query=workflow%3ACI">
<img src="https://github.com/Juanpe/SkeletonView/workflows/CI/badge.svg">
</a>
<a href="https://codebeat.co/projects/github-com-juanpe-skeletonview-master"><img alt="codebeat badge" src="https://codebeat.co/badges/f854fdfd-31e5-4689-ba04-075d83653e60" /></a>
<img src="https://img.shields.io/badge/Swift-5-orange.svg" />
<img src="http://img.shields.io/badge/dependency%20manager-swiftpm%2Bcocoapods%2Bcarthage-green" />
<img src="https://img.shields.io/badge/platforms-ios%2Btvos-green" />
<a href="https://badge.bow-swift.io/recipe?name=SkeletonView&description=An%20elegant%20way%20to%20show%20users%20that%20something%20is%20happening%20and%20also%20prepare%20them%20to%20which%20contents%20he%20is%20waiting&url=https://github.com/juanpe/skeletonview&owner=Juanpe&avatar=https://avatars0.githubusercontent.com/u/1409041?v=4&tag=1.8.7"><img src="https://raw.githubusercontent.com/bow-swift/bow-art/master/badges/nef-playgrounds-badge.svg" alt="SkeletonView Playground" style="height:20px"></a>
<br/>
<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://gitter.im/SkeletonView/community?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge">
<img src="https://badges.gitter.im/SkeletonView/community.svg?style=flat" />
</a>
<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 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="Licence" />
</a>
</p>
🌎 Traductions : </br>
[Original](https://github.com/Juanpe/SkeletonView) </br>
[🇨🇳](https://github.com/Juanpe/SkeletonView/blob/master/README_zh.md) [@WhatsXie](https://twitter.com/WhatsXie) </br>
[🇧🇷](https://github.com/Juanpe/SkeletonView/blob/master/README_pt-br.md) [@brunomunizaf](https://twitter.com/brunomuniz_af) </br>
[🇰🇷](https://github.com/Juanpe/SkeletonView/blob/master/README_ko.md) [@techinpark](https://twitter.com/techinpark) </br>
[🇫🇷](https://github.com/Juanpe/SkeletonView/blob/master/README_fr.md) [@OmarJalil](https://github.com/OmarJalil)
Aujourd'hui, presque toutes les applications ont des processus asynchrones, tels que les requêtes Api, les processus de longue durée, etc. Et pendant que les processus fonctionnent, les développeurs affichent généralement une vue de chargement pour montrer aux utilisateurs que quelque chose se passe.
"SkeletonView" a été créé pour répondre à ce besoin, une manière élégante de montrer aux utilisateurs que quelque chose se passe et aussi de les préparer aux contenus qu'ils attendent.
Profitez-en! 🙂
- [🌟 Caractéristiques](#-caractéristiques)
- [🎬 Guides](#-guides)
- [📲 Installation](#-installation)
- [Utilisation de CocoaPods](#utilisation-de-cocoapods)
- [Utilisation de Carthage](#utilisation-de-carthage)
- [Utilisation du gestionnaire de paquets Swift](#utilisation-du-gestionnaire-de-paquets-swift)
- [🐒 Mode d'emploi](#-mode-demploi)
- [Extra](#extra)
- [Mise en page des vues squelettes](#mise-en-page-des-vues-squelettes)
- [Mise à jour de la configuration du squelette](#mise-à-jour-de-la-configuration-du-squelette)
- [🌿 Collections](#-collections)
- [UITableView](#uitableview)
- [UICollectionView](#uicollectionview)
- [📰 Texte multiligne](#-texte-multiligne)
- [🎛 Personnaliser](#-personnaliser)
- [🎨 Couleurs personnalisées](#-couleurs-personnalisées)
- [Image tirée du site web https://flatuicolors.com](#image-tirée-du-site-web-httpsflatuicolorscom)
- [🦋 Présentation](#-présentation)
- [🤓 Animations personnalisées](#-animations-personnalisées)
- [🏄 Transitions](#-transitions)
- [👨👧👦 Hiérarchie](#-hiérarchie)
- [🔬 Débugger](#-débugger)
- [📚 Documentation](#-documentation)
- [📋 Versions OS et SDK supportées](#-versions-os-et-sdk-supportées)
- [📬 Prochaines étapes](#-prochaines-étapes)
- [❤️ Contribuer](#-contribuer)
- [Projet généré avec SwiftPlate](#projet-généré-avec-swiftplate)
- [📢 Mentions](#-mentions)
- [👨🏻‍💻 Auteur](#-auteur)
- [👮🏻 Licence](#-licence)
## 🌟 Caractéristiques
- [x] Facile à utiliser
- [x] Tous les UIViews sont squelettisables
- [x] Entièrement personnalisable
- [x] Universel (iPhone et iPad)
- [x] Interface Builder friendly
- [x] Syntaxe Swift simple
- [x] Base de code légère et lisible
## 🎬 Guides
[<img src="Assets/thumb_getting_started.png">](https://youtu.be/75kgOhWsPNA)
## 📲 Installation
#### Utilisation de [CocoaPods](https://cocoapods.org)
Editez votre "podfile" et spécifiez la dépendance:
```ruby
pod "SkeletonView"
```
#### Utilisation de [Carthage](https://github.com/carthage)
Modifiez votre "Cartfile" et spécifiez la dépendance:
```bash
github "Juanpe/SkeletonView"
```
#### Utilisation du [gestionnaire de paquets Swift](https://github.com/apple/swift-package-manager)
Une fois que vous avez configuré votre paquet Swift, ajouter `SkeletonView` comme dépendance est aussi facile que de l'ajouter à la valeur des `dépendances` de votre `Package.swift`.
```swift
dependencies: [
.package(url: "https://github.com/Juanpe/SkeletonView.git", from: "1.7.0")
]
```
## 🐒 Mode d'emploi
Seulement **3** étapes nécessaires pour utiliser `SkeletonView` :
**1.** Importer SkeletonView au bon endroit.
```swift
import SkeletonView
```
**2.** Maintenant, définissez les vues qui seront `squelettisables`. Vous y arrivez de deux façons :
**En utilisant du code:**
```swift
avatarImageView.isSkeletonable = true
```
**Utilisation des IB/Storyboards:**
![](Assets/storyboard.png)
**Une fois que vous avez défini les vues, vous pouvez montrer le **squelette**. Pour le faire, vous avez quatre choix :
```swift
(1) view.showSkeleton() // Solide
(2) view.showGradientSkeleton() // Gradient
(3) view.showAnimatedSkeleton() // Solide animé
(4) view.showAnimatedGradientSkeleton() // Gradient animé
```
**Preview**
<table>
<tr>
<td width="25%">
<center>Solide</center>
</td>
<td width="25%">
<center>Gradient</center>
</td>
<td width="25%">
<center>Animé Solide</center>
</td>
<td width="25%">
<center>Animé Gradient</center>
</td>
</tr>
<tr>
<td width="25%">
<img src="Assets/solid.png"></img>
</td>
<td width="25%">
<img src="Assets/gradient.png"></img>
</td>
<td width="25%">
<img src="Assets/solid_animated.gif"></img>
</td>
<td width="25%">
<img src="Assets/gradient_animated.gif"></img>
</td>
</tr>
</table>
> **IMPORTANT!**
>>```SkeletonView``` est récursif, donc si vous voulez montrer le squelette dans toutes les vues squelettables, il vous suffit d'appeler la méthode `show` dans la vue principale du conteneur. Par exemple, avec UIViewControllers
### Extra
#### Mise en page des vues squelettes
Il arrive que le squelette ne corresponde pas à votre mise en page parce que les limites de la vue parent ont changé. ~Par exemple, la rotation de l'appareil.~
Vous pouvez relayer les vues du squelette de cette manière :
```swift
override func viewDidLayoutSubviews() {
view.layoutSkeletonIfNeeded()
}
```
⚠️⚠️ Vous ne devriez pas appeler cette méthode. À partir de la *version 1.8.1*, vous n'avez pas besoin d'appeler cette méthode, la bibliothèque le fait automatiquement. Vous pouvez donc utiliser cette méthode *seulement* dans les cas où vous devez mettre à jour manuellement la présentation du squelette.
#### Mise à jour de la configuration du squelette
Vous pouvez modifier la configuration du squelette à tout moment comme sa couleur, son animation, etc :
```swift
(1) view.updateSkeleton() // Solide
(2) view.updateGradientSkeleton() // Gradient
(3) view.updateAnimatedSkeleton() // Solid animated
(4) view.updateAnimatedGradientSkeleton() // Gradient animé
```
### 🌿 Collections
Maintenant, `SkeletonView` est compatible avec `UITableView` et `UICollectionView`.
#### UITableView
Si vous voulez montrer le squelette dans un `UITableView`, vous devez vous conformer au protocole `SkeletonTableViewDataSource`.
``` swift
public protocol SkeletonTableViewDataSource: UITableViewDataSource {
func numSections(in collectionSkeletonView: UITableView) -> Int
func collectionSkeletonView(_ skeletonView: UITableView, numberOfRowsInSection section: Int) -> Int
func collectionSkeletonView(_ skeletonView: UITableView, cellIdentifierForRowAt indexPath: IndexPath) -> ReusableCellIdentifier
func collectionSkeletonView(_ skeletonView: UITableView, identifierForHeaderInSection section: Int) -> ReusableHeaderFooterIdentifier?
func collectionSkeletonView(_ skeletonView: UITableView, identifierForFooterInSection section: Int) -> ReusableHeaderFooterIdentifier?
}
```
Comme vous pouvez le voir, ce protocole hérite de `UITableViewDataSource`, vous pouvez donc remplacer ce protocole par le protocole squelette.
Ce protocole a une implémentation par défaut:
``` swift
func numSections(in collectionSkeletonView: UITableView) -> Int
// Par défaut: 1
```
``` swift
func collectionSkeletonView(_ skeletonView: UITableView, numberOfRowsInSection section: Int) -> Int
// Par défaut:
// Il calcule le nombre de cellules nécessaires pour remplir l'ensemble du tableau
```
``` swift
func collectionSkeletonView(_ skeletonView: UITableView, identifierForHeaderInSection section: Int) -> ReusableHeaderFooterIdentifier?
// Par défaut: nil
```
``` swift
func collectionSkeletonView(_ skeletonView: UITableView, identifierForFooterInSection section: Int) -> ReusableHeaderFooterIdentifier?
// Par défaut: nil
```
Il n'y a qu'une seule méthode à mettre en œuvre pour faire connaître au Squelette l'identifiant de la cellule. Cette méthode n'a pas d'implémentation par défaut :
``` swift
func collectionSkeletonView(_ skeletonView : UITableView, cellIdentifierForRowAt indexPath : IndexPath) -> ReusableCellIdentifier
```
**Exemple**
``` swift
func collectionSkeletonView(_ skeletonView : UITableView, cellIdentifierForRowAt indexPath : IndexPath) -> ReusableCellIdentifier {
return "CellIdentifier".
}
```
> **IMPORTANT!**
> Si vous utilisez des cellules redimensionnables (`tableView.rowHeight = UITableViewAutomaticDimension` ), il est obligatoire de définir la `estimatedRowHeight`.
👩🏼 **Comment préciser quels éléments sont squelettisables ?
Voici une illustration qui montre comment vous devez spécifier quels éléments sont squelettisables lorsque vous utilisez une `UITableView` :
![](Assets/tableview_scheme.png)
Comme vous pouvez le voir, nous devons faire `skeletonable` la tableview, la cellule et les éléments de l'interface visuelle, mais nous n'avons pas besoin de faire `skeletonable` le `contentView`.
#### UICollectionView
Pour ```UICollectionView```, vous devez conformer le protocole `SkeletonCollectionViewDataSource`.
``` swift
public protocol SkeletonCollectionViewDataSource: UICollectionViewDataSource {
func numSections(in collectionSkeletonView: UICollectionView) -> Int
func collectionSkeletonView(_ skeletonView: UICollectionView, numberOfItemsInSection section: Int) -> Int
func collectionSkeletonView(_ skeletonView: UICollectionView, cellIdentifierForItemAt indexPath: IndexPath) -> ReusableCellIdentifier
}
```
Le reste du processus ressemble à une `UITableView`.
### 📰 Texte multiligne
![](Assets/multilines2.png)
Lorsqu'on utilise des éléments avec du texte, `SkeletonView` dessine des lignes pour simuler le texte.
En outre, vous pouvez décider combien de lignes vous voulez. Si `numberOfLines` est réglé à zéro, il calculera le combien de lignes sont nécessaires pour remplir tout le squelette et il sera dessiné. Au contraire, si vous le réglez sur un, deux ou tout autre nombre supérieur à zéro, il ne dessinera que ce nombre de lignes.
##### 🎛 Personnaliser
Vous pouvez définir certaines propriétés pour les éléments multilignes.
| Propriété | Valeurs | Par défaut | Aperçu
| ------- | ------- |------- | -------
| **Pourcentage de remplissage** de la dernière ligne. | `0...100` | `70%` | ![](Assets/multiline_lastline.png)
| **Corner radius** des lignes. (**NEW**) | `0...10` | `0` | ![](Assets/multiline_corner.png)
Pour modifier le pourcentage ou le rayon **à l'aide du code**, définissez les propriétés :
``` swift
descriptionTextView.lastLineFillPercent = 50
descriptionTextView.linesCornerRadius = 5
```
Ou, si vous préférez, utilisez l'**IB/Storyboard** :
![](Assets/multiline_customize.png)
### 🎨 Couleurs personnalisées
Vous pouvez décider la couleur du squelette. Il vous suffit de passer comme paramètre la couleur ou le gradient que vous souhaitez.
**Utiliser des couleurs solides**
``` swift
view.showSkeleton(usingColor : UIColor.gray) // Solide
// ou
view.showSkeleton(usingColor : UIColor(red : 25.0, green : 30.0, blue : 255.0, alpha : 1.0))
```
**Utilisation des gradients**
``` swift
let gradient = SkeletonGradient(baseColor : UIColor.midnightBlue)
view.showGradientSkeleton(usingGradient : gradient) // Gradient
```
En outre, `SkeletonView` dispose de 20 couleurs unies 🤙🏼
`UIColor.turquoise, UIColor.greenSea, UIColor.sunFlower, UIColor.flatOrange ...`
![](Assets/flatcolors.png)
###### Image tirée du site web [https://flatuicolors.com](https://flatuicolors.com)
### 🦋 Présentation
**NOUVEAU** Les squelettes ont une apparence par défaut. Ainsi, lorsque vous ne spécifiez pas la couleur, le gradient ou les propriétés multilignes, `SkeletonView` utilise les valeurs par défaut.
Valeurs par défaut :
- **tintColor** : UIColor
- *défaut : `.skeletonDefault` (comme `.clouds` mais adaptable au thème sombre)*
- **gradient** : SkeletonGradient
- *défaut : `SkeletonGradient(baseColor : .skeletonDefault)`*
- **multilineHeight** : CGFloat
- *défaut : 15*
- **multilineSpacing** : CGFloat
- *défaut : 10*
- **multilineLastLineFillPercent** : Int
- *défaut : 70*
- **multilineCornerRadius** : Int
- *défaut : 0*
- **skeletonCornerRadius** : CGFloat (IBInspectable) (Faites votre vue squelette avec des coins)
- *défaut : 0*
Pour obtenir ces valeurs par défaut, vous pouvez utiliser `SkeletonAppearance.default`. En utilisant cette propriété, vous pouvez également définir les valeurs :
``` swift
SkeletonAppearance.default.multilineHeight = 20
SkeletonAppearance.default.tintColor = .green
```
### 🤓 Animations personnalisées
`SkeletonView` a deux animations intégrées, *pulse* pour les squelettes solides et *sliding* pour les gradients.
De plus, si vous voulez faire votre propre animation de squelette, c'est très facile.
Skeleton fournit la fonction `showAnimatedSkeleton` qui possède une fermeture `SkeletonLayerAnimation` où vous pouvez définir votre animation personnalisée.
``` swift
public typealias SkeletonLayerAnimation = (CALayer) -> CAAnimation
```
Vous pouvez appeler la fonction comme ceci :
```swift
view.showAnimatedSkeleton { (layer) -> CAAnimation in
let animation = CAAnimation()
// Personnalisez ici votre animation
return animation
}
```
`SkeletonAnimationBuilder` est disponible. C'est un constructeur pour faire `SkeletonLayerAnimation`.
Aujourd'hui, vous pouvez créer des **animations glissantes** pour les gradients, en décidant de la **direction** et en fixant la **durée** de l'animation (par défaut = 1,5s).
```swift
// func makeSlidingAnimation(withDirection direction : GradientDirection, duration : CFTimeInterval = 1.5) -> SkeletonLayerAnimation
let animation = SkeletonAnimationBuilder().makeSlidingAnimation(withDirection : .leftToRight)
view.showAnimatedGradientSkeleton(usingGradient : gradient, animation : animation)
```
`GradientDirection` est une `enum`, avec ces cas :
| Direction | Aperçu
|------- | -------
| .leftRight | ![](Assets/sliding_left_to_right.gif)
| .rightLeft | ![](Assets/sliding_right_to_left.gif)
| .topBottom | ![](Assets/sliding_top_to_bottom.gif)
| .bottomTop | ![](Assets/sliding_bottom_to_top.gif)
| .topLeftBottomRight | ![](Assets/sliding_topLeft_to_bottomRight.gif)
| .bottomRightTopLeft | ![](Assets/sliding_bottomRight_to_topLeft.gif)
> **😉 TRICK!**
Il existe une autre façon de créer des animations de glissement, en utilisant simplement ce raccourci :
>>```let animation = GradientDirection.leftToRight.slidingAnimation()```
### 🏄 Transitions
`SkeletonView` a des transitions intégrées pour **montrer** ou **cacher** les squelettes d'une manière *lisse* 🤙
Pour utiliser la transition, il suffit d'ajouter le paramètre "transition" à votre fonction `showSkeleton()` ou `hideSkeleton()` avec le temps de transition, comme ceci :
```swift
view.showSkeleton(transition : .crossDissolve(0.25)) //Montrer la transition de dissolution croisée du squelette avec un temps de fondu de 0,25 seconde
view.hideSkeleton(transition : .crossDissolve(0.25)) //Cachez la transition de dissolution croisée du squelette avec un temps de fondu de 0,25 seconde
```
La valeur par défaut est `crossDissolve(0.25)`.
**Preview**
<table>
<tr>
<td width="50%">
<center>None</center>
</td>
<td width="50%">
<center>Cross dissolve</center>
</td>
</tr>
<tr>
<td width="50%">
<img src="Assets/skeleton_transition_nofade.gif"></img>
</td>
<td width="50%">
<img src="Assets/skeleton_transition_fade.gif"></img>
</td>
</tr>
</table>
### 👨👧👦 Hiérarchie
Puisque `SkeletonView` est récursif, et que nous voulons que le squelette soit très efficace, nous voulons arrêter la récursivité dès que possible. Pour cette raison, vous devez définir la vue du conteneur comme `Skeletonable`, parce que Skeleton arrêtera de chercher des sous-vues `squelettisables` dès qu'une vue n'est pas `Skeletonable`, cassant alors la récursivité.
Parce qu'une image vaut mille mots :
Dans cet exemple, nous avons un `UIViewController` avec une `ContainerView` et une `UITableView`. Lorsque la vue est prête, nous montrons le squelette en utilisant cette méthode :
```
view.showSkeleton()
```
> ```isSkeletonable```= ☠️
| Configuration | Résultat|
|:-------:|:-------:|
|<img src="Assets/no_skeletonable.jpg" width="350"/> | <img src="Assets/no_skeletonables_result.png" width="350"/>|
|<img src="Assets/container_no_skeletonable.jpg" width="350"/> | <img src="Assets/no_skeletonables_result.png" width="350"/>|
|<img src="Assets/container_skeletonable.jpg" width="350"/> | <img src="Assets/container_skeletonable_result.png" width="350"/>|
|<img src="Assets/all_skeletonables.jpg" width="350"/>| <img src="Assets/all_skeletonables_result.png" width="350"/>|
|<img src="Assets/tableview_no_skeletonable.jpg" width="350"/> | <img src="Assets/tableview_no_skeletonable_result.png" height="350"/>|
|<img src="Assets/tableview_skeletonable.jpg" width="350"/> | <img src="Assets/tableview_skeletonable_result.png" height="350"/>|
### 🔬 Débugger
**NOUVEAU** Afin de faciliter les tâches de debuggage lorsque quelque chose ne fonctionne pas bien. `SkeletonView` a de nouveaux outils.
Tout d'abord, `UIView` a une nouvelle propriété disponible avec son squelette d'information :
```swift
var skeletonDescription : String
```
La représentation du squelette ressemble à ceci :
![](Assets/debug_description.png)
En outre, vous pouvez activer le nouveau mode **debug**. Il suffit d'ajouter la variable d'environnement `SKELETON_DEBUG` et de l'activer.
![](Assets/debug_mode.png)
Ensuite, lorsque le squelette apparaît, vous pouvez voir la hiérarchie des vues dans la console Xcode.
<details>
<summary>Ouvrez pour voir un exemple de sortie</summary>
<img src="Assets/hierarchy_output.png" />
</details>
### 📚 Documentation
Bientôt disponible...😅
### 📋 Versions OS et SDK supportées
* iOS 9.0+
* tvOS 9.0+
* Swift 5
## 📬 Prochaines étapes
* [x] Fixer le pourcentage de remplissage de la dernière ligne dans les éléments multilignes
* [x] Ajout d'autres animations en dégradé
* [x] Cellules redimensionnables prises en charge
* [x] Compatible avec CollectionView
* [x] Compatible avec tvOS
* [x] Ajouter l'état de recouvrement
* [x] Apparence personnalisée par défaut
* [x] Mode de debuggage
* [x] Ajouter des animations lorsqu'il montre/cache les squelettes
* [ ] Compatible avec les collections personnalisées
* [ ] Compatible avec MacOS et WatchOS
## ❤️ Contribuer
Il s'agit d'un projet open source, alors n'hésitez pas à y contribuer. Comment ?
- Ouvrez un [numéro](https://github.com/Juanpe/SkeletonView/issues/new).
- Envoyez vos commentaires via [email](mailto://juanpecatalan.com).
- Proposez vos propres correctifs, suggestions et ouvrez une `pull request` avec les changements.
Voir [tous les contributeurs](https://github.com/Juanpe/SkeletonView/graphs/contributors)
###### Projet généré avec [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 articles Swift de novembre] (https://medium.mybridge.co/swift-top-10-articles-for-the-past-month-v-nov-2017-dfed7861cd65)
- [30 bibliothèques incroyables pour iOS Swift (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)
- [Bulletin d'information sur les développements Swift #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)
- [Bulletin d'information Génial iOS #74](https://ios.libhunt.com/newsletter/74)
- [Swift News #36](https://www.youtube.com/watch?v=mAGpsQiy6so)
- [Meilleurs articles sur iOS, nouveaux outils et plus](https://medium.com/flawless-app-stories/best-ios-articles-new-tools-more-fcbe673e10d)
## 👨🏻‍💻 Auteur
[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>
## 👮🏻 Licence
```
MIT License
Copyright (c) 2017 Juanpe Catalán
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
```
+498
View File
@@ -0,0 +1,498 @@
![](Assets/header2.jpg)
<p align="center">
<a href="https://github.com/Juanpe/SkeletonView/actions?query=workflow%3ACI">
<img src="https://github.com/Juanpe/SkeletonView/workflows/CI/badge.svg">
</a>
<a href="https://codebeat.co/projects/github-com-juanpe-skeletonview-master"><img alt="codebeat badge" src="https://codebeat.co/badges/f854fdfd-31e5-4689-ba04-075d83653e60" /></a>
<img src="https://img.shields.io/badge/Swift-5-orange.svg" />
<img src="http://img.shields.io/badge/dependency%20manager-swiftpm%2Bcocoapods%2Bcarthage-green" />
<img src="https://img.shields.io/badge/platforms-ios%2Btvos-green" />
<a href="https://badge.bow-swift.io/recipe?name=SkeletonView&description=An%20elegant%20way%20to%20show%20users%20that%20something%20is%20happening%20and%20also%20prepare%20them%20to%20which%20contents%20he%20is%20waiting&url=https://github.com/juanpe/skeletonview&owner=Juanpe&avatar=https://avatars0.githubusercontent.com/u/1409041?v=4&tag=1.8.7"><img src="https://raw.githubusercontent.com/bow-swift/bow-art/master/badges/nef-playgrounds-badge.svg" alt="SkeletonView Playground" style="height:20px"></a>
<br/>
<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://gitter.im/SkeletonView/community?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge">
<img src="https://badges.gitter.im/SkeletonView/community.svg?style=flat" />
</a>
<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 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>
</p>
🌎 번역에 도움을 주신분들: </br>
[Original](https://github.com/Juanpe/SkeletonView) </br>
[🇨🇳](https://github.com/Juanpe/SkeletonView/blob/master/README_zh.md) [@WhatsXie](https://twitter.com/WhatsXie) </br>
[🇧🇷](https://github.com/Juanpe/SkeletonView/blob/master/README_pt-br.md) [@brunomunizaf](https://twitter.com/brunomuniz_af) </br>
[🇰🇷](https://github.com/Juanpe/SkeletonView/blob/master/README_ko.md) [@techinpark](https://twitter.com/techinpark) </br>
[🇫🇷](https://github.com/Juanpe/SkeletonView/blob/master/README_fr.md) [@OmarJalil](https://github.com/OmarJalil)
오늘날 거의 대부분의 앱들은 비동기 방식의 API 호출을 사용하는 프로세스를 가지고 있습니다.
프로세스가 작동하는동안 개발자들은 작업이 실행되고 있다는것을 사용자들에게 보여주기 위해서 로딩 뷰를 배치합니다.
```SkeletonView```는 이러한 필요에 의해 고안되었고, 사용자들에게 무엇인가 로딩이 되고 있다는것을 보여주면서 기다리는 콘텐츠에 대해서도 미리 준비할 수 있게 해주는 우아하게 표현할수 있는 방법입니다
맘껏 누리세요 🙂
* [기능](#-features)
* [가이드](#-guides)
* [설치방법](#-installation)
* [Cocoapods](#using-cocoapods)
* [Carthage](#using-carthage)
* [SPM](#using-swift-package-manager)
* [어떻게 사용하나요?](#-how-to-use)
* [Collections](#-collections)
* [Multiline text](#-multiline-text)
* [Custom colors](#-custom-colors)
* [Appearance](#-appearance)
* [Custom animations](#-custom-animations)
* [Hierarchy](#-hierarchy)
* [Debug](#-debug)
* [문서화](#-documentation)
* [지원되는 OS와 SDK 버전](#-supported-os--sdk-versions)
* [Next steps](#-next-steps)
* [Contributing](#-contributing)
* [Mentions](#-mentions)
* [개발자](#-author)
* [라이센스](#-license)
## 🌟 기능
- [x] 사용이 쉽습니다
- [x] 모든 `UIView`에서 사용가능합니다
- [x] 전체 커스터마이징이 가능합니다
- [x] 공통으로 이용가능합니다 (iPhone & iPad)
- [x] `Interface Builder` 에서 사용 가능합니다.
- [x] 간단한 스위프트 문법
- [x] 가볍고 가독성 좋은 코드
## 🎬 사용가이드
[<img src="Assets/thumb_getting_started.png">](https://youtu.be/75kgOhWsPNA)
## 📲 설치 방법
#### [CocoaPods](https://cocoapods.org) 로 사용하기
당신의 프로젝트 `Podfile` 파일에 아래와 같이 입력합니다:
```ruby
pod "SkeletonView"
```
#### [Carthage](https://github.com/carthage)로 사용하기
당신의 프로젝트 `Cartfile` 파일에 아래와 같이 입력합니다:
```bash
github "Juanpe/SkeletonView"
```
#### [Swift Package Manager](https://github.com/apple/swift-package-manager)로 사용하기
당신의 프로젝트에 Swift package를 설정한다면, `SkeletonView` 를 `Package.swift` 파일에 있는 `dependencies`에 추가하시면 됩니다.
```swift
dependencies: [
.package(url: "https://github.com/Juanpe/SkeletonView.git", from: "1.6")
]
```
## 🐒 어떻게 사용하나요?
`SkeletonView` 를 이용하기 위해서는 딱 **3** 단계만 기억하세요:
**1.** 사용하고자 하는 파일에서 `SkeletonView` 를 `Import` 합니다.
```swift
import SkeletonView
```
**2.** 자, 그렇다면 UIView 속성에 `skeletonables` 를 이용하실 수 있습니다. 두가지 옵션이 있습니다
**코드로 사용하는 방법:**
```swift
avatarImageView.isSkeletonable = true
```
**인터페이스빌더 / 스토리보드를 이용하는 방법:**
![](Assets/storyboard.png)
**3.** 당신이 뷰를 세팅할때, **skeleton** 옵션을 사용 할 수 있습니다. 총 **4** 가지 옵션을 지원합니다:
```swift
(1) view.showSkeleton() // Solid
(2) view.showGradientSkeleton() // Gradient
(3) view.showAnimatedSkeleton() // Solid animated
(4) view.showAnimatedGradientSkeleton() // Gradient animated
```
**미리보기**
<table>
<tr>
<td width="25%">
<center>Solid</center>
</td>
<td width="25%">
<center>Gradient</center>
</td>
<td width="25%">
<center>Solid Animated</center>
</td>
<td width="25%">
<center>Gradient Animated</center>
</td>
</tr>
<tr>
<td width="25%">
<img src="Assets/solid.png"></img>
</td>
<td width="25%">
<img src="Assets/gradient.png"></img>
</td>
<td width="25%">
<img src="Assets/solid_animated.gif"></img>
</td>
<td width="25%">
<img src="Assets/gradient_animated.gif"></img>
</td>
</tr>
</table>
> **중요!**
>>```SkeletonView``` 는 재귀적으로 되어있습니다, 만약 모든 뷰에 대해서 skeleton을 호출하고 싶다면, 메인 컨테이너 뷰에서 show `method`를 호출하여야 합니다. 예를 들자면 UIViewControllers가 있습니다.
### 🌿 Collections
현재, ```SkeletonView``` 는 ```UITableView``` 와 ```UICollectionView```에서 호환됩니다.
#### UITableView
만약 ```UITableView```에서 skeleton을 호출하고 싶다면, ```SkeletonTableViewDataSource``` protocol 을 구현하여야 합니다.
``` swift
public protocol SkeletonTableViewDataSource: UITableViewDataSource {
func numSections(in collectionSkeletonView: UITableView) -> Int
func collectionSkeletonView(_ skeletonView: UITableView, numberOfRowsInSection section: Int) -> Int
func collectionSkeletonView(_ skeletonView: UITableView, cellIdentifierForRowAt indexPath: IndexPath) -> ReusableCellIdentifier
}
```
해당 프로토클은 보시다시피 ```UITableViewDataSource```를 상속받아 구현하였으므로, skeleton의 protocol과 대체 가능합니다.
프로토콜의 기본 구현은 다음과 같습니다:
``` swift
func numSections(in collectionSkeletonView: UITableView) -> Int
// Default: 1
```
``` swift
func collectionSkeletonView(_ skeletonView: UITableView, numberOfRowsInSection section: Int) -> Int
// Default:
// 전체 테이블 뷰를 채우는데 필요한 셀 수를 계산합니다
```
해당 메소드는 당신이 구현하여야할 cell identifier을 아는 경우에만 사용합니다, 해당 메소드는 기본으로 구현하지 않아도됩니다 :
``` swift
func collectionSkeletonView(_ skeletonView: UITableView, cellIdentifierForRowAt indexPath: IndexPath) -> ReusableCellIdentifier
```
**Example**
``` swift
func collectionSkeletonView(_ skeletonView: UITableView, cellIdentifierForRowAt indexPath: IndexPath) -> ReusableCellIdentifier {
return "CellIdentifier"
}
```
> **중요!**
> 만약 사이즈가 변하는 셀을 사용한다면 (`tableView.rowHeight = UITableViewAutomaticDimension` ),`estimatedRowHeight`를 무조건 정의해주세요.
👩🏼‍🏫 **어떻게 특정 요소에 skeleton 을 지정할까요?**
아래의 그림은 `UITableView` 에서 특정한 요소에 skeleton 을 지정하는 방법을 보여주는 이미지 입니다:
![](Assets/tableview_scheme.png)
위의 이미지에서 보이듯, 테이블 뷰와 셀에 들어가는 UI 요소들에는 적용을 해야하지만, `contentView`에 skeleton을 적용할 필요는 없습니다.
#### UICollectionView
```UICollectionView``` 에 적용을 하기 위해서는, ```SkeletonCollectionViewDataSource``` protocol 을 구현할 필요가 있습니다.
``` swift
public protocol SkeletonCollectionViewDataSource: UICollectionViewDataSource {
func numSections(in collectionSkeletonView: UICollectionView) -> Int
func collectionSkeletonView(_ skeletonView: UICollectionView, numberOfItemsInSection section: Int) -> Int
func collectionSkeletonView(_ skeletonView: UICollectionView, cellIdentifierForItemAt indexPath: IndexPath) -> ReusableCellIdentifier
}
```
```UITableView``` 와 사용방법은 같습니다.
### 📰 Multiline text
![](Assets/multilines2.png)
텍스트가 들어있는 요소를 사용한다면, ```SkeletonView``` 에서 텍스트의 라인을 그려줍니다.
그리고, 원하는 라인 수를 설정할 수 있습니다. 만약 ```numberOfLines``` 을 0으로 설정한다면, 자동으로 필요한 라인수를 계산해서 그려줍니다. 대신 값이 설정되어있다면 설정된 수만큼의 라인이 그려집니다.
##### 🎛 Customize
당신은 멀티라인을 위해 몇가지 옵션을 설정할 수 있습니다.
| 속성 | 값 | 기본값 | 미리보기 |
| ----------------------------------------------- | --------- | ----- | ---------------------------------- |
| 마지막 라인의 **퍼센트** 를 지정 할 수 있습니다. | `0...100` | `70%` | ![](Assets/multiline_lastline.png) |
| 라인의 **Corner radius** 를 지정할 수 있습니다. (**새로운기능**) | `0...10` | `0` | ![](Assets/multiline_corner.png) |
라인의 radius를 지정하기 위해서는 **코드** 를 이용합니다, 아래 처럼 코드를 작성합니다:
```swift
descriptionTextView.lastLineFillPercent = 50
descriptionTextView.linesCornerRadius = 5
```
혹은 **IB/Storyboard** 를 이용하실 수 있습니다:
![](Assets/multiline_customize.png)
### 🎨 Custom colors
당신은 skeleton의 색상을 지정 할 수 있습니다. 간단하게 원하는 색상을 파라미터로 넘겨주시면 됩니다.
**단색 이용방법**
``` swift
view.showSkeleton(usingColor: UIColor.gray) // Solid
// or
view.showSkeleton(usingColor: UIColor(red: 25.0, green: 30.0, blue: 255.0, alpha: 1.0))
```
**그라디언트 이용 방법**
``` swift
let gradient = SkeletonGradient(baseColor: UIColor.midnightBlue)
view.showGradientSkeleton(usingGradient: gradient) // Gradient
```
게다가, ```SkeletonView``` 에서는 20가지의 기본 컬러를 지원합니다 🤙🏼
```UIColor.turquoise, UIColor.greenSea, UIColor.sunFlower, UIColor.flatOrange ...```
![](Assets/flatcolors.png)
###### 위 이미지는 [https://flatuicolors.com](https://flatuicolors.com) 사이트에서 발췌했습니다.
### 🦋 Appearance
**새로운 사항** skeleton 은 기본설정 값이 정해져 있습니다. 만약 커스텀 컬러를 사용할 필요가 없다면, `SkeletonView` 에 지정 되어있는 기본설정을 사용하시면 됩니다.
기본 설정값:
- **tintColor**: UIColor
- *기본값: .clouds*
- **gradient**: SkeletonGradient
- *기본값: SkeletonGradient(baseColor: .clouds)*
- **multilineHeight**: CGFloat
- *기본값: 15*
- **multilineSpacing**: CGFloat
- *기본값: 10*
- **multilineLastLineFillPercent**: Int
- *기본값: 70*
- **multilineCornerRadius**: Int
- *기본값: 0*
`SkeletonAppearance.default` 에는 사용 되어지는 기본 값들이 설정되어 있습니다 . 아래의 코드와 같이 사용할 수 있습니다:
```Swift
SkeletonAppearance.default.multilineHeight = 20
SkeletonAppearance.default.tintColor = .green
```
### 🤓 커스텀 애니메이션
```SkeletonView``` 에는 두가지 애니메이션이 내장되어 있습니다, 단색 *바운스* 애니메이션과 그라디언트 *슬라이드* 애니메이션 입니다 .
게다가, 직접 애니메이션을 추가하고 싶다면 정말 간단합니다.
Skeleton 에서는 `showAnimatedSkeleton` 함수를 ```SkeletonLayerAnimation```에 정의하여 맞춤형 애니메이션을 정의할 수 있도록 되어 있습니다.
```swift
public typealias SkeletonLayerAnimation = (CALayer) -> CAAnimation
```
함수는 이렇게 호출 가능합니다:
```swift
view.showAnimatedSkeleton { (layer) -> CAAnimation in
let animation = CAAnimation()
// Customize here your animation
return animation
}
```
```SkeletonAnimationBuilder```의 사용이 가능합니다. ```SkeletonLayerAnimation```을 만들기 위해 사용됩니다.
이제, 그라디언트를 위한 **슬라이딩 애니메이션** 을 만들 수 있습니다, 애니메이션을 위한 **방향** 과 **지속시간** 을 설정 할 수 있습니다. (기본값 = 1.5초).
```swift
// func makeSlidingAnimation(withDirection direction: GradientDirection, duration: CFTimeInterval = 1.5) -> SkeletonLayerAnimation
let animation = SkeletonAnimationBuilder().makeSlidingAnimation(withDirection: .leftToRight)
view.showAnimatedGradientSkeleton(usingGradient: gradient, animation: animation)
```
```GradientDirection``` 는 enum 으로 정의 되어있습니다., 아래의 케이스를 참조하세요:
| 방향 | 미리보기 |
| ------------------- | ---------------------------------------------- |
| .leftRight | ![](Assets/sliding_left_to_right.gif) |
| .rightLeft | ![](Assets/sliding_right_to_left.gif) |
| .topBottom | ![](Assets/sliding_top_to_bottom.gif) |
| .bottomTop | ![](Assets/sliding_bottom_to_top.gif) |
| .topLeftBottomRight | ![](Assets/sliding_topLeft_to_bottomRight.gif) |
| .bottomRightTopLeft | ![](Assets/sliding_bottomRight_to_topLeft.gif) |
> **😉 꿀팁!**
슬라이딩 애니메이션을 만들기 위한 또다른 방법이 있습니다, 아래의 코드를 참조하세요:
>>```let animation = GradientDirection.leftToRight.slidingAnimation()```
### 👨‍👧‍👦 계층 구조
```SkeletonView```는 재귀적입니다 , 그리고 우리는 skeleton이 효율적으로 작동하기를 원하기 때문에, 가능한 빨리 재귀작업을 중단하기를 원합니다. 이러한 이유때문에 반드시 컨테이너 뷰를 `Skeletonable` 로 설정해야 합니다, `skeletonable` 되지 않는 뷰를 만나는 순간 재귀 작업을 중단하기 떄문입니다.
아래의 이미지를 참고하세요 이미지는 한눈에 이해되실겁니다:
> ```ìsSkeletonable```= ☠️
| 설정값 | 결과 |
| ----------------------------------------- | --------------------------------------------- |
| ![](Assets/no_skeletonable.png) | ![](Assets/no_skeletonables_result.png) |
| ![](Assets/container_no_skeletonable.png) | ![](Assets/no_skeletonables_result.png) |
| ![](Assets/container_skeletonable.png) | ![](Assets/container_skeletonable_result.png) |
| ![](Assets/all_skeletonables.png) | ![](Assets/all_skeletonables_result.png) |
### 🔬 디버그
**새로운소식** 어떤것들이 잘 동작 하지 않을때를 위해 디버그 작업을 용이하게 하기 위해서 `SkeletonView` 에는 몇가지 새로운 것들이 있습니다.
첫번쨰로, `UIView` 에서 skeleton 정보를 보기위해 다음과 같이 지원하고 있습니다:
```swift
var skeletonDescription: String
```
skeleton은 이렇게 생겼습니다:
![](Assets/debug_description.png)
그리고, 새로운 **디버그 모드**를 활성화 시킬 수 있습니다. 간단하게 `SKELETON_DEBUG` 이라는 환경 변수를 추가해 활성화 하면 됩니다.
![](Assets/debug_mode.png)
그런 이후 skeleton이 나오면 Xcode 콘솔창에서 계층 구조를 볼 수 있습니다.
<details>
<summary>예제를 확인해보세요. </summary>
<img src="Assets/hierarchy_output.png" />
</details>
### 📚 문서화
조금만 기다려주세요...😅
### 📋 지원 가능한 OS & SDK 버전
* iOS 9.0+
* tvOS 9.0+
* Swift 4.2
## 📬 예정된 기능들
* [x] 멀티라인 에서의 마지막 라인의 채우기 비율 설정
* [x] 더많은 그라디언트 애니메이션
* [x] resizable cells 지원
* [x] CollectionView 호환
* [x] tvOS 호환
* [x] recovery state 추가
* [x] Custom default appearance
* [x] 디버그 모드
* [ ] Custom collections 호환
* [ ] skeletons 가 보이거나 가려질때 애니메이션 추가
* [ ] MacOS 와 WatchOS 호환
## ❤️ 기여하기
이 프로젝트는 오픈소스 프로젝트 입니다, 마음편하게 기여해주시면 됩니다 어떻게 하냐구요?
- 새로운 [이슈](https://github.com/Juanpe/SkeletonView/issues/new)를 등록합니다.
- [email](mailto://juanpecatalan.com)을 보냅니다.
- 당신의 수정을 제안합니다, pull request를 포함한 수정을 권장합니다.
전체 [기여자목록](https://github.com/Juanpe/SkeletonView/graphs/contributors)
###### [SwiftPlate](https://github.com/JohnSundell/SwiftPlate)를 통해 프로젝트가 생성되었습니다
## 📢 소식들
- [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)
- [Swift News #36](https://www.youtube.com/watch?v=mAGpsQiy6so)
## 👨🏻‍💻 개발자
[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>
## 👮🏻 라이센스
```
MIT License
Copyright (c) 2017 Juanpe Catalán
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
```
+446
View File
@@ -0,0 +1,446 @@
![](Assets/header2.jpg)
<p align="center">
<a href="https://github.com/Juanpe/SkeletonView/actions?query=workflow%3ACI">
<img src="https://github.com/Juanpe/SkeletonView/workflows/CI/badge.svg">
</a>
<a href="https://codebeat.co/projects/github-com-juanpe-skeletonview-master"><img alt="codebeat badge" src="https://codebeat.co/badges/f854fdfd-31e5-4689-ba04-075d83653e60" /></a>
<img src="https://img.shields.io/badge/Swift-5-orange.svg" />
<img src="http://img.shields.io/badge/dependency%20manager-swiftpm%2Bcocoapods%2Bcarthage-green" />
<img src="https://img.shields.io/badge/platforms-ios%2Btvos-green" />
<a href="https://badge.bow-swift.io/recipe?name=SkeletonView&description=An%20elegant%20way%20to%20show%20users%20that%20something%20is%20happening%20and%20also%20prepare%20them%20to%20which%20contents%20he%20is%20waiting&url=https://github.com/juanpe/skeletonview&owner=Juanpe&avatar=https://avatars0.githubusercontent.com/u/1409041?v=4&tag=1.8.7"><img src="https://raw.githubusercontent.com/bow-swift/bow-art/master/badges/nef-playgrounds-badge.svg" alt="SkeletonView Playground" style="height:20px"></a>
<br/>
<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://gitter.im/SkeletonView/community?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge">
<img src="https://badges.gitter.im/SkeletonView/community.svg?style=flat" />
</a>
<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 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>
</p>
🌎 Traduções: </br>
[Original](https://github.com/Juanpe/SkeletonView) </br>
[🇨🇳](https://github.com/Juanpe/SkeletonView/blob/master/README_zh.md) [@WhatsXie](https://twitter.com/WhatsXie) </br>
[🇧🇷](https://github.com/Juanpe/SkeletonView/blob/master/README_pt-br.md) [@brunomunizaf](https://twitter.com/brunomuniz_af) </br>
[🇰🇷](https://github.com/Juanpe/SkeletonView/blob/master/README_ko.md) [@techinpark](https://twitter.com/techinpark) </br>
[🇫🇷](https://github.com/Juanpe/SkeletonView/blob/master/README_fr.md) [@OmarJalil](https://github.com/OmarJalil)
Hoje, quase todos os apps têm processos assíncronos, como requisições de API, processos longos, etc. E enquanto os processos estão ocorrendo, normalmente os desenvolvedores usam uma view que mostra os usuarios que algo está ocorrendo.
```SkeletonView``` foi criado para essa necessidade, um jeito elegante de mostrar aos usuários que algo está acontecendo e já prepará-los para qual conteúdo será carregado.
Aproveite! 🙂
- [🌟 Features](#-features)
- [📋 Versões do SDK e OS suportados](#-versões-do-sdk-e-os-suportados)
- [🔮 Exemplo](#-exemplo)
- [📲 Instalação](#-instalação)
- [Usando CocoaPods](#usando-cocoapods)
- [Usando Carthage](#usando-carthage)
- [🐒 Como usar](#-como-usar)
- [🌿 Coleções](#-coleções)
- [UITableView](#uitableview)
- [UICollectionView](#uicollectionview)
- [📰 Texto de várias linhas](#-texto-de-várias-linhas)
- [🎛 Customização](#-customização)
- [🎨 Cores customizadas](#-cores-customizadas)
- [Imagem capturada do site https://flatuicolors.com](#imagem-capturada-do-site-httpsflatuicolorscom)
- [🦋 Aparência](#-aparência)
- [🤓 Animações customizadas](#-animações-customizadas)
- [👨‍👧‍👦 Hierarquia](#-hierarquia)
- [📚 Documentação](#-documentação)
- [📬 Próximos passos](#-próximos-passos)
- [❤️ Contribuindo](#-contribuindo)
- [Projeto gerado com SwiftPlate](#projeto-gerado-com-swiftplate)
- [📢 Menções](#-menções)
- [👨🏻‍💻 Autor](#-autor)
- [👮🏻 Licença](#-licença)
## 🌟 Features
- [x] Fácil de usar
- [x] Todas as UIViews são skeletonables
- [x] Completamente customizável
- [x] Universal (iPhone & iPad)
- [x] Interface Builder friendly
- [x] Sintaxe simples em Swift
- [x] Código leve e legível
### 📋 Versões do SDK e OS suportados
* iOS 9.0+
* tvOS 9.0+
* Swift 4.2
### 🔮 Exemplo
Para rodar o projeto de exemplo, clone o repositório e use o target `SkeletonViewExample`.
## 📲 Instalação
#### Usando [CocoaPods](https://cocoapods.org)
Edite seu `Podfile` e especifíque a dependência:
```ruby
pod "SkeletonView"
```
#### Usando [Carthage](https://github.com/carthage)
Edite seu `Cartfile` e especifíque a dependência:
```bash
github "Juanpe/SkeletonView"
```
## 🐒 Como usar
Apenas **3** passos necessários para usar `SkeletonView`:
**1.** Importe SkeletonView no lugar desejado.
```swift
import SkeletonView
```
**2.** Agora, especifíque quais views serão `skeletonables`. Você consegue fazer isso de duas formas:
**Usando código:**
```swift
avatarImageView.isSkeletonable = true
```
**Usando IB/Storyboards:**
![](Assets/storyboard.png)
**3.** Uma vez que você setou as views, você pode mostrar o **skeleton**. Para fazê-lo, você tem **4** escolhas:
```swift
(1) view.showSkeleton() // Solid
(2) view.showGradientSkeleton() // Gradient
(3) view.showAnimatedSkeleton() // Solid animated
(4) view.showAnimatedGradientSkeleton() // Gradient animated
```
**Pré-visualização**
<table>
<tr>
<td width="25%">
<center>Solid</center>
</td>
<td width="25%">
<center>Gradient</center>
</td>
<td width="25%">
<center>Solid Animated</center>
</td>
<td width="25%">
<center>Gradient Animated</center>
</td>
</tr>
<tr>
<td width="25%">
<img src="Assets/solid.png"></img>
</td>
<td width="25%">
<img src="Assets/gradient.png"></img>
</td>
<td width="25%">
<img src="Assets/solid_animated.gif"></img>
</td>
<td width="25%">
<img src="Assets/gradient_animated.gif"></img>
</td>
</tr>
</table>
> **IMPORTANTE!**
>>```SkeletonView``` é recursivo, então se você quer mostrar o esqueleto em todas as views skeletonables, você só precisa chamar o método na main container view. Por exemplo, com UIViewControllers
### 🌿 Coleções
```SkeletonView``` é compatível com ```UITableView``` e ```UICollectionView```.
###### UITableView
Se você quer mostrar o skeleton em uma ```UITableView```, você precisa conformar com o protocolo ```SkeletonTableViewDataSource```.
``` swift
public protocol SkeletonTableViewDataSource: UITableViewDataSource {
func numSections(in collectionSkeletonView: UITableView) -> Int
func collectionSkeletonView(_ skeletonView: UITableView, numberOfRowsInSection section: Int) -> Int
func collectionSkeletonView(_ skeletonView: UITableView, cellIdentifierForRowAt indexPath: IndexPath) -> ReusableCellIdentifier
}
```
Como você pode ver, esse protocolo herda de ```UITableViewDataSource```, então você pode substituir esse protocolo com o protocolo do skeleton.
Esse protocolo tem uma implementação padrão:
``` swift
func numSections(in collectionSkeletonView: UITableView) -> Int
// Default: 1
```
``` swift
func collectionSkeletonView(_ skeletonView: UITableView, numberOfRowsInSection section: Int) -> Int
// Default:
// It calculates how many cells need to populate whole tableview
```
Esse é o único método que você precisa implementar para informar o skeleton sobre o cell identifier. Esse método não possui uma implementação padrão:
``` swift
func collectionSkeletonView(_ skeletonView: UITableView, cellIdentifierForRowAt indexPath: IndexPath) -> ReusableCellIdentifier
```
**Exemplo**
``` swift
func collectionSkeletonView(_ skeletonView: UITableView, cellIdentifierForRowAt indexPath: IndexPath) -> ReusableCellIdentifier {
return "CellIdentifier"
}
```
> **IMPORTANTE!**
> Se você está usando resizable cells (`tableView.rowHeight = UITableViewAutomaticDimension` ), é obrigatório definir a `estimatedRowHeight`.
###### UICollectionView
Para ```UICollectionView```, você precisa conformar com o protocolo ```SkeletonCollectionViewDataSource```.
``` swift
public protocol SkeletonCollectionViewDataSource: UICollectionViewDataSource {
func numSections(in collectionSkeletonView: UICollectionView) -> Int
func collectionSkeletonView(_ skeletonView: UICollectionView, numberOfItemsInSection section: Int) -> Int
func collectionSkeletonView(_ skeletonView: UICollectionView, cellIdentifierForItemAt indexPath: IndexPath) -> ReusableCellIdentifier
}
```
O resto do processo é o mesmo da ```UITableView```
### 📰 Texto de várias linhas
![](Assets/multilines2.png)
Quando você usar elementos com texto, ```SkeletonView``` desenha linhas para simular o texto.
Além disso, você pode decidir quantas linhas você quer. Se ```numberOfLines``` está setado para zero (0), haverá um cálculo para saber quantas linhas são necessárias para preencher o skeleton inteiro e será desenhado. Caso contrário, se você setar para um (1) ou qualquer outro número maior que zero, só serão desenhadas aquele número de linhas.
##### 🎛 Customização
Você pode setar algumas propriedades para elementos de várias linhas.
| Property | Values | Default | Preview
| ------- | ------- |------- | -------
| **Filling percent** of the last line. | `0...100` | `70%` | ![](Assets/multiline_lastline.png)
| **Corner radius** of lines. (**NEW**) | `0...10` | `0` | ![](Assets/multiline_corner.png)
Para modificar a percentagem ou o raio **usando código**, especifique as propriedades:
```swift
descriptionTextView.lastLineFillPercent = 50
descriptionTextView.linesCornerRadius = 5
```
Ou, se você preferir use **IB/Storyboard**:
![](Assets/multiline_customize.png)
### 🎨 Cores customizadas
Você pode decidir que cor o skeleton esta pintado. Você só precisa parametrizar a cor e o gradiente que deseja.
**Usando cores sólidas**
``` swift
view.showSkeleton(usingColor: UIColor.gray) // Solid
// or
view.showSkeleton(usingColor: UIColor(red: 25.0, green: 30.0, blue: 255.0, alpha: 1.0))
```
**Usando gradientes**
``` swift
let gradient = SkeletonGradient(baseColor: UIColor.midnightBlue)
view.showGradientSkeleton(usingGradient: gradient) // Gradient
```
Além do mais, ```SkeletonView``` tem 20 cores flat 🤙🏼
```UIColor.turquoise, UIColor.greenSea, UIColor.sunFlower, UIColor.flatOrange ...```
![](Assets/flatcolors.png)
###### Imagem capturada do site [https://flatuicolors.com](https://flatuicolors.com)
### 🦋 Aparência
**NOVIDADE** Os skeletons tem uma aparência padrão. Então, quando você não especifíca a cor, gradiente ou propriedades de várias linhas, `SkeletonView` usa os valores padrões.
Valores padrões:
- **tintColor**: UIColor
- *default: .clouds*
- **gradient**: SkeletonGradient
- *default: SkeletonGradient(baseColor: .clouds)*
- **multilineHeight**: CGFloat
- *default: 15*
- **multilineSpacing**: CGFloat
- *default: 10*
- **multilineLastLineFillPercent**: Int
- *default: 70*
- **multilineCornerRadius**: Int
- *default: 0*
Para obter esses valores padrões você pode usar `SkeletonAppearance.default`. Usando essa propriedade você pode declarar os valores também:
```Swift
SkeletonAppearance.default.multilineHeight = 20
SkeletonAppearance.default.tintColor = .green
```
### 🤓 Animações customizadas
```SkeletonView``` tem duas animações pré-definidas, *pulse* para skeletons solidos e *sliding* para gradientes.
Além disso, se você quiser fazer suas próprias animações no skeleton, é muito fácil.
Skeleton disponibiliza a função `showAnimatedSkeleton` que tem o closure ```SkeletonLayerAnimation``` onde você pode definir sua animação customizada.
```swift
public typealias SkeletonLayerAnimation = (CALayer) -> CAAnimation
```
Você pode chamar esta função assim:
```swift
view.showAnimatedSkeleton { (layer) -> CAAnimation in
let animation = CAAnimation()
// Customize here your animation
return animation
}
```
Está disponível ```SkeletonAnimationBuilder```. É um construtor para ```SkeletonLayerAnimation```.
Hoje, você pode criar **sliding animations** para gradientes, decidindo a **direction** e setando a **duration** da animaçāo (padrão = 1.5s).
```swift
// func makeSlidingAnimation(withDirection direction: GradientDirection, duration: CFTimeInterval = 1.5) -> SkeletonLayerAnimation
let animation = SkeletonAnimationBuilder().makeSlidingAnimation(withDirection: .leftToRight)
view.showAnimatedGradientSkeleton(usingGradient: gradient, animation: animation)
```
```GradientDirection``` é um enum, com os seguintes cases:
| Direction | Preview
|------- | -------
| .leftRight | ![](Assets/sliding_left_to_right.gif)
| .rightLeft | ![](Assets/sliding_right_to_left.gif)
| .topBottom | ![](Assets/sliding_top_to_bottom.gif)
| .bottomTop | ![](Assets/sliding_bottom_to_top.gif)
| .topLeftBottomRight | ![](Assets/sliding_topLeft_to_bottomRight.gif)
| .bottomRightTopLeft | ![](Assets/sliding_bottomRight_to_topLeft.gif)
> **😉 TRUQUE!**
Existe outra forma de criar sliding animations, apenas usando este atalho:
>>```let animation = GradientDirection.leftToRight.slidingAnimation()```
### 👨‍👧‍👦 Hierarquia
Já que ```SkeletonView``` é recursiva, e queremos que o skeleton seja muito eficiente, queremos parar a recursão assim que possível. Por este motivo, você deve setar a container view como `Skeletonable`, porque o Skeleton vai parar de procurar por subviews `skeletonable` assim que a view não for mais skeletonable, quebrando a recursão.
Porque uma imagem vale mais que mil palavras:
> ```ìsSkeletonable```= ☠️
| Configuration | Result
|------- | -------
|![](Assets/no_skeletonable.png) | ![](Assets/no_skeletonables_result.png)
|![](Assets/container_no_skeletonable.png) | ![](Assets/no_skeletonables_result.png)
|![](Assets/container_skeletonable.png) | ![](Assets/container_skeletonable_result.png)
|![](Assets/all_skeletonables.png) | ![](Assets/all_skeletonables_result.png)
### 📚 Documentação
Em breve...😅
## 📬 Próximos passos
* [x] Setar o percentual de preenchimento da última linha em elementos de várias linhas
* [x] Adicionar mais animações de gradiente
* [x] Suporte para resizable cells
* [x] Compatível com CollectionView
* [x] Compatível com tvOS
* [x] Adicionar recovery state
* [x] Aparência padrão customizável
* [ ] Compatível com coleções customizáveis
* [ ] Adicionar animações quando mostra/esconde os skeletons
* [ ] Compatível com MacOS e WatchOS
## ❤️ Contribuindo
Este é um projeto de código aberto, então sinta-se a vontade para contribuir. Como?
- Abra uma [issue](https://github.com/Juanpe/SkeletonView/issues/new).
- Envie feedback por [email](mailto://juanpecatalan.com).
- Proponha seus próprios fixes, sugestões e abra um pull request com as alterações.
Ver [todos os contribuidores](https://github.com/Juanpe/SkeletonView/graphs/contributors)
###### Projeto gerado com [SwiftPlate](https://github.com/JohnSundell/SwiftPlate)
## 📢 Menções
- [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)
## 👨🏻‍💻 Autor
[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>
## 👮🏻 Licença
```
MIT License
Copyright (c) 2017 Juanpe Catalán
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
```
Executable
+421
View File
@@ -0,0 +1,421 @@
![](Assets/header2.jpg)
<p align="center">
<a href="https://github.com/Juanpe/SkeletonView/actions?query=workflow%3ACI">
<img src="https://github.com/Juanpe/SkeletonView/workflows/CI/badge.svg">
</a>
<a href="https://codebeat.co/projects/github-com-juanpe-skeletonview-master"><img alt="codebeat badge" src="https://codebeat.co/badges/f854fdfd-31e5-4689-ba04-075d83653e60" /></a>
<img src="https://img.shields.io/badge/Swift-5-orange.svg" />
<img src="http://img.shields.io/badge/dependency%20manager-swiftpm%2Bcocoapods%2Bcarthage-green" />
<img src="https://img.shields.io/badge/platforms-ios%2Btvos-green" />
<a href="https://badge.bow-swift.io/recipe?name=SkeletonView&description=An%20elegant%20way%20to%20show%20users%20that%20something%20is%20happening%20and%20also%20prepare%20them%20to%20which%20contents%20he%20is%20waiting&url=https://github.com/juanpe/skeletonview&owner=Juanpe&avatar=https://avatars0.githubusercontent.com/u/1409041?v=4&tag=1.8.7"><img src="https://raw.githubusercontent.com/bow-swift/bow-art/master/badges/nef-playgrounds-badge.svg" alt="SkeletonView Playground" style="height:20px"></a>
<br/>
<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://gitter.im/SkeletonView/community?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge">
<img src="https://badges.gitter.im/SkeletonView/community.svg?style=flat" />
</a>
<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 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>
</p>
🌎 翻译: [ [原版的](https://github.com/Juanpe/SkeletonView) ] </br>
[Original](https://github.com/Juanpe/SkeletonView) </br>
[🇨🇳](https://github.com/Juanpe/SkeletonView/blob/master/README_zh.md) [@WhatsXie](https://twitter.com/WhatsXie) </br>
[🇧🇷](https://github.com/Juanpe/SkeletonView/blob/master/README_pt-br.md) [@brunomunizaf](https://twitter.com/brunomuniz_af) </br>
[🇰🇷](https://github.com/Juanpe/SkeletonView/blob/master/README_ko.md) [@techinpark](https://twitter.com/techinpark) </br>
[🇫🇷](https://github.com/Juanpe/SkeletonView/blob/master/README_fr.md) [@OmarJalil](https://github.com/OmarJalil)
今天,几乎所有的应用程序都有异步流程,例如:Api请求、长时间运行的流程等。虽然流程正在运行,但通常开发人员会设置一个加载视图来向用户显示正在发生的事情。
```SkeletonView``` 已经构想出来满足这种需求,这是一种优雅的方式,向用户展示正在发生的事情,并为他们等待的内容做好准备。
好好享受! 🙂
- [🌟 特征](#-特征)
- [📋 版本要求](#-版本要求)
- [🔮 示例](#-示例)
- [📲 安装](#-安装)
- [使用 CocoaPods](#使用-cocoapods)
- [使用 Carthage](#使用-carthage)
- [🐒 如何使用](#-如何使用)
- [🌿 集合](#-集合)
- [UITableView](#uitableview)
- [UICollectionView](#uicollectionview)
- [📰 多行文字](#-多行文字)
- [🎛 定制](#-定制)
- [🎨 自定义颜色](#-自定义颜色)
- [从网站 https://flatuicolors.com捕获的图像](#从网站-httpsflatuicolorscom捕获的图像)
- [🤓 自定义动画](#-自定义动画)
- [👨‍👧‍👦 等级制度](#-等级制度)
- [📚 文档](#-文档)
- [📬 下一步](#-下一步)
- [❤️ 特约](#-特约)
- [使用 SwiftPlate 生成的项目](#使用-swiftplate-生成的项目)
- [📢 提及](#-提及)
- [👨🏻‍💻 作者](#-作者)
- [👮🏻 许可证](#-许可证)
## 🌟 特征
- [x] 使用方便
- [x] 支持所有 UIView
- [x] 完全可定制
- [x] 通用(iPhone和iPad
- [x] Interface Builder 友好
- [x] 简单的 Swift 语法
- [x] 轻量级可读代码库
### 📋 版本要求
* iOS 10.0+
* tvOS 10.0+
* Swift 4.2
### 🔮 示例
要运行示例项目,请克隆并运行 `SkeletonViewExample` 项目。
## 📲 安装
#### 使用 [CocoaPods](https://cocoapods.org)
使用 CocoaPods 编辑您的 Podfile 并指定依赖项:
```ruby
pod "SkeletonView"
```
#### 使用 [Carthage](https://github.com/carthage)
编辑您的 Cartfile 并指定依赖项:
```bash
github "Juanpe/SkeletonView"
```
## 🐒 如何使用
只需 **3** 个步骤即可使用 `SkeletonView`:
**1.** 在适当的位置导入SkeletonView
```swift
import SkeletonView
```
**2.** 现在,您可以通过两种设置方式实现 `SkeletonView` 效果
**使用纯代码:**
```swift
avatarImageView.isSkeletonable = true
```
**使用 IB/Storyboards**
![](Assets/storyboard.png)
**3.** 设置视图后,可以显示 **skeleton**. 并且您有 **4** 种效果可供选择:
```swift
(1) view.showSkeleton() // 固体
(2) view.showGradientSkeleton() // 渐变
(3) view.showAnimatedSkeleton() // 纯色动画
(4) view.showAnimatedGradientSkeleton() // 渐变动画
```
**Preview**
<table>
<tr>
<td width="25%">
<center>固体</center>
</td>
<td width="25%">
<center>渐变</center>
</td>
<td width="25%">
<center>纯色动画</center>
</td>
<td width="25%">
<center>渐变动画</center>
</td>
</tr>
<tr>
<td width="25%">
<img src="Assets/solid.png"></img>
</td>
<td width="25%">
<img src="Assets/gradient.png"></img>
</td>
<td width="25%">
<img src="Assets/solid_animated.gif"></img>
</td>
<td width="25%">
<img src="Assets/gradient_animated.gif"></img>
</td>
</tr>
</table>
> **重要!**
>>```SkeletonView``` 是递归的,所以如果你想在所有可骨架化的视图中显示骨架,你只需要在主容器视图中调用show方法。例如,使用UIViewControllers
### 🌿 集合
现在,```SkeletonView``` 兼容 ```UITableView``` 和 ```UICollectionView```。
###### UITableView
如果你要显示 skeleton 在一个 ```UITableView```上,你需要符合 ```SkeletonTableViewDataSource``` 协议。
``` swift
public protocol SkeletonTableViewDataSource: UITableViewDataSource {
func numSections(in collectionSkeletonView: UITableView) -> Int
func collectionSkeletonView(_ skeletonView: UITableView, numberOfRowsInSection section: Int) -> Int
func collectionSkeletonView(_ skeletonView: UITableView, cellIdentifierForRowAt indexPath: IndexPath) -> ReusableCellIdentifier
}
```
如您所见,此协议继承自 UITableViewDataSource,因此您可以使用骨架协议替换此协议。
该协议具有默认实现:
``` swift
func numSections(in collectionSkeletonView: UITableView) -> Int
// 默认值:1
```
``` swift
func collectionSkeletonView(_ skeletonView: UITableView, numberOfRowsInSection section: Int) -> Int
// 默认值:
// 它计算填充整个tableview需要多少个单元格
```
为了让Skeleton知道单元标识符,您只需要实现一种方法。此方法没有默认实现:
``` swift
func collectionSkeletonView(_ skeletonView: UITableView, cellIdentifierForRowAt indexPath: IndexPath) -> ReusableCellIdentifier
```
**示例**
``` swift
func collectionSkeletonView(_ skeletonView: UITableView, cellIdentifierForRowAt indexPath: IndexPath) -> ReusableCellIdentifier {
return "CellIdentifier"
}
```
> **重要!**
> 如果您使用可调整大小的单元格 (`tableView.rowHeight = UITableViewAutomaticDimension` ),则必须定义 `estimatedRowHeight`。
###### UICollectionView
要为 ```UICollectionView``` 设置效果, 您需要符合 ```SkeletonCollectionViewDataSource``` 协议。
``` swift
public protocol SkeletonCollectionViewDataSource: UICollectionViewDataSource {
func numSections(in collectionSkeletonView: UICollectionView) -> Int
func collectionSkeletonView(_ skeletonView: UICollectionView, numberOfItemsInSection section: Int) -> Int
func collectionSkeletonView(_ skeletonView: UICollectionView, cellIdentifierForItemAt indexPath: IndexPath) -> ReusableCellIdentifier
}
```
其余操作与 ```UITableView``` 相同。
### 📰 多行文字
![](Assets/multilines2.png)
使用带有文本的元素时, ```SkeletonView``` 绘制线条以模拟文本。此外,您可以决定您想要多少行。如果 ```numberOfLines``` 设置为零,它将计算填充整个骨架所需的行数,并将绘制它。相反,如果将其设置为一,二或任何大于零的数字,它将只绘制此行数。
##### 🎛 定制
您可以为多行元素设置一些属性。
| 属性 | 值范围 | 默认 | 延时
| ------- | ------- |------- | -------
| **Filling percent** 最后一行的长度百分比 | `0...100` | `70%` | ![](Assets/multiline_lastline.png)
| **Corner radius** 条目圆角半径. (**新**) | `0...10` | `0` | ![](Assets/multiline_corner.png)
**纯代码**修改百分比或半径:
```swift
descriptionTextView.lastLineFillPercent = 50
descriptionTextView.linesCornerRadius = 5
```
或者,如果您更喜欢使用 **IB/Storyboard**:
![](Assets/multiline_customize.png)
### 🎨 自定义颜色
您可以决定 ```SkeletonView``` 的显示颜色。您只需要传递颜色或渐变的参数。
**使用纯色**
``` swift
view.showSkeleton(usingColor: UIColor.gray) // 固体效果
// 或者
view.showSkeleton(usingColor: UIColor(red: 25.0, green: 30.0, blue: 255.0, alpha: 1.0))
```
**使用渐变色**
``` swift
let gradient = SkeletonGradient(baseColor: UIColor.midnightBlue)
view.showGradientSkeleton(usingGradient: gradient) // 梯度效果
```
此外, ```SkeletonView``` 附带的 20 种颜色 🤙🏼
```UIColor.turquoise, UIColor.greenSea, UIColor.sunFlower, UIColor.flatOrange ...```
![](Assets/flatcolors.png)
###### 从网站 [https://flatuicolors.com](https://flatuicolors.com)捕获的图像
### 🤓 自定义动画
现在,```SkeletonView``` 有两个内置动画,*pulse* 脉冲效果和 *sliding* 渐变滑动效果。
此外,如果你想做自己的 skeleton 动画,那真的很容易。
Skeleton 提供了 `showAnimatedSkeleton` 一个具有 ```SkeletonLayerAnimation``` 闭包的功能,您可以在其中定义自定义动画。
```swift
public typealias SkeletonLayerAnimation = (CALayer) -> CAAnimation
```
您可以像这样调用函数:
```swift
view.showAnimatedSkeleton { (layer) -> CAAnimation in
let animation = CAAnimation()
// 在这里自定义你的动画
return animation
}
```
**新** 它可用 ```SkeletonAnimationBuilder```。这是一个 ```SkeletonLayerAnimation```的衍生。
今天,您可以为渐变创建 **滑动动画**,确定 **方向** 并设置动画的 **持续时间** (默认值 = 1.5s)。
```swift
// func makeSlidingAnimation(withDirection direction: GradientDirection, duration: CFTimeInterval = 1.5) -> SkeletonLayerAnimation
let animation = SkeletonAnimationBuilder().makeSlidingAnimation(withDirection: .leftToRight)
view.showAnimatedGradientSkeleton(usingGradient: gradient, animation: animation)
```
```GradientDirection``` 是一个枚举,在这种情况下:
| 方向 | 效果
|------- | -------
| .leftRight | ![](Assets/sliding_left_to_right.gif)
| .rightLeft | ![](Assets/sliding_right_to_left.gif)
| .topBottom | ![](Assets/sliding_top_to_bottom.gif)
| .bottomTop | ![](Assets/sliding_bottom_to_top.gif)
| .topLeftBottomRight | ![](Assets/sliding_topLeft_to_bottomRight.gif)
| .bottomRightTopLeft | ![](Assets/sliding_bottomRight_to_topLeft.gif)
> **😉 技巧!**
存在另一种创建滑动动画的方法,只需使用此快捷方式:
>>```let animation = GradientDirection.leftToRight.slidingAnimation()```
### 👨‍👧‍👦 等级制度
由于 ```SkeletonView``` 是递归的,我们希望 skeleton 效率高效, 我们希望尽快停止递归。因此,您必须将容器视图设置为 `Skeletonable` ,因为`skeletonable` 一旦视图不是 Skeletonable, Skeleton 将停止查找子视图,然后断开递归。
一图胜千言:
> 设置 ```ìsSkeletonable```= ☠️
| 分组 | 结果
|------- | -------
|![](Assets/no_skeletonable.png) | ![](Assets/no_skeletonables_result.png)
|![](Assets/container_no_skeletonable.png) | ![](Assets/no_skeletonables_result.png)
|![](Assets/container_skeletonable.png) | ![](Assets/container_skeletonable_result.png)
|![](Assets/all_skeletonables.png) | ![](Assets/all_skeletonables_result.png)
### 📚 文档
快出来...😅
## 📬 下一步
* [x] 设置多行元素中最后一行的填充百分比
* [x] 添加更多渐变动画
* [x] 支持可调整大小的单元
* [x] CollectionView 兼容
* [x] tvOS 兼容
* [x] 添加恢复状态
* [ ] 自定义集合兼容
* [ ] 在显示/隐藏骨架时添加动画
* [ ] MacOS 和 WatchOS兼容
## ❤️ 特约
这是一个开源项目,所以请随时贡献。怎么样?
- 打开一个 [issue](https://github.com/Juanpe/SkeletonView/issues/new)
- 反馈通过发送 [email](mailto://juanpecatalan.com)
- 提出您自己的修复和建议,并带有拉取的请求。
查看 [所有贡献者](https://github.com/Juanpe/SkeletonView/graphs/contributors)
###### 使用 [SwiftPlate](https://github.com/JohnSundell/SwiftPlate) 生成的项目
## 📢 提及
- [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)
## 👨🏻‍💻 作者
[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>
## 👮🏻 许可证
```
MIT License
Copyright (c) 2017 Juanpe Catalán
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
```
+3 -1
View File
@@ -1,6 +1,6 @@
Pod::Spec.new do |s|
s.name = "SkeletonView"
s.version = "1.1"
s.version = "1.20.0"
s.summary = "An elegant way to show users that something is happening and also prepare them to which contents he is waiting"
s.description = <<-DESC
Today almost all apps have async processes, as API requests, long runing processes, etc. And while the processes are working, usually developers place a loading view to show users that something is going on.
@@ -11,6 +11,8 @@ 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.swift_version = "5.0"
s.source = { :git => "https://github.com/Juanpe/SkeletonView.git", :tag => s.version.to_s }
s.source_files = "Sources/**/*"
end
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>IDEDidComputeMac32BitWarning</key>
<true/>
</dict>
</plist>
@@ -0,0 +1,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>FILEHEADER</key>
<string> ___COPYRIGHT___</string>
</dict>
</plist>
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "0920"
LastUpgradeVersion = "1020"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"
@@ -26,10 +26,18 @@
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
language = ""
shouldUseLaunchSchemeArgsEnv = "YES">
<Testables>
</Testables>
<MacroExpansion>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "52D6D97B1BEFF229002C0205"
BuildableName = "SkeletonView.framework"
BlueprintName = "SkeletonView-iOS"
ReferencedContainer = "container:SkeletonView.xcodeproj">
</BuildableReference>
</MacroExpansion>
<AdditionalOptions>
</AdditionalOptions>
</TestAction>
@@ -37,7 +45,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 = "1020"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"
buildImplicitDependencies = "YES">
<BuildActionEntries>
<BuildActionEntry
buildForTesting = "YES"
buildForRunning = "YES"
buildForProfiling = "YES"
buildForArchiving = "YES"
buildForAnalyzing = "YES">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "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>
@@ -0,0 +1,91 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "1020"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"
buildImplicitDependencies = "YES">
<BuildActionEntries>
<BuildActionEntry
buildForTesting = "YES"
buildForRunning = "YES"
buildForProfiling = "YES"
buildForArchiving = "YES"
buildForAnalyzing = "YES">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "F5F899F11FABA607002E8FDA"
BuildableName = "SkeletonViewExample.app"
BlueprintName = "SkeletonViewExample"
ReferencedContainer = "container:SkeletonView.xcodeproj">
</BuildableReference>
</BuildActionEntry>
</BuildActionEntries>
</BuildAction>
<TestAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
shouldUseLaunchSchemeArgsEnv = "YES">
<Testables>
</Testables>
<MacroExpansion>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "F5F899F11FABA607002E8FDA"
BuildableName = "SkeletonViewExample.app"
BlueprintName = "SkeletonViewExample"
ReferencedContainer = "container:SkeletonView.xcodeproj">
</BuildableReference>
</MacroExpansion>
<AdditionalOptions>
</AdditionalOptions>
</TestAction>
<LaunchAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
launchStyle = "0"
useCustomWorkingDirectory = "NO"
ignoresPersistentStateOnLaunch = "NO"
debugDocumentVersioning = "YES"
debugServiceExtension = "internal"
allowLocationSimulation = "YES">
<BuildableProductRunnable
runnableDebuggingMode = "0">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "F5F899F11FABA607002E8FDA"
BuildableName = "SkeletonViewExample.app"
BlueprintName = "SkeletonViewExample"
ReferencedContainer = "container:SkeletonView.xcodeproj">
</BuildableReference>
</BuildableProductRunnable>
<AdditionalOptions>
</AdditionalOptions>
</LaunchAction>
<ProfileAction
buildConfiguration = "Release"
shouldUseLaunchSchemeArgsEnv = "YES"
savedToolIdentifier = ""
useCustomWorkingDirectory = "NO"
debugDocumentVersioning = "YES">
<BuildableProductRunnable
runnableDebuggingMode = "0">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "F5F899F11FABA607002E8FDA"
BuildableName = "SkeletonViewExample.app"
BlueprintName = "SkeletonViewExample"
ReferencedContainer = "container:SkeletonView.xcodeproj">
</BuildableReference>
</BuildableProductRunnable>
</ProfileAction>
<AnalyzeAction
buildConfiguration = "Debug">
</AnalyzeAction>
<ArchiveAction
buildConfiguration = "Release"
revealArchiveInOrganizer = "YES">
</ArchiveAction>
</Scheme>
@@ -0,0 +1,91 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "1020"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"
buildImplicitDependencies = "YES">
<BuildActionEntries>
<BuildActionEntry
buildForTesting = "YES"
buildForRunning = "YES"
buildForProfiling = "YES"
buildForArchiving = "YES"
buildForAnalyzing = "YES">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "42ABD05A210B548200BEEFF4"
BuildableName = "SkeletonViewExampleUICollectionView.app"
BlueprintName = "SkeletonViewExampleUICollectionView"
ReferencedContainer = "container:SkeletonView.xcodeproj">
</BuildableReference>
</BuildActionEntry>
</BuildActionEntries>
</BuildAction>
<TestAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
shouldUseLaunchSchemeArgsEnv = "YES">
<Testables>
</Testables>
<MacroExpansion>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "42ABD05A210B548200BEEFF4"
BuildableName = "SkeletonViewExampleUICollectionView.app"
BlueprintName = "SkeletonViewExampleUICollectionView"
ReferencedContainer = "container:SkeletonView.xcodeproj">
</BuildableReference>
</MacroExpansion>
<AdditionalOptions>
</AdditionalOptions>
</TestAction>
<LaunchAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
launchStyle = "0"
useCustomWorkingDirectory = "NO"
ignoresPersistentStateOnLaunch = "NO"
debugDocumentVersioning = "YES"
debugServiceExtension = "internal"
allowLocationSimulation = "YES">
<BuildableProductRunnable
runnableDebuggingMode = "0">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "42ABD05A210B548200BEEFF4"
BuildableName = "SkeletonViewExampleUICollectionView.app"
BlueprintName = "SkeletonViewExampleUICollectionView"
ReferencedContainer = "container:SkeletonView.xcodeproj">
</BuildableReference>
</BuildableProductRunnable>
<AdditionalOptions>
</AdditionalOptions>
</LaunchAction>
<ProfileAction
buildConfiguration = "Release"
shouldUseLaunchSchemeArgsEnv = "YES"
savedToolIdentifier = ""
useCustomWorkingDirectory = "NO"
debugDocumentVersioning = "YES">
<BuildableProductRunnable
runnableDebuggingMode = "0">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "42ABD05A210B548200BEEFF4"
BuildableName = "SkeletonViewExampleUICollectionView.app"
BlueprintName = "SkeletonViewExampleUICollectionView"
ReferencedContainer = "container:SkeletonView.xcodeproj">
</BuildableReference>
</BuildableProductRunnable>
</ProfileAction>
<AnalyzeAction
buildConfiguration = "Debug">
</AnalyzeAction>
<ArchiveAction
buildConfiguration = "Release"
revealArchiveInOrganizer = "YES">
</ArchiveAction>
</Scheme>
@@ -0,0 +1,37 @@
// Copyright © 2017 SkeletonView. All rights reserved.
import UIKit
public protocol Appearance {
var tintColor: UIColor { get set }
var gradient: SkeletonGradient { get set }
var multilineHeight: CGFloat { get set }
var multilineSpacing: CGFloat { get set }
var multilineLastLineFillPercent: Int { get set }
var multilineCornerRadius: Int { get set }
var renderSingleLineAsView: Bool { get set }
}
public enum SkeletonAppearance {
public static var `default`: Appearance = SkeletonViewAppearance.shared
}
// codebeat:disable[TOO_MANY_IVARS]
class SkeletonViewAppearance: Appearance {
static var shared = SkeletonViewAppearance()
var tintColor: UIColor = .skeletonDefault
var gradient = SkeletonGradient(baseColor: .skeletonDefault)
var multilineHeight: CGFloat = 15
var multilineSpacing: CGFloat = 10
var multilineLastLineFillPercent: Int = 70
var multilineCornerRadius: Int = 0
var renderSingleLineAsView: Bool = false
}
// codebeat:enable[TOO_MANY_IVARS]

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