Особенности • Руководства • Установка • Использование • Разное • Внесение
? Readme доступен на других языках: ?? Полем ?? Полем ?? Полем ?? Полем ?? Полем ??
Сегодня почти все приложения имеют асинхронные процессы, такие как запросы API, длительные процессы и т. Д. В то время как процессы работают, обычно разработчики ставят представление о загрузке, чтобы показать пользователям, что что -то происходит.
SkeletonView был задумана для удовлетворения этой потребности, элегантного способа показать пользователям, что что -то происходит, а также подготовить их, для которого ожидают содержимое.
Наслаждайся этим! ?
| Руководства SkeletonView - начало работы | Как создать погрузочный вид с Skeleton View в Swift 5.2 от ikh4ever Studio | Создание скелета загрузки в приложении (Swift 5) - Xcode 11, 2020 от Academy iOS | Cómo Crear Una animación de Carga de Datos en ios от midev |
pod 'SkeletonView' github "Juanpe/SkeletonView"dependencies: [
. package ( url : " https://github.com/Juanpe/SkeletonView.git " , from : " 1.7.0 " )
]ВАЖНЫЙ!
Поскольку версия 1.30.0,
SkeletonViewподдерживает XCFrameWorks , поэтому, если вы хотите установить его в качестве XCFrameWork , вместо этого используйте этот репо.
Только 3 шага, необходимые для использования SkeletonView :
1⃣ Импорт SkeletonView в правильном месте.
import SkeletonView 2⃣ Теперь установите, какие виды будут skeletonables . Вы достигаете этого двумя способами:
Использование кода:
avatarImageView . isSkeletonable = trueИспользуя IB/Рагульсы:

3⃣ Как только вы установите представления, вы можете показать скелет . Для этого у вас есть 4 варианта:
( 1 ) view . showSkeleton ( ) // Solid
( 2 ) view . showGradientSkeleton ( ) // Gradient
( 3 ) view . showAnimatedSkeleton ( ) // Solid animated
( 4 ) view . showAnimatedGradientSkeleton ( ) // Gradient animatedПредварительный просмотр
| Твердый | Градиент | Твердый анимирован | Градиент анимирован |
![]() | ![]() | ![]() | ![]() |
ВАЖНЫЙ!
SkeletonViewрекурсивна, поэтому, если вы хотите показать скелет во всех скелетных представлениях, вам нужно только вызвать метод шоу в основном представлении контейнера. Например, сUIViewControllers.
SkeletonView совместим с UITableView и UICollectionView .
UitableView
Если вы хотите показать скелет в UITableView , вам необходимо соответствовать протоколу SkeletonTableViewDataSource .
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 )
} Как вы можете видеть, этот протокол наследует от UITableViewDataSource , так что вы можете заменить этот протокол на скелетный протокол.
Этот протокол имеет реализацию по умолчанию для некоторых методов. Например, количество строк для каждого раздела рассчитывается во время выполнения:
func collectionSkeletonView ( _ skeletonView : UITableView , numberOfRowsInSection section : Int ) -> Int
// Default:
// It calculates how many cells need to populate whole tableviewВАЖНЫЙ!
Если вы возвращаете
UITableView.automaticNumberOfSkeletonRowsв приведенном выше методе, он действует как поведение по умолчанию (то есть он вычисляет, сколько ячеек нужно для заполнения всего таблицы).
Есть только один метод, который вам необходимо реализовать, чтобы скелет знал идентификатор ячейки. Этот метод не имеет реализации по умолчанию:
func collectionSkeletonView ( _ skeletonView : UITableView , cellIdentifierForRowAt indexPath : IndexPath ) -> ReusableCellIdentifier {
return " CellIdentifier "
}По умолчанию библиотека отбирает ячейки из каждого индексного пути, но вы также можете сделать это, если хотите внести некоторые изменения до появления скелета:
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
}Если вы предпочитаете оставить часть Deque в библиотеку, вы можете настроить ячейку, используя этот метод:
func collectionSkeletonView ( _ skeletonView : UITableView , prepareCellForSkeleton cell : UITableViewCell , at indexPath : IndexPath ) {
let cell = cell as? Cell
cell ? . textField . isHidden = indexPath . row == 0
} Кроме того, вы можете скелетизировать как заголовки, так и нижние колонтитулы. Вы должны соответствовать протоколу SkeletonTableViewDelegate .
public protocol SkeletonTableViewDelegate : UITableViewDelegate {
func collectionSkeletonView ( _ skeletonView : UITableView , identifierForHeaderInSection section : Int ) -> ReusableHeaderFooterIdentifier ? // default: nil
func collectionSkeletonView ( _ skeletonView : UITableView , identifierForFooterInSection section : Int ) -> ReusableHeaderFooterIdentifier ? // default: nil
}ВАЖНЫЙ!
1 Если вы используете Resizeable Cells (
tableView.rowHeight = UITableViewAutomaticDimension), это обязательно определитьestimatedRowHeight.2⃣ Когда вы добавляете элементы в
UITableViewCellвы должны добавить их вcontentView, а не к ячейке напрямую.self . contentView . addSubview ( titleLabel ) ✅ self . addSubview ( titleLabel )
UicollectionView
Для UICollectionView вам необходимо соответствовать протоколу SkeletonCollectionViewDataSource .
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 )
} Остальная часть процесса такая же, как UITableView

