Swift 2 - 以常规间隔从滑块打印新值

时间:2016-09-09 17:27:40

标签: ios swift nstimer

我试图定期从滑块打印一个值。但只有在与最后打印的值不同时才打印该值。我也不想错过滑块的任何输出值。

为了做到这一点,我创建了一个数组,并在该数组的开头添加了一个元素,如果它与已经开始的数组不同。然后我使用重复的NSTimer定期调用一个函数,在从数组中删除之前打印数组中的最后一个元素。

当我运行应用程序时会发生什么是NSTimer在设定的时间内停止打印任何内容,但随后所有元素一次打印并且每次打印都超过一个。我已经尝试过搞乱很多不同的东西 - 这是我必须要做的最接近的事情。

如果您需要了解更多信息,请与我们联系。

我非常感谢任何帮助,非常感谢。

var sliderArray: [Float] = []
var timer: NSTimer!
let step: Float = 1

@IBAction func sliderValueChanged(sender: AnyObject) 
{
    let roundedValue = round(slider.value / step) * step
    slider.value = roundedValue

    if sliderArray.first != slider.value
    {
        sliderArray.insert(slider.value, atIndex: 0)
    }

    NSTimer.scheduledTimerWithTimeInterval(1, target: self, selector: #selector(sendSliderPosition), userInfo: nil, repeats: true)

}

func sendSliderPosition()
{
    if sliderArray.count > 0
    {
        print(self.sliderArray.last)
        sliderArray.removeLast()
    }

}

2 个答案:

答案 0 :(得分:0)

我建议使用CADisplayLink。 CADisplayLink对象是一个计时器对象,允许您的应用程序将其绘图与显示的刷新率同步。这适合您的滑盖盒。

当滑块或UI处于静止状态时,这也不会触发不必要的调用。

class C: UIViewController {

    var displayLinkTimer: CADisplayLink?
    @IBOutlet weak var slider: UISlider!

    override func viewDidLoad() {
        super.viewDidLoad()
        displayLinkTimer = CADisplayLink(target: self, selector: #selector(printSliderValue))
        let runLoop = NSRunLoop.mainRunLoop()
        displayLinkTimer?.addToRunLoop(runLoop, forMode: runLoop.currentMode ?? NSDefaultRunLoopMode )
        displayLinkTimer?.paused = true
    }

    override func viewWillDisappear(animated: Bool) {
        super.viewWillDisappear(animated)
        displayLinkTimer?.paused = true
    }

    deinit {
        displayLinkTimer?.invalidate()
    }



    func printSliderValue()
    {
        let step: Float = 1
        let roundedValue = round(slider.value / step) * step
        slider.value = roundedValue
        print(roundedValue)
    }


}

基本理念是:

- >每次屏幕需要重绘时(考虑到这是fps速率,这将在每秒最大约60帧发生),我们有机会执行功能。

- >为此,我们将displayLink添加到Run Loop。 (运行lopp进程输入/刷新UI和时间片)

- > 注意如果屏幕上不需要重绘,则不会调用此方法。这不是每个人定期发射的计时器。需要重绘时会触发。在Sliders的情况下,当我们移动最轻微的滑块时,我们希望它能够触发。

有关它实际工作原理的更多信息,请试试看苹果文档。在取消初始化ViewController之前,请确保无效。

答案 1 :(得分:0)

找出答案,感谢大家的帮助和建议:

override func viewDidLoad()
{
    super.viewDidLoad()

    NSTimer.scheduledTimerWithTimeInterval(0.02, target: self, selector: #selector(sendSliderPosition), userInfo: nil, repeats: true)
}

@IBAction func sliderValueChanged(sender: AnyObject)
{

    let step: Float = 1
    let roundedValue = round(slider.value / step) * step
    slider.value = roundedValue

    if sliderArray.first != slider.value
    {
        sliderArray.insert(slider.value, atIndex: 0)
    }

}

func sendSliderPosition()
{
    if sliderArray.count > 1
    {
        let end1 = sliderArray.count-2

        print(sliderArray[end1])

        sliderArray.removeLast()
    }

}

说明:

如果新滑块值与阵列中已有的滑块值不同,则在开始时将其添加到阵列中。使用NSTimer从viewDidLoad重复调用sendSliderPosition函数。只有在数组中有多个元素时才会执行该函数。如果有,请在最后一个之前打印元素并删除最后一个元素。这总是确保数组中有一个元素,因此函数并不总是运行,并且打印的元素是最新的元素尚未打印。