Git Product home page Git Product logo

skeletonview's Introduction

codebeat badge SkeletonView Playground

FeaturesGuidesInstallationUsageMiscellaneousContributing

🌎 README is available in other languages: 🇪🇸 . 🇨🇳 . 🇧🇷 . 🇰🇷 . 🇫🇷 . 🇩🇪

Today almost all apps have async processes, such as API requests, long running processes, etc. While the processes are working, usually developers place a loading view to show users that something is going on.

SkeletonView has been conceived to address this need, an elegant way to show users that something is happening and also prepare them for which contents are waiting.

Enjoy it! 🙂

🌟 Features

  • Easy to use
  • All UIViews are skeletonables
  • Fully customizable
  • Universal (iPhone & iPad)
  • Interface Builder friendly
  • Simple Swift syntax
  • Lightweight readable codebase

🎬 Guides

SkeletonView Guides - Getting started How to Create Loading View with Skeleton View in Swift 5.2 by iKh4ever Studio Create Skeleton Loading View in App (Swift 5) - Xcode 11, 2020 by iOS Academy Cómo crear una ANIMACIÓN de CARGA de DATOS en iOS by MoureDev

📲 Installation

pod 'SkeletonView'
github "Juanpe/SkeletonView"
dependencies: [
  .package(url: "https://github.com/Juanpe/SkeletonView.git", from: "1.7.0")
]

📣 IMPORTANT!

Since version 1.30.0, SkeletonView supports XCFrameworks, so if you want to install it as a XCFramework, please use this repo instead.

🐒 Usage

Only 3 steps needed to use SkeletonView:

1️⃣ Import SkeletonView in proper place.

import SkeletonView

2️⃣ Now, set which views will be skeletonables. You achieve this in two ways:

Using code:

avatarImageView.isSkeletonable = true

Using IB/Storyboards:

3️⃣ Once you've set the views, you can show the skeleton. To do so, you have 4 choices:

(1) view.showSkeleton()                 // Solid
(2) view.showGradientSkeleton()         // Gradient
(3) view.showAnimatedSkeleton()         // Solid animated
(4) view.showAnimatedGradientSkeleton() // Gradient animated

Preview

Solid Gradient Solid Animated Gradient Animated

📣 IMPORTANT!

SkeletonView is recursive, so if you want show the skeleton in all skeletonable views, you only need to call the show method in the main container view. For example, with UIViewControllers.

🌿 Collections

SkeletonView is compatible with UITableView and UICollectionView.

UITableView

If you want to show the skeleton in a UITableView, you need to conform to SkeletonTableViewDataSource protocol.

public protocol SkeletonTableViewDataSource: UITableViewDataSource {
    func numSections(in collectionSkeletonView: UITableView) -> Int // Default: 1
    func collectionSkeletonView(_ skeletonView: UITableView, numberOfRowsInSection section: Int) -> Int
    func collectionSkeletonView(_ skeletonView: UITableView, cellIdentifierForRowAt indexPath: IndexPath) -> ReusableCellIdentifier
    func collectionSkeletonView(_ skeletonView: UITableView, skeletonCellForRowAt indexPath: IndexPath) -> UITableViewCell? // Default: nil
    func collectionSkeletonView(_ skeletonView: UITableView, prepareCellForSkeleton cell: UITableViewCell, at indexPath: IndexPath)
}

As you can see, this protocol inherits from UITableViewDataSource, so you can replace this protocol with the skeleton protocol.

This protocol has a default implementation for some methods. For example, the number of rows for each section is calculated in runtime:

func collectionSkeletonView(_ skeletonView: UITableView, numberOfRowsInSection section: Int) -> Int
// Default:
// It calculates how many cells need to populate whole tableview

📣 IMPORTANT!

If you return UITableView.automaticNumberOfSkeletonRows in the above method, it acts like the default behavior (i.e. it calculates how many cells needed to populate the whole tableview).

There is only one method you need to implement to let Skeleton know the cell identifier. This method doesn't have default implementation:

func collectionSkeletonView(_ skeletonView: UITableView, cellIdentifierForRowAt indexPath: IndexPath) -> ReusableCellIdentifier {
   return "CellIdentifier"
}

By default, the library dequeues the cells from each indexPath, but you can also do this if you want to make some changes before the skeleton appears:

func collectionSkeletonView(_ skeletonView: UITableView, skeletonCellForRowAt indexPath: IndexPath) -> UITableViewCell? {
    let cell = skeletonView.dequeueReusableCell(withIdentifier: "CellIdentifier", for: indexPath) as? Cell
    cell?.textField.isHidden = indexPath.row == 0
    return cell
}

If you prefer to leave the deque part to the library you can configure the cell using this method:

func collectionSkeletonView(_ skeletonView: UITableView, prepareCellForSkeleton cell: UITableViewCell, at indexPath: IndexPath) {
    let cell = cell as? Cell
    cell?.textField.isHidden = indexPath.row == 0
}

Besides, you can skeletonize both the headers and footers. You need to conform to SkeletonTableViewDelegate protocol.

public protocol SkeletonTableViewDelegate: UITableViewDelegate {
    func collectionSkeletonView(_ skeletonView: UITableView, identifierForHeaderInSection section: Int) -> ReusableHeaderFooterIdentifier? // default: nil
    func collectionSkeletonView(_ skeletonView: UITableView, identifierForFooterInSection section: Int) -> ReusableHeaderFooterIdentifier? // default: nil
}

📣 IMPORTANT!

1️⃣ If you are using resizable cells (tableView.rowHeight = UITableViewAutomaticDimension), it's mandatory define the estimatedRowHeight.

2️⃣ When you add elements in a UITableViewCell you should add it to contentView and not to the cell directly.

self.contentView.addSubview(titleLabel)          
self.addSubview(titleLabel) 

UICollectionView

For UICollectionView, you need to conform to SkeletonCollectionViewDataSource protocol.

