Rajesh Nair
Rajesh Nair

Reputation: 31

Swift - How to toggle between Play and Pause with UIBarButtonItem

I am trying with the below Swift code in my timer application to start and pause with the same button I have. But it is does not toggle. The button is set with Identifier as "Play" in the IDE. When I run the app, Timer starts and pauses correctly. But it does not toggle button. It always remain as "Play"

@IBAction func pressPausePlay(sender: AnyObject) {

    if playPause == false
    {
            timer.invalidate()
            self.playPauseButtonVar = UIBarButtonItem(barButtonSystemItem: UIBarButtonSystemItem.Play, target: self, action: "pressPausePlay")

            playPause = true
    }
    else
    {
           timer = NSTimer.scheduledTimerWithTimeInterval(1, target: self, selector: Selector("updateTime"), userInfo: nil, repeats: true)

           self.playPauseButtonVar = UIBarButtonItem(barButtonSystemItem: UIBarButtonSystemItem.Pause, target: self, action: "pressPausePlay")

           playPause = false
    }

}

Upvotes: 3

Views: 3774

Answers (4)

Naishta
Naishta

Reputation: 12373

You can use this Example scenarios to toggle between Play and Pause, for Button Titles, Image, Navigation Bar, ToolBar

import UIKit
import AVFoundation


class ViewController: UIViewController {

      var myPlayer = AVAudioPlayer()


    @IBOutlet var myNaviBar: UINavigationBar! //OUTLET TO NAVIGATION BAR IMPORTANT TO WORK WITH ITS BARBUTTON ITEMS

    @IBOutlet var myToolBar: UIToolbar!


//**************START :Bottom LEFT TOOLBAR Bar Button Item***********/
    @IBAction func toolBarItemPlay(sender: AnyObject) {

        myToolBar.setItems([UIBarButtonItem(barButtonSystemItem: UIBarButtonSystemItem.Pause, target: self, action: "toolBarItemPause:")], animated: true)
        myPlayer.play()
    }


    @IBAction func toolBarItemPause(sender: AnyObject) {

        myToolBar.setItems([UIBarButtonItem(barButtonSystemItem: UIBarButtonSystemItem.Play, target: self, action: "toolBarItemPlay:")], animated: true)
        myPlayer.pause()
    }
//**************END :Bottom LEFT TOOLBAR Bar Button Item***********/




//**************START :Top LEFT Naivation Bar Button Item***********/

    @IBAction func leftNavgationbarPlay(sender: UIBarButtonItem) {
        myNaviBar.topItem?.leftBarButtonItem = UIBarButtonItem(barButtonSystemItem: .Pause, target: self, action: "leftNavigationbarPause:")
        myPlayer.play()
    }

    //no need of control drag to this one below because we are calling from the above leftNavgationbarPlay's Selector/action
    @IBAction func leftNavigationbarPause(sender : UIBarButtonItem) {
        myNaviBar.topItem?.leftBarButtonItem = UIBarButtonItem(barButtonSystemItem: .Play, target: self, action: "leftNavgationbarPlay:")
        myPlayer.pause()
    }
//**************END :Top LEFT Naivation Bar Button Item***********/




//**************START :Top Right Naivation Bar Button Item***********/
    @IBAction func naviPlay(sender: UIBarButtonItem) {
        //change the topright navigation bar item from SystemItem Play '>' to systemitem pause '||'
        //  here I am assigning the top left item Play to Bar button item Pause

        /* ACTION SELECTOR IMPORTANT. IT MUST CALL THE IB ACTION FUNCTION OF PAUSE AND VICEVERSA, WITH ":" */
        myNaviBar.topItem?.rightBarButtonItem = UIBarButtonItem(barButtonSystemItem: UIBarButtonSystemItem.Pause, target: self, action: "naviPause:")
        myPlayer.play()
    }

    @IBAction func naviPause(sender: UIBarButtonItem) {
    myNaviBar.topItem?.rightBarButtonItem = UIBarButtonItem(barButtonSystemItem: UIBarButtonSystemItem.Play, target: self, action: "naviPlay:")
      myPlayer.pause()
    }
//**************END : Top Right Naivation Bar Button Item***********/





//************START :BUTTON IMAGE CHANGE - ">"to "||"************//

