feat: Added: maxWidth parameter to BaseViewSkeletonsConfiguration. #19

Merged
ivan.smolin merged 1 commits from feature/skeletons_configuration into master 2023-11-02 21:55:22 +03:00
32 changed files with 208 additions and 108 deletions

View File

@ -1,5 +1,11 @@
# Changelog
### 1.54.0
- **Added**: `maxWidth` parameter to `BaseViewSkeletonsConfiguration`.
- **Added**: custom `SkeletonConfigurations` for nested `SkeletonPresenters`.
- **Update**: Many fixes and improvenments to `TextSkeletonsConfiguration`.
### 1.53.3
- **Update**: `Skeletonable` can now control custom geometry change notification.

View File

@ -1,6 +1,6 @@
Pod::Spec.new do |s|
s.name = 'TIAppleMapUtils'
s.version = '1.53.3'
s.version = '1.54.0'
s.summary = 'Set of helpers for map objects clustering and interacting using Apple MapKit.'
s.homepage = 'https://git.svc.touchin.ru/TouchInstinct/LeadKit/src/tag/' + s.version.to_s + '/' + s.name
s.license = { :type => 'MIT', :file => 'LICENSE' }

View File

@ -1,6 +1,6 @@
Pod::Spec.new do |s|
s.name = 'TIApplication'
s.version = '1.53.3'
s.version = '1.54.0'
s.summary = 'Application architecture.'
s.homepage = 'https://git.svc.touchin.ru/TouchInstinct/LeadKit/src/tag/' + s.version.to_s + '/' + s.name
s.license = { :type => 'MIT', :file => 'LICENSE' }

View File

@ -1,6 +1,6 @@
Pod::Spec.new do |s|
s.name = 'TIAuth'
s.version = '1.53.3'
s.version = '1.54.0'
s.summary = 'Login, registration, confirmation and other related actions'
s.homepage = 'https://git.svc.touchin.ru/TouchInstinct/LeadKit/src/tag/' + s.version.to_s + '/' + s.name
s.license = { :type => 'MIT', :file => 'LICENSE' }

View File

@ -1,6 +1,6 @@
Pod::Spec.new do |s|
s.name = 'TIBottomSheet'
s.version = '1.53.3'
s.version = '1.54.0'
s.summary = 'Base models for creating bottom sheet view controllers'
s.homepage = 'https://git.svc.touchin.ru/TouchInstinct/LeadKit/src/tag/' + s.version.to_s + '/' + s.name
s.license = { :type => 'MIT', :file => 'LICENSE' }

View File

@ -1,6 +1,6 @@
Pod::Spec.new do |s|
s.name = 'TICoreGraphicsUtils'
s.version = '1.53.3'
s.version = '1.54.0'
s.summary = 'CoreGraphics drawing helpers'
s.homepage = 'https://git.svc.touchin.ru/TouchInstinct/LeadKit/src/tag/' + s.version.to_s + '/' + s.name
s.license = { :type => 'MIT', :file => 'LICENSE' }

View File

@ -1,6 +1,6 @@
Pod::Spec.new do |s|
s.name = 'TIDeeplink'
s.version = '1.53.3'
s.version = '1.54.0'
s.summary = 'Deeplink service API'
s.homepage = 'https://git.svc.touchin.ru/TouchInstinct/LeadKit/src/tag/' + s.version.to_s + '/' + s.name
s.license = { :type => 'MIT', :file => 'LICENSE' }

View File

@ -1,6 +1,6 @@
Pod::Spec.new do |s|
s.name = 'TIDeveloperUtils'
s.version = '1.53.3'
s.version = '1.54.0'
s.summary = 'Universal web view API'
s.homepage = 'https://git.svc.touchin.ru/TouchInstinct/LeadKit/src/tag/' + s.version.to_s + '/' + s.name
s.license = { :type => 'MIT', :file => 'LICENSE' }

View File