public protocol SkeletonCollectionViewDataSource: UICollectionViewDataSource {
    func numSections(in collectionSkeletonView: UICollectionView) -> Int  // default: 1
    func collectionSkeletonView(_ skeletonView: UICollectionView, numberOfItemsInSection section: Int) -> Int
    func collectionSkeletonView(_ skeletonView: UICollectionView, cellIdentifierForItemAt indexPath: IndexPath) -> ReusableCellIdentifier
    func collectionSkeletonView(_ skeletonView: UICollectionView, supplementaryViewIdentifierOfKind: String, at indexPath: IndexPath) -> ReusableCellIdentifier? // default: nil
    func collectionSkeletonView(_ skeletonView: UICollectionView, skeletonCellForItemAt indexPath: IndexPath) -> UICollectionViewCell?  // default: nil
    func collectionSkeletonView(_ skeletonView: UICollectionView, prepareCellForSkeleton cell: UICollectionViewCell, at indexPath: IndexPath)
    func collectionSkeletonView(_ skeletonView: UICollectionView, prepareViewForSkeleton view: UICollectionReusableView, at indexPath: IndexPath)
}

The rest of the process is the same as UITableView

🔠 Texts

When using elements with text, SkeletonView draws lines to simulate text.

You can set some properties for multilines elements.

Property Type Default Preview
lastLineFillPercent CGFloat 70
linesCornerRadius Int 0
skeletonLineSpacing CGFloat 10
skeletonPaddingInsets UIEdgeInsets .zero
skeletonTextLineHeight SkeletonTextLineHeight .fixed(15)
skeletonTextNumberOfLines SkeletonTextNumberOfLines .inherited

To modify the percent or radius using code, set the properties:

descriptionTextView.lastLineFillPercent = 50
descriptionTextView.linesCornerRadius = 5

Or, if you prefer use IB/Storyboard:


How to define the number of lines?

By default, the number of lines is the same as the value of the numberOfLines property. And, if it's set to zero, it'll calculate how many lines are needed to populate the whole skeleton and draw it.

However, if you want to set a specific number of skeleton lines you can do it by setting the skeletonTextNumberOfLines property. This property has two possible values, inherited which returns numberOfLines value and custom(Int) which returns the specific number of lines specified as the associated value.

For example:

label.skeletonTextNumberOfLines = 3   // .custom(3)

⚠️ DEPRECATED!

useFontLineHeight has been deprecated. You can use skeletonTextLineHeight instead:

descriptionTextView.skeletonTextLineHeight = .relativeToFont

📣 IMPORTANT!

Please note that for views without multiple lines, the single line will be considered as the last line.

🦋 Appearance

The skeletons have a default appearance. So, when you don't specify the color, gradient or multilines properties, SkeletonView uses the default values.

Default values:

  • tintColor: UIColor
    • default: .skeletonDefault (same as .clouds but adaptive to dark mode)
  • gradient: SkeletonGradient
    • default: SkeletonGradient(baseColor: .skeletonDefault)
  • multilineHeight: CGFloat
    • default: 15
  • multilineSpacing: CGFloat
    • default: 10
  • multilineLastLineFillPercent: Int
    • default: 70
  • multilineCornerRadius: Int
    • default: 0
  • skeletonCornerRadius: CGFloat (IBInspectable) (Make your skeleton view with corner)
    • default: 0

To get these default values you can use SkeletonAppearance.default. Using this property you can set the values as well:

SkeletonAppearance.default.multilineHeight = 20
SkeletonAppearance.default.tintColor = .green

⚠️ DEPRECATED!

useFontLineHeight has been deprecated. You can use textLineHeight instead:

SkeletonAppearance.default.textLineHeight = .relativeToFont

🎨 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.

Using solid colors

view.showSkeleton(usingColor: UIColor.gray) // Solid
// or
view.showSkeleton(usingColor: UIColor(red: 25.0, green: 30.0, blue: 255.0, alpha: 1.0))

Using gradients

let gradient = SkeletonGradient(baseColor: UIColor.midnightBlue)
view.showGradientSkeleton(usingGradient: gradient) // Gradient

Besides, SkeletonView features 20 flat colors 🤙🏼

UIColor.turquoise, UIColor.greenSea, UIColor.sunFlower, UIColor.flatOrange ...

Image captured from website https://flatuicolors.com

🏃‍♀️ Animations

SkeletonView has two built-in animations, pulse for solid skeletons and sliding for gradients.

Besides, if you want to do your own skeleton animation, it's really easy.

Skeleton provides the showAnimatedSkeleton function which has a SkeletonLayerAnimation closure where you can define your custom animation.

public typealias SkeletonLayerAnimation = (CALayer) -> CAAnimation

You can call the function like this:

view.showAnimatedSkeleton { (layer) -> CAAnimation in
  let animation = CAAnimation()
  // Customize here your animation

  return animation
}

It's available SkeletonAnimationBuilder. It's a builder to make SkeletonLayerAnimation.

Today, you can create sliding animations for gradients, deciding the direction and setting the duration of the animation (default = 1.5s).

// func makeSlidingAnimation(withDirection direction: GradientDirection, duration: CFTimeInterval = 1.5) -> SkeletonLayerAnimation

let animation = SkeletonAnimationBuilder().makeSlidingAnimation(withDirection: .leftToRight)
view.showAnimatedGradientSkeleton(usingGradient: gradient, animation: animation)

GradientDirection is an enum, with theses cases:

Direction Preview
.leftRight
.rightLeft
.topBottom
.bottomTop
.topLeftBottomRight
.bottomRightTopLeft

😉 TRICK!

Exist another way to create sliding animations, just using this shortcut:

let animation = GradientDirection.leftToRight.slidingAnimation()

🏄 Transitions

SkeletonView has built-in transitions to show or hide the skeletons in a smoother way 🤙

To use the transition, simply add the transition parameter to your showSkeleton() or hideSkeleton() function with the transition time, like this:

view.showSkeleton(transition: .crossDissolve(0.25))     //Show skeleton cross dissolve transition with 0.25 seconds fade time
view.hideSkeleton(transition: .crossDissolve(0.25))     //Hide skeleton cross dissolve transition with 0.25 seconds fade time

The default value is crossDissolve(0.25)

Preview

None Cross dissolve

✨ Miscellaneous

Hierarchy

