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
- Protocol
- 리팩토링
- map
- 애니메이션
- uitableview
- tableView
- Clean Code
- MVVM
- swiftUI
- clean architecture
- HIG
- UITextView
- RxCocoa
- rxswift
- 스위프트
- uiscrollview
- combine
- ribs
- swift documentation
- 리펙터링
- collectionview
- 리펙토링
- 클린 코드
- Observable
- ios
- Human interface guide
- SWIFT
- Xcode
- Refactoring
- UICollectionView
Archives
- Today
- Total
김종권의 iOS 앱 개발 알아가기
[iOS - swift] custom loading 구현 방법 (UIWindow 사용) 본문
Custom Loading 구현 아이디어
- 최상위 UIWindow는 UIView를 서브클래싱한 인스턴스이므로, window.addSubview하여 커스텀 로딩 화면을 넣어주면 UIWindow하위에 존재하는 현재 화면위에 로딩이 뜨도록 구현
- Loading 애니메이션은 Lottie 사용
사용한 프레임워크
pod 'lottie-ios'
pod 'SnapKit'
UIWindow 개념
- UIWindow는 사용자에게 보여지는 화면을 담고 있는 최상위 ContainerView
- 실제로도 UIWindow는 UIView의 서브클래스
- 이 밖에도 UI 이벤트 처리도 같이 담당
- 싱글톤인, AppDelegate로 window에 접근하여 사용할 수 있도록 AppDelegate에 아래 코드 추가
static var window: UIWindow { (UIApplication.shared.delegate?.window!)! }
Custom Loading 뷰 구현
- 사용하는쪽에서 로딩 뷰의 auto layout을 화면에 꽉차게 해놓고 사용
- 커스텀 로딩 뷰 UI 구성
- 원래 가지고 있는 view - 아래 깔려있는 뷰들을 눌러도 interaction이 동작하지 않게끔 가려지는 역할
- contentView - 이 뷰의 addSubview되게하고, 혹시 다른 인터렉션이 필요한 경우 이 위에다 UI를 배치
- loadingView - Lottie 프레임워크에서 지원해주는 AnimationView이며, 애니메이션 재생에 사용
import UIKit
import Lottie
import SnapKit
final class MyLoadingView: UIView {
private let contentView: UIView = {
let view = UIView()
view.backgroundColor = .white
view.alpha = 0
return view
}()
private let loadingView: AnimationView = {
let view = AnimationView(name: "loading_ball")
view.loopMode = .loop
return view
}()
}
- 레이아웃
override init(frame: CGRect) {
super.init(frame: frame)
self.backgroundColor = .black.withAlphaComponent(0.3)
self.addSubview(self.contentView)
self.contentView.addSubview(self.loadingView)
self.contentView.snp.makeConstraints {
$0.center.equalTo(self.safeAreaLayoutGuide)
}
self.loadingView.snp.makeConstraints {
$0.center.equalTo(self.safeAreaLayoutGuide)
$0.size.equalTo(300)
}
}
- show와 hide 메소드 구현
- show 메소드에서는 window에 넣는것임을 주의
- 로딩 화면이 서서히 보여지는 애니메이션을 주기 위해서 alpha값을 이용
func show() {
guard !AppDelegate.window.subviews.contains(where: { $0 is MyLoadingView }) else { return }
AppDelegate.window.addSubview(self)
self.snp.makeConstraints {
$0.edges.equalToSuperview()
}
self.layoutIfNeeded()
self.loadingView.play()
UIView.animate(
withDuration: 0.7,
animations: { self.contentView.alpha = 1 }
)
}
func hide(completion: @escaping () -> () = {}) {
self.loadingView.stop()
self.removeFromSuperview()
completion()
}
로딩뷰를 사용하는 쪽
- 인스턴스를 만들어서 show()
// ViewController.swift
@objc private func didTapButton() {
let loadingView = MyLoadingView()
loadingView.show()
DispatchQueue.main.asyncAfter(deadline: .now() + 5) {
loadingView.hide {
self.loadingButton.setTitle("로딩 종료!", for: .normal)
}
}
}
- 위와같이 사용해도 괜찮지만, 위 인스턴스는 단순히 show(), hide()메소드만 호출하므로 싱글톤으로 만들어서 사용하면 깔끔한 코드 완성
// MyLoadingView.swift
final class MyLoadingView: UIView {
static let shared = MyLoadingView()
...
private init() {
...
}
...
}
// ViewController.swift
@objc private func didTapButton() {
MyLoadingView.shared.show()
DispatchQueue.main.asyncAfter(deadline: .now() + 5) {
MyLoadingView.shared.hide() {
self.loadingButton.setTitle("로딩 종료!", for: .normal)
}
}
}
* 전체 코드: https://github.com/JK0369/ExCustomLoading
* 참고
'iOS 기본 (swift)' 카테고리의 다른 글
Comments