Compare commits

...

106 Commits

Author SHA1 Message Date
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
52 changed files with 643 additions and 231 deletions
@@ -1,3 +1,12 @@
---
name: "\U0001F41B Bug report"
about: Report a bug or unexpected behavior while using SkeletonView
title: ''
labels: bug
assignees: ''
---
### Description
Describe your issue here.
@@ -10,8 +19,8 @@ Describe your issue here.
- [ ] discussion
### Requirements (place an `x` in each of the `[ ]`)
* [ ] I've read and understood the [Contributing guidelines](https://github.com/Juanpe/SkeletonView/blob/develop/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/develop/CODE_OF_CONDUCT.md).
* [ ] 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.
---
+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.
+2 -2
View File
@@ -3,5 +3,5 @@
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/develop/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/develop/CODE_OF_CONDUCT.md).
* [ ] 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'
+2 -2
View File
@@ -4,7 +4,7 @@ onlyLabels:
- awaiting user input
staleLabel: given up
markComment: >
This issue has been automatically marked as stale because it has not had
🤖 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.
for your contributions 🙂
closeComment: false
-20
View File
@@ -1,20 +0,0 @@
name: build
on:
push:
branches:
- develop
pull_request:
branches:
- develop
jobs:
build:
runs-on: macos-latest
steps:
- uses: actions/checkout@v2
- name: xcodebuild
run: |
xcodebuild -project SkeletonView.xcodeproj -target SkeletonView-iOS -sdk iphonesimulator -destination 'platform=iOS Simulator,name=iPhone 7,OS=12'
xcodebuild -project SkeletonView.xcodeproj -target SkeletonView-tvOS -sdk appletvsimulator -destination 'platform=tvOS Simulator,name=Apple TV,OS=12'
xcodebuild -project SkeletonView.xcodeproj -target SkeletonViewExample -sdk iphonesimulator -destination 'platform=iOS Simulator,name=iPhone 7,OS=12'
-15
View File
@@ -1,15 +0,0 @@
name: CI
on: [pull_request]
jobs:
danger:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v1
- name: Execute danger
uses: danger/swift@3.5.0
with:
args: --failOnErrors --no-publish-check
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+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 }}
-17
View File
@@ -1,17 +0,0 @@
name: SwiftLint
on:
pull_request:
branches: [ develop ]
paths:
- '.github/workflows/swiftlint-macos.yml'
- '.swiftlint.yml'
- '**/*.swift'
jobs:
lint:
runs-on: macos-latest
steps:
- uses: actions/checkout@v1
- name: Run SwiftLint
run: swiftlint lint --reporter github-actions-logging
+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 }}
+7 -2
View File
@@ -5,9 +5,12 @@ All notable changes to this project will be documented in this file
#### 🙌 New
#### 🔬Improvements
#### 🔬 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)
@@ -15,6 +18,8 @@ All notable changes to this project will be documented in this file
#### 🙌 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
+2 -2
View File
@@ -1,7 +1,7 @@
# Contributors Guide
Interested in contributing? Awesome! Before you do though, please read our
[Code of Conduct](https://github.com/Juanpe/SkeletonView/blob/develop/CODE_OF_CONDUCT.md). We take it very seriously, and expect that you will as
[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:
@@ -45,7 +45,7 @@ If the contribution doesn't meet the above criteria, you may fail our automated
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 `develop` in this
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
-10
View File
@@ -3,16 +3,6 @@ import Danger
let danger = Danger()
let github = danger.github
// Changelog entries are required for changes to library files.
let allSourceFiles = danger.git.modifiedFiles + danger.git.createdFiles
let noChangelogEntry = !allSourceFiles.contains("CHANGELOG.md")
let sourceChanges = allSourceFiles.contains { $0.hasPrefix("Sources") }
let isNotTrivial = !danger.github.pullRequest.title.contains("#trivial")
if isNotTrivial && noChangelogEntry && sourceChanges {
fail("Any changes to library code should be reflected in the Changelog.")
}
// 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")
+15 -6
View File
@@ -1,9 +1,9 @@
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="17156" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES" initialViewController="Va7-1y-Tel">
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="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="17125"/>
<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"/>
@@ -50,12 +50,9 @@
<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="0" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="CJW-A4-Fb8">
<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"/>
<constraints>
<constraint firstAttribute="height" relation="lessThanOrEqual" constant="80" id="XAA-g8-NVH"/>
</constraints>
<fontDescription key="fontDescription" type="system" pointSize="10"/>
<nil key="textColor"/>
<nil key="highlightedColor"/>
@@ -128,14 +125,25 @@
</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"/>
@@ -147,6 +155,7 @@
<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>
+16 -2
View File
@@ -9,11 +9,25 @@
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() {
}
}
+23 -6
View File
@@ -1,8 +1,8 @@
![](Assets/header2.jpg)
<p align="center">
<a href="https://github.com/Juanpe/SkeletonView/workflows/build">
<img src="https://github.com/Juanpe/SkeletonView/workflows/build/badge.svg">
<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" />
@@ -19,7 +19,7 @@
• <a href="#-contributing">Contributing</a>
</p>
**🌎 README is available in other languages: [🇪🇸](https://github.com/Juanpe/SkeletonView/blob/develop/README_es.md) . [🇨🇳](https://github.com/Juanpe/SkeletonView/blob/master/README_zh.md) . [🇧🇷](https://github.com/Juanpe/SkeletonView/blob/master/README_pt-br.md) . [🇰🇷](https://github.com/Juanpe/SkeletonView/blob/master/README_ko.md) . [🇫🇷](https://github.com/Juanpe/SkeletonView/blob/master/README_fr.md)**
**🌎 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.
@@ -28,7 +28,7 @@ Today almost all apps have async processes, such as API requests, long running p
Enjoy it! 🙂
##
##
- [🌟 Features](#-features)
- [🎬 Guides](#-guides)
- [📲 Installation](#-installation)
@@ -37,10 +37,14 @@ Enjoy it! 🙂
- [🔠 Texts](#-texts)
- [🦋 Appearance](#-appearance)
- [🎨 Custom colors](#-custom-colors)
- [ 🏃‍♀️ Animations](#%EF%B8%8F-animations)
- [Image captured from website https://flatuicolors.com](#image-captured-from-website-httpsflatuicolorscom)
- [🏃‍♀️ Animations](#-animations)
- [🏄 Transitions](#-transitions)
- [✨ Miscellaneous](#-miscellaneous)
- [❤️ Contributing](#-contributing)
- [📢 Mentions](#-mentions)
- [👨🏻‍💻 Author](#-author)
- [👮🏻 License](#-license)
@@ -185,6 +189,10 @@ func collectionSkeletonView(_ skeletonView: UITableView, numberOfRowsInSection s
// It calculates how many cells need to populate whole tableview
```
> 📣 **IMPORTANT!**
>
> If you return `SkeletonCollectionDataSource.automaticNumberOfRows` 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, cellIdentifierForRowAt indexPath: IndexPath) -> ReusableCellIdentifier
@@ -487,6 +495,15 @@ Sometimes you wanna hide some view when the animation starts, so there is a quic
view.isHiddenWhenSkeletonIsActive = true // This works only when isSkeletonable = true
```
**Don't modify user interaction when the skeleton is active**
By default, 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 `isDisableWhenSkeletonIsActive` property:
```swift
view.isDisableWhenSkeletonIsActive = false // The view will be active when the skeleton will be active.
```
**Debug**
To facilitate the debug tasks when something is not working fine. **`SkeletonView`** has some new tools.
@@ -527,7 +544,7 @@ This is an open source project, so feel free to contribute. How?
See [all contributors](https://github.com/Juanpe/SkeletonView/graphs/contributors)
For more information, please read the [contributing guidelines](https://github.com/Juanpe/SkeletonView/blob/develop/CONTRIBUTING.md).
For more information, please read the [contributing guidelines](https://github.com/Juanpe/SkeletonView/blob/main/CONTRIBUTING.md).
## 📢 Mentions
+8 -5
View File
@@ -1,8 +1,8 @@
![](Assets/header2.jpg)
<p align="center">
<a href="https://github.com/Juanpe/SkeletonView/workflows/build">
<img src="https://github.com/Juanpe/SkeletonView/workflows/build/badge.svg">
<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" />
@@ -27,18 +27,21 @@ Hoy en día, La mayoría de las apps tiene procesos asíncronos, como peticiones
Enjoy it! 🙂
##
- [](#)
- [🌟 Destacado](#-destacado)
- [🎬 Videotutoriales](#-videotutoriales)
- [📲 Instalación](#-instalación)
- [🐒 ¿Cómo funciona?](#-cómo-funciona)
- [](#-1)
- [🌿 Colecciones](#-colecciones)
- [🔠 Textos](#-textos)
- [🦋 Apariencia](#-apariencia)
- [🎨 Colores](#-colors)
- [🎨 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)
- [❤️ Contribuir](#-contribuir)
- [❤️ Contributing](#-contributing)
- [📢 Menciones](#-menciones)
- [👨🏻‍💻 Autor](#-autor)
- [👮🏻 Licencia](#-licencia)
@@ -474,7 +477,7 @@ Esto es un proyecto open source, siéntete libre de contribuir. ¿Cómo?
É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/develop/CONTRIBUTING.md).
Para más información, por favor, lee la [guía de contribución](https://github.com/Juanpe/SkeletonView/blob/main/CONTRIBUTING.md).
## 📢 Menciones
+32 -24
View File
@@ -1,8 +1,8 @@
![](Assets/header2.jpg)
<p align="center">
<a href="https://github.com/Juanpe/SkeletonView/workflows/build">
<img src="https://github.com/Juanpe/SkeletonView/workflows/build/badge.svg">
<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" />
@@ -37,28 +37,36 @@ Aujourd'hui, presque toutes les applications ont des processus asynchrones, tels
Profitez-en! 🙂
* [Caractéristiques](#-caractéristiques)
* [Guides](#-guides)
* [Installation](#-installation)
* [Cocoapods](#utilisation-de-cocoapods)
* [Carthage](#utilisation-de-carthage)
* [SPM](#utilisation-du-gestionnaire-de-paquets-Swift)
* [Comment utiliser](#-mode-d'emploi)
* [Collections](#-collections)
* [Texte Multiligne](#-texte-multiligne)
* [Couleurs personnalisées](#-couleurs-personnalisées)
* [Présentation](#-présentation)
* [Animations personnalisées](#-animations-personnalisées)
* [Transitions](#-transitions)
* [Hiérarchie](#-hiérarchie)
* [Débugger](#-débugger)
* [Documentation](#-documentation)
* [Versions OS & SDK supportées](#-versions-os-et-sdk-supportées)
* [Prochaines étapes](#-prochaines-étapes)
* [Contribuer](#-contribuer)
* [Mentions](#-mentions)
* [Auteur](#-auteur)
* [Licence](#-licence)
- [🌟 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
+2 -2
View File
@@ -1,8 +1,8 @@
![](Assets/header2.jpg)
<p align="center">
<a href="https://github.com/Juanpe/SkeletonView/workflows/build">
<img src="https://github.com/Juanpe/SkeletonView/workflows/build/badge.svg">
<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" />
+26 -21
View File
@@ -1,8 +1,8 @@
![](Assets/header2.jpg)
<p align="center">
<a href="https://github.com/Juanpe/SkeletonView/workflows/build">
<img src="https://github.com/Juanpe/SkeletonView/workflows/build/badge.svg">
<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" />
@@ -36,25 +36,30 @@ Hoje, quase todos os apps têm processos assíncronos, como requisições de API
Aproveite! 🙂
* [Features](#-features)
* [Requerimentos](#-supported-os--sdk-versions)
* [Projeto de exemplo](#-example)
* [Instalação](#-installation)
* [Cocoapods](#using-cocoapods)
* [Carthage](#using-carthage)
* [Como usar](#-how-to-use)
* [Coleções](#-collections)
* [Texto em várias linhas](#-multiline-text)
* [Cores customizadas](#-custom-colors)
* [Aparência](#-appearance)
* [Animaçōes customizadas](#-custom-animations)
* [Hierarquia](#-hierarchy)
* [Documentação](#-documentation)
* [Próximos passos](#-next-steps)
* [Contribuindo](#-contributing)
* [Menções](#-mentions)
* [Autor](#-author)
* [Licença](#-license)
- [🌟 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
+25 -20
View File
@@ -1,8 +1,8 @@
![](Assets/header2.jpg)
<p align="center">
<a href="https://github.com/Juanpe/SkeletonView/workflows/build">
<img src="https://github.com/Juanpe/SkeletonView/workflows/build/badge.svg">
<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" />
@@ -36,24 +36,29 @@
好好享受! 🙂
* [特征](#-特征)
* [版本要求](#-版本要求)
* [示例项目](#-示例)
* [安装](#-安装)
* [Cocoapods](#使用-cocoapods)
* [Carthage](#使用-carthage)
* [如何使用](#-如何使用)
* [集合](#-集合)
* [多行文字](#-多行文字)
* [自定义颜色](#-自定义颜色)
* [自定义动画](#-自定义动画)
* [等级制度](#-等级制度)
* [文档](#-文档)
* [下一步](#-下一步)
* [特约](#-特约)
* [提及](#-提及)
* [作者](#-作者)
* [许可证](#-许可证)
- [🌟 特征](#-特征)
- [📋 版本要求](#-版本要求)
- [🔮 示例](#-示例)
- [📲 安装](#-安装)
- [使用 CocoaPods](#使用-cocoapods)
- [使用 Carthage](#使用-carthage)
- [🐒 如何使用](#-如何使用)
- [🌿 集合](#-集合)
- [UITableView](#uitableview)
- [UICollectionView](#uicollectionview)
- [📰 多行文字](#-多行文字)
- [🎛 定制](#-定制)
- [🎨 自定义颜色](#-自定义颜色)
- [从网站 https://flatuicolors.com捕获的图像](#从网站-httpsflatuicolorscom捕获的图像)
- [🤓 自定义动画](#-自定义动画)
- [👨‍👧‍👦 等级制度](#-等级制度)
- [📚 文档](#-文档)
- [📬 下一步](#-下一步)
- [❤️ 特约](#-特约)
- [使用 SwiftPlate 生成的项目](#使用-swiftplate-生成的项目)
- [📢 提及](#-提及)
- [👨🏻‍💻 作者](#-作者)
- [👮🏻 许可证](#-许可证)
## 🌟 特征
+1 -1
View File
@@ -1,6 +1,6 @@
Pod::Spec.new do |s|
s.name = "SkeletonView"
s.version = "1.11.0"
s.version = "1.16.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 -2
View File
@@ -619,6 +619,7 @@
52D6D97B1BEFF229002C0205 = {
CreatedOnToolsVersion = 7.1;
LastSwiftMigration = 1000;
ProvisioningStyle = Automatic;
};
F5F899F11FABA607002E8FDA = {
CreatedOnToolsVersion = 9.1;
@@ -1117,8 +1118,10 @@
buildSettings = {
APPLICATION_EXTENSION_API_ONLY = NO;
CLANG_ENABLE_MODULES = YES;
CODE_SIGN_IDENTITY = "iPhone Developer";
CODE_SIGN_IDENTITY = "Apple Development";
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "";
"CODE_SIGN_IDENTITY[sdk=macosx*]" = "Apple Development";
CODE_SIGN_STYLE = Automatic;
DEFINES_MODULE = YES;
DEVELOPMENT_TEAM = "";
DYLIB_COMPATIBILITY_VERSION = 1;
@@ -1131,6 +1134,8 @@
ONLY_ACTIVE_ARCH = NO;
PRODUCT_BUNDLE_IDENTIFIER = "com.SkeletonView.SkeletonView-iOS";
PRODUCT_NAME = SkeletonView;
PROVISIONING_PROFILE_SPECIFIER = "";
"PROVISIONING_PROFILE_SPECIFIER[sdk=macosx*]" = "";
SKIP_INSTALL = YES;
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
SWIFT_VERSION = 5.0;
@@ -1142,8 +1147,10 @@
buildSettings = {
APPLICATION_EXTENSION_API_ONLY = NO;
CLANG_ENABLE_MODULES = YES;
CODE_SIGN_IDENTITY = "iPhone Developer";
CODE_SIGN_IDENTITY = "Apple Development";
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "";
"CODE_SIGN_IDENTITY[sdk=macosx*]" = "Apple Development";
CODE_SIGN_STYLE = Automatic;
DEFINES_MODULE = YES;
DEVELOPMENT_TEAM = "";
DYLIB_COMPATIBILITY_VERSION = 1;
@@ -1155,6 +1162,8 @@
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
PRODUCT_BUNDLE_IDENTIFIER = "com.SkeletonView.SkeletonView-iOS";
PRODUCT_NAME = SkeletonView;
PROVISIONING_PROFILE_SPECIFIER = "";
"PROVISIONING_PROFILE_SPECIFIER[sdk=macosx*]" = "";
SKIP_INSTALL = YES;
SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule";
SWIFT_VERSION = 5.0;
@@ -29,6 +29,18 @@ extension CollectionSkeleton where Self: UIScrollView {
var estimatedNumberOfRows: Int { return 0 }
func addDummyDataSource() {}
func removeDummyDataSource(reloadAfter: Bool) {}
func disableUserInteraction() { isUserInteractionEnabled = false; isScrollEnabled = false }
func enableUserInteraction() { isUserInteractionEnabled = true; isScrollEnabled = true }
func disableUserInteraction() {
if isDisableWhenSkeletonIsActive {
isUserInteractionEnabled = false
isScrollEnabled = false
}
}
func enableUserInteraction() {
if isDisableWhenSkeletonIsActive {
isUserInteractionEnabled = true
isScrollEnabled = true
}
}
}
@@ -17,7 +17,7 @@ public protocol SkeletonCollectionViewDataSource: UICollectionViewDataSource {
public extension SkeletonCollectionViewDataSource {
func collectionSkeletonView(_ skeletonView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return skeletonView.estimatedNumberOfRows
return SkeletonCollectionDataSource.automaticNumberOfRows
}
func collectionSkeletonView(_ skeletonView: UICollectionView,
@@ -7,11 +7,18 @@
//
import UIKit
extension UICollectionView: CollectionSkeleton {
var estimatedNumberOfRows: Int {
guard let flowlayout = collectionViewLayout as? UICollectionViewFlowLayout else { return 0 }
return Int(ceil(frame.height / flowlayout.itemSize.height))
switch flowlayout.scrollDirection {
case .vertical:
return Int(ceil(frame.height / flowlayout.itemSize.height))
case .horizontal:
return Int(ceil(frame.width / flowlayout.itemSize.width))
default:
return 0
}
}
var skeletonDataSource: SkeletonCollectionDataSource? {
@@ -11,6 +11,8 @@ import UIKit
public typealias ReusableCellIdentifier = String
class SkeletonCollectionDataSource: NSObject {
static let automaticNumberOfRows = -1
weak var originalTableViewDataSource: SkeletonTableViewDataSource?
weak var originalCollectionViewDataSource: SkeletonCollectionViewDataSource?
var rowHeight: CGFloat = 0.0
@@ -28,11 +30,21 @@ class SkeletonCollectionDataSource: NSObject {
// MARK: - UITableViewDataSource
extension SkeletonCollectionDataSource: UITableViewDataSource {
func numberOfSections(in tableView: UITableView) -> Int {
return originalTableViewDataSource?.numSections(in: tableView) ?? 0
originalTableViewDataSource?.numSections(in: tableView) ?? 0
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return originalTableViewDataSource?.collectionSkeletonView(tableView, numberOfRowsInSection: section) ?? 0
guard let originalTableViewDataSource = originalTableViewDataSource else {
return 0
}
let numberOfRows = originalTableViewDataSource.collectionSkeletonView(tableView, numberOfRowsInSection: section)
if numberOfRows == Self.automaticNumberOfRows {
return tableView.estimatedNumberOfRows
} else {
return numberOfRows
}
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
@@ -46,11 +58,21 @@ extension SkeletonCollectionDataSource: UITableViewDataSource {
// MARK: - UICollectionViewDataSource
extension SkeletonCollectionDataSource: UICollectionViewDataSource {
func numberOfSections(in collectionView: UICollectionView) -> Int {
return originalCollectionViewDataSource?.numSections(in: collectionView) ?? 0
originalCollectionViewDataSource?.numSections(in: collectionView) ?? 0
}
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return originalCollectionViewDataSource?.collectionSkeletonView(collectionView, numberOfItemsInSection: section) ?? 0
guard let originalCollectionViewDataSource = originalCollectionViewDataSource else {
return 0
}
let numberOfItems = originalCollectionViewDataSource.collectionSkeletonView(collectionView, numberOfItemsInSection: section)
if numberOfItems == Self.automaticNumberOfRows {
return collectionView.estimatedNumberOfRows
} else {
return numberOfItems
}
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
@@ -21,23 +21,11 @@ class SkeletonCollectionDelegate: NSObject {
// MARK: - UITableViewDelegate
extension SkeletonCollectionDelegate: UITableViewDelegate {
func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
if let viewIdentifier = originalTableViewDelegate?.collectionSkeletonView(tableView, identifierForHeaderInSection: section),
let header = tableView.dequeueReusableHeaderFooterView(withIdentifier: viewIdentifier) {
skeletonViewIfContainerSkeletonIsActive(container: tableView, view: header)
return header
}
return nil
headerOrFooterView(tableView, for: originalTableViewDelegate?.collectionSkeletonView(tableView, identifierForHeaderInSection: section))
}
func tableView(_ tableView: UITableView, viewForFooterInSection section: Int) -> UIView? {
if let viewIdentifier = originalTableViewDelegate?.collectionSkeletonView(tableView, identifierForFooterInSection: section),
let footer = tableView.dequeueReusableHeaderFooterView(withIdentifier: viewIdentifier) {
skeletonViewIfContainerSkeletonIsActive(container: tableView, view: footer)
return footer
}
return nil
headerOrFooterView(tableView, for: originalTableViewDelegate?.collectionSkeletonView(tableView, identifierForFooterInSection: section))
}
func tableView(_ tableView: UITableView, didEndDisplayingHeaderView view: UIView, forSection section: Int) {
@@ -54,6 +42,12 @@ extension SkeletonCollectionDelegate: UITableViewDelegate {
cell.hideSkeleton()
originalTableViewDelegate?.tableView?(tableView, didEndDisplaying: cell, forRowAt: indexPath)
}
private func headerOrFooterView(_ tableView: UITableView, for viewIdentifier: String? ) -> UIView? {
guard let viewIdentifier = viewIdentifier, let header = tableView.dequeueReusableHeaderFooterView(withIdentifier: viewIdentifier) else { return nil }
skeletonViewIfContainerSkeletonIsActive(container: tableView, view: header)
return header
}
}
// MARK: - UICollectionViewDelegate
@@ -16,7 +16,7 @@ public protocol SkeletonTableViewDataSource: UITableViewDataSource {
public extension SkeletonTableViewDataSource {
func collectionSkeletonView(_ skeletonView: UITableView, numberOfRowsInSection section: Int) -> Int {
return skeletonView.estimatedNumberOfRows
return SkeletonCollectionDataSource.automaticNumberOfRows
}
func numSections(in collectionSkeletonView: UITableView) -> Int { return 1 }
+8 -3
View File
@@ -125,8 +125,12 @@ extension CALayer {
private func calculateNumLines(for config: SkeletonMultilinesLayerConfig) -> Int {
let definedNumberOfLines = config.lines
let requiredSpaceForEachLine = config.lineHeight + config.multilineSpacing
let calculatedNumberOfLines = Int(round(CGFloat(bounds.height - config.paddingInsets.top - config.paddingInsets.bottom) / CGFloat(requiredSpaceForEachLine)))
let neededLines = round(CGFloat(bounds.height - config.paddingInsets.top - config.paddingInsets.bottom) / CGFloat(requiredSpaceForEachLine))
guard neededLines.isNormal else {
return 0
}
let calculatedNumberOfLines = Int(neededLines)
guard calculatedNumberOfLines > 0 else {
return 1
}
@@ -152,7 +156,8 @@ public extension CALayer {
var pulse: CAAnimation {
let pulseAnimation = CABasicAnimation(keyPath: #keyPath(CALayer.backgroundColor))
pulseAnimation.fromValue = backgroundColor
//swiftlint:disable:next force_unwrapping
// swiftlint:disable:next force_unwrapping
pulseAnimation.toValue = UIColor(cgColor: backgroundColor!).complementaryColor.cgColor
pulseAnimation.duration = 1
pulseAnimation.timingFunction = CAMediaTimingFunction(name: CAMediaTimingFunctionName.easeInEaseOut)
+2 -2
View File
@@ -4,10 +4,10 @@ import Foundation
extension Int {
var whitespace: String {
return whitespaces
whitespaces
}
var whitespaces: String {
return String(repeating: " ", count: self)
String(repeating: " ", count: self)
}
}
+3 -3
View File
@@ -31,11 +31,11 @@ extension UIColor {
}
public var lighter: UIColor {
return adjust(by: 1.35)
adjust(by: 1.35)
}
public var darker: UIColor {
return adjust(by: 0.94)
adjust(by: 0.94)
}
func adjust(by percent: CGFloat) -> UIColor {
@@ -45,7 +45,7 @@ extension UIColor {
}
func makeGradient() -> [UIColor] {
return [self, self.complementaryColor, self]
[self, self.complementaryColor, self]
}
}
@@ -16,6 +16,7 @@ enum ViewAssociatedKeys {
static var buttonViewState = "buttonViewState"
static var currentSkeletonConfig = "currentSkeletonConfig"
static var skeletonCornerRadius = "skeletonCornerRadius"
static var disableWhenSkeletonIsActive = "disableWhenSkeletonIsActive"
}
// codebeat:enable[TOO_MANY_IVARS]
@@ -49,4 +50,8 @@ extension UIView {
get { return ao_get(pkey: &ViewAssociatedKeys.isSkeletonAnimated) as? Bool ?? false }
set { ao_set(newValue, pkey: &ViewAssociatedKeys.isSkeletonAnimated) }
}
var isSuperviewAStackView: Bool {
superview is UIStackView
}
}
@@ -14,6 +14,12 @@ public extension UIView {
get { return hiddenWhenSkeletonIsActive }
set { hiddenWhenSkeletonIsActive = newValue }
}
@IBInspectable
var isDisableWhenSkeletonIsActive: Bool {
get { return disableWhenSkeletonIsActive }
set { disableWhenSkeletonIsActive = newValue }
}
@IBInspectable
var skeletonCornerRadius: Float {
@@ -34,6 +40,11 @@ public extension UIView {
get { return ao_get(pkey: &ViewAssociatedKeys.hiddenWhenSkeletonIsActive) as? Bool ?? false }
set { ao_set(newValue, pkey: &ViewAssociatedKeys.hiddenWhenSkeletonIsActive) }
}
private var disableWhenSkeletonIsActive: Bool {
get { return ao_get(pkey: &ViewAssociatedKeys.disableWhenSkeletonIsActive) as? Bool ?? true }
set { ao_set(newValue, pkey: &ViewAssociatedKeys.disableWhenSkeletonIsActive) }
}
private var skeletonableCornerRadius: Float {
get { return ao_get(pkey: &ViewAssociatedKeys.skeletonCornerRadius) as? Float ?? 0.0 }
+2 -2
View File
@@ -2,7 +2,7 @@
import Foundation
//Partially copy/pasted from https://github.com/jameslintaylor/AssociatedObjects/blob/master/AssociatedObjects/AssociatedObjects.swift
// Partially copy/pasted from https://github.com/jameslintaylor/AssociatedObjects/blob/master/AssociatedObjects/AssociatedObjects.swift
enum AssociationPolicy: UInt {
// raw values map to objc_AssociationPolicy's raw values
case assign = 0
@@ -17,7 +17,7 @@ enum AssociationPolicy: UInt {
}
}
protocol AssociatedObjects: class { }
protocol AssociatedObjects: AnyObject { }
// transparent wrappers
extension AssociatedObjects {
@@ -10,16 +10,19 @@ import UIKit
extension UIView {
@objc func prepareViewForSkeleton() {
if isDisableWhenSkeletonIsActive {
isUserInteractionEnabled = false
}
startTransition { [weak self] in
self?.backgroundColor = .clear
self?.isUserInteractionEnabled = false
}
}
}
extension UILabel {
var desiredHeightBasedOnNumberOfLines: CGFloat {
let lineHeight = multilineTextFont?.lineHeight ?? SkeletonAppearance.default.multilineHeight
let lineHeight = constraintHeight ?? SkeletonAppearance.default.multilineHeight
let spaceNeededForEachLine = lineHeight * CGFloat(numberOfLines)
let spaceNeededForSpaces = skeletonLineSpacing * CGFloat(numberOfLines - 1)
let padding = paddingInsets.top + paddingInsets.bottom
@@ -28,7 +31,13 @@ extension UILabel {
}
func updateHeightConstraintsIfNeeded() {
guard numberOfLines > 1 else { return }
guard numberOfLines > 1 || numberOfLines == 0 else { return }
// Workaround to simulate content when the label is contained in a `UIStackView`.
if isSuperviewAStackView, bounds.height == 0 {
// This is a placeholder text to simulate content because it's contained in a stack view in order to prevent that the content size will be zero.
text = " "
}
let desiredHeight = desiredHeightBasedOnNumberOfLines
if desiredHeight > definedMaxHeight {
@@ -39,14 +48,21 @@ extension UILabel {
}
func restoreBackupHeightConstraints() {
heightConstraints.forEach {
removeConstraint($0)
}
guard !backupHeightConstraints.isEmpty else { return }
NSLayoutConstraint.deactivate(heightConstraints)
NSLayoutConstraint.activate(backupHeightConstraints)
backupHeightConstraints.removeAll()
}
override func prepareViewForSkeleton() {
backgroundColor = .clear
if isDisableWhenSkeletonIsActive {
isUserInteractionEnabled = false
}
resignFirstResponder()
startTransition { [weak self] in
self?.updateHeightConstraintsIfNeeded()
@@ -58,6 +74,11 @@ extension UILabel {
extension UITextView {
override func prepareViewForSkeleton() {
backgroundColor = .clear
if isDisableWhenSkeletonIsActive {
isUserInteractionEnabled = false
}
resignFirstResponder()
startTransition { [weak self] in
self?.textColor = .clear
@@ -65,9 +86,26 @@ extension UITextView {
}
}
extension UITextField {
override func prepareViewForSkeleton() {
backgroundColor = .clear
resignFirstResponder()
startTransition { [weak self] in
self?.textColor = .clear
self?.placeholder = nil
}
}
}
extension UIImageView {
override func prepareViewForSkeleton() {
backgroundColor = .clear
if isDisableWhenSkeletonIsActive {
isUserInteractionEnabled = false
}
startTransition { [weak self] in
self?.image = nil
}
@@ -77,6 +115,11 @@ extension UIImageView {
extension UIButton {
override func prepareViewForSkeleton() {
backgroundColor = .clear
if isDisableWhenSkeletonIsActive {
isUserInteractionEnabled = false
}
startTransition { [weak self] in
self?.setTitle(nil, for: .normal)
}
+10 -3
View File
@@ -4,21 +4,28 @@ import Foundation
extension DispatchQueue {
private static var _onceTracker = [String]()
class func once(token: String, block: () -> Void) {
objc_sync_enter(self); defer { objc_sync_exit(self) }
guard !_onceTracker.contains(token) else { return }
_onceTracker.append(token)
block()
}
class func removeOnce(token: String, block: () -> Void) {
objc_sync_enter(self); defer { objc_sync_exit(self) }
guard let index = _onceTracker.firstIndex(of: token) else { return }
_onceTracker.remove(at: index)
block()
}
}
func swizzle(selector originalSelector: Selector, with swizzledSelector: Selector, inClass: AnyClass, usingClass: AnyClass) {
guard let originalMethod = class_getInstanceMethod(inClass, originalSelector),
let swizzledMethod = class_getInstanceMethod(usingClass, swizzledSelector)
else { return }
if class_addMethod(inClass, swizzledSelector, method_getImplementation(originalMethod), method_getTypeEncoding(originalMethod)) {
class_replaceMethod(inClass, originalSelector, method_getImplementation(swizzledMethod), method_getTypeEncoding(swizzledMethod))
} else {
@@ -11,7 +11,7 @@ enum MultilineAssociatedKeys {
}
protocol ContainsMultilineText {
var multilineTextFont: UIFont? { get }
var constraintHeight: CGFloat? { get }
var numLines: Int { get }
var lastLineFillingPercent: Int { get }
var multilineCornerRadius: Int { get }
+6 -6
View File
@@ -12,13 +12,13 @@ public extension UILabel {
@IBInspectable
var linesCornerRadius: Int {
get { return multilineCornerRadius }
set { multilineCornerRadius = min(newValue, 10) }
set { multilineCornerRadius = newValue }
}
@IBInspectable
var skeletonLineSpacing: CGFloat {
get { return multilineSpacing }
set { multilineSpacing = min(newValue, 10) }
set { multilineSpacing = newValue }
}
var skeletonPaddingInsets: UIEdgeInsets {
@@ -28,10 +28,10 @@ public extension UILabel {
}
extension UILabel: ContainsMultilineText {
var multilineTextFont: UIFont? {
return font
}
var constraintHeight: CGFloat? {
backupHeightConstraints.first?.constant
}
var numLines: Int {
return numberOfLines
}
@@ -12,13 +12,13 @@ public extension UITextView {
@IBInspectable
var linesCornerRadius: Int {
get { return multilineCornerRadius }
set { multilineCornerRadius = min(newValue, 10) }
set { multilineCornerRadius = newValue }
}
@IBInspectable
var skeletonLineSpacing: CGFloat {
get { return multilineSpacing }
set { multilineSpacing = min(newValue, 10) }
set { multilineSpacing = newValue }
}
var skeletonPaddingInsets: UIEdgeInsets {
@@ -28,8 +28,8 @@ public extension UITextView {
}
extension UITextView: ContainsMultilineText {
var multilineTextFont: UIFont? {
font
var constraintHeight: CGFloat? {
heightConstraints.first?.constant
}
var numLines: Int {
+37 -5
View File
@@ -27,12 +27,17 @@ extension UIView: Recoverable {
guard let storedViewState = viewState else { return }
startTransition { [weak self] in
self?.layer.cornerRadius = storedViewState.cornerRadius
self?.layer.masksToBounds = storedViewState.clipToBounds
self?.isUserInteractionEnabled = storedViewState.isUserInteractionsEnabled
guard let self = self else { return }
if self?.backgroundColor == .clear || forced {
self?.backgroundColor = storedViewState.backgroundColor
self.layer.cornerRadius = storedViewState.cornerRadius
self.layer.masksToBounds = storedViewState.clipToBounds
if self.isDisableWhenSkeletonIsActive {
self.isUserInteractionEnabled = storedViewState.isUserInteractionsEnabled
}
if self.backgroundColor == .clear || forced {
self.backgroundColor = storedViewState.backgroundColor
}
}
}
@@ -86,6 +91,33 @@ extension UITextView {
}
}
extension UITextField {
var textState: RecoverableTextFieldState? {
get { return ao_get(pkey: &ViewAssociatedKeys.labelViewState) as? RecoverableTextFieldState }
set { ao_setOptional(newValue, pkey: &ViewAssociatedKeys.labelViewState) }
}
override func saveViewState() {
super.saveViewState()
textState = RecoverableTextFieldState(view: self)
}
override func recoverViewState(forced: Bool) {
super.recoverViewState(forced: forced)
startTransition { [weak self] in
guard let storedLabelState = self?.textState else { return }
if self?.textColor == .clear || forced {
self?.textColor = storedLabelState.textColor
}
if self?.placeholder == nil || forced {
self?.placeholder = storedLabelState.placeholder
}
}
}
}
extension UIImageView {
var imageState: RecoverableImageViewState? {
get { return ao_get(pkey: &ViewAssociatedKeys.imageViewState) as? RecoverableImageViewState }
@@ -34,6 +34,16 @@ struct RecoverableTextViewState {
}
}
struct RecoverableTextFieldState {
var textColor: UIColor?
var placeholder: String?
init(view: UITextField) {
self.textColor = view.textColor
self.placeholder = view.placeholder
}
}
struct RecoverableImageViewState {
var image: UIImage?
+1 -1
View File
@@ -63,7 +63,7 @@ public class SkeletonAnimationBuilder {
public init() { }
public func makeSlidingAnimation(withDirection direction: GradientDirection, duration: CFTimeInterval = 1.5, autoreverses: Bool = false) -> SkeletonLayerAnimation {
return { layer in
return { _ in
let startPointAnim = CABasicAnimation(keyPath: #keyPath(CAGradientLayer.startPoint))
startPointAnim.fromValue = direction.startPoint.from
startPointAnim.toValue = direction.startPoint.to
+2 -2
View File
@@ -83,7 +83,7 @@ struct SkeletonLayer {
/// If there is more than one line, or custom preferences have been set for a single line, draw custom layers
func addTextLinesIfNeeded() {
guard let textView = holderAsTextView else { return }
let lineHeight = textView.multilineTextFont?.lineHeight ?? SkeletonAppearance.default.multilineHeight
let lineHeight = textView.constraintHeight ?? SkeletonAppearance.default.multilineHeight
let config = SkeletonMultilinesLayerConfig(lines: textView.numLines,
lineHeight: lineHeight,
type: type,
@@ -98,7 +98,7 @@ struct SkeletonLayer {
func updateLinesIfNeeded() {
guard let textView = holderAsTextView else { return }
let lineHeight = textView.multilineTextFont?.lineHeight ?? SkeletonAppearance.default.multilineHeight
let lineHeight = textView.constraintHeight ?? SkeletonAppearance.default.multilineHeight
let config = SkeletonMultilinesLayerConfig(lines: textView.numLines,
lineHeight: lineHeight,
type: type,
+25 -2
View File
@@ -136,7 +136,7 @@ extension UIView {
private func showSkeletonIfNotActive(skeletonConfig config: SkeletonConfig) {
guard !isSkeletonActive else { return }
saveViewState()
isUserInteractionEnabled = false
prepareViewForSkeleton()
addSkeletonLayer(skeletonConfig: config)
}
@@ -190,7 +190,8 @@ extension UIView {
isHidden = false
}
currentSkeletonConfig?.transition = transition
isUserInteractionEnabled = true
unSwizzleLayoutSubviews()
unSwizzleTraitCollectionDidChange()
removeDummyDataSourceIfNeeded(reloadAfter: reload)
subviewsSkeletonables.recursiveSearch(leafBlock: {
recoverViewState(forced: false)
@@ -234,6 +235,17 @@ extension UIView {
}
}
private func unSwizzleLayoutSubviews() {
DispatchQueue.main.asyncAfter(deadline: .now() + 0.01) {
DispatchQueue.removeOnce(token: "UIView.SkeletonView.swizzleLayoutSubviews") {
swizzle(selector: #selector(UIView.skeletonLayoutSubviews),
with: #selector(UIView.layoutSubviews),
inClass: UIView.self,
usingClass: UIView.self)
}
}
}
private func swizzleTraitCollectionDidChange() {
DispatchQueue.main.asyncAfter(deadline: .now() + 0.01) {
DispatchQueue.once(token: "UIView.SkeletonView.swizzleTraitCollectionDidChange") {
@@ -244,6 +256,17 @@ extension UIView {
}
}
}
private func unSwizzleTraitCollectionDidChange() {
DispatchQueue.main.asyncAfter(deadline: .now() + 0.01) {
DispatchQueue.removeOnce(token: "UIView.SkeletonView.swizzleTraitCollectionDidChange") {
swizzle(selector: #selector(UIView.skeletonTraitCollectionDidChange(_:)),
with: #selector(UIView.traitCollectionDidChange(_:)),
inClass: UIView.self,
usingClass: UIView.self)
}
}
}
}
extension UIView {
+12 -8
View File
@@ -4,46 +4,50 @@ import UIKit
extension UIView {
@objc var subviewsSkeletonables: [UIView] {
return subviewsToSkeleton.filter { $0.isSkeletonable }
subviewsToSkeleton.filter { $0.isSkeletonable }
}
@objc var subviewsToSkeleton: [UIView] {
return subviews
subviews
}
}
extension UITableView {
override var subviewsToSkeleton: [UIView] {
return visibleCells + visibleSectionHeaders + visibleSectionFooters
// on `UIViewController'S onViewDidLoad`, the window is still nil.
// Some developer trying to call `view.showAnimatedSkeleton()`
// when the request or data is loading which sometimes happens before the ViewDidAppear
guard window != nil else { return [] }
return subviews
}
}
extension UITableViewCell {
override var subviewsToSkeleton: [UIView] {
return contentView.subviews
contentView.subviews
}
}
extension UITableViewHeaderFooterView {
override var subviewsToSkeleton: [UIView] {
return contentView.subviews
contentView.subviews
}
}
extension UICollectionView {
override var subviewsToSkeleton: [UIView] {
return subviews
subviews
}
}
extension UICollectionViewCell {
override var subviewsToSkeleton: [UIView] {
return contentView.subviews
contentView.subviews
}
}
extension UIStackView {
override var subviewsToSkeleton: [UIView] {
return arrangedSubviews
arrangedSubviews
}
}
+4
View File
@@ -1,6 +1,10 @@
default_platform(:ios)
podspec_name = "SkeletonView.podspec"
lane :bump_version do |options|
version_bump_podspec(path: @podspec_name, version_number: options[:next_version])
end
lane :release_current do
version = version_get_podspec(path: @podspec_name)
if git_tag_exists(tag: version)
+5
View File
@@ -15,6 +15,11 @@ Install _fastlane_ using
or alternatively using `brew install fastlane`
# Available Actions
### bump_version
```
fastlane bump_version
```
### release_current
```
fastlane release_current