11

我创建了一个Slider(作为视频控件操作,如YouTube在底部)并设置最大值(持续时间)和最小值。然后使用SeekToTime更改当前时间。现在,用户可以滑动滑块的大拇指来更改数值点击UISlider设置值

我想要实现的是让用户点击滑块上的任意位置并设置视频的当前时间。

我得到了一个办法,从this answer,我试图将它应用到我的情况,但不能使它工作

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

我想这应该工作,但没有运气。然后我尝试着打印“A”到日志进行调试,但它并没有显然不会进入sliderTapped()函数。

我在做什么错?还是有更好的方法来实现我想要实现的目标?

+1

你忘了设定手势识别的代表? – whatever0010011

回答

20

看起来像你需要实际初始化你的viewDidLoad()中每个上面的代码示例的轻拍手势识别器。这里有一条评论,但我没有看到识别器在任何地方被创建。

斯威夫特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)  
    } 
} 

斯威夫特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) 
    } 
} 
+0

非常感谢!像魅力一样工作! – senty

+0

这个答案比我找到的其他人都好得多!谢谢! – kenjikato

+0

创建'action:“sliderTapped:''在Xcode 8.2.1中不再有效。我尝试了Xcode给我的建议,但它仍然失败。有没有人知道它? –

9

好像只是继承UISlider始终返回true到beginTracking产生预期的效果。

iOS的10和斯威夫特3

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

使用CustomSlider,而不是事后UISlider在你的代码。

+0

这是正确的答案!谢谢。 –

+0

好的答案,简单而且简单 – SPatel

0

pteofil的答案应该是这里接受的答案。

下面是大家Xamarin的解决方案的兴趣:

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

如前所述pteofil,你需要继承UISlider这个工作。

+0

你的答案有哪些新内容? –

1

这是我的代码,基于“myuiviews”的答案。
我修复了原始代码中的两个小“bug”。

1 - 攻丝0是太难了,所以我可以更容易
2 - 滑动滑块的拇指只是一点点,也被解雇了“tapGestureRecognizer”,这使得它恢复到初始位置,所以我加了避免这种情况的最小距离过滤器。

斯威夫特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) 
    } 
} 
+0

我对newValue计算进行了一些改动,以便在滑块的最小值不是零时满足。 ((pointTapped.x - positionOfSlider.x)* CGFloat(self.offerSliderView.maximumValue - self.offerSliderView.minimumValue)/ widthOfSlider)+ CGFloat(self.offerSliderView.minimumValue))'code' – jpmastermind