При использовании элементов с текстом SkeletonView рисует линии для имитации текста.
Вы можете установить некоторые свойства для многолинерных элементов.
| Свойство | Тип | По умолчанию | Предварительный просмотр |
|---|---|---|---|
| LastlineFillPercent | CGFloat | 70 | ![]() |
| Linescornerradius | Int | 0 | ![]() |
| Skeletonlinespocing | CGFloat | 10 | ![]() |
| SkeletonPaddingInsets | UIEdgeInsets | .zero | ![]() |
| SkeletontextlineHeight | SkeletonTextLineHeight | .fixed(15) | ![]() |
| SkeletontextNumberOflines | SkeletonTextNumberOfLines | .inherited | ![]() |
Чтобы изменить процент или радиус, используя код , установите свойства:
descriptionTextView . lastLineFillPercent = 50
descriptionTextView . linesCornerRadius = 5Или, если вы предпочитаете использовать IB/Скаущество :

Как определить количество строк?
По умолчанию количество строк такое же, как и значение свойства numberOfLines . И, если он установлен на ноль , он рассчитывает, сколько линий нужно, чтобы заполнить весь скелет и нарисовать его.
Однако, если вы хотите установить определенное количество скелетных линий, вы можете сделать это, установив свойство skeletonTextNumberOfLines . Это свойство имеет два возможных значения, inherited , которые возвращают значение numberOfLines и custom(Int) , которое возвращает конкретное количество строк, указанных в качестве связанного значения.
Например:
label . skeletonTextNumberOfLines = 3 // .custom(3)
️ Устроительно!UseFontlineHeight был устарел. Вместо этого вы можете использовать SkeletontextlineHeight :
descriptionTextView . skeletonTextLineHeight = . relativeToFont
ВАЖНЫЙ!
Обратите внимание, что для представлений без нескольких строк одна строка будет рассматриваться как последняя строка.
Скелеты имеют вид по умолчанию. Таким образом, когда вы не указываете свойства цвета, градиента или многолинейных свойств, SkeletonView использует значения по умолчанию.
Значения по умолчанию:
UIColor.skeletonDefault (так же, как и .cloudsSkeletonGradient(baseColor: .skeletonDefault)CGFloatCGFloatIntIntCGFloat (ibinspectable) (сделайте свой скелет с углом) Чтобы получить эти значения по умолчанию, вы можете использовать SkeletonAppearance.default . Используя это свойство, вы также можете установить значения:
SkeletonAppearance . default . multilineHeight = 20
SkeletonAppearance . default . tintColor = . green
️ Устроительно!UseFontlineHeight был устарел. Вместо этого вы можете использовать TextlineHeight :
SkeletonAppearance . default . textLineHeight = . relativeToFont
Вы можете решить, какой цвет скелет окрашен. Вам нужно только пройти в качестве параметра цвет или градиент, который вы хотите.
Используя сплошные цвета
view . showSkeleton ( usingColor : UIColor . gray ) // Solid
// or
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 ) // GradientКроме того, SkeletonView имеет 20 плоских цветов ??
UIColor.turquoise, UIColor.greenSea, UIColor.sunFlower, UIColor.flatOrange ...