Since SkeletonView is recursive, and we want skeleton to be very efficient, we want to stop recursion as soon as possible. For this reason, you must set the container view as Skeletonable, because Skeleton will stop looking for skeletonable subviews as soon as a view is not Skeletonable, breaking then the recursion.

Because an image is worth a thousand words:

In this example we have a UIViewController with a ContainerView and a UITableView. When the view is ready, we show the skeleton using this method:

view.showSkeleton()

isSkeletonable= ☠️

Configuration Result

Skeleton views layout

Sometimes skeleton layout may not fit your layout because the parent view bounds have changed. For example, rotating the device.

You can relayout the skeleton views like so:

override func viewDidLayoutSubviews() {
    view.layoutSkeletonIfNeeded()
}

📣 IMPORTANT!

You shouldn't call this method. From version 1.8.1 you don't need to call this method, the library does automatically. So, you can use this method ONLY in the cases when you need to update the layout of the skeleton manually.

Update skeleton

You can change the skeleton configuration at any time like its colour, animation, etc. with the following methods:

(1) view.updateSkeleton()                 // Solid
(2) view.updateGradientSkeleton()         // Gradient
(3) view.updateAnimatedSkeleton()         // Solid animated
(4) view.updateAnimatedGradientSkeleton() // Gradient animated

Hiding views when the animation starts

Sometimes you wanna hide some view when the animation starts, so there is a quick property that you can use to make this happen:

view.isHiddenWhenSkeletonIsActive = true  // This works only when isSkeletonable = true

Don't modify user interaction when the skeleton is active

By default, the user interaction is disabled for skeletonized items, but if you don't want to modify the user interaction indicator when skeleton is active, you can use the isUserInteractionDisabledWhenSkeletonIsActive property:

view.isUserInteractionDisabledWhenSkeletonIsActive = false  // The view will be active when the skeleton will be active.

Don't use the font line height for the skeleton lines in labels

False to disable skeleton to auto-adjust to font height for a UILabel or UITextView. By default, the skeleton lines height is auto-adjusted to font height to more accurately reflect the text in the label rect rather than using the bounding box.

label.useFontLineHeight = false

Delayed show skeleton

You can delay the presentation of the skeleton if the views update quickly.

func showSkeleton(usingColor: UIColor,
                  animated: Bool,
                  delay: TimeInterval,
                  transition: SkeletonTransitionStyle)
func showGradientSkeleton(usingGradient: SkeletonGradient,
                          animated: Bool,
                          delay: TimeInterval,
                          transition: SkeletonTransitionStyle)

Debug

To facilitate the debug tasks when something is not working fine. SkeletonView has some new tools.

First, UIView has available a property with his skeleton info:

var sk.skeletonTreeDescription: String

Besides, you can activate the new debug mode. You just add the environment variable SKELETON_DEBUG and activate it.

Then, when the skeleton appears, you can see the view hierarchy in the Xcode console.

{ 
  "type" : "UIView", // UITableView, UILabel...
  "isSkeletonable" : true,
  "reference" : "0x000000014751ce30",
  "children" : [
    {
      "type" : "UIView",
      "isSkeletonable" : true,
      "children" : [ ... ],
      "reference" : "0x000000014751cfa0"
    }
  ]
}

Supported OS & SDK Versions

  • iOS 9.0+
  • tvOS 9.0+
  • Swift 5.3

❤️ Contributing

This is an open source project, so feel free to contribute. How?

  • Open an issue.
  • Send feedback via email.
  • Propose your own fixes, suggestions and open a pull request with the changes.

See all contributors

For more information, please read the contributing guidelines.

📢 Mentions

🏆 Sponsors

Open-source projects cannot live long without your help. If you find SkeletonView is useful, please consider supporting this project by becoming a sponsor.

Become a sponsor through GitHub Sponsors ❤️

👨🏻‍💻 Author

Juanpe Catalán

Buy me a coffee

👮🏻 License

MIT License

Copyright (c) 2017 Juanpe Catalán

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.

skeletonview's People

Contributors

ahmedos avatar damien-danglard-cegid avatar darkside999 avatar dependabot[bot] avatar drykun avatar eduardbosch avatar esme-putt avatar guidev avatar harrisonsj avatar hisaac avatar juanpe avatar keshavamurthy1 avatar koooootake avatar literallysofia avatar marisalaneous avatar marshalgeazipp avatar michaelhenry avatar mohn93 avatar nikitskynikita avatar omarjalil avatar paulanatoleclaudot-betclic avatar reececomo avatar rlziii avatar stasmalinovsky avatar techinpark avatar tomcheung avatar wilsongramer avatar wsalim1610 avatar xpereta avatar zigzagg16 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

skeletonview's Issues

Private properties

You are using many private properties in public properties, thus it throws accessibility level error and it won't build.

screen shot 2017-11-09 at 13 16 49

SkeletonView does not work with resizable UITableViewCells

⚠️ Please fill out this template when filing an issue.

What did you do?

  • Import import SkeletonView
  • Conform to SkeletonTableViewDataSource (aka class MyTabViewController : UIViewController, SkeletonTableViewDataSource, UITableViewDelegate { ... })
  • Set myTableView.isSkeletonable = true in viewDidLoad()
  • Set myTableView.rowHeight = UITableViewAutomaticDimension and myTableView.estimatedRowHeight = 414 as I am using a custom UITableViewCell with a UIView in it, containing three UILabels (one multiline, two single line)
  • Return cell identifier in func collectionSkeletonView(_ skeletonView: UITableView, cellIdenfierForRowAt indexPath: IndexPath) -> ReusableCellIdentifier { ... }
  • Call myTableView.showAnimatedSkeleton() before loading data to be displayed, and myTableView.hideSkeleton() after data has been received and myTableView.reloadData() has been called

What did you expect to happen?

The UITableView will show the animated skeleton and then the skeleton will disappear once the data has been loaded

What happened instead?

The UITableView shows a grey background, and the skeleton does not show. After calling myTableView.hideSkeleton(), the every loaded cell's height changes to the value provided inestimatedRowHeight instead of being dynamic.

SkeletonView Environment

SkeletonView version: 1.1
Xcode version: 9.2 (9C40b)
Swift version: 4.0

Custom Tableviewcell

