Search code examples
iosswiftmpmovieplayercontrolleruislider

How to stop UISlider immediately when the user taps the pause button?


I've implemented my own custom video player controls with MPMoviePlayerController, but I'm running into an issue.

When the video is playing and the slider progresses, if I tap the pause button, the slider moves an extra second before it stops.

How can I ensure that when the user taps pause, the UISlider stops immediately?

override func viewDidLoad()
{
    super.viewDidLoad()

    youtubeVideoPlayer.moviePlayer.controlStyle = MPMovieControlStyle.None

    isSliderTouched = false

    initUI()

    tapGesture = UITapGestureRecognizer(target: self, action: "handleSingleTap:")

    tapGesture2 = UITapGestureRecognizer(target: self, action: "handleSingleTap:")
}

override func viewDidAppear(animated: Bool)
{
    super.viewDidAppear(true)

    timer = NSTimer.scheduledTimerWithTimeInterval(1, target: self, selector: "updateSlider", userInfo: nil, repeats: true)

    playerSlider.addTarget(self, action: "sliderMoveStart", forControlEvents: .TouchDown)

    playerSlider.addTarget(self, action: "sliderMoving", forControlEvents: .TouchDragInside)

    playerSlider.addTarget(self, action: "sliderMoveEnd", forControlEvents: .TouchUpInside)

    centerButton.addTarget(self, action: "onClick:", forControlEvents: .TouchUpInside)

    playerSlider.addGestureRecognizer(tapGesture2)

    lastControlTime = CFAbsoluteTimeGetCurrent()
}

override func viewWillDisappear(animated: Bool)
{
    super.viewWillDisappear(true)   

    timer.invalidate()

    playerSlider.removeTarget(self, action: "sliderMoveStart", forControlEvents: .TouchDown)      

    playerSlider.removeTarget(self, action: "sliderMoving", forControlEvents: .TouchDragInside)

    playerSlider.removeTarget(self, action: "sliderMoveEnd", forControlEvents: .TouchUpInside)

    centerButton.removeTarget(self, action: "onClick:", forControlEvents: .TouchUpInside)

    playerSlider.removeGestureRecognizer(tapGesture2)
}

func initUI()
{
    bottomBarBG = UIView(frame: CGRectMake(0, UIScreen.mainScreen().bounds.height - 75, UIScreen.mainScreen().bounds.width, 80) )

    playerSlider = UISlider()

    playerSlider.setThumbImage(UIImage(named: "slider"), forState: .Normal)

    playerSlider.continuous = true

    playerSlider.highlighted = true

    playerSlider.frame = CGRectMake(UIScreen.mainScreen().bounds.width * 0.035, 45, UIScreen.mainScreen().bounds.height * 0.52, 22)

    bottomBarBG.addSubview(playerSlider)

    centerButton = UIButton( frame: CGRectMake( (UIScreen.mainScreen().bounds.width / 2) - 25, 0, 50, 50) )

    centerButton.setImage( UIImage(named: "pause_filled"), forState: .Normal )

    centerButton.setImage( UIImage(named: "play_filled"), forState: .Selected)

    bottomBarBG.addSubview(centerButton)
    view.addSubview(bottomBarBG)
}

func handleSingleTap(recogizer: UITapGestureRecognizer)
{
    if recogizer.view == playerSlider
    {
        isSliderTouched = true
        lastControlTime = CFAbsoluteTimeGetCurrent()

        let translation: CGPoint = recogizer.locationInView(recogizer.view)

        let rate: Double = Double( translation.x / (UIScreen.mainScreen().bounds.size.width * 0.8) )

        playerSlider.value = Float(rate)

        youtubeVideoPlayer.moviePlayer.currentPlaybackTime = Double(youtubeVideoPlayer.moviePlayer.duration) * rate
    }
}

func updateSlider()
{
    if !isSliderTouched
    {
        let value: Float = Float(youtubeVideoPlayer.moviePlayer.currentPlaybackTime / youtubeVideoPlayer.moviePlayer.duration)

        playerSlider.setValue(value, animated: true)
    }
}

func sliderMoveStart()
{
    isSliderTouched = true
}

func sliderMoving()
{
    lastControlTime = CFAbsoluteTimeGetCurrent()

    isSliderTouched = true

    let time: Double = youtubeVideoPlayer.moviePlayer.duration * Double(playerSlider.value)
}

func sliderMoveEnd()
{
    youtubeVideoPlayer.moviePlayer.currentPlaybackTime = youtubeVideoPlayer.moviePlayer.duration * Double(playerSlider.value)
}

func onClick(sender: UIButton)
{
    if sender == centerButton
    {
        lastControlTime = CFAbsoluteTimeGetCurrent()

        if sender.selected
        {
            youtubeVideoPlayer.moviePlayer.play()
            sender.selected = false
        }
        else
        {
            youtubeVideoPlayer.moviePlayer.pause()
            sender.selected = true
        }
    }
}

FYI, the centerButton is my play/pause button.

Thanks.


Solution

  • Add timer.invalidate() on pause and again star the timer on play.