SkeletonView имеет две встроенные анимации, импульс для твердых скелетов и скольжение для градиентов.
Кроме того, если вы хотите сделать свою собственную анимацию скелета, это действительно легко.
Skeleton обеспечивает функцию showAnimatedSkeleton , которая имеет закрытие SkeletonLayerAnimation , где вы можете определить свою пользовательскую анимацию.
public typealias SkeletonLayerAnimation = ( CALayer ) -> CAAnimationВы можете назвать функцию так:
view . showAnimatedSkeleton { ( layer ) -> CAAnimation in
let animation = CAAnimation ( )
// Customize here your animation
return animation
} Это доступно SkeletonAnimationBuilder . Это строитель, чтобы сделать SkeletonLayerAnimation .
Сегодня вы можете создать скользящую анимацию для градиентов, решая направление и установить продолжительность анимации (по умолчанию = 1,5 с).
// 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 имеет встроенные переходы, чтобы показать или скрыть скелеты более плавным образом?
Чтобы использовать переход, просто добавьте параметр transition в свою функцию showSkeleton() или hideSkeleton() со временем перехода, например, это:
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 Значение по умолчанию - crossDissolve(0.25)
Предварительный просмотр
| Никто | Крест растворить |
![]() | ![]() |
Иерархия
Поскольку SkeletonView рекурсивна, и мы хотим, чтобы скелет был очень эффективным, мы хотим как можно скорее прекратить рекурсию. По этой причине вы должны установить представление о контейнере как Skeletonable , потому что Skeleton перестанет искать skeletonable подвесы, как только представление не станет скелетом, разбивая, а затем рекурсия.
Потому что изображение стоит тысячи слов:
В этом примере у нас есть UIViewController с ContainerView и UITableView . Когда представление будет готово, мы показываем скелет, используя этот метод:
view.showSkeleton()
isSkeletonable= ☠
| Конфигурация | Результат |
|---|---|
![]() | ![]() |
![]() | ![]() |
![]() | ![]() |
![]() | ![]() |
![]() | ![]() |
![]() | ![]() |
Скелетонный вид с макетом
Иногда планировка скелета может не соответствовать вашему расположению, потому что границы родительского представления изменились. Например, вращение устройства.
Вы можете передавать скелетные представления так:
override func viewDidLayoutSubviews ( ) {
view . layoutSkeletonIfNeeded ( )
}ВАЖНЫЙ!
Вы не должны вызывать этот метод. Из версии 1.8.1 вам не нужно вызывать этот метод, библиотека делает автоматически. Таким образом, вы можете использовать этот метод только в случаях, когда вам нужно обновить макет скелета вручную.
Обновить скелет
Вы можете изменить конфигурацию скелета в любое время, например, его цвет, анимация и т. Д. С следующими методами:
( 1 ) view . updateSkeleton ( ) // Solid
( 2 ) view . updateGradientSkeleton ( ) // Gradient
( 3 ) view . updateAnimatedSkeleton ( ) // Solid animated
( 4 ) view . updateAnimatedGradientSkeleton ( ) // Gradient animatedСкрытие просмотров, когда начинается анимация
Иногда вы хотите скрыть представление, когда начинается анимация, поэтому есть быстрое свойство, которое вы можете использовать, чтобы это произошло:
view . isHiddenWhenSkeletonIsActive = true // This works only when isSkeletonable = trueНе изменяйте взаимодействие с пользователем, когда скелет активен
По умолчанию взаимодействие с пользователем отключено для скелетонированных элементов, но если вы не хотите изменять индикатор взаимодействия пользователя, когда скелет активен, вы можете использовать свойство isUserInteractionDisabledWhenSkeletonIsActive :
view . isUserInteractionDisabledWhenSkeletonIsActive = false // The view will be active when the skeleton will be active.Не используйте высоту линии шрифта для линий скелетов в меток
Неверно, чтобы отключить скелет для автоматического настроения к высоте шрифта для UILabel или UITextView . По умолчанию высота линий скелета автоматически поправку на высоту шрифта, чтобы более точно отражать текст в прямом направлении метки, а не использование ограничивающей коробки.
label . useFontLineHeight = falseЗадержка шоу -скелета
Вы можете отложить презентацию скелета, если представления быстро обновились.
func showSkeleton ( usingColor : UIColor ,
animated : Bool ,
delay : TimeInterval ,
transition : SkeletonTransitionStyle ) func showGradientSkeleton ( usingGradient : SkeletonGradient ,
animated : Bool ,
delay : TimeInterval ,
transition : SkeletonTransitionStyle )Отлаживать
Чтобы облегчить задачи отладки, когда что -то не работает нормально. SkeletonView имеет несколько новых инструментов.
Во -первых, UIView есть недвижимость со своим скелетом:
var sk . skeletonTreeDescription : String Кроме того, вы можете активировать новый режим отладки . Вы просто добавляете переменную среду SKELETON_DEBUG и активируете ее.

Затем, когда появляется скелет, вы можете увидеть иерархию представления в консоли Xcode.
{
"type" : "UIView", // UITableView, UILabel...
"isSkeletonable" : true,
"reference" : "0x000000014751ce30",
"children" : [
{
"type" : "UIView",
"isSkeletonable" : true,
"children" : [ ... ],
"reference" : "0x000000014751cfa0"
}
]
}
Поддерживаемые версии OS и SDK
Это проект с открытым исходным кодом, так что не стесняйтесь вносить свой вклад. Как?
Смотрите всех участников
Для получения дополнительной информации, пожалуйста, прочитайте рекомендации.
Проекты с открытым исходным кодом не могут жить долго без вашей помощи. Если вы обнаружите, что SkeletonView полезен, пожалуйста, рассмотрите возможность поддержки этого проекта, став спонсором.
Станьте спонсором через спонсоров GitHub ❤
Хуанпе Каталан
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.