⚠️ Please fill out this template when filing an issue.

🙏🏼 Please check if it already exists other issue related with yours.

What did you do?

I followed the implementation of UITableView

What did you expect to happen?

I'm using a custom tableviewcell. I was expecting to have the skeletonview mimic the layout of my tableviewcell also I created a separate nib for the tableviewcell.

image

What happened instead?

It only animated the whole table while loading the data then disappears when it's done loading.
https://www.dropbox.com/s/o7044yeoi5ka56u/skeletonview.gif?dl=0 (I uploaded a gif to show the behavior)

SkeletonView Environment

SkeletonView version: 1.2
Xcode version: 9.4
Swift version: 4

Problem with UIStackView

What did you do?

I have a UIStackView that contains several labels. I called showSkeleton() on all the labels.

What did you expect to happen?

Each label shows up skeletonized.

What happened instead?

Because SkeletonView sets the text of each label to nil, UIStackView sets the height of each label to 0 and lays them out on top of each other.

SkeletonView Environment

SkeletonView version:
1.0.4
Xcode version:
9.2
Swift version:
4

Recursion working incorrectly

What did you do?

  1. Called showSkeleton() on a view which was not skeletonable, but had skeletonable direct subviews.
  2. Called showSkeleton() on a view which was not skeletonable, and had no skeletonable direct subviews.

What did you expect to happen?

  1. Nothing.
  2. Nothing.

What happened instead?

  1. The subviews where skeletonized even though the Hierarchy documentation claims they shouldn't be.
  2. The view on which I called showSkeleton() was skeletonized.

Steps to reproduce the behavior

Using the example project:

  1. Out of the box, the project is incorrectly configured, but still works. The root view is not marked as skeletonable.
  2. Change all direct subviews of the root view to not be skeletonable. The root view is already not skeletonable. When running the project, the root view is skeletonized.

SkeletonView Environment

SkeletonView version:
1.0.4
Xcode version:
9.2
Swift version:
4

CollectionView with multiple cell types

Hi,

I have a UICollectionViewController that uses multiple cell types to build the final result.

What i do is to register each cell to the collection view like below:

private let defaultCellId = "cellIdDefault"
private let typeACellId = "cellIdA"

collectionView?.register(DefaultCell.self, forCellWithReuseIdentifier: defaultCellId)
collectionView?.register(TypeACell.self, forCellWithReuseIdentifier: typeACellId)

The data is received by performing a GET request to my server. Using a parameter in the respone i can tell which cell type i should display. Then:

override func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
    if cellType == ... {
        return collectionView.dequeueReusableCell(withReuseIdentifier: typeACellId, for: indexPath) as! TypeACell

    }

    if cellType == ... {
        return collectionView.dequeueReusableCell(withReuseIdentifier: defaultCellId, for: indexPath) as! DefaultTypeCell

    }
}

And this is working just fine, rendering the correct type of cell.

Reading your documentation I couldn't find a way to let SkeletonView know the cell identifier of a set of cells. As i understand i can only use one cell identifier:

func collectionSkeletonView(_ skeletonView: UICollectionView, cellIdentifierForItemAt indexPath: IndexPath) -> ReusableCellIdentifier {
    return defaultCellId
}

Am i wrong? Or is there a way to use multiple Cell Identifiers?

Also, as i saw in your example, you are using a ViewController that is a subclass of UIViewController and SkeletonTableViewDataSource. What if i decide that my ViewController is a subclass of UICollectionViewController instead? How does it change, provided that UICollectionViewController forces us to use the following methods by conforming to UICollectionViewDataSource protocol:

collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int

collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell

Thanks in advance!

SkeletonView Environment

**SkeletonView version: 1.1.1 (by the way, just installed it today)
**Xcode version: 9.3.1
**Swift version: 4.1

Adding framework with Carthage does not show Storyboard property

What did you do?

When I add the library with Carthage and open a Storyboard, I cannot see the "is skeletonable" property when selectin views.

What did you expect to happen?

I expect to configure skeletonable property through Interface Builder.

What happened instead?

Skeletonable property does not appear.

Steps to reproduce the behaviour

  • Add library with carthage.
  • Update Carthage.
  • Add the framework to the project.
  • Open a Storyboard

SkeletonView Environment

SkeletonView version: 1.1.1
Xcode version: 9.3
Swift version: 4.1

why funtions in Oc like "[aLabel showAnimatedGradientSkeleton]" doesn't work,? and propertys are available such as "isSkeletonable/lastLineFillPercent".

⚠️ Please fill out this template when filing an issue.

What did you do?

Please replace this with what you did.

What did you expect to happen?

Please replace this with what you expected to happen.

What happened instead?

Please replace this with of what happened instead.

Steps to reproduce the behavior

Please replace this with the steps to reproduce the behavior.

SkeletonView Environment

SkeletonView version:
Xcode version:
Swift version:

Problem with position of mask

@Juanpe

What did you do?

Use your project in my app :)

What did you expect to happen?

This will work perfectly :)

What happened instead?

Something weird :)

Steps to reproduce the behavior

Don't worry, I changed your example, added my cell and this still not work. Without skeleton tableView look good, but with animated skeleton some of views in cell have problems.
Can you help me fix this ? :) My app has complicated logic and unfortunately I need this and others cells AS IS :/

SkeletonViewWithError.zip

SkeletonView Environment

SkeletonView version: 1.0.4
Xcode version: 9.1
Swift version: 4

[Suggestion] Make last line of text skeleton not full width

Generally when drawing text, especially multiple lines, the last line is drawn with a shorter length than the other lines.

For this project, it could be optionally enabled if the user wants it as well as only on when there's 2+ lines.

If it sounds interesting I could maybe do it in a PR, but if not I won't bother (hence this ticket).

can't find pod spec

screenshot

when use "pod search skelentonView" in terminate, can't find pod spec.
Also pod install failed.

Cannot make it work with UITableView.

⚠️ Please fill out this template when filing an issue.

What did you do?

  1. import SkeletonView
  2. conform to 'SkeletonTableViewDataSource' and return cell identifier.
  3. tableView.isSkeletonable = true
  4. tableView.showSkeleton() before loading and tableView.hideSkeleton() after data is received.

