Fitur • Panduan • Instalasi • Penggunaan • Lain -lain • Berkontribusi
? ReadMe tersedia dalam bahasa lain: ?? . ?? . ?? . ?? . ?? . ??
Hari ini hampir semua aplikasi memiliki proses async, seperti permintaan API, proses berjalan yang lama, dll. Saat prosesnya berfungsi, biasanya pengembang menempatkan tampilan pemuatan untuk menunjukkan kepada pengguna bahwa sesuatu sedang terjadi.
SkeletonView telah dikandung untuk memenuhi kebutuhan ini, cara yang elegan untuk menunjukkan kepada pengguna bahwa sesuatu sedang terjadi dan juga mempersiapkan mereka untuk konten mana yang menunggu.
Nikmati! ?
| Panduan SkeletonView - Memulai | Cara membuat tampilan pemuatan dengan tampilan kerangka di Swift 5.2 oleh IKH4ever Studio | Buat Tampilan Pemuatan Kerangka di Aplikasi (Swift 5) - Xcode 11, 2020 oleh iOS Academy | Cómo crear una animación de carake de datos en ios oleh mouredev |
pod 'SkeletonView' github "Juanpe/SkeletonView"dependencies: [
. package ( url : " https://github.com/Juanpe/SkeletonView.git " , from : " 1.7.0 " )
]PENTING!
Karena versi 1.30.0,
SkeletonViewmendukung XCFRAMEWorks , jadi jika Anda ingin menginstalnya sebagai XCFramework , silakan gunakan repo ini sebagai gantinya.
Hanya 3 langkah yang diperlukan untuk menggunakan SkeletonView :
1️⃣ Impor SkeletonView di tempat yang tepat.
import SkeletonView 2️⃣ Sekarang, atur pemandangan mana yang akan menjadi skeletonables . Anda mencapai ini dalam dua cara:
Menggunakan kode:
avatarImageView . isSkeletonable = trueMenggunakan IB/Storyboard:

3️⃣ Setelah Anda mengatur tampilan, Anda dapat menunjukkan kerangka . Untuk melakukannya, Anda memiliki 4 pilihan:
( 1 ) view . showSkeleton ( ) // Solid
( 2 ) view . showGradientSkeleton ( ) // Gradient
( 3 ) view . showAnimatedSkeleton ( ) // Solid animated
( 4 ) view . showAnimatedGradientSkeleton ( ) // Gradient animatedPratinjau
| Padat | Gradien | Animasi solid | Animasi gradien |
![]() | ![]() | ![]() | ![]() |
PENTING!
SkeletonViewadalah rekursif, jadi jika Anda ingin menampilkan kerangka di semua tampilan kerangka, Anda hanya perlu memanggil metode acara di tampilan kontainer utama. Misalnya, denganUIViewControllers.
SkeletonView kompatibel dengan UITableView dan UICollectionView .
UitableView
Jika Anda ingin menampilkan kerangka dalam UITableView , Anda harus menyesuaikan diri dengan protokol 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 )
} Seperti yang Anda lihat, protokol ini mewarisi dari UITableViewDataSource , sehingga Anda dapat mengganti protokol ini dengan protokol kerangka.
Protokol ini memiliki implementasi default untuk beberapa metode. Misalnya, jumlah baris untuk setiap bagian dihitung dalam runtime:
func collectionSkeletonView ( _ skeletonView : UITableView , numberOfRowsInSection section : Int ) -> Int
// Default:
// It calculates how many cells need to populate whole tableviewPENTING!
Jika Anda mengembalikan
UITableView.automaticNumberOfSkeletonRowsdalam metode di atas, ia bertindak seperti perilaku default (yaitu menghitung berapa banyak sel yang diperlukan untuk mengisi seluruh tableview).
Hanya ada satu metode yang perlu Anda terapkan untuk memberi tahu kerangka pengidentifikasi sel. Metode ini tidak memiliki implementasi default:
func collectionSkeletonView ( _ skeletonView : UITableView , cellIdentifierForRowAt indexPath : IndexPath ) -> ReusableCellIdentifier {
return " CellIdentifier "
}Secara default, perpustakaan menghilangkan sel -sel dari masing -masingpath index, tetapi Anda juga dapat melakukan ini jika Anda ingin membuat beberapa perubahan sebelum kerangka muncul:
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
}Jika Anda lebih suka meninggalkan bagian deque ke perpustakaan, Anda dapat mengonfigurasi sel menggunakan metode ini:
func collectionSkeletonView ( _ skeletonView : UITableView , prepareCellForSkeleton cell : UITableViewCell , at indexPath : IndexPath ) {
let cell = cell as? Cell
cell ? . textField . isHidden = indexPath . row == 0
} Selain itu, Anda dapat menjelaskan baik header dan footer. Anda harus menyesuaikan diri dengan Protokol 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
}PENTING!
1️⃣ Jika Anda menggunakan sel yang dapat diputar ulang (
tableView.rowHeight = UITableViewAutomaticDimension), itu wajib menentukanestimatedRowHeight.2️⃣ Ketika Anda menambahkan elemen di
UITableViewCellAnda harus menambahkannya kecontentViewdan tidak ke sel secara langsung.self . contentView . addSubview ( titleLabel ) ✅ self . addSubview ( titleLabel )
UiCollectionView
Untuk UICollectionView , Anda harus menyesuaikan diri dengan protokol 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 )
} Sisa prosesnya sama dengan UITableView

