J'ai créé un curseur (servant de contrôle de la vidéo, comme YouTube en bas) et défini les valeurs maximale (durée) et minimale. Et ensuite utilisé SeekToTime
pour changer le currentTime. Maintenant, l'utilisateur peut faire glisser le curseur du curseur pour changer la valeur
Ce que je veux réaliser est de laisser l'utilisateur appuyer n'importe où sur le curseur et régler l'heure actuelle de la vidéo.
J'ai eu une approche de cette réponse , et j'ai essayé de l'appliquer à mon cas, mais je n'ai pas réussi à la 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" dans les journaux, mais cela ne semble donc pas aller dans la fonction sliderTapped()
.
Qu'est-ce que je fais mal? Ou y a-t-il un meilleur moyen de réaliser ce que j'essaie de réaliser?
Il semble que vous ayez besoin d'initialiser la reconnaissance des gestes du tap dans votre viewDidLoad () conformément à l'exemple de code ci-dessus. Il y a un commentaire là-bas, mais je ne vois pas le logiciel 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-classer UISlider et de revenir toujours à true pour beginTracking produise l'effet souhaité.
iOS 10 et Swift 3
class CustomSlider: UISlider {
override func beginTracking(_ touch: UITouch, with event: UIEvent?) -> Bool {
return true
}
}
Utilisez ensuite CustomSlider au lieu de UISlider dans votre code.
Ceci 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, alors j'ai rendu les choses plus faciles
2 - Faire glisser légèrement le pouce du curseur a également déclenché le "tapGestureRecognizer", ce qui le fait revenir à la position initiale. J'ai donc ajouté un filtre de distance minimale 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)
}
}
La solution la plus simple serait probablement, en utilisant l'action "Retouche à l'intérieur", connectées via le constructeur d'interface.
@IBAction func finishedTouch(_ sender: UISlider) {
finishedMovingSlider(sender)
}
Celui-ci sera appelé dès que votre doigt aura quitté l'écran du téléphone.
la réponse de pteofil devrait être la réponse acceptée ici.
Voici la solution pour Xamarin pour tous les intéressés:
public override bool BeginTracking(UITouch uitouch, UIEvent uievent)
{
return true;
}
Comme mentionné par pteofil, vous devez sous-classer UISlider pour que cela fonctionne.