当Anmation运行时,UISlider获得价值

时间:2018-03-23 22:38:43

标签: ios swift uislider

我使用此功能为UISlider设置动画:

func animateSlider(){
    slider.value = Float(min)
    UIView.animate(withDuration: 2.0, animations: {
        self.slider.setValue(Float(self.max), animated:true)
    })

当我点击屏幕时,我想获得当前值,但它只返回最大值。我该怎么做才能解决这个问题?

2 个答案:

答案 0 :(得分:0)

我不认为可以使用UIView.animate()为滑块的value属性设置动画。但是,如果您阅读UISlider上的文档,您将找到该功能

func setValue(Float, animated: Bool)

使用它可以将滑块设置为新位置。

如果您想在较长的时间段(例如2秒)内设置更改动画,则可能需要设置重复计时器或CADisplayLink计时器,每次触发时都会以较小的增量更改滑块值

至于你的陈述"当我点击屏幕时,我想获得当前值,但它只返回最大值"这就是Cocoa动画的工作方式。您无法查询飞行中的动画,并获得一个值,该值是您当时正在制作动画的属性的值。 (如果您使用重复计时器为滑块设置动画,那么可以这样做。)

答案 1 :(得分:0)

当您安排动画时,Core Animation会立即设置模型图层的属性,并创建一个您可以检查的演示文稿图层。此表示层是您在屏幕上实际看到的内容,可用于查询其属性,例如frameboundsposition等。

您要求的是动画块中立即设置的模型图层值,而不是您想要的是通过表示层显示的内容。

通过在UISlider上使用此扩展程序,当有正在进行的动画时,您可以从标签获取当前显示的演示文稿值:

extension UISlider {
    var currentPresentationValue: Float {
        guard let presentation = layer.presentation(),
            let thumbSublayer = presentation.sublayers?.max(by: {
                $0.frame.height < $1.frame.height
            })
            else { return self.value }

        let bounds = self.bounds
        let trackRect = self.trackRect(forBounds: bounds)
        let minRect = self.thumbRect(forBounds: bounds, trackRect: trackRect, value: 0)
        let maxRect = self.thumbRect(forBounds: bounds, trackRect: trackRect, value: 1)
        let value = (thumbSublayer.frame.minX - minRect.minX) / (maxRect.minX - minRect.minX)
        return Float(value)
    }
}

及其用法:

func animateSlider() {
    slider.value = 0
    DispatchQueue.main.async {
        UIView.animate(withDuration: 2, delay: 0, options: .curveLinear, animations: {
            self.slider.setValue(1, animated: true)
        }, completion: nil)
    }

    // quarter done:
    DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) {
        print(self.slider.currentPresentationValue)
        // prints 0.272757, expected 0.25 with some tolerance
    }

    // half done:
    DispatchQueue.main.asyncAfter(deadline: .now() + 1) {
        print(self.slider.currentPresentationValue)
        // prints 0.547876, expected 0.5 with some tolerance
    }

    // three quarters done:
    DispatchQueue.main.asyncAfter(deadline: .now() + 1.5) {
        print(self.slider.currentPresentationValue)
        // prints 0.769981, expected 0.75 with some tolerance
    }
}