Compare commits

..

6 Commits

Author SHA1 Message Date
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
13 changed files with 44 additions and 33 deletions
+3 -3
View File
@@ -191,7 +191,7 @@ func collectionSkeletonView(_ skeletonView: UITableView, numberOfRowsInSection s
> 📣 **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).
> 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
@@ -498,10 +498,10 @@ view.isHiddenWhenSkeletonIsActive = true // This works only when isSkeletonable
**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:
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.isDisableWhenSkeletonIsActive = false // The view will be active when the skeleton will be active.
view.isUserInteractionDisabledWhenSkeletonIsActive = false // The view will be active when the skeleton will be active.
```
**Debug**
+1 -1
View File
@@ -1,6 +1,6 @@
Pod::Spec.new do |s|
s.name = "SkeletonView"
s.version = "1.16.0"
s.version = "1.17.1"
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.
@@ -31,14 +31,14 @@ extension CollectionSkeleton where Self: UIScrollView {
func removeDummyDataSource(reloadAfter: Bool) {}
func disableUserInteraction() {
if isDisableWhenSkeletonIsActive {
if isUserInteractionDisabledWhenSkeletonIsActive {
isUserInteractionEnabled = false
isScrollEnabled = false
}
}
func enableUserInteraction() {
if isDisableWhenSkeletonIsActive {
if isUserInteractionDisabledWhenSkeletonIsActive {
isUserInteractionEnabled = true
isScrollEnabled = true
}
@@ -17,7 +17,7 @@ public protocol SkeletonCollectionViewDataSource: UICollectionViewDataSource {
public extension SkeletonCollectionViewDataSource {
func collectionSkeletonView(_ skeletonView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return SkeletonCollectionDataSource.automaticNumberOfRows
return UICollectionView.automaticNumberOfSkeletonItems
}
func collectionSkeletonView(_ skeletonView: UICollectionView,
@@ -9,6 +9,8 @@
import UIKit
extension UICollectionView: CollectionSkeleton {
public static let automaticNumberOfSkeletonItems = -1
var estimatedNumberOfRows: Int {
guard let flowlayout = collectionViewLayout as? UICollectionViewFlowLayout else { return 0 }
switch flowlayout.scrollDirection {
@@ -11,8 +11,6 @@ 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
@@ -40,7 +38,7 @@ extension SkeletonCollectionDataSource: UITableViewDataSource {
let numberOfRows = originalTableViewDataSource.collectionSkeletonView(tableView, numberOfRowsInSection: section)
if numberOfRows == Self.automaticNumberOfRows {
if numberOfRows == UITableView.automaticNumberOfSkeletonRows {
return tableView.estimatedNumberOfRows
} else {
return numberOfRows
@@ -68,7 +66,7 @@ extension SkeletonCollectionDataSource: UICollectionViewDataSource {
let numberOfItems = originalCollectionViewDataSource.collectionSkeletonView(collectionView, numberOfItemsInSection: section)
if numberOfItems == Self.automaticNumberOfRows {
if numberOfItems == UICollectionView.automaticNumberOfSkeletonItems {
return collectionView.estimatedNumberOfRows
} else {
return numberOfItems
@@ -16,7 +16,7 @@ public protocol SkeletonTableViewDataSource: UITableViewDataSource {
public extension SkeletonTableViewDataSource {
func collectionSkeletonView(_ skeletonView: UITableView, numberOfRowsInSection section: Int) -> Int {
return SkeletonCollectionDataSource.automaticNumberOfRows
return UITableView.automaticNumberOfSkeletonRows
}
func numSections(in collectionSkeletonView: UITableView) -> Int { return 1 }
@@ -11,6 +11,8 @@ import UIKit
public typealias ReusableHeaderFooterIdentifier = String
extension UITableView: CollectionSkeleton {
public static let automaticNumberOfSkeletonRows = -1
var estimatedNumberOfRows: Int {
return Int(ceil(frame.height / rowHeight))
}
@@ -12,9 +12,17 @@ extension UIView {
nonContentSizeLayoutConstraints.filter { $0.firstAttribute == NSLayoutConstraint.Attribute.height }
}
var skeletonHeightConstraints: [NSLayoutConstraint] {
nonContentSizeLayoutConstraints.filter {
$0.firstAttribute == NSLayoutConstraint.Attribute.height
&& $0.identifier?.contains("SkeletonView.Constraint.Height") ?? false
}
}
@discardableResult
func setHeight(equalToConstant constant: CGFloat) -> NSLayoutConstraint {
let heightConstraint = heightAnchor.constraint(equalToConstant: constant)
heightConstraint.identifier = "SkeletonView.Constraint.Height.\(constant)"
NSLayoutConstraint.activate([heightConstraint])
return heightConstraint
}
+1 -1
View File
@@ -16,7 +16,7 @@ enum ViewAssociatedKeys {
static var buttonViewState = "buttonViewState"
static var currentSkeletonConfig = "currentSkeletonConfig"
static var skeletonCornerRadius = "skeletonCornerRadius"
static var disableWhenSkeletonIsActive = "disableWhenSkeletonIsActive"
static var disabledWhenSkeletonIsActive = "disabledWhenSkeletonIsActive"
}
// codebeat:enable[TOO_MANY_IVARS]
@@ -16,9 +16,9 @@ public extension UIView {
}
@IBInspectable
var isDisableWhenSkeletonIsActive: Bool {
get { return disableWhenSkeletonIsActive }
set { disableWhenSkeletonIsActive = newValue }
var isUserInteractionDisabledWhenSkeletonIsActive: Bool {
get { return disabledWhenSkeletonIsActive }
set { disabledWhenSkeletonIsActive = newValue }
}
@IBInspectable
@@ -41,9 +41,9 @@ public extension UIView {
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 disabledWhenSkeletonIsActive: Bool {
get { return ao_get(pkey: &ViewAssociatedKeys.disabledWhenSkeletonIsActive) as? Bool ?? true }
set { ao_set(newValue, pkey: &ViewAssociatedKeys.disabledWhenSkeletonIsActive) }
}
private var skeletonableCornerRadius: Float {
@@ -10,7 +10,7 @@ import UIKit
extension UIView {
@objc func prepareViewForSkeleton() {
if isDisableWhenSkeletonIsActive {
if isUserInteractionDisabledWhenSkeletonIsActive {
isUserInteractionEnabled = false
}
@@ -47,10 +47,7 @@ extension UILabel {
}
}
func restoreBackupHeightConstraints() {
heightConstraints.forEach {
removeConstraint($0)
}
func restoreBackupHeightConstraintsIfNeeded() {
guard !backupHeightConstraints.isEmpty else { return }
NSLayoutConstraint.activate(backupHeightConstraints)
backupHeightConstraints.removeAll()
@@ -59,7 +56,7 @@ extension UILabel {
override func prepareViewForSkeleton() {
backgroundColor = .clear
if isDisableWhenSkeletonIsActive {
if isUserInteractionDisabledWhenSkeletonIsActive {
isUserInteractionEnabled = false
}
@@ -75,7 +72,7 @@ extension UITextView {
override func prepareViewForSkeleton() {
backgroundColor = .clear
if isDisableWhenSkeletonIsActive {
if isUserInteractionDisabledWhenSkeletonIsActive {
isUserInteractionEnabled = false
}
@@ -102,7 +99,7 @@ extension UIImageView {
override func prepareViewForSkeleton() {
backgroundColor = .clear
if isDisableWhenSkeletonIsActive {
if isUserInteractionDisabledWhenSkeletonIsActive {
isUserInteractionEnabled = false
}
@@ -116,7 +113,7 @@ extension UIButton {
override func prepareViewForSkeleton() {
backgroundColor = .clear
if isDisableWhenSkeletonIsActive {
if isUserInteractionDisabledWhenSkeletonIsActive {
isUserInteractionEnabled = false
}
+9 -5
View File
@@ -32,7 +32,7 @@ extension UIView: Recoverable {
self.layer.cornerRadius = storedViewState.cornerRadius
self.layer.masksToBounds = storedViewState.clipToBounds
if self.isDisableWhenSkeletonIsActive {
if self.isUserInteractionDisabledWhenSkeletonIsActive {
self.isUserInteractionEnabled = storedViewState.isUserInteractionsEnabled
}
@@ -57,12 +57,16 @@ extension UILabel {
override func recoverViewState(forced: Bool) {
super.recoverViewState(forced: forced)
startTransition { [weak self] in
guard let storedLabelState = self?.labelState else { return }
guard let self = self,
let storedLabelState = self.labelState else {
return
}
self?.restoreBackupHeightConstraints()
NSLayoutConstraint.deactivate(self.skeletonHeightConstraints)
self.restoreBackupHeightConstraintsIfNeeded()
if self?.textColor == .clear || forced {
self?.textColor = storedLabelState.textColor
if self.textColor == .clear || forced {
self.textColor = storedLabelState.textColor
}
}
}