How to toggle Play and Pause with a UIBarbuttonItem - ios

Can anyone help me. I've search for my question and still can't figure out a solution, everything I found was not formatted in swift 3. Im trying to make a toggle Play and Pause out of a UIBarButtonItem. Whenever the play button is click I want it to play the file and at the same time change the UIBarButtonItem to pause and vise versa.
By the way I have embed in a navigation controller into my main view controller from the editor.
Here is my Code Snippet.
import UIKit
import AVFoundation
class ViewController: UIViewController {
#IBOutlet weak var pausePlayBtn: UIBarButtonItem!
var audioPlayer = AVAudioPlayer()
override func viewDidLoad() {
super.viewDidLoad()
prepareMusic()
}
func prepareMusic() {
let path = Bundle.main.path(forResource: "SomeFileName", ofType: "TypeOfFile")!
do {
audioPlayer = try AVAudioPlayer(contentsOf: URL(fileURLWithPath: path))
audioPlayer.prepareToPlay()
} catch let err as NSError {
print(err)
}
}
#IBAction func togglePausePlay(sender: UIBarButtonItem) {
if !audioPlayer.isPlaying {
audioPlayer.play()
} else {
audioPlayer.stop()
}
}
}
I've tried the following.
First I started by creating play button and a pause button and adding them in my togglePausePlay func.
let playBtn = UIBarButtonItem(barButtonSystemItem: .play, target: self, action: nil)
let pauseBtn = UIBarButtonItem(barButtonSystemItem: .pause, target: self, action: nil)
#IBAction func togglePausePlay(sender: UIBarButtonItem) {
if !audioPlayer.isPlaying {
audioPlayer.play()
pausePlayBtn = playBtn
} else {
audioPlayer.stop()
pausePlayBtn = pauseBtn
}
}
The second thing I tried was this.
#IBAction func togglePausePlay(sender: UIBarButtonItem) {
if !audioPlayer.isPlaying {
audioPlayer.play()
self.navigationController?.navigationBar.topItem?.rightBarButtonItem = UIBarButtonItem(barButtonSystemItem: .play, target: self, action: nil)
} else {
audioPlayer.stop()
self.navigationController?.navigationBar.topItem?.rightBarButtonItem = UIBarButtonItem(barButtonSystemItem: .pause, target: self, action: nil)
}
}
This work at the start of the app, I would click the button for the first time and everything would work the button would change to pause and file would start. However when I tried to click it again nothing happens, button stays on pause and file still keeps playing until I stop the project.
Any help would be appreciated. :)

