Swift 2 - 定期从滑块打印新值
Swift 2 - Print New Value from Slider at Regular Interval
我正在尝试定期从滑块打印一个值。但只有当它与上次打印的不同时才打印该值。我也不想错过滑块的任何输出值。
为此,我创建了一个数组并在该数组的开头添加了一个元素(如果它与开头的元素不同)。然后我使用了一个重复的 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()
}
}
我建议使用 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 添加到 运行 循环中。 (运行 lopp 处理输入/刷新 UI 和时间片)
--> 注意 如果屏幕上不需要重绘,则不会调用此方法。这不是一个定时器,据说会定期触发。它在需要重绘时触发。在 Sliders 的情况下,我们希望它在我们移动最轻微的滑块时触发。
有关其实际工作原理的更多信息,请试用并查看苹果文档。确保在取消初始化 ViewController 之前使无效。
找到答案了,感谢大家的帮助和建议:
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 函数。仅当数组中有多个元素时才会执行该函数。如果有,则打印最后一个之前的元素并删除最后一个。这始终确保数组中只有一个元素,因此函数并不总是 运行 并且打印的元素是尚未打印的最新元素。
我正在尝试定期从滑块打印一个值。但只有当它与上次打印的不同时才打印该值。我也不想错过滑块的任何输出值。
为此,我创建了一个数组并在该数组的开头添加了一个元素(如果它与开头的元素不同)。然后我使用了一个重复的 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()
}
}
我建议使用 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 添加到 运行 循环中。 (运行 lopp 处理输入/刷新 UI 和时间片)
--> 注意 如果屏幕上不需要重绘,则不会调用此方法。这不是一个定时器,据说会定期触发。它在需要重绘时触发。在 Sliders 的情况下,我们希望它在我们移动最轻微的滑块时触发。
有关其实际工作原理的更多信息,请试用并查看苹果文档。确保在取消初始化 ViewController 之前使无效。
找到答案了,感谢大家的帮助和建议:
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 函数。仅当数组中有多个元素时才会执行该函数。如果有,则打印最后一个之前的元素并删除最后一个。这始终确保数组中只有一个元素,因此函数并不总是 运行 并且打印的元素是尚未打印的最新元素。