Iphone:How to Detect the End of Slider Drag

iPhone : How to detect the end of slider drag?

If you don't need any data inbetween drag, than you should simply set:

[mySlider setContinuous: NO];

This way you will receive valueChanged event only when the user stops moving the slider.

Swift 5 version:

mySlider.isContinuous = false

How to detect when user finished moving Range slider in Swift

To detect when user finished moving the range slider you can add a controlevent to your slider , you can add it programatically :

mySlider.addTarget(self, action: "sliderDidEndSliding:", forControlEvents: .UIControlEventTouchUpInside)

then you have to do your logic the recieving methode .

    func sliderDidEndSliding(sender: UISlider) {
}

How to handle a slider in 3 phases?

UIControl.Event has many other values besides .valueChanged. .touchDowncan tell you when the user starts interacting with the slider and the pair . touchUpInside and .touchUpOutside can tell you when the user finishes dragging. Here is a playground example:

import SwiftUI
import PlaygroundSupport

class V: UIViewController {
let slider = UISlider(frame: .init(origin: .zero, size: .init(width: 200, height: 50)))
override func viewDidLoad() {
super.viewDidLoad()
slider.minimumValue = 0
slider.maximumValue = 100
slider.value = 50
slider.translatesAutoresizingMaskIntoConstraints = false
view.addSubview(slider)
slider.addTarget(self, action: #selector(changed), for: .valueChanged)
slider.addTarget(self, action: #selector(began), for: .touchDown)
slider.addTarget(self, action: #selector(ended), for: .touchUpInside)
slider.addTarget(self, action: #selector(ended), for: .touchUpOutside)
}
@objc private func changed(sender: UISlider) {
print("Changed")
}
@objc private func began(sender: UISlider) {
print("Began")
}
@objc private func ended(sender: UISlider) {
print("Ended")
}
}
PlaygroundPage.current.liveView = V()

How can I track when value changed AND when dragging stopped?

The term for the solution you are trying to find is called "Debouncing". The idea is that you coalesce frequent calls to the same method and only execute the method once the calls have stopped for a period of time. Debouncing is a great way to improve the user experience when you are taking in a lot of user input quickly and must do a relatively heavy workload on that input. Only executing the work when the user has completed their input saves the cpu from doing too much work and slowing the app down. Some examples might be moving a view when the user scrolls the page, updating a table view when the user enters a search term or making network calls after a series of button taps.

An example showing how one may implemented it with a UISlider is shown below in a playground. You can copy and paste the example into an empty playground to give it a try.

//: A UIKit based Playground for presenting user interface

import UIKit
import PlaygroundSupport

class MyViewController : UIViewController {

// Timer to record the length of time between debounced calls
var timer: Timer? = nil

override func loadView() {
super.loadView()

let view = UIView()
view.backgroundColor = .white

// Set up the slider
let slider = UISlider(frame: CGRect(x: 100, y: 100, width: 200, height: 50))
slider.minimumValue = 0
slider.maximumValue = 100
slider.isContinuous = true
slider.addTarget(self, action: #selector(sliderValueDidChange(_:)), for: .valueChanged)
self.view.addSubview(slider)
}

@objc func sliderValueDidChange(_ sender: UISlider) {
// Coalesce the calls until the slider valude has not changed for 0.2 seconds
debounce(seconds: 0.2) {
print("slider value: \(sender.value)")
}
}

// Debounce function taking a time interval to wait before firing after user input has stopped
// and a function to execute when debounce has stopped being called for a period of time.
func debounce(seconds: TimeInterval, function: @escaping () -> Swift.Void ) {
timer?.invalidate()
timer = Timer.scheduledTimer(withTimeInterval: seconds, repeats: false, block: { _ in
function()
})
}
}

// Present the view controller in the Live View window
PlaygroundPage.current.liveView = MyViewController()
PlaygroundPage.current.needsIndefiniteExecution = true

The meat of the example is this function:

func debounce(seconds: TimeInterval, function: @escaping () -> Swift.Void ) {
timer?.invalidate()
timer = Timer.scheduledTimer(withTimeInterval: seconds, repeats: false, block: { _ in
function()
})
}

Here every time debounce is called it invalidates a timer and then schedules a new timer to call the function passed in. This ensures that the function is not called until enough time has elapsed to not have the timer invalidated.

How to detect that a UISlider has been tapped using RubyMotion?

To get notified when the slider has been changed, you need to set up the target/action.
The target is the object containing the method you want called, and the action is the
method you want called. I called my action sliderValueChanged:. You can choose anything. Be sure to append the colon to the name because that tells it to send a pointer to the sender which is the UISlider object. You need the sender so that you can ask for the value of the slider.

If you don't set a minimumValue and maximumValue for the slider, the values will range from 0.0 to 1.0.

def viewDidLoad
slider = UISlider.alloc.initWithFrame([[20, 70], [260, 40]])
slider.addTarget(self, action:'sliderValueChanged:', forControlEvents:UIControlEventValueChanged)
self.view.addSubview(slider)
end

def sliderValueChanged(sender)
puts sender.value
end

As shown, sliderValueChanged will get called continuously as the user moves the slider. To be notified only when the user stops touching the slider, set:

slider.continuous = no

Now, if you want a clickable slider that moves the thumb to where you click, then you need to add a UITapGestureRecognizer to the slider. This code demonstrates this:

def viewDidLoad
slider = UISlider.alloc.initWithFrame([[50, 50], [200, 40]])
tapGestureRecognizer = UITapGestureRecognizer.alloc.initWithTarget(self, action:'sliderTapped:')
tapGestureRecognizer.numberOfTapsRequired = 2
slider.addGestureRecognizer(tapGestureRecognizer)

slider.continuous = false
slider.minimumValue = 77
slider.maximumValue = 129
slider.addTarget(self, action:'sliderValueChanged:', forControlEvents:UIControlEventValueChanged)
self.view.addSubview(slider)
end

# This is called when the slider changes either from taps or from moving the thumb
def handle_new_slider_value(value)
puts "New slider value: #{value}"
end

def sliderValueChanged(slider)
handle_new_slider_value(slider.value)
end

# These were determined empirically by setting the thumb to the minimum and
# then clicking on the center and printing out gestureRecognizer.locationInView(slider).x
# and then repeating for the maximum.
SLIDER_MIN = 11
SLIDER_MAX = 189

def sliderTapped(gestureRecognizer)
if gestureRecognizer.state == UIGestureRecognizerStateEnded
slider = gestureRecognizer.view
x = gestureRecognizer.locationInView(slider).x
# Uncomment this to determine values for SLIDER_MIN/SLIDER_MAX
# puts x
x = SLIDER_MIN if x < SLIDER_MIN
x = SLIDER_MAX if x > SLIDER_MAX
slider_min_val = slider.minimumValue
slider_max_val = slider.maximumValue

# Convert from the location in the view to the slider value
slider.value = slider_min_val + (x - SLIDER_MIN) / (SLIDER_MAX - SLIDER_MIN) * (slider_max_val - slider_min_val)
handle_new_slider_value(slider.value)
end
end

Note that this code moves the slider on a double tap. I had trouble with just a single tap because if you move the thumb quickly, the code treats it as a tap and snaps the thumb back to its starting position. Set tapGestureRecognizer.numberOfTapsRequired = 1 to play around with the single tap.

iOS how to make slider stop at discrete points

To make the slider "stick" at specific points, your viewcontroller should, in the valueChanged method linked to from the slider, determine the appropriate rounded from the slider's value and then use setValue: animated: to move the slider to the appropriate place. So, if your slider goes from 0 to 2, and the user changes it to 0.75, you assume this should be 1 and set the slider value to that.



Related Topics



Leave a reply



Submit