i figured out a solution for u and its working for me.
Here's the code i tried and its working. the buttonitem is changing on its click.
import UIKit
class ViewController: UIViewController {
var playBtn = UIBarButtonItem()
var pauseBtn = UIBarButtonItem()
#IBOutlet var labelMusicState: UILabel!
override func viewDidLoad()
{
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
self.playBtn = UIBarButtonItem(barButtonSystemItem: .play , target: self, action: #selector(playBtnAction(sender:)))
self.pauseBtn = UIBarButtonItem(barButtonSystemItem: .pause , target: self, action: #selector(pauseBtnAction(sender:)))
self.navigationItem.rightBarButtonItem = playBtn
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
func playBtnAction(sender: UIBarButtonItem)
{
self.navigationItem.rightBarButtonItem = pauseBtn
self.labelMusicState.text = "Music is Playing"
}
func pauseBtnAction(sender: UIBarButtonItem)
{
self.navigationItem.rightBarButtonItem = playBtn
self.labelMusicState.text = "Music Not Playing"
}
}

In both the scenarios, you are trying to assign .play button to your existing button whenever the player starts playing music. It should be opposite. whenever the player starts playing music, your button should change to .pause mode and when the player stops playing music, the button should go to .play mode.
do the following modification:
let playBtn = UIBarButtonItem(barButtonSystemItem: .play, target: self, action: nil)
let pauseBtn = UIBarButtonItem(barButtonSystemItem: .pause, target: self, action: nil)
#IBAction func togglePausePlay(sender: UIBarButtonItem) {
if !audioPlayer.isPlaying {
audioPlayer.play()
pausePlayBtn = pauseBtn
} else {
audioPlayer.stop()
pausePlayBtn = playBtn
}
}
You were doing the opposite due to which once the music starts playing, the button does not change its state from play to pause but remains in play state due to which the next time user presses the button, it plays the music and doesnt stop it.

Related

How to change the collor of a button once timer runs out?

Here is the code that I am using, at the bottom of the code is my timer it is a timer counting up and once it hits 60 minutes I would like for a button to turn red.
import UIKit
import AVFoundation
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
}
#IBAction func btnPressed1(_ sender: UIButton) {
sender.backgroundColor = sender.backgroundColor == UIColor.red ? UIColor.black : UIColor.red
}
#IBOutlet weak var titleLabel: UILabel!
#IBOutlet weak var progressBar1: UIProgressView!
let start = 5
var timer = Timer()
var player: AVAudioPlayer!
var totalTime = 0
var secondsPassed = 0
#IBAction func startButtonPressed(_ sender: UIButton) {
let startB = sender.titleLabel?.text
totalTime = start
progressBar1.progress = 0.0
secondsPassed = 0
titleLabel.text = "coffee timer"
timer = Timer.scheduledTimer(timeInterval: 1.0, target:self, selector: #selector(updateTimer), userInfo:nil, repeats: true)
}
#objc func updateTimer() {
if secondsPassed < totalTime {
secondsPassed += 1
progressBar1.progress = Float(secondsPassed) / Float(totalTime)
print(Float(secondsPassed) / Float(totalTime))
} else {
timer.invalidate()
titleLabel.text = "check coffee"
let url = Bundle.main.url(forResource: "alarm_sound", withExtension: "mp3")
player = try! AVAudioPlayer(contentsOf: url!)
player.play()
}
}
}
I need the button to turn the color red after my timer ends and if possible when the button is pressed have the color turn back to black.
You could add an IBOutlet to the button, and then use that outlet to update the button in your updateTimer routine.
An alternative to adding an IBOutlet to the button is to pass the button as the userInfo: parameter of the Timer.
You can pass anything you want as the userInfo: and right now you're just passing nil. If you change nil to sender, then the button will be passed along to the Timer.
timer = Timer.scheduledTimer(timeInterval: 1.0, target:self,
selector: #selector(updateTimer), userInfo: sender,
repeats: true)
Then, add the Timer parameter to updateTimer:
#objc func updateTimer(t: Timer) {
if let button = t.userInfo as? UIButton {
button.backgroundColor = .red
}
}
Making use of userInfo makes even better sense if you have multiple buttons that share the same updateTimer code. By creating a structure to hold the secondsPassed and button and passing that structure as userInfo:, you could have multiple buttons using multiple timers at the same time and each Timer would know which button it was assigned to.

UIButtonBarItem not changing

