         
     }
 
+    // MARK: - Private configuration methods
+
+    private func configureSKView() -> SKView {
+        let skView = SKView(frame: CGRect(x: 0, y: 0, width: frame.width, height: frame.height))
+        skView.backgroundColor = defaultBackgroundColor
+        skView.showsFPS = false
+        skView.showsNodeCount = false
+        // Sprite Kit applies additional optimizations to improve rendering performance
+        skView.ignoresSiblingOrder = true
+        return skView
+    }
+
+    private func configureRainScene() -> RainScene {
+        let scene = RainScene(size: skView.bounds.size)
+        scene.backgroundColor = defaultBackgroundColor
+        // Set the scale mode to scale to fit the window
+        scene.scaleMode = .aspectFill
+        scene.particles.particleBirthRate = 0
+        return scene
+    }
+
+    private func configureUmbrellaView() -> UmbrellaView {
+        let width = skView.frame.height * 0.6
+        let umrellaViewFrame = CGRect(x: 0, y: 0, width: width, height: width)
+        let umbrellaView = UmbrellaView(frame: umrellaViewFrame)
+        umbrellaView.strokeColor = UIColor.white
+        umbrellaView.lineWidth = 1
+        umbrellaView.backgroundColor = UIColor.clear
+        return umbrellaView
+    }
+
+    private func updateUmbrellaView() {
+        let width = thresholdValue * 0.36
+        umbrellaView.frame = CGRect(x: 0, y: 0, width: width, height: width)
+        umbrellaView.center = CGPoint(x: center.x, y: skView.frame.height - thresholdValue / 2)
+    }
 
 }

            offset = min(offset, thresholdValue)
            scrollView.contentInset = UIEdgeInsetsMake(offset, 0.0, 0.0, 0.0)
            UIView.commitAnimations()
            
        } else if scrollView.isDragging {
            let loading = false
            if state == .pulling && scrollView.contentOffset.y > -thresholdValue && scrollView.contentOffset.y < 0.0 && !loading {
                state = .normal
                
            } else if state == .normal && scrollView.contentOffset.y < -thresholdValue && !loading {
                state = .pulling
            }
        }

    }
    
    public func refreshScrollViewDidEndDragging(_ scrollView: UIScrollView) {
        let loading = false
        if scrollView.contentOffset.y <= -thresholdValue && !loading {

import UIKit
import SpriteKit

private enum RefreshState {
    case normal
    case pulling
    case loading
}

protocol RainyRefreshControlDelegate {
    func pullToRefreshDidTrigger(_ view: RainyRefreshControl)
}

final class RainyRefreshControl: UIView {

    public var thresholdValue: CGFloat = 100.0
    public var delegate: RainyRefreshControlDelegate?

    private var state: RefreshState = .normal {
        didSet {
            switch state {