@ -1,6 +1,6 @@
Pod::Spec.new do |s|
s.name = 'TIEcommerce'
s.version = '1.53.3'
s.version = '1.54.0'
s.summary = 'Cart, products, promocodes, bonuses and other related actions'
s.homepage = 'https://git.svc.touchin.ru/TouchInstinct/LeadKit/src/tag/' + s.version.to_s + '/' + s.name
s.license = { :type => 'MIT', :file => 'LICENSE' }

View File

@ -1,6 +1,6 @@
Pod::Spec.new do |s|
s.name = 'TIFoundationUtils'
s.version = '1.53.3'
s.version = '1.54.0'
s.summary = 'Set of helpers for Foundation framework classes.'
s.homepage = 'https://git.svc.touchin.ru/TouchInstinct/LeadKit/src/tag/' + s.version.to_s + '/' + s.name
s.license = { :type => 'MIT', :file => 'LICENSE' }

View File

@ -1,6 +1,6 @@
Pod::Spec.new do |s|
s.name = 'TIGoogleMapUtils'
s.version = '1.53.3'
s.version = '1.54.0'
s.summary = 'Set of helpers for map objects clustering and interacting using Google Maps SDK.'
s.homepage = 'https://git.svc.touchin.ru/TouchInstinct/LeadKit/src/tag/' + s.version.to_s + '/' + s.name
s.license = { :type => 'MIT', :file => 'LICENSE' }

View File

@ -1,6 +1,6 @@
Pod::Spec.new do |s|
s.name = 'TIKeychainUtils'
s.version = '1.53.3'
s.version = '1.54.0'
s.summary = 'Set of helpers for Keychain classes.'
s.homepage = 'https://git.svc.touchin.ru/TouchInstinct/LeadKit/src/tag/' + s.version.to_s + '/' + s.name
s.license = { :type => 'MIT', :file => 'LICENSE' }

View File

@ -1,6 +1,6 @@
Pod::Spec.new do |s|
s.name = 'TILogging'
s.version = '1.53.3'
s.version = '1.54.0'
s.summary = 'Logging for TI libraries.'
s.homepage = 'https://git.svc.touchin.ru/TouchInstinct/LeadKit/src/tag/' + s.version.to_s + '/' + s.name
s.license = { :type => 'MIT', :file => 'LICENSE' }

View File

@ -1,6 +1,6 @@
Pod::Spec.new do |s|
s.name = 'TIMapUtils'
s.version = '1.53.3'
s.version = '1.54.0'
s.summary = 'Set of helpers for map objects clustering and interacting.'
s.homepage = 'https://git.svc.touchin.ru/TouchInstinct/LeadKit/src/tag/' + s.version.to_s + '/' + s.name
s.license = { :type => 'MIT', :file => 'LICENSE' }

View File

@ -1,6 +1,6 @@
Pod::Spec.new do |s|
s.name = 'TIMoyaNetworking'
s.version = '1.53.3'
s.version = '1.54.0'
s.summary = 'Moya + Swagger network service.'
s.homepage = 'https://git.svc.touchin.ru/TouchInstinct/LeadKit/src/tag/' + s.version.to_s + '/' + s.name
s.license = { :type => 'MIT', :file => 'LICENSE' }

View File

@ -1,6 +1,6 @@
Pod::Spec.new do |s|
s.name = 'TINetworking'
s.version = '1.53.3'
s.version = '1.54.0'
s.summary = 'Swagger-frendly networking layer helpers.'
s.homepage = 'https://git.svc.touchin.ru/TouchInstinct/LeadKit/src/tag/' + s.version.to_s + '/' + s.name
s.license = { :type => 'MIT', :file => 'LICENSE' }

View File

@ -1,6 +1,6 @@
Pod::Spec.new do |s|
s.name = 'TINetworkingCache'
s.version = '1.53.3'
s.version = '1.54.0'
s.summary = 'Caching results of EndpointRequests.'
s.homepage = 'https://git.svc.touchin.ru/TouchInstinct/LeadKit/src/tag/' + s.version.to_s + '/' + s.name
s.license = { :type => 'MIT', :file => 'LICENSE' }

