在 Swift 动画中实现 CSS [英] Implement CSS into Swift Animation

查看:27
本文介绍了在 Swift 动画中实现 CSS的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在 HTML 中使用 CSS 编写了一个加载器.我想在我的 iOS 应用中实现完全相同的目标.

I have a loader written in CSS inside HTML. And I want to achieve exact same thing in my iOS App.

这是加载器的 CSS.

Here is the CSS of the loader.

<!DOCTYPE html>
<html>
<head>
    <style>
    @-webkit-keyframes spin {
        0% {
            -webkit-transform: rotate(0deg);
            -ms-transform: rotate(0deg);
            transform: rotate(0deg);
        }
        50% {
            -webkit-transform: rotate(360deg);
            -ms-transform: rotate(360deg);
            transform: rotate(360deg);
        }
        100% {
            -webkit-transform: rotate(360deg);
            -ms-transform: rotate(360deg);
            transform: rotate(360deg);
        }
    }
    @keyframes spin {
        0% {
            -webkit-transform: rotate(0deg);
            -ms-transform: rotate(0deg);
            transform: rotate(0deg);
        }
        100% {
            -webkit-transform: rotate(360deg);
            -ms-transform: rotate(360deg);
            transform: rotate(360deg);
        }
    }
    .loader {
        display: block;
        width: 75px;
        height: 75px;
        margin: 0 auto;
        border-radius: 50%;
        border: 1px solid transparent;
        border-top-color: #ff9000;
        -webkit-animation: spin 2s linear infinite;
        animation: spin 2s linear infinite;
        position: fixed;
        z-index: 9999;
        left: 0;
        right: 0;
        top: 50%;
        transform: translateY(-50%)
    }
    .loader:before {
        content: "";
        position: absolute;
        top: 5px;
        left: 5px;
        right: 5px;
        bottom: 5px;
        border-radius: 50%;
        border: 1px solid transparent;
        border-top-color: #f00;
        -webkit-animation: spin 3s linear infinite;
        animation: spin 3s linear infinite
    }
    
    .loader:after {
        content: "";
        position: absolute;
        top: 11px;
        left: 11px;
        right: 11px;
        bottom: 11px;
        border-radius: 50%;
        border: 1px solid transparent;
        border-top-color: #0a00b2;
        -webkit-animation: spin 1.5s linear infinite;
        animation: spin 1.5s linear infinite
    }
    </style>
</head>
<body>
    <div class="loader"></div>
</body>
</html>

如果有任何库、工具或任何东西可以帮助我在我的 iOS 应用中获得完全相同的工具,那将非常有帮助.

If there is any library, tool or anything which can help me to get the exact same tool in my iOS app, it will be very helpful.

我尝试修改相同的外观,但即使经过如此多的调整,我也无法获得完全相同的结果.

I tried to modify the same look but even after tweaking so much, I was unable to exact same result.

提前致谢.

推荐答案

我想我已经实现了我最初想要的.

I guess I have achieved what I initially wanted.

import UIKit

class CustomLoader: UIViewController {
    
    static let shared = CustomLoader()
    var arcsNotAdded: Bool = true
    
    override func viewDidLoad() {
        super.viewDidLoad()
        self.view.backgroundColor = .clear
    }
    
    func showLoader(_ interactionEnabled: Bool = true) {
        if let appDelegate = UIApplication.shared.delegate, let window = appDelegate.window, let rootViewController = window?.rootViewController {
            var topViewController = rootViewController
            let topVCArray = topViewController.children
            for obj in topVCArray where obj is CustomLoader { return }
            while topViewController.presentedViewController != nil {
                topViewController = topViewController.presentedViewController!
            }
            if topVCArray.count == 1 && topVCArray.first is InitialLandingController { //HOTFix for initial landing controller
                topViewController = topVCArray.first!
            }
            topViewController.addChild(self)
            topViewController.view.addSubview(view)
            didMove(toParent: topViewController)
            view.autoresizingMask = [.flexibleWidth, .flexibleHeight]
            view.frame = CGRect(topViewController.view.center.x, topViewController.view.center.y, 20, 20)
            view.center = topViewController.view.center
            kAppDelegate.window?.isUserInteractionEnabled = interactionEnabled
            arcsNotAdded ? configureArcs() : debugPrint("Arcs are already added")
        }
    }
    
