Compare commits

...

9 Commits

Author SHA1 Message Date
Juanpe Catalán 8448a53b79 feat: updated podspec file 2017-11-22 20:56:09 +01:00
Juanpe Catalán 42f0886c77 feat: update README file to include latest changes 2017-11-22 20:54:12 +01:00
Juanpe Catalán 4e63a2a1e3 feat: added filling percent to last line in elements with multilines 2017-11-22 20:39:37 +01:00
Juanpe Catalán 9523446c53 fix: issue #14 2017-11-22 20:36:12 +01:00
Juanpe Catalán dd66df733c Merge pull request #11 from jontelang/multiline-last-line-shorter
feat: making the last line in a skeleton-text-view shorter [step 1]
2017-11-22 19:44:43 +01:00
Juanpe Catalán 8021f1260b feat: updated README file to add a new demo app image 2017-11-22 09:16:50 +01:00
Juanpe Catalán 3f3b4f498b feat: updated example project 2017-11-22 09:13:58 +01:00
Juanpe Catalán 6a07b423a9 feat: added example app to show a rounded view 2017-11-22 09:12:16 +01:00
Jonathan Winger Lang 6bd03081d6 Add config to enable / disable making the last line in a skeleton-text-view shorter 2017-11-20 18:29:02 +07:00
17 changed files with 85 additions and 15 deletions
Binary file not shown.

Before

Width:  |  Height:  |  Size: 200 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 46 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 31 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 164 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 176 KiB