View File

@ -1,6 +1,6 @@
Pod::Spec.new do |s|
s.name = 'TIPagination'
s.version = '1.53.3'
s.version = '1.54.0'
s.summary = 'Generic pagination component.'
s.homepage = 'https://git.svc.touchin.ru/TouchInstinct/LeadKit/src/tag/' + s.version.to_s + '/' + s.name
s.license = { :type => 'MIT', :file => 'LICENSE' }

View File

@ -1,6 +1,6 @@
Pod::Spec.new do |s|
s.name = 'TISwiftUICore'
s.version = '1.53.3'
s.version = '1.54.0'
s.summary = 'Core UI elements: protocols, views and helpers.'
s.homepage = 'https://git.svc.touchin.ru/TouchInstinct/LeadKit/src/tag/' + s.version.to_s + '/' + s.name
s.license = { :type => 'MIT', :file => 'LICENSE' }

View File

@ -1,6 +1,6 @@
Pod::Spec.new do |s|
s.name = 'TISwiftUtils'
s.version = '1.53.3'
s.version = '1.54.0'
s.summary = 'Bunch of useful helpers for Swift development.'
s.homepage = 'https://git.svc.touchin.ru/TouchInstinct/LeadKit/src/tag/' + s.version.to_s + '/' + s.name
s.license = { :type => 'MIT', :file => 'LICENSE' }

View File

@ -1,6 +1,6 @@
Pod::Spec.new do |s|
s.name = 'TITableKitUtils'
s.version = '1.53.3'
s.version = '1.54.0'
s.summary = 'Set of helpers for TableKit classes.'
s.homepage = 'https://git.svc.touchin.ru/TouchInstinct/LeadKit/src/tag/' + s.version.to_s + '/' + s.name
s.license = { :type => 'MIT', :file => 'LICENSE' }

View File

@ -1,6 +1,6 @@
Pod::Spec.new do |s|
s.name = 'TITextProcessing'
s.version = '1.53.3'
s.version = '1.54.0'
s.summary = 'A text processing service helping to get a text mask and a placeholder from incoming regex.'
s.homepage = 'https://git.svc.touchin.ru/TouchInstinct/LeadKit/src/tag/' + s.version.to_s + '/' + s.name
s.license = { :type => 'MIT', :file => 'LICENSE' }

View File

