Tap on UISlider to Set the Value
Looks like you need to actually initialize the tap gesture recognizer in your viewDidLoad() per the code example above. There's a comment there, but I don't see the recognizer being created anywhere.
Swift 2:
class ViewController: UIViewController {
var slider: UISlider!
override func viewDidLoad() {
super.viewDidLoad()
// Setup the slider
// Add a gesture recognizer to the slider
let tapGestureRecognizer = UITapGestureRecognizer(target: self, action: "sliderTapped:")
self.slider.addGestureRecognizer(tapGestureRecognizer)
}
func sliderTapped(gestureRecognizer: UIGestureRecognizer) {
// print("A")
let pointTapped: CGPoint = gestureRecognizer.locationInView(self.view)
let positionOfSlider: CGPoint = slider.frame.origin
let widthOfSlider: CGFloat = slider.frame.size.width
let newValue = ((pointTapped.x - positionOfSlider.x) * CGFloat(slider.maximumValue) / widthOfSlider)
slider.setValue(Float(newValue), animated: true)
}
}
Swift 3:
class ViewController: UIViewController {
var slider: UISlider!
override func viewDidLoad() {
super.viewDidLoad()
// Setup the slider
// Add a gesture recognizer to the slider
let tapGestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(sliderTapped(gestureRecognizer:)))
self.slider.addGestureRecognizer(tapGestureRecognizer)
}
func sliderTapped(gestureRecognizer: UIGestureRecognizer) {
// print("A")
let pointTapped: CGPoint = gestureRecognizer.location(in: self.view)
let positionOfSlider: CGPoint = slider.frame.origin
let widthOfSlider: CGFloat = slider.frame.size.width
let newValue = ((pointTapped.x - positionOfSlider.x) * CGFloat(slider.maximumValue) / widthOfSlider)
slider.setValue(Float(newValue), animated: true)
}
}
Go to tapped position of UISlider
UISlider
's method is func setValue(_ value: Float, animated animated: Bool)
.
You'll need to cast your CGFloat to a Float.
So durationSlider.setValue(Float(newValue), animated: true)
iOS -How to have a separate UIView take control of a UISlider's thumbRect
I found the key to the problem here in this answer. @PaulaHasstenteufel said
// also remember to call valueChanged if there's any
// custom behaviour going on there and pass the slider
// variable as the parameter, as indicated below
self.sliderValueChanged(slider)
What I had to do was
- Use a
UIPanGestureRecognizer
- comment out the UISlider's target action
- use the code from the target action's selector method in step-4 instead of using it in
@objc func onSliderValChanged(sender: UISlider, event: UIEvent { }
- take the code from step-3 and add it to a new function
- add the function from step-5 to the bottom of the
UIPanGetstureRecognizer
's method
1- use the UIPanGestureRecognizer
and make userInteraction is enabled for the UIView
let panGesture = UIPanGestureRecognizer(target: self, action: #selector(draggedView(_:)))
clearView.isUserInteractionEnabled = true
clearView.addGestureRecognizer(panGesture)
2- the Slider, I commented out it's addTarget for the .valueChanged
event
let slider: UISlider = {
let slider = UISlider()
slider.translatesAutoresizingMaskIntoConstraints = false
slider.minimumValue = 1
slider.maximumValue = 5
slider.value = 1
slider.isContinuous = true
slider.maximumTrackTintColor = UIColor(white: 0, alpha: 0.3)
// ** COMMENT THIS OUT **
//slider.addTarget(self, action: #selector(onSliderValChanged(sender:event:)), for: .valueChanged)
return slider
}()
3- Take the code from the selector method the targetAction from above was using and instead insert that code in step 4
@objc func onSliderValChanged(sender: UISlider, event: UIEvent) {
/*
use this code in step-4 instead
slider.value = round(sender.value)
UIView.animate(withDuration: 0.25, animations: {
self.slider.layoutIfNeeded()
let trackRect = sender.trackRect(forBounds: sender.frame)
let thumbRect = sender.thumbRect(forBounds: sender.bounds, trackRect: trackRect, value: sender.value)
self.milesLabel.center = CGPoint(x: thumbRect.midX, y: sender.frame.origin.y - 55)
// ** all the other views are aligned with the thumbRect's center as it slides **
self.clearView.frame.origin = self.milesLabel.frame.origin
})
*/
}
4- Create a new method and insert the code from step-3
func sliderValueChanged(_ sender: UISlider, value: Float) {
// round the value for smooth sliding
sender.value = round(value)
UIView.animate(withDuration: 0.25, animations: {
self.slider.layoutIfNeeded()
let trackRect = sender.trackRect(forBounds: sender.frame)
let thumbRect = sender.thumbRect(forBounds: sender.bounds, trackRect: trackRect, value: sender.value)
self.milesLabel.center = CGPoint(x: thumbRect.midX, y: sender.frame.origin.y - 55)
// ** all the other views are aligned with the thumbRect's center as it slides **
self.clearView.frame.origin = self.milesLabel.frame.origin
})
}
5- I used the same code that I used for the UIGestureRecognizer but commented out the setValue function and instead used the function from step 4
@objc fileprivate func draggedView(_ sender: UIPanGestureRecognizer) {
if slider.isHighlighted { return }
let point = sender.location(in: slider)
let percentage = Float(point.x / slider.bounds.size.width)
let delta = percentage * (slider.maximumValue - slider.minimumValue)
let value = slider.minimumValue + delta
// I had to comment this out because the siding was to abrupt
//slider.setValue(value, animated: true)
// ** CALLING THIS FUNCTION FROM STEP-3 IS THE KEY TO GET THE UIView TO CONTROL THE SLIDER **
sliderValueChanged(slider, value: value)
}
How to delay start touch event of a UISlider in iOS?
You can disable user interaction on slider and then add a gesture recogniser over it (Not exactly sure about user interaction though). Maybe do something like this
let longPress = UILongPressGestureRecognizer(target: self.slider, action: Selector("longPressAndSlide:"))
longPress.minimumPressDuration = 0
self.addGestureRecognizer(longPress)
In longPressAndSlide
you can calculate the direction and delta of movement and set the value of slider accordingly.
This has been answer multiple times actually. just a better search would help you more.
Update
Check answers under - How to enable "tap and slide" in a UISlider?
Latest Update
As the comments suggest, we can add a button on top of the slider and add longPress gesture over it. The handling can be done in the handler Action for the gesture.
Swift 4 The UISlider with AVPlayer doesn't slide
Fixed it by deleting AVPlayer
and changing AVPlayerItem
to AVAudioPlayer
, then putting the song URL into data : `
//DOWNLOADS THE SONG IN THE URL AND PUTS IT IN DATA
var task: URLSessionTask? = nil
if let songUrl = songUrl {
task = URLSession.shared.dataTask(with: songUrl, completionHandler: { data, response, error in
// SELF.PLAYER IS STRONG PROPERTY
if let data = data {
self.playerItem = try? AVAudioPlayer(data: data)
self.playPause()
DispatchQueue.main.async {
self.sliderProgress()
}
}
})
task?.resume()`
Then I changed UISlider
IBAction
Value Changed
to Touch Down
and Touch Up Inside
when I connected it to the ViewController
:
// TOUCH DOWN
@IBAction func SliderTouchDown(_ sender: UISlider) {
playerItem?.pause()
}
//TOUCH UP INSIDE
@IBAction func SliderTouchUpInside(_ sender: UISlider) {
playerItem?.currentTime = TimeInterval(sliderProgressOutlet.value)
playerItem?.play()
}
UISlider sliding event when its continuous set to No
It turns out It's my problem. I thought continous
property set to YES
will allow the UISlider
to slide in float(While my value must be int, not float type).
self.progressSlider.continuous = YES;
just call the value changed as long as the slider's value changed. It won't change the value to double.
self.progressSlider.continuous = No;
When you're sliding the slider, value changed event won't be called until you release it.
Related Topics
Exc_Bad_Access Automatic Handling
Xcode Warning When Using Mapkit and Corelocation
Swift UI Remove Extra List Empty Cells Without Navigation Controller
How to Get Email Id of User Using Facebook Sdk 4.7 in iOS 9
User Set Time for Notification in Swift
Xmlparser.Sharedparser.Decode() in Swift3
Make Timer Run on Background iOS for More Than 3 Minutes
JSON Text Did Not Start with Array or Object and Option to Allow Fragments Not Set
How to Load Icarousel View from Storyboard or Xib
iOS Web Page Errors Over Cellular Data But Not Over Wifi? Recent Change to At&T Cellular Network
How to Make Generics in Collection Type Constraint
Swift - Fatal Error: Array Index Out of Range
Uicellview Cell Layout in Swift
iOS Swift Navigate to Certain Viewcontroller Programmatically from Push Notification