+1 -1
View File
@@ -15,7 +15,7 @@
<key>CFBundlePackageType</key>
<string>FMWK</string>
<key>CFBundleShortVersionString</key>
<string>1.0.3</string>
<string>1.0.4</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.0.3</string>
<string>1.0.4</string>
<key>CFBundleVersion</key>
<string>1</string>
<key>LSRequiresIPhoneOS</key>
+5 -1
View File
@@ -96,6 +96,9 @@
<textInputTraits key="textInputTraits" autocapitalizationType="sentences"/>
<userDefinedRuntimeAttributes>
<userDefinedRuntimeAttribute type="boolean" keyPath="isSkeletonable" value="YES"/>
<userDefinedRuntimeAttribute type="number" keyPath="lastLineFillPercent">
<integer key="value" value="40"/>
</userDefinedRuntimeAttribute>
</userDefinedRuntimeAttributes>
</textView>
<imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="avatar" translatesAutoresizingMaskIntoConstraints="NO" id="nMj-pU-5wJ">
@@ -195,6 +198,7 @@
</view>
<navigationItem key="navigationItem" id="BEI-dU-kr2"/>
<connections>
<outlet property="avatarImage" destination="nMj-pU-5wJ" id="9fa-Z7-vYi"/>
<outlet property="colorSelectedView" destination="iGp-rp-t1d" id="0Zm-9d-jRU"/>
<outlet property="skeletonTypeSelector" destination="xOL-Sq-r4i" id="yTr-8L-I4Y"/>
<outlet property="switchAnimated" destination="vz0-qg-GcZ" id="d2R-8x-lRb"/>
@@ -203,7 +207,7 @@
</viewController>
<placeholder placeholderIdentifier="IBFirstResponder" id="dkx-z0-nzr" sceneMemberID="firstResponder"/>
</objects>
<point key="canvasLocation" x="-594.39999999999998" y="85.007496251874073"/>
<point key="canvasLocation" x="-482" y="-6"/>
</scene>
</scenes>
<resources>
+8
View File
@@ -14,6 +14,14 @@ let colors = [(UIColor.turquoise,"turquoise"), (UIColor.emerald,"emerald"), (UIC
class ViewController: UIViewController {
@IBOutlet weak var tableview: UITableView!
@IBOutlet weak var avatarImage: UIImageView! {
didSet {
avatarImage.layer.cornerRadius = avatarImage.frame.width/2
avatarImage.layer.masksToBounds = true
}
}
@IBOutlet weak var colorSelectedView: UIView! {
didSet {
colorSelectedView.layer.cornerRadius = 5
+14 -2
View File
@@ -65,7 +65,7 @@ Enjoy it! 🙂
To run the example project, clone the repo and run `SkeletonViewExample` target.
![](Assets/demoApp.png)
![](Assets/demoApp2.png)
## 📲 Installation
@@ -192,11 +192,23 @@ There is only one method you need to implement to let Skeleton know the cell ide
### 📰 Multiline text
![](Assets/multilines.png)
![](Assets/multilines2.png)
When using elements with text, ```SkeletonView``` draws lines to simulate text.
Besides, you can decide how many lines you want. If ```numberOfLines``` is set to zero, it will calculate how many lines needed to populate the whole skeleton and it will be drawn. Instead, if you set it to one, two or any number greater than zero, it will only draw this number of lines.
**NEW** Now, you can set the filling percent of the last line. **Default: 80%**
To modify the percent **using code**, set the property:
```swift
descriptionTextView.lastLineFillPercent = 50
```
Or, if you prefer use **IB/Storyboard**:
![](Assets/lastline_storyboard.png)
### 🎨 Custom colors
You can decide which color the skeleton is tinted with. You only need to pass as a parameter the color or gradient you want.
+1 -1
View File
@@ -1,6 +1,6 @@
Pod::Spec.new do |s|
s.name = "SkeletonView"
s.version = "1.0.3"
s.version = "1.0.4"
s.summary = "An elegant way to show users that something is happening and also prepare them to which contents he is waiting"
s.description = <<-DESC
Today almost all apps have async processes, as API requests, long runing processes, etc. And while the processes are working, usually developers place a loading view to show users that something is going on.
+8 -2
View File
@@ -36,10 +36,16 @@ extension CALayer {
return sublayers?.filter { $0.name == CALayer.skeletonSubLayersName } ?? [CALayer]()
}
func addMultilinesLayers(lines: Int, type: SkeletonType) {
func addMultilinesLayers(lines: Int, type: SkeletonType, lastLineFillPercent: Int) {
let numberOfSublayers = calculateNumLines(maxLines: lines)
for index in 0..<numberOfSublayers {
let layer = SkeletonLayerFactory().makeMultilineLayer(withType: type, for: index, width: Int(bounds.width))
var width = bounds.width
if index == numberOfSublayers-1 && numberOfSublayers != 1 {
width = width * CGFloat(lastLineFillPercent)/100;
}
let layer = SkeletonLayerFactory().makeMultilineLayer(withType: type, for: index, width: width)
addSublayer(layer)
}
}
+35 -1
View File
@@ -8,17 +8,51 @@
import UIKit
private enum AssociatedKeys {
static var lastLineFillingPercent = "lastLineFillingPercent"
}
protocol ContainsMultilineText {
var numLines: Int { get }
var lastLineFillingPercent: Int { get }
}
extension ContainsMultilineText {
var numLines: Int { return 0 }
}
public extension UILabel {
@IBInspectable
var lastLineFillPercent: Int {
get { return lastLineFillingPercent }
set { lastLineFillingPercent = min(newValue, 100) }
}
}
public extension UITextView {
@IBInspectable
var lastLineFillPercent: Int {
get { return lastLineFillingPercent }
set { lastLineFillingPercent = min(newValue, 100) }
}
}
extension UILabel: ContainsMultilineText {
var numLines: Int {
return numberOfLines
}
var lastLineFillingPercent: Int {
get { return objc_getAssociatedObject(self, &AssociatedKeys.lastLineFillingPercent) as? Int ?? SkeletonDefaultConfig.multilineLastLineFillPercent }
set { objc_setAssociatedObject(self, &AssociatedKeys.lastLineFillingPercent, newValue, AssociationPolicy.retain.objc) }
}
}
extension UITextView: ContainsMultilineText {
var lastLineFillingPercent: Int {
get { return objc_getAssociatedObject(self, &AssociatedKeys.lastLineFillingPercent) as? Int ?? SkeletonDefaultConfig.multilineLastLineFillPercent }
set { objc_setAssociatedObject(self, &AssociatedKeys.lastLineFillingPercent, newValue, AssociationPolicy.retain.objc) }
}
}
extension UITextView: ContainsMultilineText {}
@@ -15,12 +15,14 @@ protocol PrepareForSkeleton {
extension UILabel: PrepareForSkeleton {
func prepareViewForSkeleton() {
text = nil
resignFirstResponder()
}
}
extension UITextView: PrepareForSkeleton {
func prepareViewForSkeleton() {
text = nil
resignFirstResponder()
}
}
+4 -2
View File
@@ -14,7 +14,9 @@ public enum SkeletonDefaultConfig {
public static let gradient = SkeletonGradient(baseColor: tintColor)
public static let multilineHeight = 15
public static let multilineHeight: CGFloat = 15
public static let multilineSpacing = 10
public static let multilineSpacing: CGFloat = 10
public static let multilineLastLineFillPercent = 70
}
+4 -4
View File
@@ -14,12 +14,12 @@ class SkeletonLayerFactory {
return SkeletonLayer(withType: type, usingColors: colors, andSkeletonHolder: holder)
}
func makeMultilineLayer(withType type: SkeletonType, for index: Int, width: Int) -> CALayer {
let spaceRequitedForEachLine = SkeletonDefaultConfig.multilineHeight + SkeletonDefaultConfig.multilineSpacing
func makeMultilineLayer(withType type: SkeletonType, for index: Int, width: CGFloat) -> CALayer {
let spaceRequiredForEachLine = SkeletonDefaultConfig.multilineHeight + SkeletonDefaultConfig.multilineSpacing
let layer = type.layer
layer.anchorPoint = .zero
layer.name = CALayer.skeletonSubLayersName
layer.frame = CGRect(x: 0, y: (index * spaceRequitedForEachLine), width: width, height: SkeletonDefaultConfig.multilineHeight)
layer.frame = CGRect(x: 0.0, y: CGFloat(index) * spaceRequiredForEachLine, width: width, height: SkeletonDefaultConfig.multilineHeight)
return layer
}
}
@@ -77,7 +77,7 @@ struct SkeletonLayer {
func addMultilinesIfNeeded() {
guard let multiLineView = holder as? ContainsMultilineText else { return }
maskLayer.addMultilinesLayers(lines: multiLineView.numLines, type: type)
maskLayer.addMultilinesLayers(lines: multiLineView.numLines, type: type, lastLineFillPercent: multiLineView.lastLineFillingPercent)
}
}
+2
View File
@@ -28,6 +28,7 @@ public extension UIView {
func hideSkeleton(reloadDataAfter reload: Bool = true) {
removeDummyDataSourceIfNeeded(reloadAfter: reload)
isUserInteractionEnabled = true
recursiveSearch(inArray: subviewsSkeletonables,
leafBlock: { removeSkeletonLayer() },
recursiveBlock: {
@@ -57,6 +58,7 @@ extension UIView {
recursiveSearch(inArray: subviewsSkeletonables,
leafBlock: {
guard !isSkeletonActive else { return }
isUserInteractionEnabled = false
(self as? PrepareForSkeleton)?.prepareViewForSkeleton()
addSkeletonLayer(withType: type, usingColors: colors, animated: animated, animation: animation)
}) {