🌎 翻译: [ 原版的 ]
🇧🇷 @brunomunizaf
今天,几乎所有的应用程序都有异步流程,例如:Api请求、长时间运行的流程等。虽然流程正在运行,但通常开发人员会设置一个加载视图来向用户显示正在发生的事情。
SkeletonView
已经构想出来满足这种需求,这是一种优雅的方式,向用户展示正在发生的事情,并为他们等待的内容做好准备。
好好享受! 🙂
- 使用方便
- 支持所有 UIView
- 完全可定制
- 通用(iPhone和iPad)
- Interface Builder 友好
- 简单的 Swift 语法
- 轻量级可读代码库
- iOS 9.0+
- tvOS 9.0+
- Swift 4
要运行示例项目,请克隆并运行 SkeletonViewExample
项目。
使用 CocoaPods
使用 CocoaPods 编辑您的 Podfile 并指定依赖项:
pod "SkeletonView"
使用 Carthage
编辑您的 Cartfile 并指定依赖项:
github "Juanpe/SkeletonView"
只需 3 个步骤即可使用 SkeletonView
:
1. 在适当的位置导入SkeletonView
import SkeletonView
2. 现在,您可以通过两种设置方式实现 SkeletonView
效果
使用纯代码:
avatarImageView.isSkeletonable = true
使用 IB/Storyboards:
3. 设置视图后,可以显示 skeleton. 并且您有 4 种效果可供选择:
(1) view.showSkeleton() // 固体
(2) view.showGradientSkeleton() // 渐变
(3) view.showAnimatedSkeleton() // 纯色动画
(4) view.showAnimatedGradientSkeleton() // 渐变动画
Preview
固体 | 渐变 | 纯色动画 | 渐变动画 |
重要!
SkeletonView
是递归的,所以如果你想在所有可骨架化的视图中显示骨架,你只需要在主容器视图中调用show方法。例如,使用UIViewControllers
现在,SkeletonView
兼容 UITableView
和 UICollectionView
。
如果你要显示 skeleton 在一个 UITableView
上,你需要符合 SkeletonTableViewDataSource
协议。
public protocol SkeletonTableViewDataSource: UITableViewDataSource {
func numSections(in collectionSkeletonView: UITableView) -> Int
func collectionSkeletonView(_ skeletonView: UITableView, numberOfRowsInSection section: Int) -> Int
func collectionSkeletonView(_ skeletonView: UITableView, cellIdentifierForRowAt indexPath: IndexPath) -> ReusableCellIdentifier
}
如您所见,此协议继承自 UITableViewDataSource,因此您可以使用骨架协议替换此协议。
该协议具有默认实现:
func numSections(in collectionSkeletonView: UITableView) -> Int
// 默认值:1
func collectionSkeletonView(_ skeletonView: UITableView, numberOfRowsInSection section: Int) -> Int
// 默认值:
// 它计算填充整个tableview需要多少个单元格
为了让Skeleton知道单元标识符,您只需要实现一种方法。此方法没有默认实现:
func collectionSkeletonView(_ skeletonView: UITableView, cellIdentifierForRowAt indexPath: IndexPath) -> ReusableCellIdentifier
示例
func collectionSkeletonView(_ skeletonView: UITableView, cellIdentifierForRowAt indexPath: IndexPath) -> ReusableCellIdentifier {
return "CellIdentifier"
}
重要! 如果您使用可调整大小的单元格 (
tableView.rowHeight = UITableViewAutomaticDimension
),则必须定义estimatedRowHeight
。
要为 UICollectionView
设置效果, 您需要符合 SkeletonCollectionViewDataSource
协议。
public protocol SkeletonCollectionViewDataSource: UICollectionViewDataSource {
func numSections(in collectionSkeletonView: UICollectionView) -> Int
func collectionSkeletonView(_ skeletonView: UICollectionView, numberOfItemsInSection section: Int) -> Int
func collectionSkeletonView(_ skeletonView: UICollectionView, cellIdentifierForItemAt indexPath: IndexPath) -> ReusableCellIdentifier
}
其余操作与 UITableView
相同。
使用带有文本的元素时, SkeletonView
绘制线条以模拟文本。此外,您可以决定您想要多少行。如果 numberOfLines
设置为零,它将计算填充整个骨架所需的行数,并将绘制它。相反,如果将其设置为一,二或任何大于零的数字,它将只绘制此行数。
您可以为多行元素设置一些属性。
属性 | 值范围 | 默认 | 延时 |
---|---|---|---|
Filling percent 最后一行的长度百分比 | 0...100 |
70% |
|
Corner radius 条目圆角半径. (新) | 0...10 |
0 |
纯代码修改百分比或半径:
descriptionTextView.lastLineFillPercent = 50
descriptionTextView.linesCornerRadius = 5
或者,如果您更喜欢使用 IB/Storyboard:
您可以决定 SkeletonView
的显示颜色。您只需要传递颜色或渐变的参数。
使用纯色
view.showSkeleton(usingColor: UIColor.gray) // 固体效果
// 或者
view.showSkeleton(usingColor: UIColor(red: 25.0, green: 30.0, blue: 255.0, alpha: 1.0))
使用渐变色
let gradient = SkeletonGradient(baseColor: UIColor.midnightBlue)
view.showGradientSkeleton(usingGradient: gradient) // 梯度效果
此外, SkeletonView
附带的 20 种颜色 🤙🏼
UIColor.turquoise, UIColor.greenSea, UIColor.sunFlower, UIColor.flatOrange ...
从网站 https://flatuicolors.com捕获的图像
现在,SkeletonView
有两个内置动画,pulse 脉冲效果和 sliding 渐变滑动效果。
此外,如果你想做自己的 skeleton 动画,那真的很容易。
Skeleton 提供了 showAnimatedSkeleton
一个具有 SkeletonLayerAnimation
闭包的功能,您可以在其中定义自定义动画。
public typealias SkeletonLayerAnimation = (CALayer) -> CAAnimation
您可以像这样调用函数:
view.showAnimatedSkeleton { (layer) -> CAAnimation in
let animation = CAAnimation()
// 在这里自定义你的动画
return animation
}
新 它可用 SkeletonAnimationBuilder
。这是一个 SkeletonLayerAnimation
的衍生。
今天,您可以为渐变创建 滑动动画,确定 方向 并设置动画的 持续时间 (默认值 = 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
是一个枚举,在这种情况下:
方向 | 效果 |
---|---|
.leftRight | |
.rightLeft | |
.topBottom | |
.bottomTop | |
.topLeftBottomRight | |
.bottomRightTopLeft |
😉 技巧! 存在另一种创建滑动动画的方法,只需使用此快捷方式:
let animation = GradientDirection.leftToRight.slidingAnimation()
由于 SkeletonView
是递归的,我们希望 skeleton 效率高效, 我们希望尽快停止递归。因此,您必须将容器视图设置为 Skeletonable
,因为skeletonable
一旦视图不是 Skeletonable, Skeleton 将停止查找子视图,然后断开递归。
一图胜千言:
设置
ìsSkeletonable
= ☠️
分组 | 结果 |
---|---|
快出来...😅
- 设置多行元素中最后一行的填充百分比
- 添加更多渐变动画
- 支持可调整大小的单元
- CollectionView 兼容
- tvOS 兼容
- 添加恢复状态
- 自定义集合兼容
- 在显示/隐藏骨架时添加动画
- MacOS 和 WatchOS兼容
这是一个开源项目,所以请随时贡献。怎么样?
查看 所有贡献者
使用 SwiftPlate 生成的项目
- iOS Dev Weekly #327
- Hacking with Swift Articles
- Top 10 Swift Articles November
- 30 Amazing iOS Swift Libraries (v2018)
- AppCoda Weekly #44
- iOS Cookies Newsletter #103
- Swift Developments Newsletter #113
- iOS Goodies #204
- Swift Weekly #96
- CocoaControls
- Awesome iOS Newsletter #74
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.