What did you expect to happen?

To see a template of the provided cell while the data is being loaded.

What happened instead?

The whole table had a gray overlay view and it disappeared after the data was received.

SkeletonView Environment

**SkeletonView version: 1.0.4
**Xcode version: 9.2
**Swift version: 4

Gray area on iPhone 8 plus

⚠️ Please fill out this template when filing an issue.

What did you do?

Loaded table view that is skeletonable

What did you expect to happen?

I expected the gradient animation to expand full-width on
views that are skeletonable.

What happened instead?

Gray area on view that was supposed to display gradient animation full-width
image

Steps to reproduce the behavior

SkeletonView Environment

SkeletonView version: 1.0.5
Xcode version: 9.2
Swift version: 4.1

UITableViewAutomaticDimension not working

⚠️ Please fill out this template when filing an issue.

What did you do?

import SkeletonView
conform to 'SkeletonTableViewDataSource' and return cell identifier.
tableView.isSkeletonable = true
tableView.showSkeleton() before loading and tableView.hideSkeleton() after data is received.
tableview with rowHeight as default (UITableViewAutomaticDimension)
tableview with custom tableviewcell with a multiline with constraints to superview.

What did you expect to happen?

cell height should grow with the text

What happened instead?

cell height is equal to estimatedRowHeight
SkeletonView version 1.0.4 works as expected

SkeletonView Environment

SkeletonView version: 1.0.5
Xcode version: 9.2
Swift version: 4.0

How to work with SkeletonView and UITableViewDataSource

I am trying to implement a tableview with SkeletonView but it's giving me a compile-time error saying that my UIViewController does not conform to protocol UITableViewDataSource. Before trying to implement SkeletonView it was working perfect.

I have the following in my view controller:

extension ChooseListViewController : SkeletonTableViewDataSource {
    func numSections(in collectionSkeletonView: UITableView) -> Int {
        return 1
    }
    
    func collectionSkeletonView(_ skeletonView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return food.count
    }
    
    func collectionSkeletonView(_ skeletonView: UITableView, cellIdenfierForRowAt indexPath: IndexPath) -> ReusableCellIdentifier {
       /* let cell = tableView.dequeueReusableCell(withIdentifier: "FoodCell") as! ChooseTableViewCell
        
        cell.delegate = self
        
        cell.food = foods[indexPath.row]
        
        return cell*/
        
        return "FoodCell"
    }
}

I commented how my code was beforehand. What I don't understand is how do you expect me to customize my cell if I should rather return only its identifier?

Wrong skeleton view width on iPhone 8 plus

What did you do?

Just create a Table View with a skeletonable cell that has views that set its width with Leading and Trailing constraints with 0dp.

What did you expect to happen?

The skeleton view should match the screen width

What happened instead?

The skeleton view does not match the screen width in an iPhone 8 plus, but it does in an iPhone 5.

iPhone 8 plus (wrong skeleton views width)

iPhone 5 (correct skeleton views width)

Steps to reproduce the behaviour

Just start a new project, follow the steps to add skeletonable to table view and in the skeleton cell, add an imageview that should match cell width defining Leading and Trailing with 0 value.

SkeletonView Environment

SkeletonView version: 1.2
Xcode version: 9.4
Swift version: 4.1

How to condition import SkeletonView?

What did you do?

My Deployment Target is 8.0
How to condition import SkeletonView?
Like #available(iOS 9, *) import SkeletonView

SkeletonView Environment

SkeletonView version:1.1.1
Xcode version:9.2
Swift version:4

How to reload the original view controller / view ?

What did you do?

Experimented with the Pod's example, using all publicly-available functions {hideSkeleton(reloadDataAfter: true), hideSkeleton(), stopSkeletonAnimation(), plus setting isSkeletonable to false} inside of a DispatchQueue.main.asyncAfter call (time-delayed to show changes after a few seconds, to simulate a network-layer displaying the skeleton views first, then the original content).

The example's original storyboard was left untouched, as was viewDidLoad. ViewDidAppear had a call to view.showAnimatedSkeleton, which was also not altered.

What did you expect to happen?

Expected to see the original view controller layout after the end of the various skeleton-display-stop calls

What happened instead?

I eventually tweaked the example to focus on the avatar image only, and eventually got it to show an altered colour background (still in circular format). However I wasn't able to see the original content.

Alternatively I put the Dispatch call into a button press (button inserted on the bottom panel). Also experimented with reversing the order of calling isSkeletonable = false and hideSkeleton(), always putting self.view.layoutIfNeeded() last.

Steps to reproduce the behavior

In viewDidAppear, add a call to

DispatchQueue.main.asyncAfter(deadline: .now() + 4, execute: {
    self.turnOffAndReload()
})

the body of the turnOffAndReload() func :

func turnOffAndReload() {
    avatarImage.hideSkeleton()
    avatarImage.isSkeletonable = false

    self.view.layoutIfNeeded()
}

SkeletonView Environment

SkeletonView version: 1.2
Xcode version: 9.3
Swift version: 4.1

Editing textfield - textfield when skeleton is running

⚠️ Please fill out this template when filing an issue.

What did you do?

simulator screen shot - iphone 8 - 2017-11-21 at 09 55 17

What did you expect to happen?

nothing

What happened instead?

enter text and the keyboard has been showed

Steps to reproduce the behavior

Set a texview with skeleton and tap it

SkeletonView Environment

**SkeletonView version: Skeleton Sample project **
Xcode version: 9
Swift version: 3.2

SkeletonView-Swift.h

What did you do?

Pure OC Project Import SkeletonView

What did you expect to happen?

#import <SkeletonView/SkeletonView-Swift.h>

What happened instead?

SkeletonView-Swift.h in the code is not complete

Steps to reproduce the behavior

#import <SkeletonView/SkeletonView-Swift.h>

SkeletonView Environment

SkeletonView version: 1.0.4
Xcode version: 9.2 (9C40b)
Swift version: 3.2

SkeletonView-Swift.h code is as follows:

SWIFT_MODULE_NAMESPACE_PUSH("SkeletonView")








@class CAAnimation;

