{"id":16907003,"url":"https://github.com/hyun99999/skeletonviewtutorial-ios","last_synced_at":"2025-04-11T15:36:51.634Z","repository":{"id":104425079,"uuid":"389117357","full_name":"hyun99999/SkeletonViewTutorial-iOS","owner":"hyun99999","description":"☠️ 오픈소스 라이브러리 SkeletonView 을 활용한 튜토리얼","archived":false,"fork":false,"pushed_at":"2021-07-24T15:52:59.000Z","size":224,"stargazers_count":6,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-03-25T11:49:19.472Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Swift","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/hyun99999.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2021-07-24T14:25:26.000Z","updated_at":"2021-07-25T12:15:28.000Z","dependencies_parsed_at":null,"dependency_job_id":"0ba3e231-fc00-4b57-9cc8-24374bd41525","html_url":"https://github.com/hyun99999/SkeletonViewTutorial-iOS","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hyun99999%2FSkeletonViewTutorial-iOS","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hyun99999%2FSkeletonViewTutorial-iOS/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hyun99999%2FSkeletonViewTutorial-iOS/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hyun99999%2FSkeletonViewTutorial-iOS/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/hyun99999","download_url":"https://codeload.github.com/hyun99999/SkeletonViewTutorial-iOS/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248432238,"owners_count":21102338,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-10-13T18:45:35.905Z","updated_at":"2025-04-11T15:36:51.621Z","avatar_url":"https://github.com/hyun99999.png","language":"Swift","readme":"# SkeletonViewTutorial\n☠️ 오픈소스 라이브러리 SkeletonView 를 사용해보자\n\n\u003cimg src = \"https://user-images.githubusercontent.com/69136340/126873750-e176c158-7a68-41c2-a768-73359bf3fdcb.gif\" width =\"250\"\u003e\n\n[GitHub - Juanpe/SkeletonView](https://github.com/Juanpe/SkeletonView)\n\n- SkeletonView 는 사용자에게 어떤 일이 일어나고 있음을 보여주고 어떤 콘텐츠를 기다리고 있는지 준비하는 방법으로 소개된다.\n\n### Installation\n\n- CocoaPods:\n\n```swift\npod 'SkeletonView'\n```\n\n### Usage\n\n1️⃣ 적당한 곳에 import 한다.\n\n```swift\nimport SkeletonView\n```\n\n2️⃣ view 를 `skeletonables` 하게 만드는 방법은 2가지가 있다.\n\n**Using code:**\n\n```\navatarImageView.isSkeletonable = true\n```\n\n**Using IB/Storyboards:**\n\n\u003cimg width=\"300\" alt=\"1\" src=\"https://user-images.githubusercontent.com/69136340/126871520-7f4a2ce0-b00b-42a2-b599-330c43e82274.png\"\u003e\n\n3️⃣ 다음 4가지 선택으로 skeleton 을 보여줄 수 있다.\n\n```swift\n(1) view.showSkeleton()                 // Solid\n(2) view.showGradientSkeleton()         // Gradient\n(3) view.showAnimatedSkeleton()         // Solid animated\n(4) view.showAnimatedGradientSkeleton() // Gradient animated\n```\n\n📣 **IMPORTANT!**\n\n`SkeletonView` 은 재귀적이기 때문에 모든 skeletonable view 에서 skeleton 을 보여주고 싶다면 메인 컨테이너 뷰에서 위의 show 메서드를 호출하면 된다.\n\n---\n\n**UITableView**\n\nUITableView 에서 skeleton 을 사용하고 싶다면 `SkeletonTableViewDataSource` 프로토콜을 채택해야한다.\n\n```swift\npublic protocol SkeletonTableViewDataSource: UITableViewDataSource {\n    func numSections(in collectionSkeletonView: UITableView) -\u003e Int // Default: 1\n    func collectionSkeletonView(_ skeletonView: UITableView, numberOfRowsInSection section: Int) -\u003e Int\n    func collectionSkeletonView(_ skeletonView: UITableView, cellIdentifierForRowAt indexPath: IndexPath) -\u003e ReusableCellIdentifier\n    func collectionSkeletonView(_ skeletonView: UITableView, skeletonCellForRowAt indexPath: IndexPath) -\u003e UITableViewCell? // Default: nil\n    func collectionSkeletonView(_ skeletonView: UITableView, prepareCellForSkeleton cell: UITableViewCell, at indexPath: IndexPath)\n}\n```\n\n보는 것처럼 SkeletonTableViewDataSource 는 UITableViewDataSource 를 상속받기 때문에 대체 가능하다.\n\n**UICollectionView**\n\n `UICollectionView` 에서는 `SkeletonCollectionViewDataSource` 프로토콜을 채택해야 한다.\n\n```swift\npublic protocol SkeletonCollectionViewDataSource: UICollectionViewDataSource {\n    func numSections(in collectionSkeletonView: UICollectionView) -\u003e Int  // default: 1\n    func collectionSkeletonView(_ skeletonView: UICollectionView, numberOfItemsInSection section: Int) -\u003e Int\n    func collectionSkeletonView(_ skeletonView: UICollectionView, cellIdentifierForItemAt indexPath: IndexPath) -\u003e ReusableCellIdentifier\n    func collectionSkeletonView(_ skeletonView: UICollectionView, supplementaryViewIdentifierOfKind: String, at indexPath: IndexPath) -\u003e ReusableCellIdentifier? // default: nil\n    func collectionSkeletonView(_ skeletonView: UICollectionView, skeletonCellForItemAt indexPath: IndexPath) -\u003e UICollectionViewCell?  // default: nil\n    func collectionSkeletonView(_ skeletonView: UICollectionView, prepareCellForSkeleton cell: UICollectionViewCell, at indexPath: IndexPath)\n}\n```\n\n### **🔠 Texts**\n\n텍스트가 있는 elements 를 사용할 때 `SkeletonView` 는 시뮬레이션하기 위해서 그려본다. 게다가 원하는 라인 수를 결정할 수 있다. `numberOfLines` 이 0 으로 설정되어 있다면 전체 골격을 채우는 데 필요한 선 수를 계산하여 그려진다. 대신 0보다 큰 숫자로 설정하면 이 수의 선만 그린다.\n\n```swift\n// Corner radius of lines \n// 0...100 (default: 70)\ndescriptionTextView.lastLineFillPercent = 50\n\n// Filling percent of the last line.\n// 0...10 (default: 0)\ndescriptionTextView.linesCornerRadius = 5\n```\n\n- storyboard 에서도 설정 가능\n\nCorner radius of lines.\n\n\u003cimg width=\"600\" alt=\"스크린샷 2021-07-24 오후 8 52 49\" src=\"https://user-images.githubusercontent.com/69136340/126871530-b81e8430-93c0-4cc5-90fe-34168f7ff867.png\"\u003e\n\nFilling percent of the last line.\n\n\u003cimg width=\"600\" alt=\"스크린샷 2021-07-24 오후 8 53 12\" src=\"https://user-images.githubusercontent.com/69136340/126871534-6af34ddf-355b-4626-8138-972becf2c314.png\"\u003e\n\n### 실습해보자\n\n- ViewController.swift\n\n```swift\nimport UIKit\nimport SkeletonView\n\nclass ViewController: UIViewController {\n    var countData: [Int] = []\n\n    // MARK: - @IBOutlet Properties\n    @IBOutlet weak var skeletonCollectionView: UICollectionView!\n    \n    // MARK: - View Life Cycle\n    override func viewDidLoad() {\n        super.viewDidLoad()\n        \n        skeletonCollectionView.delegate = self\n        skeletonCollectionView.dataSource = self\n        skeletonCollectionView.register(UINib(nibName: \"SkeletonCollectionViewCell\", bundle: nil), forCellWithReuseIdentifier: \"SkeletonCollectionViewCell\")\n        \n        skeletonCollectionView.isSkeletonable = true\n        skeletonCollectionView.showSkeleton()\n        // 다음과 같이 설정 가능\n//        skeletonCollectionView.showSkeleton(usingColor: .clouds, transition: .crossDissolve(0.25))\n        \n        // 네트워크 통신 대신 DisdspatchQueue 를 통해서 2초간 딜레이를 주어서 구현\n        DispatchQueue.main.asyncAfter(deadline: .now() + 2) {\n            for i in 0..\u003c10 {\n                self.countData.append(i)\n            }\n            \n            self.skeletonCollectionView.stopSkeletonAnimation()\n            self.skeletonCollectionView.hideSkeleton()\n            // 다음과 같이 설정 가능\n    //        skeletonCollectionView.hideSkeleton(reloadDataAfter: true, transition: .crossDissolve(0.25))\n        }\n    }\n}\n```\n\nexestion\n\n```swift\n// MARK: - SkeletonTableViewDelegate\nextension ViewController: SkeletonCollectionViewDelegate { }\n\n// MARK: - SkeletonTableViewDataSource\nextension ViewController: SkeletonCollectionViewDataSource {\n    func collectionSkeletonView(_ skeletonView: UICollectionView, cellIdentifierForItemAt indexPath: IndexPath) -\u003e ReusableCellIdentifier {\n        return \"SkeletonCollectionViewCell\"\n    }\n    \n    func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -\u003e Int {\n        return countData.count\n    }\n    \n    func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -\u003e UICollectionViewCell {\n        guard let cell = collectionView.dequeueReusableCell(withReuseIdentifier: \"SkeletonCollectionViewCell\", for: indexPath) as? SkeletonCollectionViewCell else {\n            return UICollectionViewCell()\n        }\n        cell.skeletonImageView.image = UIImage(named: \"icon\") ?? UIImage()\n        cell.skeletonFirstLabel.text = String(countData[indexPath.row])\n        cell.skeletonTextView.text = String(countData[indexPath.row])\n\n        return cell\n    }\n    \n    // skeletonView 으로 보여질 section 의 item 개수\n    func collectionSkeletonView(_ skeletonView: UICollectionView, numberOfItemsInSection section: Int) -\u003e Int {\n        \n        // 아래의 코드로 컬렉션뷰를 다 채울 수 있다.\n        return UICollectionView.automaticNumberOfSkeletonItems\n    }\n}\n\nextension ViewController: UICollectionViewDelegateFlowLayout {\n    func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -\u003e CGSize {\n        let cellWidth = collectionView.frame.width\n        return CGSize(width: cellWidth, height: 150)\n    }\n}\n```\n\n- SkeletonCollectionViewCell.xib\n\n\u003cimg width=\"600\" alt=\"스크린샷 2021-07-25 오전 12 28 53\" src=\"https://user-images.githubusercontent.com/69136340/126873478-8708bf20-4535-49f0-8a69-ccca05445fc5.png\"\u003e\n\n- SkeletonCollectionViewCell.swift\n\n```swift\nimport UIKit\n\nclass SkeletonCollectionViewCell: UICollectionViewCell {\n    \n\n    @IBOutlet weak var skeletonTextView: UITextView!\n    @IBOutlet weak var skeletonFirstLabel: UILabel!\n    @IBOutlet weak var skeletonImageView: UIImageView!\n    \n    override func awakeFromNib() {\n        super.awakeFromNib()\n        \n        self.isSkeletonable = true\n        self.skeletonImageView.isSkeletonable = true\n        self.skeletonFirstLabel.isSkeletonable = true\n        self.skeletonTextView.isSkeletonable = true\n        \n        // 둥근 모서리\n        \n        self.skeletonImageView.skeletonCornerRadius = 10\n        self.skeletonFirstLabel.linesCornerRadius = 5\n        self.skeletonTextView.linesCornerRadius = 5\n\n        // 마지막 줄에 skeleton 채우는 비율\n        \n        // numberOfLines 가 1 이면 적용되지 않음\n        self.skeletonFirstLabel.numberOfLines = 2\n        self.skeletonFirstLabel.lastLineFillPercent = 50\n\n        self.skeletonTextView.lastLineFillPercent = 50\n    }\n}\n```\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fhyun99999%2Fskeletonviewtutorial-ios","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fhyun99999%2Fskeletonviewtutorial-ios","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fhyun99999%2Fskeletonviewtutorial-ios/lists"}