feat: Create SkeletonViewAppearance

This commit is contained in:
Juanpe Catalán
2018-08-02 16:18:41 +02:00
parent 3bf613da0d
commit 804390e98a
13 changed files with 88 additions and 60 deletions
+1 -1
View File
@@ -15,7 +15,7 @@
<key>CFBundlePackageType</key>
<string>FMWK</string>
<key>CFBundleShortVersionString</key>
<string>1.2.1</string>
<string>1.3</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
+1 -1
View File
@@ -15,7 +15,7 @@
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>CFBundleShortVersionString</key>
<string>1.2.1</string>
<string>1.3</string>
<key>CFBundleVersion</key>
<string>1</string>
<key>LSRequiresIPhoneOS</key>
@@ -36,7 +36,7 @@ class ViewController: UIViewController {
didSet {
colorSelectedView.layer.cornerRadius = 5
colorSelectedView.layer.masksToBounds = true
colorSelectedView.backgroundColor = SkeletonConfig.shared.tintColor
colorSelectedView.backgroundColor = SkeletonView.appearance.defaultTintColor
}
}
+1 -1
View File
@@ -29,7 +29,7 @@ class ViewController: UIViewController {
didSet {
colorSelectedView.layer.cornerRadius = 5
colorSelectedView.layer.masksToBounds = true
colorSelectedView.backgroundColor = SkeletonConfig.shared.tintColor
colorSelectedView.backgroundColor = SkeletonView.appearance.defaultTintColor
}
}
+4 -6
View File
@@ -39,7 +39,7 @@
42ABD07B210B54E200BEEFF4 /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 42ABD073210B54E100BEEFF4 /* ViewController.swift */; };
42ABD07C210B54E200BEEFF4 /* Base.lproj in Resources */ = {isa = PBXBuildFile; fileRef = 42ABD074210B54E100BEEFF4 /* Base.lproj */; };
42ABD07D210B54E200BEEFF4 /* Constants.swift in Sources */ = {isa = PBXBuildFile; fileRef = 42ABD075210B54E100BEEFF4 /* Constants.swift */; };
42ABD07E210B54E200BEEFF4 /* Info.plist in Resources */ = {isa = PBXBuildFile; fileRef = 42ABD076210B54E200BEEFF4 /* Info.plist */; };
42ABD07E210B54E200BEEFF4 /* SkeletonViewExampleCollectionview-Info.plist in Resources */ = {isa = PBXBuildFile; fileRef = 42ABD076210B54E200BEEFF4 /* SkeletonViewExampleCollectionview-Info.plist */; };
42ABD07F210B54E200BEEFF4 /* CollectionViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 42ABD077210B54E200BEEFF4 /* CollectionViewCell.swift */; };
8748240D20C6A88A00E92179 /* UIView+IBInspectable.swift in Headers */ = {isa = PBXBuildFile; fileRef = F5F899CF1FAA6A4D002E8FDA /* UIView+IBInspectable.swift */; settings = {ATTRIBUTES = (Public, ); }; };
8748240E20C6A88E00E92179 /* ContainsMultilineText.swift in Headers */ = {isa = PBXBuildFile; fileRef = F5307E3A1FB123C100EE67C5 /* ContainsMultilineText.swift */; settings = {ATTRIBUTES = (Public, ); }; };
@@ -137,14 +137,13 @@
3B83EE4520C41488005178A4 /* ContainsMultilineText.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = ContainsMultilineText.swift; path = Sources/Helpers/ContainsMultilineText.swift; sourceTree = "<group>"; };
3B83EE4620C41488005178A4 /* UIView+IBInspectable.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = "UIView+IBInspectable.swift"; path = "Sources/Extensions/UIView+IBInspectable.swift"; sourceTree = "<group>"; };
42ABD06D210B548200BEEFF4 /* SkeletonViewExampleUICollectionView.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = SkeletonViewExampleUICollectionView.app; sourceTree = BUILT_PRODUCTS_DIR; };
42ABD06E210B548200BEEFF4 /* SkeletonViewExample copy-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; name = "SkeletonViewExample copy-Info.plist"; path = "/Users/andreihogea/Skeleton/SkeletonView/SkeletonViewExample copy-Info.plist"; sourceTree = "<absolute>"; };
42ABD070210B54E100BEEFF4 /* AppDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = "<group>"; };
42ABD071210B54E100BEEFF4 /* Main.storyboard */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.storyboard; path = Main.storyboard; sourceTree = "<group>"; };
42ABD072210B54E100BEEFF4 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = "<group>"; };
42ABD073210B54E100BEEFF4 /* ViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ViewController.swift; sourceTree = "<group>"; };
42ABD074210B54E100BEEFF4 /* Base.lproj */ = {isa = PBXFileReference; lastKnownFileType = folder; path = Base.lproj; sourceTree = "<group>"; };
42ABD075210B54E100BEEFF4 /* Constants.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Constants.swift; sourceTree = "<group>"; };
42ABD076210B54E200BEEFF4 /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
42ABD076210B54E200BEEFF4 /* SkeletonViewExampleCollectionview-Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = "SkeletonViewExampleCollectionview-Info.plist"; sourceTree = "<group>"; };
42ABD077210B54E200BEEFF4 /* CollectionViewCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CollectionViewCell.swift; sourceTree = "<group>"; };
52D6D97C1BEFF229002C0205 /* SkeletonView.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = SkeletonView.framework; sourceTree = BUILT_PRODUCTS_DIR; };
88DEA97D1FCDBD1F006C80EF /* Constants.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Constants.swift; sourceTree = "<group>"; };
@@ -228,7 +227,6 @@
42ABD074210B54E100BEEFF4 /* Base.lproj */,
42ABD077210B54E200BEEFF4 /* CollectionViewCell.swift */,
42ABD075210B54E100BEEFF4 /* Constants.swift */,
42ABD076210B54E200BEEFF4 /* Info.plist */,
42ABD071210B54E100BEEFF4 /* Main.storyboard */,
42ABD073210B54E100BEEFF4 /* ViewController.swift */,
);
@@ -246,7 +244,6 @@
52D6D99C1BEFF38C002C0205 /* Configs */,
52D6D97D1BEFF229002C0205 /* Products */,
F5F89A041FABA614002E8FDA /* Frameworks */,
42ABD06E210B548200BEEFF4 /* SkeletonViewExample copy-Info.plist */,
);
sourceTree = "<group>";
};
@@ -394,6 +391,7 @@
F5F89A061FABA725002E8FDA /* Example */ = {
isa = PBXGroup;
children = (
42ABD076210B54E200BEEFF4 /* SkeletonViewExampleCollectionview-Info.plist */,
F5F89A001FABA607002E8FDA /* SkeletonViewExampleInfo.plist */,
);
name = Example;
@@ -560,7 +558,7 @@
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
files = (
42ABD07E210B54E200BEEFF4 /* Info.plist in Resources */,
42ABD07E210B54E200BEEFF4 /* SkeletonViewExampleCollectionview-Info.plist in Resources */,
42ABD07A210B54E200BEEFF4 /* Assets.xcassets in Resources */,
42ABD07C210B54E200BEEFF4 /* Base.lproj in Resources */,
42ABD079210B54E200BEEFF4 /* Main.storyboard in Resources */,
@@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>FILEHEADER</key>
<string> ___COPYRIGHT___</string>
</dict>
</plist>
+1 -1
View File
@@ -15,7 +15,7 @@
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>CFBundleShortVersionString</key>
<string>1.2.1</string>
<string>1.3</string>
<key>CFBundleVersion</key>
<string>1</string>
<key>LSRequiresIPhoneOS</key>
+1 -1
View File
@@ -51,7 +51,7 @@ extension CALayer {
}
private func calculateNumLines(maxLines: Int) -> Int {
let spaceRequitedForEachLine = SkeletonConfig.shared.multilineHeight + SkeletonConfig.shared.multilineSpacing
let spaceRequitedForEachLine = SkeletonView.appearance.multilineHeight + SkeletonView.appearance.multilineSpacing
var numberOfSublayers = Int(round(CGFloat(bounds.height)/CGFloat(spaceRequitedForEachLine)))
if maxLines != 0, maxLines <= numberOfSublayers { numberOfSublayers = maxLines }
return numberOfSublayers
+4 -4
View File
@@ -59,11 +59,11 @@ extension UILabel: ContainsMultilineText {
}
var lastLineFillingPercent: Int {
get { return objc_getAssociatedObject(self, &AssociatedKeys.lastLineFillingPercent) as? Int ?? SkeletonConfig.shared.multilineLastLineFillPercent }
get { return objc_getAssociatedObject(self, &AssociatedKeys.lastLineFillingPercent) as? Int ?? SkeletonView.appearance.multilineLastLineFillPercent }
set { objc_setAssociatedObject(self, &AssociatedKeys.lastLineFillingPercent, newValue, AssociationPolicy.retain.objc) }
}
var multilineCornerRadius: Int {
get { return objc_getAssociatedObject(self, &AssociatedKeys.multilineCornerRadius) as? Int ?? SkeletonConfig.shared.multilineCornerRadius }
get { return objc_getAssociatedObject(self, &AssociatedKeys.multilineCornerRadius) as? Int ?? SkeletonView.appearance.multilineCornerRadius }
set { objc_setAssociatedObject(self, &AssociatedKeys.multilineCornerRadius, newValue, AssociationPolicy.retain.objc) }
}
@@ -71,12 +71,12 @@ extension UILabel: ContainsMultilineText {
extension UITextView: ContainsMultilineText {
var lastLineFillingPercent: Int {
get { return objc_getAssociatedObject(self, &AssociatedKeys.lastLineFillingPercent) as? Int ?? SkeletonConfig.shared.multilineLastLineFillPercent }
get { return objc_getAssociatedObject(self, &AssociatedKeys.lastLineFillingPercent) as? Int ?? SkeletonView.appearance.multilineLastLineFillPercent }
set { objc_setAssociatedObject(self, &AssociatedKeys.lastLineFillingPercent, newValue, AssociationPolicy.retain.objc) }
}
var multilineCornerRadius: Int {
get { return objc_getAssociatedObject(self, &AssociatedKeys.multilineCornerRadius) as? Int ?? SkeletonConfig.shared.multilineCornerRadius }
get { return objc_getAssociatedObject(self, &AssociatedKeys.multilineCornerRadius) as? Int ?? SkeletonView.appearance.multilineCornerRadius }
set { objc_setAssociatedObject(self, &AssociatedKeys.multilineCornerRadius, newValue, AssociationPolicy.retain.objc) }
}
}
+56 -32
View File
@@ -1,37 +1,61 @@
//
// SkeletonConfig.shared.swift
// SkeletonView-iOS
//
// Created by Juanpe Catalán on 06/11/2017.
// Copyright © 2017 SkeletonView. All rights reserved.
//
import UIKit
public struct SkeletonConfig {
// MARK: - Defaults
public static var shared = SkeletonConfig(
tintColor: .clouds,
gradient: SkeletonGradient(baseColor: .clouds),
multilineHeight: 15,
multilineSpacing: 10,
multilineLastLineFillPercent: 70,
multilineCornerRadius: 0
)
// MARK: - Properties
public var tintColor: UIColor
public var gradient: SkeletonGradient
public var multilineHeight: CGFloat
public var multilineSpacing: CGFloat
public var multilineLastLineFillPercent: Int
public var multilineCornerRadius: Int
public protocol SkeletonAppearance {
var defaultTintColor: UIColor { get set }
var defaultGradient: SkeletonGradient { get set }
var multilineHeight: CGFloat { get set }
var multilineSpacing: CGFloat { get set }
var multilineLastLineFillPercent: Int { get set }
var multilineCornerRadius: Int { get set }
}
public protocol Customizable {
static var appearance: SkeletonAppearance { get }
}
class SkeletonViewAppearance: SkeletonAppearance {
static var shared = SkeletonViewAppearance()
var defaultTintColor: UIColor = .clouds
var defaultGradient: SkeletonGradient = SkeletonGradient(baseColor: .clouds)
var multilineHeight: CGFloat = 15
var multilineSpacing: CGFloat = 10
var multilineLastLineFillPercent: Int = 70
var multilineCornerRadius: Int = 0
}
//public struct SkeletonConfig {
//
// // MARK: - Defaults
//
// public static var shared = SkeletonConfig(
// tintColor: .clouds,
// gradient: SkeletonGradient(baseColor: .clouds),
// multilineHeight: 15,
// multilineSpacing: 10,
// multilineLastLineFillPercent: 70,
// multilineCornerRadius: 0
// )
//
// // MARK: - Properties
//
// public var tintColor: UIColor
//
// public var gradient: SkeletonGradient
//
// public var multilineHeight: CGFloat
//
// public var multilineSpacing: CGFloat
//
// public var multilineLastLineFillPercent: Int
//
// public var multilineCornerRadius: Int
//}
+2 -2
View File
@@ -15,11 +15,11 @@ class SkeletonLayerFactory {
}
func makeMultilineLayer(withType type: SkeletonType, for index: Int, width: CGFloat, multilineCornerRadius: Int) -> CALayer {
let spaceRequiredForEachLine = SkeletonConfig.shared.multilineHeight + SkeletonConfig.shared.multilineSpacing
let spaceRequiredForEachLine = SkeletonView.appearance.multilineHeight + SkeletonView.appearance.multilineSpacing
let layer = type.layer
layer.anchorPoint = .zero
layer.name = CALayer.skeletonSubLayersName
layer.frame = CGRect(x: 0.0, y: CGFloat(index) * spaceRequiredForEachLine, width: width, height: SkeletonConfig.shared.multilineHeight)
layer.frame = CGRect(x: 0.0, y: CGFloat(index) * spaceRequiredForEachLine, width: width, height: SkeletonView.appearance.multilineHeight)
layer.cornerRadius = CGFloat(multilineCornerRadius)
layer.masksToBounds = true
+8 -10
View File
@@ -1,28 +1,26 @@
//
// SkeletonView.swift
// SkeletonView
//
// Created by Juanpe Catalán on 01/11/2017.
// Copyright © 2017 SkeletonView. All rights reserved.
//
import UIKit
public enum SkeletonView: Customizable {
public static var appearance: SkeletonAppearance = SkeletonViewAppearance.shared
}
public extension UIView {
func showSkeleton(usingColor color: UIColor = SkeletonConfig.shared.tintColor) {
func showSkeleton(usingColor color: UIColor = SkeletonView.appearance.defaultTintColor) {
showSkeleton(withType: .solid, usingColors: [color])
}
func showGradientSkeleton(usingGradient gradient: SkeletonGradient = SkeletonConfig.shared.gradient) {
func showGradientSkeleton(usingGradient gradient: SkeletonGradient = SkeletonView.appearance.defaultGradient) {
showSkeleton(withType: .gradient, usingColors: gradient.colors)
}
func showAnimatedSkeleton(usingColor color: UIColor = SkeletonConfig.shared.tintColor, animation: SkeletonLayerAnimation? = nil) {
func showAnimatedSkeleton(usingColor color: UIColor = SkeletonView.appearance.defaultTintColor, animation: SkeletonLayerAnimation? = nil) {
showSkeleton(withType: .solid, usingColors: [color], animated: true, animation: animation)
}
func showAnimatedGradientSkeleton(usingGradient gradient: SkeletonGradient = SkeletonConfig.shared.gradient, animation: SkeletonLayerAnimation? = nil) {
func showAnimatedGradientSkeleton(usingGradient gradient: SkeletonGradient = SkeletonView.appearance.defaultGradient, animation: SkeletonLayerAnimation? = nil) {
showSkeleton(withType: .gradient, usingColors: gradient.colors, animated: true, animation: animation)
}