@interface CALayer (SWIFT_EXTENSION(SkeletonView))
@property (nonatomic, readonly, strong) CAAnimation * _Nonnull pulse;
@property (nonatomic, readonly, strong) CAAnimation * _Nonnull sliding;
- (void)playAnimation:(SWIFT_NOESCAPE CAAnimation * _Nonnull (^ _Nonnull)(CALayer * _Nonnull))anim key:(NSString * _Nonnull)key;
- (void)stopAnimationForKey:(NSString * _Nonnull)key;
@end




@interface UIColor (SWIFT_EXTENSION(SkeletonView))
@property (nonatomic, readonly, strong) UIColor * _Nonnull complementaryColor;
@property (nonatomic, readonly, strong) UIColor * _Nonnull lighter;
@property (nonatomic, readonly, strong) UIColor * _Nonnull darker;
@end


@interface UIColor (SWIFT_EXTENSION(SkeletonView))
SWIFT_CLASS_PROPERTY(@property (nonatomic, class, strong) UIColor * _Nonnull greenSea;)
+ (UIColor * _Nonnull)greenSea SWIFT_WARN_UNUSED_RESULT;
+ (void)setGreenSea:(UIColor * _Nonnull)value;
SWIFT_CLASS_PROPERTY(@property (nonatomic, class, strong) UIColor * _Nonnull turquoise;)
+ (UIColor * _Nonnull)turquoise SWIFT_WARN_UNUSED_RESULT;
+ (void)setTurquoise:(UIColor * _Nonnull)value;
SWIFT_CLASS_PROPERTY(@property (nonatomic, class, strong) UIColor * _Nonnull emerald;)
+ (UIColor * _Nonnull)emerald SWIFT_WARN_UNUSED_RESULT;
+ (void)setEmerald:(UIColor * _Nonnull)value;
SWIFT_CLASS_PROPERTY(@property (nonatomic, class, strong) UIColor * _Nonnull peterRiver;)
+ (UIColor * _Nonnull)peterRiver SWIFT_WARN_UNUSED_RESULT;
+ (void)setPeterRiver:(UIColor * _Nonnull)value;
SWIFT_CLASS_PROPERTY(@property (nonatomic, class, strong) UIColor * _Nonnull amethyst;)
+ (UIColor * _Nonnull)amethyst SWIFT_WARN_UNUSED_RESULT;
+ (void)setAmethyst:(UIColor * _Nonnull)value;
SWIFT_CLASS_PROPERTY(@property (nonatomic, class, strong) UIColor * _Nonnull wetAsphalt;)
+ (UIColor * _Nonnull)wetAsphalt SWIFT_WARN_UNUSED_RESULT;
+ (void)setWetAsphalt:(UIColor * _Nonnull)value;
SWIFT_CLASS_PROPERTY(@property (nonatomic, class, strong) UIColor * _Nonnull nephritis;)
+ (UIColor * _Nonnull)nephritis SWIFT_WARN_UNUSED_RESULT;
+ (void)setNephritis:(UIColor * _Nonnull)value;
SWIFT_CLASS_PROPERTY(@property (nonatomic, class, strong) UIColor * _Nonnull belizeHole;)
+ (UIColor * _Nonnull)belizeHole SWIFT_WARN_UNUSED_RESULT;
+ (void)setBelizeHole:(UIColor * _Nonnull)value;
SWIFT_CLASS_PROPERTY(@property (nonatomic, class, strong) UIColor * _Nonnull wisteria;)
+ (UIColor * _Nonnull)wisteria SWIFT_WARN_UNUSED_RESULT;
+ (void)setWisteria:(UIColor * _Nonnull)value;
SWIFT_CLASS_PROPERTY(@property (nonatomic, class, strong) UIColor * _Nonnull midnightBlue;)
+ (UIColor * _Nonnull)midnightBlue SWIFT_WARN_UNUSED_RESULT;
+ (void)setMidnightBlue:(UIColor * _Nonnull)value;
SWIFT_CLASS_PROPERTY(@property (nonatomic, class, strong) UIColor * _Nonnull sunFlower;)
+ (UIColor * _Nonnull)sunFlower SWIFT_WARN_UNUSED_RESULT;
+ (void)setSunFlower:(UIColor * _Nonnull)value;
SWIFT_CLASS_PROPERTY(@property (nonatomic, class, strong) UIColor * _Nonnull carrot;)
+ (UIColor * _Nonnull)carrot SWIFT_WARN_UNUSED_RESULT;
+ (void)setCarrot:(UIColor * _Nonnull)value;
SWIFT_CLASS_PROPERTY(@property (nonatomic, class, strong) UIColor * _Nonnull alizarin;)
+ (UIColor * _Nonnull)alizarin SWIFT_WARN_UNUSED_RESULT;
+ (void)setAlizarin:(UIColor * _Nonnull)value;
SWIFT_CLASS_PROPERTY(@property (nonatomic, class, strong) UIColor * _Nonnull clouds;)
+ (UIColor * _Nonnull)clouds SWIFT_WARN_UNUSED_RESULT;
+ (void)setClouds:(UIColor * _Nonnull)value;
SWIFT_CLASS_PROPERTY(@property (nonatomic, class, strong) UIColor * _Nonnull concrete;)
+ (UIColor * _Nonnull)concrete SWIFT_WARN_UNUSED_RESULT;
+ (void)setConcrete:(UIColor * _Nonnull)value;
SWIFT_CLASS_PROPERTY(@property (nonatomic, class, strong) UIColor * _Nonnull flatOrange;)
+ (UIColor * _Nonnull)flatOrange SWIFT_WARN_UNUSED_RESULT;
+ (void)setFlatOrange:(UIColor * _Nonnull)value;
SWIFT_CLASS_PROPERTY(@property (nonatomic, class, strong) UIColor * _Nonnull pumpkin;)
+ (UIColor * _Nonnull)pumpkin SWIFT_WARN_UNUSED_RESULT;
+ (void)setPumpkin:(UIColor * _Nonnull)value;
SWIFT_CLASS_PROPERTY(@property (nonatomic, class, strong) UIColor * _Nonnull pomegranate;)
+ (UIColor * _Nonnull)pomegranate SWIFT_WARN_UNUSED_RESULT;
+ (void)setPomegranate:(UIColor * _Nonnull)value;
SWIFT_CLASS_PROPERTY(@property (nonatomic, class, strong) UIColor * _Nonnull silver;)
+ (UIColor * _Nonnull)silver SWIFT_WARN_UNUSED_RESULT;
+ (void)setSilver:(UIColor * _Nonnull)value;
SWIFT_CLASS_PROPERTY(@property (nonatomic, class, strong) UIColor * _Nonnull asbestos;)
+ (UIColor * _Nonnull)asbestos SWIFT_WARN_UNUSED_RESULT;
+ (void)setAsbestos:(UIColor * _Nonnull)value;
@end