Saat menggunakan elemen dengan teks, SkeletonView menggambar garis untuk mensimulasikan teks.
Anda dapat mengatur beberapa properti untuk elemen multilines.
| Milik | Jenis | Bawaan | Pratinjau |
|---|---|---|---|
| LastLineFillpercent | CGFloat | 70 | ![]() |
| Linescornerradius | Int | 0 | ![]() |
| SkeletonSlinespacing | CGFloat | 10 | ![]() |
| Skeletonpaddinginsets | UIEdgeInsets | .zero | ![]() |
| SkeletontextLineHeight | SkeletonTextLineHeight | .fixed(15) | ![]() |
| SkeletontextNumberoflines | SkeletonTextNumberOfLines | .inherited | ![]() |
Untuk memodifikasi persen atau jari -jari menggunakan kode , atur properti:
descriptionTextView . lastLineFillPercent = 50
descriptionTextView . linesCornerRadius = 5Atau, jika Anda lebih suka menggunakan IB/Storyboard :

Bagaimana cara menentukan jumlah baris?
Secara default, jumlah baris sama dengan nilai properti numberOfLines . Dan, jika diatur ke nol , itu akan menghitung berapa banyak garis yang diperlukan untuk mengisi seluruh kerangka dan menggambarnya.
Namun, jika Anda ingin mengatur jumlah garis kerangka tertentu, Anda dapat melakukannya dengan mengatur properti skeletonTextNumberOfLines . Properti ini memiliki dua nilai yang mungkin, inherited yang mengembalikan nilai numberOfLines dan custom(Int) yang mengembalikan jumlah garis spesifik yang ditentukan sebagai nilai terkait.
Misalnya:
label . skeletonTextNumberOfLines = 3 // .custom(3)
️ DEPRECATED!UsefontLineHeight telah sudah usang. Anda dapat menggunakan SkeletontextLineHeight sebagai gantinya:
descriptionTextView . skeletonTextLineHeight = . relativeToFont
PENTING!
Harap dicatat bahwa untuk tampilan tanpa beberapa baris, baris tunggal akan dianggap sebagai baris terakhir.
Kerangka memiliki penampilan default. Jadi, ketika Anda tidak menentukan properti warna, gradien atau multilines, SkeletonView menggunakan nilai default.
Nilai default:
UIColor.skeletonDefault (sama seperti .clouds tetapi adaptif dengan mode gelap)SkeletonGradient(baseColor: .skeletonDefault)CGFloatCGFloatIntIntCGFloat (ibinspectable) (Buatlah kerangka Anda dengan sudut) Untuk mendapatkan nilai -nilai default ini, Anda dapat menggunakan SkeletonAppearance.default . Menggunakan properti ini Anda dapat mengatur nilainya juga:
SkeletonAppearance . default . multilineHeight = 20
SkeletonAppearance . default . tintColor = . green
️ DEPRECATED!UsefontLineHeight telah sudah usang. Anda dapat menggunakan TextLineHeight sebagai gantinya:
SkeletonAppearance . default . textLineHeight = . relativeToFont
Anda dapat memutuskan warna kerangka yang diwarnai. Anda hanya perlu lulus sebagai parameter warna atau gradien yang Anda inginkan.
Menggunakan warna solid
view . showSkeleton ( usingColor : UIColor . gray ) // Solid
// or
view . showSkeleton ( usingColor : UIColor ( red : 25.0 , green : 30.0 , blue : 255.0 , alpha : 1.0 ) )Menggunakan gradien
let gradient = SkeletonGradient ( baseColor : UIColor . midnightBlue )
view . showGradientSkeleton ( usingGradient : gradient ) // GradientSelain itu, SkeletonView memiliki 20 warna datar ??
UIColor.turquoise, UIColor.greenSea, UIColor.sunFlower, UIColor.flatOrange ...

