feat: added new sys of hidding views below the skeletons
This commit is contained in:
parent
597755474c
commit
19bb08aa66
|
|
@ -31,6 +31,7 @@ open class SkeletonsConfiguration {
|
|||
public var imageViewConfiguration: BaseViewSkeletonsConfiguration
|
||||
public var animation: Closure<SkeletonLayer, CAAnimationGroup>?
|
||||
|
||||
public var baseSkeletonBackgroundColor: CGColor?
|
||||
public var skeletonsBackgroundColor: CGColor
|
||||
public var skeletonsMovingColor: CGColor
|
||||
|
||||
|
|
@ -47,6 +48,7 @@ open class SkeletonsConfiguration {
|
|||
labelConfiguration: TextSkeletonsConfiguration = .init(),
|
||||
imageViewConfiguration: BaseViewSkeletonsConfiguration = .init(shape: .circle),
|
||||
animation: Closure<SkeletonLayer, CAAnimationGroup>? = nil,
|
||||
baseSkeletonBackgroundColor: UIColor? = nil,
|
||||
skeletonsBackgroundColor: UIColor = .lightGray.withAlphaComponent(0.7),
|
||||
configurationDelegate: SkeletonsConfigurationDelegate? = nil) {
|
||||
|
||||
|
|
@ -55,6 +57,7 @@ open class SkeletonsConfiguration {
|
|||
self.labelConfiguration = labelConfiguration
|
||||
self.imageViewConfiguration = imageViewConfiguration
|
||||
self.animation = animation
|
||||
self.baseSkeletonBackgroundColor = baseSkeletonBackgroundColor?.cgColor
|
||||
self.skeletonsBackgroundColor = skeletonsBackgroundColor.cgColor
|
||||
self.skeletonsMovingColor = skeletonsBackgroundColor.withAlphaComponent(0.2).cgColor
|
||||
self.configurationDelegate = configurationDelegate
|
||||
|
|
@ -70,6 +73,10 @@ open class SkeletonsConfiguration {
|
|||
layer.fillColor = skeletonsBackgroundColor
|
||||
}
|
||||
|
||||
open func configureBaseViewAppearance(layer: SkeletonLayer, view: UIView) {
|
||||
layer.fillColor = baseSkeletonBackgroundColor ?? view.backgroundColor?.cgColor
|
||||
}
|
||||
|
||||
open func configureContainerAppearance(layer: SkeletonLayer) {
|
||||
layer.fillColor = UIColor.clear.cgColor
|
||||
|
||||
|
|
|
|||
|
|
@ -26,8 +26,8 @@ extension CGRect {
|
|||
func with(padding: UIEdgeInsets) -> CGRect {
|
||||
CGRect(x: minX + padding.left,
|
||||
y: minY + padding.top,
|
||||
width: width - padding.right,
|
||||
height: height - padding.bottom)
|
||||
width: width,
|
||||
height: height)
|
||||
}
|
||||
|
||||
func reduceSize(byPadding p: UIEdgeInsets) -> CGRect {
|
||||
|
|
|
|||
|
|
@ -31,6 +31,7 @@ open class SkeletonLayer: CAShapeLayer {
|
|||
}
|
||||
|
||||
public enum ViewType {
|
||||
case base(UIView)
|
||||
case generic(UIView)
|
||||
case container(UIView)
|
||||
case label(UILabel)
|
||||
|
|
@ -53,6 +54,9 @@ open class SkeletonLayer: CAShapeLayer {
|
|||
|
||||
case let .generic(view):
|
||||
return view
|
||||
|
||||
case let .base(view):
|
||||
return view
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -140,6 +144,9 @@ open class SkeletonLayer: CAShapeLayer {
|
|||
case .container(_):
|
||||
configuration.configureContainerAppearance(layer: self)
|
||||
|
||||
case .base(_):
|
||||
configuration.configureBaseViewAppearance(layer: self, view: type.view)
|
||||
|
||||
default:
|
||||
configuration.configureAppearance(layer: self)
|
||||
}
|
||||
|
|
@ -153,23 +160,37 @@ open class SkeletonLayer: CAShapeLayer {
|
|||
switch viewType {
|
||||
case let .textView(textView):
|
||||
path = configuration.labelConfiguration.configureTextViewPath(textView: textView)
|
||||
frame = configuration.labelConfiguration.applyPadding(viewFrame: rect)
|
||||
|
||||
let viewFrame = CGRect(origin: rect.origin, size: path?.boundingBox.size ?? rect.size)
|
||||
frame = configuration.labelConfiguration.applyPadding(viewFrame: viewFrame)
|
||||
|
||||
case let .label(label):
|
||||
path = configuration.labelConfiguration.configureLabelPath(label: label)
|
||||
frame = configuration.labelConfiguration.applyPadding(viewFrame: rect)
|
||||
|
||||
let viewFrame = CGRect(origin: rect.origin, size: path?.boundingBox.size ?? rect.size)
|
||||
frame = configuration.labelConfiguration.applyPadding(viewFrame: viewFrame)
|
||||
|
||||
case .imageView(_):
|
||||
path = configuration.imageViewConfiguration.drawPath(rect: viewType.view.bounds)
|
||||
frame = configuration.imageViewConfiguration.applyPadding(viewFrame: rect)
|
||||
|
||||
let viewFrame = CGRect(origin: rect.origin, size: path?.boundingBox.size ?? rect.size)
|
||||
frame = configuration.imageViewConfiguration.applyPadding(viewFrame: viewFrame)
|
||||
|
||||
case .container(_):
|
||||
path = configuration.containerViewConfiguration.drawPath(rect: viewType.view.bounds)
|
||||
frame = configuration.containerViewConfiguration.applyPadding(viewFrame: rect)
|
||||
|
||||
let viewFrame = CGRect(origin: rect.origin, size: path?.boundingBox.size ?? rect.size)
|
||||
frame = configuration.containerViewConfiguration.applyPadding(viewFrame: viewFrame)
|
||||
|
||||
case .generic(_):
|
||||
path = configuration.viewConfiguration.drawPath(rect: viewType.view.bounds)
|
||||
frame = configuration.viewConfiguration.applyPadding(viewFrame: rect)
|
||||
|
||||
let viewFrame = CGRect(origin: rect.origin, size: path?.boundingBox.size ?? rect.size)
|
||||
frame = configuration.viewConfiguration.applyPadding(viewFrame: viewFrame)
|
||||
|
||||
default:
|
||||
path = UIBezierPath(roundedRect: rect, cornerRadius: 20).cgPath
|
||||
frame = rect
|
||||
}
|
||||
|
||||
animationLayer.frame = bounds
|
||||
|
|
|
|||
|
|
@ -20,6 +20,7 @@
|
|||
// THE SOFTWARE.
|
||||
//
|
||||
|
||||
import TISwiftUtils
|
||||
import UIKit
|
||||
|
||||
extension UIView {
|
||||
|
|
@ -37,7 +38,7 @@ extension UIView {
|
|||
let viewsToSkeletone = viewsToSkeletone ?? skeletonableViews
|
||||
isUserInteractionEnabled = false
|
||||
|
||||
subviews.forEach { $0.isHidden = true }
|
||||
configureBaseLayer(withConfiguration: config)
|
||||
|
||||
viewsToSkeletone
|
||||
.flatMap { view in
|
||||
|
|
@ -59,8 +60,6 @@ extension UIView {
|
|||
layer.remove(from: self)
|
||||
}
|
||||
}
|
||||
|
||||
subviews.forEach { $0.isHidden = false }
|
||||
}
|
||||
|
||||
public func startAnimation() {
|
||||
|
|
@ -78,18 +77,19 @@ extension UIView {
|
|||
// MARK: - Private methods
|
||||
|
||||
private func getSkeletonLayer(forView view: UIView,
|
||||
withConfiguration conf: SkeletonsConfiguration) -> [SkeletonLayer] {
|
||||
withConfiguration conf: SkeletonsConfiguration,
|
||||
forceNoContainers: Bool = false) -> [SkeletonLayer] {
|
||||
|
||||
let skeletonLayer = conf.createSkeletonLayer(for: self)
|
||||
var subviewSkeletonLayers = [SkeletonLayer]()
|
||||
|
||||
if view.isSkeletonsContainer {
|
||||
if !conf.isContainersHidden {
|
||||
if !conf.isContainersHidden, !forceNoContainers {
|
||||
skeletonLayer.bind(to: .container(view))
|
||||
}
|
||||
|
||||
subviewSkeletonLayers = view.skeletonableViews
|
||||
.map { getSkeletonLayer(forView: $0, withConfiguration: conf) }
|
||||
.map { getSkeletonLayer(forView: $0, withConfiguration: conf, forceNoContainers: true) }
|
||||
.flatMap { $0 }
|
||||
|
||||
} else {
|
||||
|
|
@ -98,6 +98,13 @@ extension UIView {
|
|||
|
||||
return [skeletonLayer] + subviewSkeletonLayers
|
||||
}
|
||||
|
||||
private func configureBaseLayer(withConfiguration conf: SkeletonsConfiguration) {
|
||||
let skeletonLayer = conf.createSkeletonLayer(for: self)
|
||||
|
||||
skeletonLayer.bind(to: .base(self))
|
||||
layer.insertSublayer(skeletonLayer, at: .max)
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: - Helper extension
|
||||
|
|
|
|||
|
|
@ -189,6 +189,9 @@ let confWithTopToBottomAnim = SkeletonsConfiguration(animation: { _ in
|
|||
*/
|
||||
let confWithRedBackgroundColor = SkeletonsConfiguration(skeletonsBackgroundColor: .red)
|
||||
|
||||
//: Для скрытия view от пользователя скелетонами накладывается специальный CALayer, чей цвет заполнения равен backgroundColor view, с которой были запущены скелетоны. Однако этот цвет можно переопределить переопределить с помощью параметра `baseSkeletonBackgroundColor`
|
||||
let confWithRedBaseBackgroundColor = SkeletonsConfiguration(baseSkeletonBackgroundColor: .red)
|
||||
|
||||
/*:
|
||||
### Форма
|
||||
|
||||
|
|
|
|||
|
|
@ -198,6 +198,12 @@ let confWithTopToBottomAnim = SkeletonsConfiguration(animation: { _ in
|
|||
let confWithRedBackgroundColor = SkeletonsConfiguration(skeletonsBackgroundColor: .red)
|
||||
```
|
||||
|
||||
Для скрытия view от пользователя скелетонами накладывается специальный CALayer, чей цвет заполнения равен backgroundColor view, с которой были запущены скелетоны. Однако этот цвет можно переопределить переопределить с помощью параметра `baseSkeletonBackgroundColor`
|
||||
|
||||
```swift
|
||||
let confWithRedBaseBackgroundColor = SkeletonsConfiguration(baseSkeletonBackgroundColor: .red)
|
||||
```
|
||||
|
||||
### Форма
|
||||
|
||||
Форму можно настраивать отдельно для `UILabel`, `UITextView`, `UIImageView` и остальных вью. Например, картинки можно сделать круглыми, а лейблы прямоугольные с закругленными краями:
|
||||
|
|
|
|||
Loading…
Reference in New Issue