@interface UILabel (SWIFT_EXTENSION(SkeletonView))
@property (nonatomic) NSInteger lastLineFillPercent;
@end














@interface UITextView (SWIFT_EXTENSION(SkeletonView))
@property (nonatomic) NSInteger lastLineFillPercent;
@end














@interface UIView (SWIFT_EXTENSION(SkeletonView))
- (void)showSkeletonUsingColor:(UIColor * _Nonnull)color;
- (void)showAnimatedSkeletonUsingColor:(UIColor * _Nonnull)color animation:(CAAnimation * _Nonnull (^ _Nullable)(CALayer * _Nonnull))animation;
- (void)hideSkeletonWithReloadDataAfter:(BOOL)reload;
- (void)startSkeletonAnimation:(CAAnimation * _Nonnull (^ _Nullable)(CALayer * _Nonnull))anim;
- (void)stopSkeletonAnimation;
@end


@interface UIView (SWIFT_EXTENSION(SkeletonView))
@property (nonatomic) BOOL isSkeletonable;
@property (nonatomic, readonly) BOOL isSkeletonActive;
@end





SWIFT_MODULE_NAMESPACE_POP
#pragma clang diagnostic pop

Skeleton cells overlaps with cell content

img-6708
⚠️ Please fill out this template when filing an issue.

🙏🏼 Please check if it already exists other issue related with yours.

What did you do?

tableView.isSkeletonable = true in ViewDidLoad()
view.showAnimatedSkeleton() in viewDidAppear()

What did you expect to happen?

Skeleton should not be there when actual contents load.

What happened instead?

I could still see skeleton over my actual cell content.

Steps to reproduce the behavior

Please replace this with the steps to reproduce the behavior.

SkeletonView Environment

SkeletonView version:
1.1
Xcode version:
9.2
Swift version:
4.0

UICollectionView wrong skeleton cell size

Hi,
I want to use SkeletonView to implement skeleton layout to collection view. I have VC that conforms to SkeletonCollectionViewDataSource. The skeleton layout works but the size of skeleton cells is wrong. I can see only the first cell, because it has size of the collectionview, or it's larger then it. Size of actual cells is correct and it's set by func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize

SkeletonView Environment

SkeletonView version: 1.1.1
Xcode version: 9.2
Swift version: 4.0

Doesn't work with TableViews with auto cell height

⚠️ Please fill out this template when filing an issue.

What did you do?

Tried to integrate with TableViews that use automatic cell height.

What did you expect to happen?

Either use the estimated cell height (if set), the height of the specific cell prototype, or an appropriate default value for cell height to display skeleton cells�.

What happened instead?

It seems the whole tableview gets treated as one single control.

Steps to reproduce the behavior

Edit TableView in example project to use auto cell height.

SkeletonView Environment

SkeletonView version: 1.0.4 (latest)
Xcode version: 9.1
Swift version: 4

Alternative solution: create an SkeletonTableViewDelegate protocol which has a method to return a skeleton cell height if the height is ambiguous.

Use SkeletonView with Bond

What did you do?

I'm trying to use SkeletonView lib with Bond library.

What did you expect to happen?

I would like to bind my TableView to a data source and allow using the Skeleton view while loading with Bond bindings.

What happened instead?

As Bond uses a plain UITableViewDataSource to bind the data to a TableView, I cannot use the protocol SkeletonTableViewDataSource that inherits from UITableViewDataSource

SkeletonView Environment

SkeletonView version: 1.2
Xcode version: 9.4
Swift version: 4.1

UITableViewHeaderFooterView support?

What did you do?

Try to make skeletonable a view inside a UITableViewHeaderFooterView subclass from a xib.

What did you expect to happen?

UITableViewHeaderFooterView be skeletonable.

What happened instead?

No option to make it skeletonable.

SkeletonView Environment

SkeletonView version: 1.0.4
Xcode version: 9.2 (9C40b)
Swift version: 3.2

Skeleton View wont go away

Implemented Skeleton View in my app correctly only problem is I can't get the cells to go away when information about the cell is returned. Has that not been implemented yet or am I just slow?

iOS 11 Large Titles don't work like it should

⚠️ Please fill out this template when filing an issue.

What did you do?

I implemented the Skeleton in my UITableview.

What did you expect to happen?

That everything remained the same and only the Skeleton placeholder would show when loading.

What happened instead?

Everything remained the same, except the Large Titles on the status bar on iOS 11. They appear small until I scroll down and then they are the way they should be.

Steps to reproduce the behavior

Implement Skeleton in UITableView, turn Prefers Large Titles on. And set the Large Title to Automatic.

SkeletonView Environment

SkeletonView version: 1.0.4
Xcode version: 9.2
Swift version: 4.0

Unable to find a specification for `SkeletonView`

⚠️ Please fill out this template when filing an issue.

What did you do?

*I tried to install it via cocoapod *

What did you expect to happen?

It should install it.

I got an error : Unable to find a specification for SkeletonView

Please replace this with of what happened instead.

SkeletonView Environment

**SkeletonView version:1.0.4 and 1.0.2
**Xcode version:9.1
**Swift version:3

Doesn't work when using in a resizable cell

When using a resizable cell:

tableView.rowHeight = UITableViewAutomaticDimension
tableView.estimatedRowHeight = 250

The skeleton animation does not work. It animates the whole tableview frame as if its childviews were configured with isSkeletonable = false.