SkeletonView memiliki dua animasi bawaan, pulsa untuk kerangka solid dan meluncur untuk gradien.
Selain itu, jika Anda ingin melakukan animasi kerangka Anda sendiri, itu sangat mudah.
Skeleton menyediakan fungsi showAnimatedSkeleton yang memiliki penutupan SkeletonLayerAnimation di mana Anda dapat menentukan animasi khusus Anda.
public typealias SkeletonLayerAnimation = ( CALayer ) -> CAAnimationAnda dapat memanggil fungsi seperti ini:
view . showAnimatedSkeleton { ( layer ) -> CAAnimation in
let animation = CAAnimation ( )
// Customize here your animation
return animation
} Ini tersedia SkeletonAnimationBuilder . Ini adalah pembangun untuk membuat SkeletonLayerAnimation .
Hari ini, Anda dapat membuat animasi geser untuk gradien, memutuskan arah dan mengatur durasi animasi (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 adalah enum, dengan kasus ini:
| Arah | Pratinjau |
|---|---|
| .leftright | ![]() |
| .RightLeft | ![]() |
| .topbottom | ![]() |
| .bottomtop | ![]() |
| .topleftbottomright | ![]() |
| .bottomrighttopleft | ![]() |
MENIPU!
Ada cara lain untuk membuat animasi geser, hanya menggunakan jalan pintas ini:
let animation = GradientDirection . leftToRight . slidingAnimation ( )
SkeletonView memiliki transisi bawaan untuk menunjukkan atau menyembunyikan kerangka dengan cara yang lebih halus ?
Untuk menggunakan transisi, cukup tambahkan parameter transition ke fungsi showSkeleton() atau hideSkeleton() dengan waktu transisi, seperti ini:
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 Nilai defaultnya adalah crossDissolve(0.25)
Pratinjau
| Tidak ada | Silang larut |
![]() | ![]() |
Hirarki
Karena SkeletonView bersifat rekursif, dan kami ingin kerangka menjadi sangat efisien, kami ingin menghentikan rekursi sesegera mungkin. Untuk alasan ini, Anda harus mengatur tampilan kontainer sebagai Skeletonable , karena kerangka akan berhenti mencari subview skeletonable segera setelah tampilan tidak dapat kerangka, pecah kemudian rekursi.
Karena suatu gambar bernilai ribuan kata:
Dalam contoh ini kami memiliki UIViewController dengan ContainerView dan UITableView . Saat tampilan sudah siap, kami menampilkan kerangka menggunakan metode ini:
view.showSkeleton()
isSkeletonable= ☠️
| Konfigurasi | Hasil |
|---|---|
![]() | ![]() |
![]() | ![]() |
![]() | ![]() |
![]() | ![]() |
![]() | ![]() |
![]() | ![]() |
Tata Letak Tampilan Kerangka
Terkadang tata letak kerangka mungkin tidak sesuai dengan tata letak Anda karena batas tampilan induk telah berubah. Misalnya, memutar perangkat.
Anda dapat menyampaikan tampilan kerangka seperti itu seperti:
override func viewDidLayoutSubviews ( ) {
view . layoutSkeletonIfNeeded ( )
}PENTING!
Anda seharusnya tidak menyebut metode ini. Dari versi 1.8.1 Anda tidak perlu memanggil metode ini, pustaka tidak secara otomatis. Jadi, Anda dapat menggunakan metode ini hanya dalam kasus ketika Anda perlu memperbarui tata letak kerangka secara manual.
Perbarui kerangka
Anda dapat mengubah konfigurasi kerangka kapan saja seperti warna, animasinya, dll. Dengan metode berikut:
( 1 ) view . updateSkeleton ( ) // Solid
( 2 ) view . updateGradientSkeleton ( ) // Gradient
( 3 ) view . updateAnimatedSkeleton ( ) // Solid animated
( 4 ) view . updateAnimatedGradientSkeleton ( ) // Gradient animatedMenyembunyikan tampilan saat animasi dimulai
Terkadang Anda ingin menyembunyikan beberapa tampilan saat animasi dimulai, jadi ada properti cepat yang dapat Anda gunakan untuk mewujudkannya:
view . isHiddenWhenSkeletonIsActive = true // This works only when isSkeletonable = trueJangan memodifikasi interaksi pengguna saat kerangka aktif
Secara default, interaksi pengguna dinonaktifkan untuk item kerangka, tetapi jika Anda tidak ingin memodifikasi indikator interaksi pengguna saat kerangka aktif, Anda dapat menggunakan properti isUserInteractionDisabledWhenSkeletonIsActive :
view . isUserInteractionDisabledWhenSkeletonIsActive = false // The view will be active when the skeleton will be active.Jangan gunakan ketinggian garis font untuk garis kerangka dalam label
Salah untuk menonaktifkan kerangka ke otomatis sesuai dengan tinggi font untuk UILabel atau UITextView . Secara default, ketinggian garis kerangka disesuaikan secara otomatis ke ketinggian font untuk lebih akurat mencerminkan teks dalam label rect daripada menggunakan kotak pembatas.
label . useFontLineHeight = falseKerangka pertunjukan yang tertunda
Anda dapat menunda penyajian kerangka jika tampilan diperbarui dengan cepat.
func showSkeleton ( usingColor : UIColor ,
animated : Bool ,
delay : TimeInterval ,
transition : SkeletonTransitionStyle ) func showGradientSkeleton ( usingGradient : SkeletonGradient ,
animated : Bool ,
delay : TimeInterval ,
transition : SkeletonTransitionStyle )Debug
Untuk memfasilitasi tugas debug ketika ada sesuatu yang tidak berfungsi dengan baik. SkeletonView memiliki beberapa alat baru.
Pertama, UIView memiliki properti dengan info kerangka:
var sk . skeletonTreeDescription : String Selain itu, Anda dapat mengaktifkan mode debug baru. Anda cukup menambahkan variabel lingkungan SKELETON_DEBUG dan mengaktifkannya.

Kemudian, ketika kerangka muncul, Anda dapat melihat hierarki tampilan di konsol Xcode.
{
"type" : "UIView", // UITableView, UILabel...
"isSkeletonable" : true,
"reference" : "0x000000014751ce30",
"children" : [
{
"type" : "UIView",
"isSkeletonable" : true,
"children" : [ ... ],
"reference" : "0x000000014751cfa0"
}
]
}
Versi OS & SDK yang didukung
Ini adalah proyek open source, jadi jangan ragu untuk berkontribusi. Bagaimana?
Lihat semua kontributor
Untuk informasi lebih lanjut, silakan baca pedoman yang berkontribusi.
Proyek sumber terbuka tidak dapat hidup lama tanpa bantuan Anda. Jika Anda menemukan skeletonView berguna, silakan pertimbangkan untuk mendukung proyek ini dengan menjadi sponsor.
Menjadi sponsor melalui sponsor gitub ❤️
Juanpe Catalán
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.