I have a bottom toolbar in an iOS app the only contains one button to play / pause a live Icecast radio stream. Everything is working except the button changing from the Play icon to the Pause icon and vice versa. Here's my code.
#IBAction func PlayStop(_ sender: Any) {
if player.timeControlStatus == .playing {
// Stop the live radio stream
player.pause()
// Set the radio tower image to off with Alpha 0.3
TowerImage.image = UIImage(named: "TowerOff")
TowerImage.alpha = 0.3
// Set the Toolbar icon to the Play Icon
PlayStopButton = UIBarButtonItem(barButtonSystemItem: UIBarButtonItem.SystemItem.play, target: self, action: #selector(ViewController.PlayStop(_:)))
} else if player.timeControlStatus != .playing {
// Play the live radio stream
player.play()
// Set the radio tower image to on with Alpha 1
TowerImage.image = UIImage(named: "TowerOn")
TowerImage.alpha = 1
// Set the Toolbar icon to the Pause Icon
PlayStopButton = UIBarButtonItem(barButtonSystemItem: UIBarButtonItem.SystemItem.pause, target: self, action: #selector(ViewController.PlayStop(_:)))
}
}
#IBOutlet var TowerImage: UIImageView!
#IBOutlet var PlayStopButton: UIBarButtonItem!
You want to hook the toolbar as outlet then
let playStopButton = UIBarButtonItem(barButtonSystemItem: UIBarButtonItem.SystemItem.pause, target: self, action: #selector(ViewController.PlayStop(_:)))
self.toolBar.items = [playStopButton]

Change BarButtonItem icon on click

I'm trying to create a counter. The idea is quite simple, you click on "play" button and once you click it should disappear and become a "pause" icon, which would trigger a different action.
I thought setting a var for counter status and changing the icon (with only one button) would do the trick but I don't have a clue how can I set the button image for "pause" or any other that appears in the drop down menu when you are creating it from the storyboard panel.
Here the code:
#IBOutlet weak var playButton: UIBarButtonItem!
var timer = NSTimer()
var currentStatus = "stopped"
#IBAction func playAction(sender: AnyObject) {
if (currentStatus == "stopped"){
timer = NSTimer.scheduledTimerWithTimeInterval(1, target: self, selector: Selector("increaseTimer"), userInfo: nil, repeats: true)
currentStatus = "running"
// change button icon (playButton) to Stop
}
else {
currentStatus = "stopped"
timer.invalidate()
// change button icon (playButton) to Play
}
}
You can set the button style like this:
//setButton to play
yourBarButtonItem = UIBarButtonItem(UIBarButtonItem(barButtonSystemItem: UIBarButtonSystemItem.Play, target: self, action: "TheMethodThatTheButtonShouldCall"), animated: true)
//setButton to stop
yourBarButtonItem = UIBarButtonItem(UIBarButtonItem(barButtonSystemItem: UIBarButtonSystemItem.Stop, target: self, action: "TheMethodThatTheButtonShouldCall"), animated: true)
You can set the button style with array like this:
func addCustomNavigationItemAtLeftAndRightSide(leftButtonItems:[UIBarButtonItem], rightButtonItems:[UIBarButtonItem]) {
self.navigationItem.leftBarButtonItems = leftButtonItems
self.navigationItem.rightBarButtonItems = rightButtonItems
}
You can use with style like this:
let leftButtonItem = UIBarButtonItem(image: UIImage(named: "ic_top_back"), style: .Plain, target: self, action: "onBackButtonClicked:")
addCustomNavigationItemAtLeftAndRightSide([leftButtonItem], rightButtonItems: [])

Change bar button Item from Play to Pause Swift

I'm creating a Pomodoro Timer. And I want change the Play bar button item to Pause when I press on it. I've already created the IBOutlet for this button and IBAction.
#IBOutlet weak var playButton: UIBarButtonItem!
#IBAction func startTimer(sender: AnyObject) {
self.playButton = UIBarButtonItem(barButtonSystemItem: .Pause, target: self, action: nil)
}
But this doesn't work. Please help.
try this,
func play() {
var pauseButton = UIBarButtonItem(barButtonSystemItem: .Pause, target: self, action: "pause") //Use a selector
navigationItem.rightBarButtonItem = pauseButton
//other stuff
}
func pause() {
var playButton = UIBarButtonItem(barButtonSystemItem: .Play, target: self, action: "play") //Use a selector
navigationItem.rightBarButtonItem = playButton
//other stuff
}

How to change the bar button icon in toolbar in swift?

I am trying to toggle between the play button and pause button in swift. I have a bar button item in the toolbar whose identifier is initially set to the play. I tried to search and found out the following piece of code but it does not work, looks like it works when the bar button is in the navigation bar
self.navigationItem.setLeftBarButtonItem(UIBarButtonItem(barButtonSystemItem: UIBarButtonSystemItem.Play, target: self, action: "TheMethodThatTheButtonShouldCall"), animated: true)
You need to set items on UIToolbar to update toolbar items: call func setItems(_items: [AnyObject]?,animated animated: Bool) with your new items to update the toolbar's items
Source: https://developer.apple.com/library/prerelease/ios/documentation/UIKit/Reference/UIToolbar_Class/index.html#//apple_ref/occ/instm/UIToolbar/setItems:animated:
Implemented your question with the code as below. works in Swift 2. Please note I connected the IBAction outlet to playBtn
import UIKit
import AVFoundation
class ViewController: UIViewController {
#IBOutlet var sliderVal: UISlider!
#IBOutlet var theToolbar: UIToolbar!
var mySound = AVAudioPlayer()
override func viewDidLoad() {
super.viewDidLoad()
let path = NSBundle.mainBundle().pathForResource("ColdPlay", ofType: "mp3")
do {
mySound = try AVAudioPlayer(contentsOfURL: NSURL(fileURLWithPath: path!))
}
catch{
print("error caught")
}
}
#IBAction func playBtn(sender: UIBarButtonItem) {
let theBarbuttonItem = UIBarButtonItem(barButtonSystemItem: UIBarButtonSystemItem.Pause, target: self, action: "pauseBtn:")
let arrayBarButtonItem = [theBarbuttonItem]
theToolbar.setItems(arrayBarButtonItem, animated: true)
mySound.play()
}
#IBAction func pauseBtn(sender: UIBarButtonItem) {
let theBarbuttonItemB = UIBarButtonItem(barButtonSystemItem: UIBarButtonSystemItem.Play, target: self, action: "playBtn:")
let arrayBarButtonItemB = [theBarbuttonItemB]
theToolbar.setItems(arrayBarButtonItemB, animated: true)
mySound.pause()
}
}

Resources