    func hideLoader() {
        self.willMove(toParent: nil)
        self.view.removeFromSuperview()
        self.removeFromParent()
        kAppDelegate.window?.isUserInteractionEnabled = true
    }
    
    private func configureArcs() {
        arcsNotAdded = false
        
        let arcStartAngle: CGFloat = -CGFloat.pi / 2
        let arcEndAngle: CGFloat = 0
        let centrePoint = CGPoint(x: view.bounds.midX, y: view.bounds.midY)
        
        let outerCircle = CAShapeLayer()
        let middleCircle = CAShapeLayer()
        let innerCircle = CAShapeLayer()
        
        let circleColorOuter: CGColor = UIColor(red: 255/255, green: 144/255, blue: 0/255, alpha: 1.0).cgColor
        let circleColorMiddle: CGColor = UIColor(red: 255/255, green: 0/255, blue: 0/255, alpha: 1.0).cgColor
        let circleColorInner: CGColor = UIColor(red: 10/255, green: 0/255, blue: 178/255, alpha: 1.0).cgColor
                
        let outerPath = UIBezierPath(arcCenter: centrePoint, radius: CGFloat(77/2), startAngle: arcStartAngle, endAngle: arcEndAngle, clockwise: true)
        let midPath = UIBezierPath(arcCenter: centrePoint, radius: CGFloat(65/2), startAngle: arcStartAngle, endAngle: arcEndAngle, clockwise: true)
        let innerPath = UIBezierPath(arcCenter: centrePoint, radius: CGFloat(53/2), startAngle: arcStartAngle, endAngle: arcEndAngle, clockwise: true)

        configureArcLayer(outerCircle, forView: view, withPath: outerPath.cgPath, withBounds: view.bounds, withColor: circleColorOuter)
        configureArcLayer(middleCircle, forView: view, withPath: midPath.cgPath, withBounds: view.bounds, withColor: circleColorMiddle)
        configureArcLayer(innerCircle, forView: view, withPath: innerPath.cgPath, withBounds: view.bounds, withColor: circleColorInner)
        
        animateArcs(outerCircle, middleCircle, innerCircle)
    }
    
    private func configureArcLayer(_ layer: CAShapeLayer, forView view: UIView, withPath path: CGPath, withBounds bounds: CGRect, withColor color: CGColor) {
        layer.path = path
        layer.frame = bounds
        layer.lineWidth = 1.5
        layer.strokeColor = color
        layer.fillColor = UIColor.clear.cgColor
        layer.isOpaque = true
        view.layer.addSublayer(layer)
    }
    
    private func animateArcs(_ outerCircle: CAShapeLayer, _ middleCircle: CAShapeLayer, _ innerCircle: CAShapeLayer) {
        DispatchQueue.main.async {
            let outerAnimation = CABasicAnimation(keyPath: "transform.rotation")
            outerAnimation.toValue = 2 * CGFloat.pi
            outerAnimation.duration = 1.5
            outerAnimation.repeatCount = Float(UINT64_MAX)
            outerAnimation.isRemovedOnCompletion = false
            outerCircle.add(outerAnimation, forKey: "outerCircleRotation")
            
            let middleAnimation = outerAnimation.copy() as! CABasicAnimation
            middleAnimation.duration = 1
            middleCircle.add(middleAnimation, forKey: "middleCircleRotation")
            
            let innerAnimation = middleAnimation.copy() as! CABasicAnimation
            innerAnimation.duration = 0.75
            innerCircle.add(innerAnimation, forKey: "middleCircleRotation")
        }
    }
}

这篇关于在 Swift 动画中实现 CSS的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