Appuyez sur UISlider pour définir la valeur

J'ai créé un slider (opérant comme le contrôle de la video, comme YouTube a en bas) et défini les valeurs maximales (durée) et minimales. Et puis utilisé SeekToTime pour changer le currentTime. Maintenant, l'user peut faire glisser le pouce du slider pour changer la valeur

Ce que je veux réaliser, c'est laisser l'user taper n'importe où sur le slider et régler l'heure actuelle de la video.

J'ai eu une approche de cette réponse , et j'ai essayé de l'appliquer à mon cas, mais je ne pouvais pas le faire fonctionner

 class ViewController: UIViewController, PlayerDelegate { var slider: UISlider! override func viewDidLoad() { super.viewDidLoad() // Setup the slider } 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) } } 

Je pensais que cela devrait fonctionner, mais pas de chance. Ensuite, j'ai essayé de déboguer en essayant d'imprimer "A" aux logs, mais ça ne semble pas aller dans la fonction sliderTapped() .

Qu'est-ce que je fais mal? Ou existe-t-il un meilleur moyen d'atteindre ce que j'essaie d'atteindre?

On dirait que vous devez réellement initialiser le reconnaisseur gestuel dans votre viewDidLoad () selon l'exemple de code ci-dessus. Il y a un commentaire, mais je ne vois pas le système de reconnaissance créé nulle part.

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) } } 

Il semble que le simple fait de sous-classr UISlider et de returnner toujours true au beginTracking produise l'effet désiré.

iOS 10 et Swift 3

 class CustomSlider: UISlider { override func beginTracking(_ touch: UITouch, with event: UIEvent?) -> Bool { return true } } 

Utilisez le CustomSlider au lieu de UISlider après dans votre code.

La réponse de pteofil devrait être la réponse acceptée ici.

Voici la solution pour Xamarin pour tout le monde intéressé:

 public override bool BeginTracking(UITouch uitouch, UIEvent uievent) { return true; } 

Comme pteofil mentionné, vous devez sous-classr l'UISlider pour que cela fonctionne.

C'est mon code, basé sur la réponse "myuiviews".
J'ai corrigé 2 petits "bugs" du code original.

1 – Taper sur 0 était trop difficile, donc je l'ai rendu plus facile
2 – Glisser un peu le pouce du slider a également déclenché le "tapGestureRecognizer", ce qui le fait revenir à la position initiale, j'ai donc ajouté un filter de distance minimum pour éviter cela.

Swift 4

 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) } @objc func sliderTapped(gestureRecognizer: UIGestureRecognizer) { // print("A") var pointTapped: CGPoint = gestureRecognizer.location(in: self.view) pointTapped.x -= 30 //Subtract left constraint (distance of the slider's origin from "self.view" let positionOfSlider: CGPoint = slider.frame.origin let widthOfSlider: CGFloat = slider.frame.size.width //If tap is too near from the slider thumb, cancel let thumbPosition = CGFloat((slider.value / slider.maximumValue)) * widthOfSlider let dif = abs(pointTapped.x - thumbPosition) let minDistance: CGFloat = 51.0 //You can calibrate this value, but I think this is the maximum distance that tap is recognized if dif < minDistance { print("tap too near") return } var newValue: CGFloat if pointTapped.x < 10 { newValue = 0 //Easier to set slider to 0 } else { newValue = ((pointTapped.x - positionOfSlider.x) * CGFloat(slider.maximumValue) / widthOfSlider) } slider.setValue(Float(newValue), animated: true) } }