feat: padding configuration for skeleton layer

This commit is contained in:
Nikita Semenov 2023-03-03 14:01:48 +03:00
parent 59ef1093c7
commit fd2fa45909
4 changed files with 59 additions and 14 deletions

View File

@ -30,10 +30,12 @@ open class BaseViewSkeletonsConfiguration {
case custom(CGPath)
}
public var padding: UIEdgeInsets
public var shape: Shape
public init(shape: Shape = .rectangle(cornerRadius: .zero)) {
public init(padding: UIEdgeInsets = .zero, shape: Shape = .rectangle(cornerRadius: .zero)) {
self.shape = shape
self.padding = padding
}
open func drawPath(rect: CGRect) -> CGPath {
@ -42,11 +44,15 @@ open class BaseViewSkeletonsConfiguration {
return path
case let .rectangle(cornerRadius: cornerRadius):
let path = UIBezierPath(roundedRect: rect, cornerRadius: cornerRadius)
let path = UIBezierPath(roundedRect: rect.reduceSize(byPadding: padding), cornerRadius: cornerRadius)
return path.cgPath
case .circle:
return CGPath(ellipseIn: rect, transform: nil)
return CGPath(ellipseIn: rect.reduceSize(byPadding: padding), transform: nil)
}
}
open func applyPadding(viewFrame: CGRect) -> CGRect {
viewFrame.with(padding: padding)
}
}

View File

@ -43,13 +43,14 @@ open class LabelSkeletonsConfiguration: BaseViewSkeletonsConfiguration {
public init(numberOfLines: LinesAmount = .constant(3),
lineHeight: Closure<UIFont?, CGFloat>? = nil,
lineSpacing: Closure<UIFont?, CGFloat>? = nil,
padding: UIEdgeInsets = .zero,
shape: Shape = .rectangle(cornerRadius: .zero)) {
self.numberOfLines = numberOfLines
self.lineHeight = lineHeight
self.lineSpacing = lineSpacing
super.init(shape: shape)
super.init(padding: padding, shape: shape)
}
open override func drawPath(rect: CGRect) -> CGPath {
@ -108,7 +109,7 @@ open class LabelSkeletonsConfiguration: BaseViewSkeletonsConfiguration {
labelNumberOfLines = label.numberOfLines
labelHeight = label.bounds.height
return drawPath(rect: label.bounds)
return drawPath(rect: label.bounds.reduceSize(byPadding: padding))
}
open func configureTextViewPath(textView: UITextView) -> CGPath {
@ -121,7 +122,7 @@ open class LabelSkeletonsConfiguration: BaseViewSkeletonsConfiguration {
labelNumberOfLines = textView.textContainer.maximumNumberOfLines
labelHeight = textView.bounds.height
return drawPath(rect: textView.bounds)
return drawPath(rect: textView.bounds.reduceSize(byPadding: padding))
}
// MARK: - Private methods

View File

@ -0,0 +1,40 @@
//
// Copyright (c) 2023 Touch Instinct
//
// 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.
//
import UIKit
extension CGRect {
func with(padding: UIEdgeInsets) -> CGRect {
CGRect(x: minX + padding.left,
y: minY + padding.top,
width: width - padding.right,
height: height - padding.bottom)
}
func reduceSize(byPadding p: UIEdgeInsets) -> CGRect {
let reducedWidth = width - p.left - p.right
let reducedHeight = height - p.top - p.bottom
let reducedSize = CGSize(width: reducedWidth, height: reducedHeight)
return CGRect(origin: origin, size: reducedSize)
}
}

View File

@ -134,28 +134,26 @@ open class SkeletonLayer: CAShapeLayer {
}
private func updateGeometry(viewType: ViewType) {
frame = viewType.view.convert(viewType.view.bounds, to: baseView)
path = drawPath(viewType: viewType)
animationLayer.frame = bounds
}
private func drawPath(viewType: ViewType) -> CGPath {
var path: CGPath
let rect = viewType.view.convert(viewType.view.bounds, to: baseView)
switch viewType {
case let .textView(textView):
path = configuration.labelConfiguration.configureTextViewPath(textView: textView)
frame = configuration.labelConfiguration.applyPadding(viewFrame: rect)
case let .label(label):
path = configuration.labelConfiguration.configureLabelPath(label: label)
frame = configuration.labelConfiguration.applyPadding(viewFrame: rect)
case .imageView(_):
path = configuration.imageViewConfiguration.drawPath(rect: viewType.view.bounds)
frame = configuration.imageViewConfiguration.applyPadding(viewFrame: rect)
default:
path = configuration.viewConfiguration.drawPath(rect: viewType.view.bounds)
frame = configuration.viewConfiguration.applyPadding(viewFrame: rect)
}
return path
animationLayer.frame = bounds
}
}