Notice
Recent Posts
Recent Comments
Link
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |
Tags
- SWIFT
- Clean Code
- uitableview
- 리펙터링
- combine
- ribs
- swiftUI
- Xcode
- UITextView
- Protocol
- rxswift
- Human interface guide
- MVVM
- clean architecture
- UICollectionView
- uiscrollview
- swift documentation
- 리팩토링
- 리펙토링
- tableView
- Refactoring
- ios
- 스위프트
- RxCocoa
- 클린 코드
- HIG
- 애니메이션
- Observable
- map
- collectionview
Archives
- Today
- Total
김종권의 iOS 앱 개발 알아가기
[iOS - swift] SkeletonView 스켈레톤 뷰 (로딩 뷰) 본문
프레임워크
- SkeletonView
pod 'SkeletonView'
- 코드로 UI 작성에 편리를 위해 사용한 프레임워크
pod 'Then' pod 'SnapKit'
Label 2개에 SkeletonView 적용 방법
- 적용하려는 View에 isSkeletonView = true로 skeleton 활성화
import SkeletonView ... label1.isSkeletonable = true label2.isSkeletonable = true
- label1과 label2의 superView에도 isSkeletonable = true 활성화
self.view.isSkeletonable = true
- SkeletonView 프레임워크는 superview.showSkeleton()하면 subview들도 모두 skeleton이 동작하므로, 아래 코드로 skeleton 실행
self.view.showSkeleton()
- skeleton의 종류
// https://swiftobc.com/repo/Juanpe-SkeletonView-swift-ui (1) view.showSkeleton() // Solid (2) view.showGradientSkeleton() // Gradient (3) view.showAnimatedSkeleton() // Solid animated (4) view.showAnimatedGradientSkeleton() // Gradient animated
- skeleton을 종료하고 싶은 경우 stopSkeleton()
self.view.showSkeleton() DispatchQueue.main.asyncAfter(deadline: .now() + 3) { self.view.hideSkeleton() }
- 애니메이션을 주고 싶은 경우,SkeletonAnimationBuilder() 객체 사용
- showAnimatedGradientSkeleton에서 transition값은 스켈레톤 애니메이션이 보여질때와 사라질때의 transition 정의
let skeletonAnimation = SkeletonAnimationBuilder().makeSlidingAnimation(withDirection: .leftRight) self.view.showAnimatedGradientSkeleton(usingGradient: .init(colors: [.lightGray, .gray]), animation: skeletonAnimation, transition: .none) DispatchQueue.main.asyncAfter(deadline: .now() + 3) { self.view.hideSkeleton() }
- showAnimatedGradientSkeleton에서 transition값은 스켈레톤 애니메이션이 보여질때와 사라질때의 transition 정의
cf) withDirection에 들어갈 수 있는 값
TableView의 Cell 내용에 Skeleton 적용 방법
- UITableViewDataSource의 성격을 가지고 있는 SkeletonTableViewDataSource 준수하여 DataSource 완성
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) }
- 구현
self.tableView.dataSource = self ... extension ViewController: SkeletonTableViewDataSource { // tableView func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { self.dataSource.count } func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath) as! MyCell let data = dataSource[indexPath.row] cell.prepare(picture: data.image, title: data.title, description: data.description) return cell } // skeletonView func collectionSkeletonView(_ skeletonView: UITableView, cellIdentifierForRowAt indexPath: IndexPath) -> ReusableCellIdentifier { return "cell" } func collectionSkeletonView(_ skeletonView: UITableView, skeletonCellForRowAt indexPath: IndexPath) -> UITableViewCell? { skeletonView.dequeueReusableCell(withIdentifier: "cell", for: indexPath) } func collectionSkeletonView(_ skeletonView: UITableView, numberOfRowsInSection section: Int) -> Int { UITableView.automaticNumberOfSkeletonRows // <- 편리하게 사용 가능 } func numSections(in collectionSkeletonView: UITableView) -> Int { 1 } }
- 주의해야할 사항
- 주의 - Cell 자체에도 isSkeletonenable = true 설정 필요
import UIKit import SnapKit import SkeletonView class MyCell: UITableViewCell { // 각 UI에 $0.isSkeletonable = true 필요 (titleLabel.isSkeletonable = true) // 자체 cell에다가도 isSkeletonable = true 필요 override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) { super.init(style: style, reuseIdentifier: reuseIdentifier) self.isSkeletonable = true // <- self.contentView.isSkeletonable = true // <- ... } }
- 주의 - Cell 자체에도 isSkeletonenable = true 설정 필요
- 사용하는 쪽
override func viewDidLoad() { super.viewDidLoad() ... let skeletonAnimation = SkeletonAnimationBuilder().makeSlidingAnimation(withDirection: .leftRight) self.view.showAnimatedGradientSkeleton(usingGradient: .init(colors: [.lightGray, .gray]), animation: skeletonAnimation, transition: .none) self.fetchDataSource() } private func fetchDataSource() { DispatchQueue.main.asyncAfter(deadline: .now() + 3) { let datas = (0...30) .map { MyData( image: UIImage(named: "jake"), title: "title \($0)", description: "description \($0)" ) } self.dataSource.append(contentsOf: datas) self.tableView.reloadData() self.view.hideSkeleton(reloadDataAfter: true, transition: .crossDissolve(0.5)) } }
cf) UICollectionView에서 skeleton 적용 방법
- 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)
}
* 전체 코드: https://github.com/JK0369/ExSkeletonView
* 참고
'iOS framework' 카테고리의 다른 글
[iOS - swift] json, codable, nestedContainer(keyedBy:forKey:), KeyedCodable로 중첩 모델 처리 방법 (0) | 2022.02.09 |
---|---|
[iOS - swift] UITextView placeholder 프레임워크 (UITextView+Placeholder) (0) | 2022.01.30 |
[iOS - swift] DragDropCollectionView 프레임워크 (0) | 2022.01.14 |
[iOS - swift] Starscream을 이용한 WebSockets (웹 소켓) 사용 방법 (0) | 2022.01.08 |
[iOS - swift] Firebase Analytics 사용 방법, 이벤트 로깅, logEvent() (5) | 2022.01.07 |
Comments