From 343d36cb8574d624ea339129de95def673e2e5f6 Mon Sep 17 00:00:00 2001 From: Nikita Semenov Date: Tue, 7 Mar 2023 10:11:56 +0300 Subject: [PATCH] feat: removed SkeletonsPresenter and move all logic to extensions of UIView and UIViewController --- ...swift => UIView+PresentingSkeletons.swift} | 82 ++++++------------- .../Skeletons/UIView+PresetingSkeletons.swift | 8 ++ ...UIViewController+PresentingSkeletons.swift | 53 ++++++++++++ 3 files changed, 87 insertions(+), 56 deletions(-) rename TIUIElements/Sources/Views/Skeletons/{Protocols/SkeletonsPresenter.swift => UIView+PresentingSkeletons.swift} (66%) create mode 100644 TIUIElements/Sources/Views/Skeletons/UIView+PresetingSkeletons.swift create mode 100644 TIUIElements/Sources/Views/Skeletons/UIViewController+PresentingSkeletons.swift diff --git a/TIUIElements/Sources/Views/Skeletons/Protocols/SkeletonsPresenter.swift b/TIUIElements/Sources/Views/Skeletons/UIView+PresentingSkeletons.swift similarity index 66% rename from TIUIElements/Sources/Views/Skeletons/Protocols/SkeletonsPresenter.swift rename to TIUIElements/Sources/Views/Skeletons/UIView+PresentingSkeletons.swift index f47b0d7c..e044e72b 100644 --- a/TIUIElements/Sources/Views/Skeletons/Protocols/SkeletonsPresenter.swift +++ b/TIUIElements/Sources/Views/Skeletons/UIView+PresentingSkeletons.swift @@ -22,38 +22,38 @@ import UIKit -public protocol SkeletonsPresenter { - var baseView: UIView? { get } - var skeletonsConfiguration: SkeletonsConfiguration { get } - var isSkeletonsHidden: Bool { get } - var viewsToSkeletone: [UIView] { get } +extension UIView { - func showSkeletons() - func hideSkeletons() - func startAnimation() - func stopAnimation() -} - -// MARK: - SkeletonsPresenter + Default implemetation - -extension SkeletonsPresenter { - - public var skeletonsConfiguration: SkeletonsConfiguration { - SkeletonsConfiguration() + @objc open var baseView: UIView? { + self } - public func showSkeletons() { + @objc open var isSkeletonsHidden: Bool { + (layer.sublayers ?? []).first { $0 is SkeletonLayer } == nil + } + + @objc open var viewsToSkeletone: [UIView] { + skeletonableViews + } + + // MARK: - Public methods + + public func showSkeletons(_ config: SkeletonsConfiguration = .init(), + viewsToSkeletone: [UIView]? = nil) { + guard let baseView = baseView else { return } + let viewsToSkeletone = viewsToSkeletone ?? self.viewsToSkeletone + baseView.isUserInteractionEnabled = false viewsToSkeletone .flatMap { view in view.isHidden = true - return getSkeletonLayer(forView: view) + return getSkeletonLayer(forView: view, withConfiguration: config) } .map { layer in layer.startAnimation() @@ -64,7 +64,7 @@ extension SkeletonsPresenter { } public func hideSkeletons() { - guard let baseView = baseView else { + guard let baseView = baseView ?? nil else { return } @@ -95,17 +95,19 @@ extension SkeletonsPresenter { // MARK: - Private methods - private func getSkeletonLayer(forView view: UIView) -> [SkeletonLayer] { - let skeletonLayer = skeletonsConfiguration.createSkeletonLayer(for: baseView) + private func getSkeletonLayer(forView view: UIView, + withConfiguration conf: SkeletonsConfiguration) -> [SkeletonLayer] { + + let skeletonLayer = conf.createSkeletonLayer(for: baseView) var subviewSkeletonLayers = [SkeletonLayer]() if view.isSkeletonsContainer { - if skeletonsConfiguration.borderWidth != .zero { + if conf.borderWidth != .zero { skeletonLayer.bind(to: .container(view)) } subviewSkeletonLayers = view.skeletonableViews - .map(getSkeletonLayer(forView:)) + .map { getSkeletonLayer(forView: $0, withConfiguration: conf) } .flatMap { $0 } } else { @@ -116,38 +118,6 @@ extension SkeletonsPresenter { } } -// MARK: - UIView + SkeletonsPresenter - -extension SkeletonsPresenter where Self: UIView { - public var baseView: UIView? { - self - } - - public var isSkeletonsHidden: Bool { - (layer.sublayers ?? []).first { $0 is SkeletonLayer } == nil - } - - public var viewsToSkeletone: [UIView] { - skeletonableViews - } -} - -// MARK: - UIViewController + SkeletonsPresenter - -extension SkeletonsPresenter where Self: UIViewController { - public var baseView: UIView? { - view - } - - public var isSkeletonsHidden: Bool { - (view.layer.sublayers ?? []).first { $0 is SkeletonLayer } == nil - } - - public var viewsToSkeletone: [UIView] { - baseView?.skeletonableViews ?? view.skeletonableViews - } -} - // MARK: - Helper extension extension Array where Element: CALayer { diff --git a/TIUIElements/Sources/Views/Skeletons/UIView+PresetingSkeletons.swift b/TIUIElements/Sources/Views/Skeletons/UIView+PresetingSkeletons.swift new file mode 100644 index 00000000..11d2ff8a --- /dev/null +++ b/TIUIElements/Sources/Views/Skeletons/UIView+PresetingSkeletons.swift @@ -0,0 +1,8 @@ +// +// File.swift +// +// +// Created by Nikita Semenov on 07.03.2023. +// + +import Foundation diff --git a/TIUIElements/Sources/Views/Skeletons/UIViewController+PresentingSkeletons.swift b/TIUIElements/Sources/Views/Skeletons/UIViewController+PresentingSkeletons.swift new file mode 100644 index 00000000..48a9d031 --- /dev/null +++ b/TIUIElements/Sources/Views/Skeletons/UIViewController+PresentingSkeletons.swift @@ -0,0 +1,53 @@ +// +// 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 UIViewController { + @objc open var baseView: UIView? { + view + } + + @objc open var isSkeletonsHidden: Bool { + (view.layer.sublayers ?? []).first { $0 is SkeletonLayer } == nil + } + + @objc open var viewsToSkeletone: [UIView] { + baseView?.skeletonableViews ?? view.skeletonableViews + } + + public func showSkeletons(_ conf: SkeletonsConfiguration = .init()) { + baseView?.showSkeletons(conf, viewsToSkeletone: viewsToSkeletone) + } + + public func hideSkeletons() { + baseView?.hideSkeletons() + } + + public func startAnimation() { + baseView?.startAnimation() + } + + public func stopAnimation() { + baseView?.stopAnimation() + } +}