@ -32,28 +32,46 @@ open class BaseViewSkeletonsConfiguration {
}
public var padding: UIEdgeInsets
public var maxWidth: CGFloat
public var shape: Shape
public init(padding: UIEdgeInsets = .edges(5), shape: Shape = .rectangle(cornerRadius: .zero)) {
public init(padding: UIEdgeInsets = .edges(5),
maxWidth: CGFloat = .infinity,
shape: Shape = .rectangle(cornerRadius: .zero)) {
self.shape = shape
self.maxWidth = maxWidth
self.padding = padding
}
open func drawPath(rect: CGRect) -> CGPath {
open func createPath(for rect: CGRect) -> CGPath {
let adjustedRect = rect.reduceSize(byPadding: padding)
.with(maxWidth: maxWidth)
switch shape {
case let .custom(path):
return path
case let .rectangle(cornerRadius: cornerRadius):
let path = UIBezierPath(roundedRect: rect.reduceSize(byPadding: padding), cornerRadius: cornerRadius)
return path.cgPath
return UIBezierPath(roundedRect: adjustedRect,
cornerRadius: cornerRadius).cgPath
case .circle:
return CGPath(ellipseIn: rect.reduceSize(byPadding: padding), transform: nil)
return CGPath(ellipseIn: adjustedRect,
transform: nil)
}
}
open func applyPadding(viewFrame: CGRect) -> CGRect {
viewFrame.with(padding: padding)
}
open func copyWith(padding: UIEdgeInsets? = nil,
maxWidth: CGFloat? = nil,
shape: Shape? = nil) -> BaseViewSkeletonsConfiguration {
BaseViewSkeletonsConfiguration(padding: padding ?? self.padding,
maxWidth: maxWidth ?? self.maxWidth,
shape: shape ?? self.shape)
}
}

View File

@ -28,10 +28,22 @@ open class ContainerViewSkeletonsConfiguration: BaseViewSkeletonsConfiguration {
public init(borderWidth: CGFloat = .zero,
padding: UIEdgeInsets = .zero,
maxWidth: CGFloat = .infinity,
shape: Shape = .rectangle(cornerRadius: .zero)) {
self.borderWidth = borderWidth
super.init(padding: padding, shape: shape)
}
open func copyWith(borderWidth: CGFloat? = nil,
padding: UIEdgeInsets? = nil,
maxWidth: CGFloat? = nil,
shape: Shape? = nil) -> ContainerViewSkeletonsConfiguration {
ContainerViewSkeletonsConfiguration(borderWidth: borderWidth ?? self.borderWidth,
padding: padding ?? self.padding,
maxWidth: maxWidth ?? self.maxWidth,
shape: shape ?? self.shape)
}
}

View File

@ -26,35 +26,68 @@ import UIKit
open class TextSkeletonsConfiguration: BaseViewSkeletonsConfiguration {
private enum Constants {
static var defaultNumberOfLines: Int {
public enum Defaults {
public static var numberOfLines: Int {
1
}
public static var multilineNumberOfLines: Int {
3
}
public static var linesWidthFraction: [CGFloat] {
[1, 0.65, 0.78]
}
public static var defaultFont: UIFont {
.systemFont(ofSize: 15)
}
}
private var isMultiline = false
private var labelNumberOfLines: Int = .zero
private var labelHeight: CGFloat = .zero
private var font: UIFont?
public var numberOfLines: Int
public var linesWidthFraction: [CGFloat]
public var lineHeight: CGFloat?
public var lineSpacing: CGFloat?
public var numberOfLines: Int?
public var lineHeight: Closure<UIFont?, CGFloat>?
public var lineSpacing: Closure<UIFont?, CGFloat>?
public init(numberOfLines: Int? = nil,
lineHeight: Closure<UIFont?, CGFloat>? = nil,
lineSpacing: Closure<UIFont?, CGFloat>? = nil,
public init(numberOfLines: Int = Defaults.numberOfLines,
linesWidthFraction: [CGFloat] = Defaults.linesWidthFraction,
lineHeight: CGFloat? = nil,
lineSpacing: CGFloat? = nil,
padding: UIEdgeInsets = .edges(5),
maxWidth: CGFloat = .infinity,
shape: Shape = .rectangle(cornerRadius: .zero)) {
self.numberOfLines = numberOfLines
self.linesWidthFraction = linesWidthFraction
self.lineHeight = lineHeight
self.lineSpacing = lineSpacing
super.init(padding: padding, shape: shape)
}
open override func drawPath(rect: CGRect) -> CGPath {
open func createConfiguration(for label: UILabel) -> TextSkeletonsConfiguration {
let labelFont = getFont(from: label)
return copyWith(numberOfLines: label.numberOfLines,
lineHeight: calculateLineHeight(for: labelFont),
lineSpacing: calculateLineSpacing(for: labelFont),
padding: padding,
maxWidth: maxWidth,
shape: shape)
}
open func createConfiguration(for textView: UITextView) -> TextSkeletonsConfiguration {
let labelFont = getFont(from: textView)
return copyWith(numberOfLines: textView.textContainer.maximumNumberOfLines,
lineHeight: calculateLineHeight(for: labelFont),
lineSpacing: calculateLineSpacing(for: labelFont),
padding: padding,
maxWidth: maxWidth,
shape: shape)
}
open override func createPath(for rect: CGRect) -> CGPath {
/*
SkeletonLayer
|-------------------------|
@ -65,10 +98,10 @@ open class TextSkeletonsConfiguration: BaseViewSkeletonsConfiguration {
||-----------------------|| - third line CGRect(0, (lineHeight + spacing) * 2, rect.width, lineHeight)
|-------------------------|
*/
let adjustedRect = rect.reduceSize(byPadding: padding).with(maxWidth: maxWidth)
let path = UIBezierPath()
let numberOfLines = getNumberOfLines()
let spacing = getLineSpacing()
let lineHeight = getLineHeight()
let spacing = lineSpacing ?? calculateLineSpacing(for: Defaults.defaultFont)
let lineHeight = self.lineHeight ?? calculateLineHeight(for: Defaults.defaultFont)
var cornerRadius = CGFloat.zero
if case let .rectangle(cornerRadius: radius) = shape {
@ -76,17 +109,27 @@ open class TextSkeletonsConfiguration: BaseViewSkeletonsConfiguration {
}
for lineNumber in 0..<numberOfLines {
let adjustedLineRect: CGRect
if linesWidthFraction.isEmpty {
adjustedLineRect = adjustedRect
} else {
let currentLineWidthFracion = linesWidthFraction[lineNumber % linesWidthFraction.count]
let currentLineWidth = adjustedRect.width * currentLineWidthFracion
adjustedLineRect = adjustedRect.with(maxWidth: currentLineWidth)
}
let y = (lineHeight + spacing) * CGFloat(lineNumber)
path.move(to: CGPoint(x: cornerRadius, y: y))
path.addLine(to: CGPoint(x: rect.width - cornerRadius, y: y))
path.addQuadCurve(to: CGPoint(x: rect.width, y: y + cornerRadius),
controlPoint: CGPoint(x: rect.width, y: y))
path.addLine(to: CGPoint(x: adjustedLineRect.width - cornerRadius, y: y))
path.addQuadCurve(to: CGPoint(x: adjustedLineRect.width, y: y + cornerRadius),
controlPoint: CGPoint(x: adjustedLineRect.width, y: y))
path.addLine(to: CGPoint(x: rect.width, y: y + lineHeight - cornerRadius))
path.addQuadCurve(to: CGPoint(x: rect.width - cornerRadius, y: y + lineHeight),
controlPoint: CGPoint(x: rect.width, y: y + lineHeight))
path.addLine(to: CGPoint(x: adjustedLineRect.width, y: y + lineHeight - cornerRadius))
path.addQuadCurve(to: CGPoint(x: adjustedLineRect.width - cornerRadius, y: y + lineHeight),
controlPoint: CGPoint(x: adjustedLineRect.width, y: y + lineHeight))
path.addLine(to: CGPoint(x: cornerRadius, y: y + lineHeight))
path.addQuadCurve(to: CGPoint(x: .zero, y: y + lineHeight - cornerRadius),
@ -100,62 +143,63 @@ open class TextSkeletonsConfiguration: BaseViewSkeletonsConfiguration {
return path.cgPath
}
open func configureLabelPath(label: UILabel) -> CGPath {
if case let .custom(path) = shape {
return path
open func getFont(from textView: UITextView) -> UIFont {
guard let attributedText = textView.attributedText else {
return textView.font ?? Defaults.defaultFont
}
isMultiline = label.isMultiline
font = label.font
labelNumberOfLines = label.numberOfLines
labelHeight = label.bounds.height
return drawPath(rect: label.bounds.reduceSize(byPadding: padding))
return getBiggestFont(from: attributedText)
}
open func configureTextViewPath(textView: UITextView) -> CGPath {
if case let .custom(path) = shape {
return path
open func getFont(from label: UILabel) -> UIFont {
guard let attributedText = label.attributedText else {
return label.font
}
isMultiline = textView.isMultiline
font = textView.font
labelNumberOfLines = textView.textContainer.maximumNumberOfLines
labelHeight = textView.bounds.height
return drawPath(rect: textView.bounds.reduceSize(byPadding: padding))
return getBiggestFont(from: attributedText)
}
// MARK: - Private methods
open func getBiggestFont(from attributedString: NSAttributedString) -> UIFont {
let text = attributedString.string
private func getLineHeight() -> CGFloat {
if let lineHeight = lineHeight?(font) {
return lineHeight
var biggestFont: UIFont = .systemFont(ofSize: 1)
attributedString.enumerateAttributes(in: NSRange(text.startIndex..., in: text)) { attributes, _, _ in
guard let fontValue = attributes[.font] as? UIFont else {
return
}
if fontValue.lineHeight > biggestFont.lineHeight {
biggestFont = fontValue
}
}
return biggestFont
}
open func calculateLineHeight(for font: UIFont) -> CGFloat {
// By default height of the line is equal to 75% of font's size
return (font?.pointSize ?? 1) * 0.75
font.pointSize * 0.75
}
private func getLineSpacing() -> CGFloat {
if let lineSpacing = lineSpacing?(font) {
return lineSpacing
}
return font?.xHeight ?? .zero
open func calculateLineSpacing(for font: UIFont) -> CGFloat {
font.xHeight
}
private func getNumberOfLines() -> Int {
guard isMultiline else {
return 1
}
open func copyWith(numberOfLines: Int? = nil,
linesWidthFraction: [CGFloat]? = nil,
lineHeight: CGFloat? = nil,
lineSpacing: CGFloat? = nil,
padding: UIEdgeInsets? = nil,
maxWidth: CGFloat? = nil,
shape: Shape? = nil) -> TextSkeletonsConfiguration {
if let numberOfLines = numberOfLines {
return numberOfLines
}
return labelNumberOfLines == .zero
? Constants.defaultNumberOfLines
: labelNumberOfLines
TextSkeletonsConfiguration(numberOfLines: numberOfLines ?? self.numberOfLines,
linesWidthFraction: linesWidthFraction ?? self.linesWidthFraction,
lineHeight: lineHeight ?? self.lineHeight,
lineSpacing: lineSpacing ?? self.lineSpacing,
padding: padding ?? self.padding,
maxWidth: maxWidth ?? self.maxWidth,
shape: shape ?? self.shape)
}
}

View File

@ -37,4 +37,13 @@ extension CGRect {
return CGRect(origin: origin, size: reducedSize)
}
func with(maxWidth: CGFloat) -> CGRect {
guard maxWidth.isFinite else {
return self
}
return CGRect(origin: origin, size: CGSize(width: min(width, maxWidth),
height: height))
}
}

View File

@ -188,31 +188,35 @@ open class SkeletonLayer: CAShapeLayer {
switch viewType {
case let .textView(textView):
path = configuration.labelConfiguration.configureTextViewPath(textView: textView)
let textViewConfig = configuration.labelConfiguration.createConfiguration(for: textView)
path = textViewConfig.createPath(for: textView.bounds)
let viewFrame = CGRect(origin: rect.origin, size: path?.boundingBox.size ?? rect.size)
frame = configuration.labelConfiguration.applyPadding(viewFrame: viewFrame)
frame = textViewConfig.applyPadding(viewFrame: viewFrame)
case let .label(label):
path = configuration.labelConfiguration.configureLabelPath(label: label)
let labelConfig = configuration.labelConfiguration.createConfiguration(for: label)
path = labelConfig.createPath(for: label.bounds)
let viewFrame = CGRect(origin: rect.origin, size: path?.boundingBox.size ?? rect.size)
frame = configuration.labelConfiguration.applyPadding(viewFrame: viewFrame)
frame = labelConfig.applyPadding(viewFrame: viewFrame)
case .imageView(_):
path = configuration.imageViewConfiguration.drawPath(rect: viewType.view.bounds)
path = configuration.imageViewConfiguration.createPath(for: viewType.view.bounds)
let viewFrame = CGRect(origin: rect.origin, size: path?.boundingBox.size ?? rect.size)
frame = configuration.imageViewConfiguration.applyPadding(viewFrame: viewFrame)
case .parentView(_):
path = configuration.containerViewConfiguration.drawPath(rect: viewType.view.bounds)
path = configuration.containerViewConfiguration.createPath(for: viewType.view.bounds)
let viewFrame = CGRect(origin: rect.origin, size: path?.boundingBox.size ?? rect.size)
frame = configuration.containerViewConfiguration.applyPadding(viewFrame: viewFrame)
case .leafView(_):
path = configuration.viewConfiguration.drawPath(rect: viewType.view.bounds)
path = configuration.viewConfiguration.createPath(for: viewType.view.bounds)
let viewFrame = CGRect(origin: rect.origin, size: path?.boundingBox.size ?? rect.size)
frame = configuration.viewConfiguration.applyPadding(viewFrame: viewFrame)

View File

@ -77,22 +77,29 @@ public extension UIView {
withConfiguration conf: SkeletonsConfiguration,
forceNoContainers: Bool = false) -> [SkeletonLayer] {
let skeletonLayer = conf.createSkeletonLayer(for: self)
var subviewSkeletonLayers = [SkeletonLayer]()
let config = (view as? SkeletonsPresenter)?.skeletonsConfiguration ?? conf
if view.isSkeletonsContainer {
if !conf.isContainersHidden, !forceNoContainers {
let skeletonLayer = config.createSkeletonLayer(for: self)
skeletonLayer.bind(to: .parentView(view))
return [skeletonLayer] + getSkeletonLayer(forView: view,
withConfiguration: config,
forceNoContainers: true)
} else {
return view.skeletonableViews
.map { getSkeletonLayer(forView: $0,
withConfiguration: config,
forceNoContainers: true) }
.flatMap { $0 }
}
subviewSkeletonLayers = view.skeletonableViews
.map { getSkeletonLayer(forView: $0, withConfiguration: conf, forceNoContainers: true) }
.flatMap { $0 }
} else {
let skeletonLayer = config.createSkeletonLayer(for: self)
skeletonLayer.bind(to: view.viewType)
}
return [skeletonLayer] + subviewSkeletonLayers
return [skeletonLayer]
}
}
private func configureBaseLayer(withConfiguration conf: SkeletonsConfiguration) {

View File

@ -1,6 +1,6 @@
Pod::Spec.new do |s|
s.name = 'TIUIElements'
s.version = '1.53.3'
s.version = '1.54.0'
s.summary = 'Bunch of useful protocols and views.'
s.homepage = 'https://git.svc.touchin.ru/TouchInstinct/LeadKit/src/tag/' + s.version.to_s + '/' + s.name
s.license = { :type => 'MIT', :file => 'LICENSE' }

View File

@ -1,6 +1,6 @@
Pod::Spec.new do |s|
s.name = 'TIUIKitCore'
s.version = '1.53.3'
s.version = '1.54.0'
s.summary = 'Core UI elements: protocols, views and helpers.'
s.homepage = 'https://git.svc.touchin.ru/TouchInstinct/LeadKit/src/tag/' + s.version.to_s + '/' + s.name
s.license = { :type => 'MIT', :file => 'LICENSE' }

View File

@ -1,6 +1,6 @@
Pod::Spec.new do |s|
s.name = 'TIWebView'
s.version = '1.53.3'
s.version = '1.54.0'
s.summary = 'Universal web view API'
s.homepage = 'https://git.svc.touchin.ru/TouchInstinct/LeadKit/src/tag/' + s.version.to_s + '/' + s.name
s.license = { :type => 'MIT', :file => 'LICENSE' }

View File

@ -1,6 +1,6 @@
Pod::Spec.new do |s|
s.name = 'TIYandexMapUtils'
s.version = '1.53.3'
s.version = '1.54.0'
s.summary = 'Set of helpers for map objects clustering and interacting using Yandex Maps SDK.'
s.homepage = 'https://git.svc.touchin.ru/TouchInstinct/LeadKit/src/tag/' + s.version.to_s + '/' + s.name
s.license = { :type => 'MIT', :file => 'LICENSE' }