首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >iOS -圆形视图的微调器

iOS -圆形视图的微调器
EN

Stack Overflow用户
提问于 2021-09-23 19:25:15
回答 1查看 80关注 0票数 0

我正在尝试为圆形视图添加微调器效果。

代码语言:javascript
运行
复制
    func spin() {
        let circlePathLayer = CAShapeLayer()
        circlePathLayer.fillColor = nil
        circlePathLayer.strokeColor = UIColor.redColor.cgColor
        circlePathLayer.lineWidth = 6
        layer.addSublayer(circlePathLayer)
        setPath(to: circlePathLayer)
        animate(layer: circlePathLayer)
    }
    
    private func setPath(to layer: CAShapeLayer) {
        layer.path = UIBezierPath(ovalIn: bounds.insetBy(dx: layer.lineWidth / 2,
                                                                   dy: layer.lineWidth / 2)).cgPath
    }
    
    private func animate(layer: CAShapeLayer) {
        animateKeyPath(keyPath: "strokeEnd",
                       duration: 1,
                       values: [0, 1],
                       layer: layer)
        animateKeyPath(keyPath: "strokeStart",
                       duration: 1,
                       values: [(0 - 0.1) as CGFloat, (1 - 0.1) as CGFloat],
                       layer: layer)
    }
    
    private func animateKeyPath(keyPath: String, duration: CFTimeInterval, values: [CGFloat], layer: CAShapeLayer) {
        let animation = CAKeyframeAnimation(keyPath: keyPath)
        animation.values = values
        animation.calculationMode = .linear
        animation.duration = duration
        animation.repeatCount = Float.infinity
        layer.add(animation, forKey: animation.keyPath)
    }

但对于上面的代码,在动画duration的末尾,每次在strokeEnd1位置都会发生闪烁。我怎样才能克服闪烁并调节旋转器?

为了在视觉上注意到效果,我将持续时间设置为5秒。请注意,当旋转器到达3点钟位置时。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2021-09-23 22:55:31

我认为strokeStartstrokeEnd被限制在0到1之间。当你试图将strokeStart设置为负数(如-0.1)时,系统会将其固定为零。

尝试此解决方案:

代码语言:javascript
运行
复制
//: A UIKit based Playground for presenting user interface

import UIKit
import PlaygroundSupport

class SpinnerView : UIView {
    let circlePathLayer = CAShapeLayer()

    override func didMoveToSuperview() {
        layer.addSublayer(circlePathLayer)
    }

    func spin() {
        let circleFrame = bounds.insetBy(dx: -40, dy: -40)
        circlePathLayer.position = CGPoint(x: bounds.midX, y: bounds.midY)
        
        circlePathLayer.strokeColor = UIColor.red.cgColor
        circlePathLayer.fillColor = nil
        circlePathLayer.lineWidth = 6

        setPath(to: circlePathLayer)
        animate(layer: circlePathLayer)
    }

    private func setPath(to layer: CAShapeLayer) {
        let path = UIBezierPath()
        path.addArc(withCenter: CGPoint(x: layer.bounds.midX,
                                        y: layer.bounds.midY),
                    radius: (bounds.width / 2.0) - layer.lineWidth / 2,
                    startAngle: 0,
                    endAngle: 2 * .pi / 10.0,
                    clockwise: true)
        layer.path = path.cgPath
    }

    private func animate(layer: CAShapeLayer) {
        let animation = CABasicAnimation(keyPath: "transform.rotation")
        animation.duration = 1
        animation.repeatCount = Float.infinity
        animation.fromValue = 0
        animation.toValue = 2 * CGFloat.pi
        layer.add(animation, forKey: "transform.rotation")
    }
}

class MyViewController : UIViewController {
    let spinner = SpinnerView()

    override func loadView() {
        let view = UIView()
        view.backgroundColor = .white

        spinner.translatesAutoresizingMaskIntoConstraints = false

        view.addSubview(spinner)

        view.addConstraints([
            NSLayoutConstraint(item: spinner,
                               attribute: .centerX,
                               relatedBy: .equal,
                               toItem: view,
                               attribute: .centerX,
                               multiplier: 1.0,
                               constant: 0),
            NSLayoutConstraint(item: spinner,
                               attribute: .centerY,
                               relatedBy: .equal,
                               toItem: view,
                               attribute: .centerY,
                               multiplier: 1.0,
                               constant: 0),
            NSLayoutConstraint(item: spinner,
                               attribute: .width,
                               relatedBy: .equal,
                               toItem: view,
                               attribute: .width,
                               multiplier: 1.0,
                               constant: -40)
        ])

        spinner.addConstraints([
            NSLayoutConstraint(item: spinner,
                               attribute: .width,
                               relatedBy: .equal,
                               toItem: spinner,
                               attribute: .height,
                               multiplier: 1.0,
                               constant: 0)
        ])

        self.view = view
    }

    override func viewDidLayoutSubviews() {
        spinner.spin()
    }
}
// Present the view controller in the Live View window
PlaygroundPage.current.liveView = MyViewController()
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/69305893

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档