swift custom loading view, custom indicator
만들어볼 custom indicator
네트워크 통신을 할때, 앱위에 로딩뷰나 인디케이터를 띄워준다. 사용자에게 무언가가 일어나고있다는 걸 보여주고, 작동중이니 걱정말라는 표시도 될 수 있다. 너무 길어지면 안되겠지만.
위 그림처럼 start 버튼을 누르면 이미지가 다양하게 바뀌면서 loading view 를 띄워주거나, indicator 를 띄워주는 예제를 정리해보았다.
먼저 loading view는 아래와 같이 스토리 보드로 만들어주었다. UIView type의 커스텀 클래스를 하나 만들어서 스토리 보드와 이어준다.
loading view나 custom indicator 만드는 방법은 여러가지가 있을 것 같다.
나는 custom view를 이용했고, timer를 이용했다.
그리고 이미지이름 배열을 이용해서 timer 0.3초마다 이미지가 바뀌도록 처리했다.
메소드는 시작 함수와 종료 함수를 만들었다.
그럼 IndicatorView를 어디서 호출해주나?
import UIKit
class IndicatorView: UIView {
var timer:Timer?
@IBOutlet weak var loadingImage: UIImageView!
@IBOutlet weak var loadingLabel: UILabel!
let imageNames = ["wand.and.rays" , "wand.and.rays.inverse", "wand.and.stars", "wand.and.stars.inverse"]
//MARK: 초기화
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
loadXib()
}
override init(frame: CGRect) {
super.init(frame: frame)
loadXib()
}
//MARK: Xib 로드
private func loadXib(){
//self 는 최상위 view - 보이지 않음
self.tag = 100
let identifier = String(describing: type(of: self))
let nibs = Bundle.main.loadNibNamed(identifier, owner: self, options: nil)
// 첫번째 Nib 중에서 첫번째 View
guard let customView = nibs?.first as? UIView else {return}
customView.frame = self.bounds
customView.backgroundColor = UIColor(white: 1, alpha: 0.3)
//customView.tag = 100
self.addSubview(customView)
}
//MARK: 시작
public func startLoading(){
var i = 0
timer = Timer.scheduledTimer(withTimeInterval: 0.3, repeats: true) { timer in
if i >= self.imageNames.count { i = 0 }
self.loadingImage.image = UIImage(systemName: self.imageNames[i])
i += 1
}
}
//MARK: 정지
public func stopLoading(){
timer?.invalidate()
}
}
IndicatorView는 어느화면에서 꼭 필요한 화면이다. 그렇기 때문에 싱글톤 클래스를 만들어서 그 싱글톤 클래스가 indicatorVIew를 컨트롤할 수있게 해보았다.
아래 처럼 Center 라는 싱글톤 클래스를 만들어주고 , indicatorView를 띄워주는 함수, 숨기는 함수를 만들었다. 그리고 indicator view, loading view를 최상위 view 위에 띄워야 되므로, 최상위 view를 구하는 함수도 만들어 주었다.
import Foundation
import UIKit
class Center {
//MARK: 로딩뷰
var indicatorView:IndicatorView?
static let shared = Center()
private init(){ }
//MARK: 보이기
func showLoadingPage(_view:UIViewController) {
let width = getRootViewController(vc: _view)?.view.frame.size.width ?? 0
let height = getRootViewController(vc: _view)?.view.frame.size.height ?? 0
indicatorView = IndicatorView(frame: CGRect(x: 0, y: 0, width: width , height: height))
if let indicatorView = indicatorView {
indicatorView.startLoading()
self.getRootViewController(vc:_view)?.view.addSubview(indicatorView)
}
}
//MARK: 숨기기
func hideLoadingPage(_view:UIViewController) {
// loading View의 tag 는 100
if let loadingView = self.getRootViewController(vc: _view)?.view.viewWithTag(100) {
indicatorView?.stopLoading()
loadingView.removeFromSuperview()
}
}
/**
# getRootViewController
- Author: k
- Date:
- Parameters:
- vc: rootViewController 혹은 UITapViewController
- Returns: UIViewController?
- Note: vc내에서 가장 최상위에 있는 뷰컨트롤러 반환
*/
public func getRootViewController(vc:UIViewController) ->UIViewController?{
///[1] 네비게이션 컨트롤러
if let nc = vc as? UINavigationController {
if let vcOfnavController = nc.visibleViewController {
return self.getRootViewController(vc: vcOfnavController)
}
///[2] 탭뷰 컨트롤러
}else if let tc = vc as? UITabBarController {
if let tcOfnavControler = tc.selectedViewController {
return self.getRootViewController(vc: tcOfnavControler)
}
///[3] 뷰 컨트롤러
}else{
if let pvc = vc.presentedViewController{
return self.getRootViewController(vc: pvc)
}else {
return vc
}
}
return nil
}
}
그리고 마지막으로 아래와 같이 위에서 만든 싱글톤 클래스를 사용해서 indicator 를 호출해주면 끝~
import UIKit
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
}
@IBAction func showLoadingImag(_ sender: UIButton) {
print("ViewController - showLoadingImag")
Center.shared.showLoadingPage(_view: self)
_ = Timer.scheduledTimer(withTimeInterval: 6, repeats: false) { _ in
Center.shared.hideLoadingPage(_view: self)
}
}
@IBAction func stopAction(_ sender: UIButton) {
print("ViewController - stopAction")
}
}
'아이폰 개발 > Swift' 카테고리의 다른 글
swift 메소드 정리 (0) | 2022.10.31 |
---|---|
swift DispatchGroup 과 DispatchSemaphore 실무에 사용+ 실험 (0) | 2021.12.07 |
swift AVAudioPlayer 로 음악앱 만들기 (0) | 2021.10.10 |
swift network conection 체크 - 인터넷 연결 체크 (0) | 2021.10.06 |
swift stackview 안에 view 동적으로 생성하기 (0) | 2021.10.05 |