    @IBAction func imagePlayButton(sender: UIButton) {
        let chkImage = sender.currentImage!
        if chkImage == UIImage(named: "play.png"){


            sender.setImage(UIImage(named: "pause.png"), forState: .Normal)

            myPlayer.play()
        } else {
            sender.setImage(UIImage(named: "play.png"), forState: .Normal)
            myPlayer.pause()
        }

    }

//************END :BUTTON IMAGE CHANGE - ">"to "||"************//






//************START BUTTON TITLE CHANGE - PLAY to PAUSE************//

    @IBAction func playButton(sender: UIButton) {
        let chkTitle = sender.currentTitle
        if chkTitle == "Play" {
            sender.setTitle("Pause", forState: .Normal)
            myPlayer.play()
        } else {
            sender.setTitle("Play", forState: .Normal)
            myPlayer.pause()
        }

    }

//************END BUTTON TITLE CHANGE - PLAY to PAUSE************//




    @IBAction func naviStop(sender: UIBarButtonItem) {

        myPlayer.stop()
        myPlayer.currentTime = 0

    }

    @IBOutlet var sliderUI: UISlider!


    @IBAction func mySlider(sender: UISlider) {


        myPlayer.volume = sliderUI.value
    }




    override func viewDidLoad() {
        super.viewDidLoad()


        let audioFilePath = NSBundle.mainBundle().pathForResource("ARRehman", ofType: "mp3")

        //need NSURL from string

        do {
            myPlayer = try AVAudioPlayer(contentsOfURL: NSURL(fileURLWithPath: audioFilePath!))

        }
        catch {
            print("Some error")

        }

    }

}

Upvotes: 2

Eman Shedeed
Eman Shedeed

Reputation: 114

it worked with me by creating bar button by code this is my code

 import UIKit

class ViewController: UIViewController {

@IBOutlet weak var navigationBar: UINavigationBar!

@IBOutlet weak var displayCountLabel: UILabel!
var buttonPause = UIBarButtonItem()
var buttonPlay = UIBarButtonItem()
var count=0
var timer=NSTimer()
override func viewDidLoad() {
    super.viewDidLoad()
    buttonPause = UIBarButtonItem(barButtonSystemItem: UIBarButtonSystemItem.Pause, target: self, action: "pauseAction")
    buttonPlay = UIBarButtonItem(barButtonSystemItem: UIBarButtonSystemItem.Play, target: self, action: "playAction")

    self.navigationBar?.topItem?.leftBarButtonItem = buttonPlay

}


override func didReceiveMemoryWarning() {
    super.didReceiveMemoryWarning()
    // Dispose of any resources that can be recreated.
}

@IBAction func stopTimer(sender: AnyObject) {
    timer.invalidate()
    count = 0
    displayCountLabel.text = "\(count)"
    self.navigationBar?.topItem?.leftBarButtonItem = buttonPlay
}

func pauseAction() {
    self.navigationBar?.topItem?.leftBarButtonItem = buttonPlay
    timer.invalidate()
}

func playAction() {
    self.navigationBar?.topItem?.leftBarButtonItem = buttonPause
    timer=NSTimer.scheduledTimerWithTimeInterval(1, target: self, selector: Selector("displayCount"), userInfo: nil, repeats: true)
}
func displayCount()
{
    count++
    displayCountLabel.text = "\(count)"
}

}

Upvotes: 0

Rajesh Nair
Rajesh Nair

Reputation: 31

Yoichi, thanks for pointing me to the correct place. I removed the references on the Tool bar Outlet variable (bottomToolBar) under "Referencing Outlets". That resolved the error. However I am not able to add the tool bar outlet again, if I add, the error comes back!

Upvotes: 0

Yoichi Tagaya
Yoichi Tagaya

Reputation: 4577

You need to replace bar button items hold in UIToolbar after you assign a new instance to self.playPauseButtonVar.

If you have toolBar or navigationBar outlets:

self.toolBar.setItems([self.playPauseButtonVar], animated: true)
// Or
self.navigationBar.setItems([self.playPauseButtonVar], animated: true)

If your class inherits UIViewController:

self.setToolbarItems([self.playPauseButtonVar], animated: true)
// Or
self.navigationItem.setRightBarButtonItem(self.playPauseButtonVar, animated: true)

Upvotes: 1

Related Questions