Swift로 안드로이드 스타일 로딩 뷰 구현하기: Circular Loading View

작성일 :

Swift로 안드로이드 스타일 로딩 뷰 구현하기: Circular Loading View

안드로이드 개발 환경에서는 원형으로 돌아가는 로딩 애니메이션이 매우 일반적입니다. 이러한 로딩 뷰는 사용자 경험을 향상시키고, 로드 중임을 명확하게 전달하는 데 유용합니다. 이 글에서는 Swift를 사용하여 iOS에서 안드로이드 스타일의 원형 로딩 뷰를 구현하는 방법을 설명하겠습니다.

1. 프로젝트 설정

새로운 Xcode 프로젝트 생성

먼저, 새로운 Xcode 프로젝트를 생성합니다. Single View App 템플릿을 선택한 후 프로젝트 이름과 기타 설정을 지정합니다. 여기서는 프로젝트 이름을 CircularLoadingViewDemo로 설정하겠습니다.

swift
import UIKit
import Foundation

2. 커스텀 로딩 뷰 클래스 만들기

팀에서 재사용할 수 있는 커스텀 로딩 뷰를 만들기 위해 새로운 Swift 파일을 생성합니다. 파일 이름은 CircularLoadingView로 합니다.

CircularLoadingView 클래스 구현

swift
class CircularLoadingView: UIView {
    private var spinnerLayer: CAShapeLayer!

    override init(frame: CGRect) {
        super.init(frame: frame)
        setupLayer()
    }

    required init?(coder: NSCoder) {
        super.init(coder: coder)
        setupLayer()
    }

    private func setupLayer() {
        spinnerLayer = CAShapeLayer()
        layer.addSublayer(spinnerLayer)
        configureSpinnerLayer()
    }

    private func configureSpinnerLayer() {
        let arcCenter = CGPoint(x: bounds.width / 2, y: bounds.height / 2)
        let radius = min(bounds.width, bounds.height) / 2.0
        let startAngle = CGFloat(-Double.pi / 2)
        let endAngle = CGFloat(1.5 * Double.pi)

        let path = UIBezierPath(arcCenter: arcCenter, radius: radius, startAngle: startAngle, endAngle: endAngle, clockwise: true)
        spinnerLayer.path = path.cgPath
        spinnerLayer.strokeColor = UIColor.blue.cgColor
        spinnerLayer.fillColor = UIColor.clear.cgColor
        spinnerLayer.lineWidth = 5
        spinnerLayer.lineCap = .round

        startSpinning()
    }

    private func startSpinning() {
        let rotationAnimation = CABasicAnimation(keyPath: "transform.rotation")
        rotationAnimation.fromValue = 0
        rotationAnimation.toValue = Double.pi * 2
        rotationAnimation.duration = 1
        rotationAnimation.repeatCount = .infinity
        spinnerLayer.add(rotationAnimation, forKey: "rotation")
    }
}

클래스를 정의하고 스피너 레이어를 설정하는 초기화 메서드(init)와 스피너 레이어의 구성 메서드를 작성했습니다. CABasicAnimation을 사용하여 스피너가 무한히 회전하도록 했습니다.

3. 뷰 컨트롤러에 CircularLoadingView 추가하기

이제 이 커스텀 뷰를 뷰 컨트롤러에 추가해 보겠습니다. ViewController.swift 파일을 열어 다음과 같이 작성합니다.

swift
import UIKit

class ViewController: UIViewController {
    private var loadingView: CircularLoadingView!

    override func viewDidLoad() {
        super.viewDidLoad()
        view.backgroundColor = .white
        addLoadingView()
    }

    private func addLoadingView() {
        let size: CGFloat = 100
        let frame = CGRect(x: (view.bounds.width - size) / 2, y: (view.bounds.height - size) / 2, width: size, height: size)
        loadingView = CircularLoadingView(frame: frame)
        view.addSubview(loadingView)
    }
}

이제 프로젝트를 빌드하고 실행하면 원형 로딩 뷰가 화면 중앙에서 회전하는 것을 볼 수 있습니다.

4. 사용자 정의 옵션 추가

필요에 따라 더 많은 사용자 정의 옵션을 추가할 수 있습니다. 예를 들어, 스피너의 색상, 선 두께 등을 매개변수로 받아 설정할 수 있도록 합니다.

CircularLoadingView 개선

swift
class CircularLoadingView: UIView {
    private var spinnerLayer: CAShapeLayer!
    var lineWidth: CGFloat = 5 {
        didSet {
            spinnerLayer.lineWidth = lineWidth
        }
    }
    var spinnerColor: UIColor = .blue {
        didSet {
            spinnerLayer.strokeColor = spinnerColor.cgColor
        }
    }

    override init(frame: CGRect) {
        super.init(frame: frame)
        setupLayer()
    }

    required init?(coder: NSCoder) {
        super.init(coder: coder)
        setupLayer()
    }

    private func setupLayer() {
        spinnerLayer = CAShapeLayer()
        layer.addSublayer(spinnerLayer)
        configureSpinnerLayer()
    }

    private func configureSpinnerLayer() {
        let arcCenter = CGPoint(x: bounds.width / 2, y: bounds.height / 2)
        let radius = min(bounds.width, bounds.height) / 2.0
        let startAngle = CGFloat(-Double.pi / 2)
        let endAngle = CGFloat(1.5 * Double.pi)

        let path = UIBezierPath(arcCenter: arcCenter, radius: radius, startAngle: startAngle, endAngle: endAngle, clockwise: true)
        spinnerLayer.path = path.cgPath
        spinnerLayer.strokeColor = spinnerColor.cgColor
        spinnerLayer.fillColor = UIColor.clear.cgColor
        spinnerLayer.lineWidth = lineWidth
        spinnerLayer.lineCap = .round

        startSpinning()
    }

    private func startSpinning() {
        let rotationAnimation = CABasicAnimation(keyPath: "transform.rotation")
        rotationAnimation.fromValue = 0
        rotationAnimation.toValue = Double.pi * 2
        rotationAnimation.duration = 1
        rotationAnimation.repeatCount = .infinity
        spinnerLayer.add(rotationAnimation, forKey: "rotation")
    }
}

이제 스피너의 색상과 두께를 쉽게 변경할 수 있습니다.

swift
// ViewController.swift
loadingView = CircularLoadingView(frame: frame)
loadingView.lineWidth = 8
loadingView.spinnerColor = .red
view.addSubview(loadingView)

이렇게 하면 붉은색의 더 두꺼운 스피너를 볼 수 있습니다.

마무리

이 글에서는 Swift를 사용해 안드로이드 스타일의 원형 로딩 뷰를 구현하는 방법을 다루었습니다. 기본적인 설정부터 시작해, 사용자 정의 옵션을 추가하는 방법까지 설명했습니다. 커스텀 로딩 뷰를 통해 앱의 사용자 경험을 향상시킬 수 있는 멋진 방법을 찾길 바랍니다.