I know this is probably because the library works with fixed cells and it needs to due to the fact that it is based on the height of the cells that the skeleton template is drawn. It would be great to allow for resizable cells as well.

Fade out effect

Is there any way to fade out the layers gracefully instead of jumping straight way to the real content?

I tried hideSkeleton but it hides the views immediately without a transition.

Why not OC version of the country???

⚠️ Please fill out this template when filing an issue.

What did you do?

Please replace this with what you did.

What did you expect to happen?

Please replace this with what you expected to happen.

What happened instead?

Please replace this with of what happened instead.

Steps to reproduce the behavior

Please replace this with the steps to reproduce the behavior.

SkeletonView Environment

SkeletonView version:
Xcode version:
Swift version:

Skeleton not working if UICollectionView cell's Nib is registered in code

Skeleton loading does't work if cells get register in code:
collectionView.register(UINib.init(nibName: "\(Cell.self)", bundle: Bundle.main), forCellWithReuseIdentifier: "Cell")

What did you do

  • Created UIViewController in .xib file
  • Added UICollectionView in UIViewController as a subview
  • Added view and collectionView as skeletonable
  • Created UICollectionView cell in a separate .xib file
  • Linked cell to UICollectionView by collectionView.register(UINib.init(nibName: "\(Cell.self)", bundle: Bundle.main), forCellWithReuseIdentifier: "Cell")
  • added delegate and dataSource for UICollectionView as self (UIViewController)
  • start animating in viewDidLoad
  • implemented SkeletonCollectionViewDataSource
  • run app

I would expect it to identify the cell and add Skeleton loading to it but instead just the UICollectionView animates

Steps to reproduce the behavior

Create a UICollectionView in a UIViewController placed in a .xib file and not .storyboard.
Register UICollectionViewCell in code as presented above.

SkeletonView version:
1.1.1
Xcode version:
9.2
Swift version:
4

CocoaPods can't work

Demo pod search SkeletonView
Creating search index for spec repo 'master'.. Done!
[!] Unable to find a pod with name, author, summary, or description matching SkeletonView

why Skeleton has been hiddened but the TextView's text does'n exist

⚠️ Please fill out this template when filing an issue.

What did you do?

Please replace this with what you did.

What did you expect to happen?

Please replace this with what you expected to happen.

What happened instead?

Please replace this with of what happened instead.

Steps to reproduce the behavior

Please replace this with the steps to reproduce the behavior.

SkeletonView Environment

SkeletonView version:
Xcode version:
Swift version:

Support for using SkeletonView with IGListKit

Hi, I would love to use this library in my app, however, I'm using IGListKit for handling my collection views. This uses it's own class called IGListAdapter as the data source for the collection view and so there's no way to use it with SkeletonView at the moment. IGListKit, like SkeletonView, is a very popular open source project and I think they'd both benefit from being able to work together. It was suggested by the founder of IGListKit to open a support request here. Would this be possible?

Proportional width on Custom TableViewCell not working

⚠️ Please fill out this template when filing an issue.

What did you do?

Follow the installation procedures and working fine.

What did you expect to happen?

Proportional width would work when two label align horizontally.
LabelLeft = EqualWidth to ContentView with 0.6 points.
LabelRight = AlignRight to LabelLeft

What happened instead?

It only shows LabelLeft skeletonView where proportional width not working. LabelLeft width overlaps device width.

Steps to reproduce the behavior

By just running the application.

SkeletonView Environment

SkeletonView version: 1.1.1
Xcode version: 9.2
Swift version: 4

UITableView Frozen

What did you do?

I Added TableView And all subviews Programmatically and Using Coordinator Delegate so There is no Storyboard or xib files. and registered cell like below
tableview.register(SearchTableViewCell.self, forCellReuseIdentifier: "searchcell")
and set tableview, cell and all subviews isSkeletonable to true.

What did you expect to happen?

It replace my subviews with grey boxes

What happened instead?

TableVIew with visible cells frozen to death.

Steps to reproduce the behavior

I am not using interface builder.

SkeletonView Environment

SkeletonView version: 1.1.1
Xcode version: 9.3
Swift version: 4

SkeletonView not showing

⚠️ Please fill out this template when filing an issue.

🙏🏼 Please check if it already exists other issue related with yours.

What did you do?

I’m trying to implement SkeletonView in an app that has to download some images from a website

What did you expect to happen?

I expect that when I tap on a button the skeleton is shown in an UIImageView while the image is downloaded from a website.

What happened instead?

The skeleton is shown only sometimes.
But if I put a breakpoint after the showSkeleton(), I can see it every time.

SkeletonView Environment

SkeletonView version: 6.0
**Xcode version: 9.3.1 **
Swift version: 4.1

UITableView solid grey

What did you do?

import SkeletonView
override func viewDidLoad() {
  ...
  tableView.isSkeletonable = true
  tableView.showSkeleton()
}

extension ChatViewController: SkeletonTableViewDataSource {
  func numSections(in collectionSkeletonView: UITableView) -> Int {
    return 1
  }

  func collectionSkeletonView(_ skeletonView: UITableView, numberOfRowsInSection section: Int) -> Int {
    return 5
  }

  func collectionSkeletonView(_ skeletonView: UITableView, cellIdenfierForRowAt indexPath: IndexPath) -> ReusableCellIdentifier {
    return ChatMessageCell.identifier
  }
}

class ChatMessageCell: UITableViewCell {
  static let identifier = "ChatMessageCell"
  let userLabel = UILabel()
  let bodyLabel = ActiveLabel()

  override init(style: UITableViewCellStyle, reuseIdentifier: String?) {
      super.init(style: style, reuseIdentifier: reuseIdentifier)
      isSkeletonable = true
      userLabel.isSkeletonable = true
      bodyLabel.isSkeletonable = true
      ...
  }
}

What did you expect to happen?

It replace my labels with grey boxes

What happened instead?

Blank white screen. Removing isSkeletonable = true from the cell makes the entire view grey

Steps to reproduce the behavior

See above. I am not using interface builder.

SkeletonView Environment

SkeletonView version: 1.1.1
Xcode version: 9.2
Swift version: 4

Add More colors

I believe in adding few more colors will enhance this project. Let me know if you want me to help you with any contributions.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.