Detect volume button press
Using the second method, the value of the key path should be "outputVolume"
. That is the property we are observing.
So change the code to,
var outputVolumeObserve: NSKeyValueObservation?
let audioSession = AVAudioSession.sharedInstance()
func listenVolumeButton() {
do {
try audioSession.setActive(true)
} catch {}
outputVolumeObserve = audioSession.observe(\.outputVolume) { (audioSession, changes) in
/// TODOs
}
}
SwiftUI: how to detect volume button pressed (hardware)?
I have had a hard time with this problem as well. I came across this project https://github.com/jpsim/JPSVolumeButtonHandler and it does the job for the most part and even hides the volume indicator when the volume buttons are pressed.
This is what I did to get it to work. I hope that it helps.
import SwiftUI
import JPSVolumeButtonHandler
struct MyView: View {
@State private var volumeHandler: JPSVolumeButtonHandler?
var body: some View {
ZStack {
Text("Hello World")
}
.onAppear {
// Setup capture of volume buttons
volumeHandler = JPSVolumeButtonHandler(up: {
// Code to run when volume button released
}, downBlock: {
// Code to run when volume button pressed
})
// Start capture of volume buttons
volumeHandler?.start(true)
}
.onDisappear {
// Stop capture of volume buttons when leaving view
volumeHandler?.start(false)
}
}
}
This is the post I used to figure it out originally: iOS. Capturing photos with volume buttons
Detect hardware volume button press when volume not changed
let volumeView = MPVolumeView(frame: CGRect.zero)
self.view.addSubview(volumeView)
NotificationCenter.default.addObserver(self, selector: #selector(volumeChanged(_:)), name: NSNotification.Name(rawValue: "AVSystemController_SystemVolumeDidChangeNotification"), object: nil)
This will get called every press regardless of volume level
@objc func volumeChanged(_ notification: NSNotification) {
if let volume = notification.userInfo!["AVSystemController_AudioVolumeNotificationParameter"] as? Float {
print("volume: \(volume)")
}
}
output:
volume: 0.8125
volume: 0.875
volume: 0.9375
volume: 1.0
volume: 1.0
volume: 1.0
volume: 1.0
Swift: Detect Volume Button Press NOT volume change events
So what I'd do is subscribe to the notification like they do in the questions you linked and then add a variable named say programmaticVolumeChange. When you change the volume programmatically set the variable to true, then in your function observeValueForKeyPath, if the variable is true don't cancel the alarm (and naturally set it to false after). That way when the user presses the volume buttons you know it wasn't your code. Maybe test the amount of time between a programmatic volume change and the function call but I think that would be fine.
Eg
var programmaticVolumeChange = false
func changeVolumeProgramatically() {
programmaticVolumeChange = true
//change volume programmatically after
}
override func observeValueForKeyPath(keyPath: String, ofObject object: AnyObject,
change: [NSObject : AnyObject], context: UnsafeMutablePointer<Void>) {
if keyPath == "outputVolume"{
if programmaticVolumeChange {
programmaticVolumeChange = false
} else {
//handle logic for user volume button press
}
}
}
How to detect volume up and down long pressed together?
You need to detect when the both of the keys are pressed using onKeyDown callback, something like should work:
public boolean up,down;
public boolean onKeyDown(int keyCode, KeyEvent event) {
if (keyCode == KeyEvent.KEYCODE_VOLUME_DOWN){
down = true;
} else if(keyCode == KeyEvent.KEYCODE_VOLUME_UP){
up = true;
}
if(up && down) {
// Two buttons pressed, call your function
}
return true;
}
public boolean onKeyUp(int keyCode, KeyEvent event) {
if (keyCode == KeyEvent.KEYCODE_VOLUME_DOWN){
down = false;
} else if(keyCode == KeyEvent.KEYCODE_VOLUME_UP){
up = false;
}
return true;
}
Related Topics
Firebase Cloud Messaging Doesn't Create Push Notifications But Gets Information
iOS Swift Call Web Service Using Soap
Xcode 6.3 Adding Margins to Tableviewcell
Upload Image to Server - Swift 3
Dismiss View Controller with Custom Animation
Wkwebview Content Loaded Function Never Get Called
Path to Bundle of iOS Framework
Capture Redirect Url in Wkwebview in iOS
Swift 2.0 Sorting Array of Objects by Property
How to Bring a View in Front of Another View, in Swift
Update the Constant Property of a Constraint Programmatically in Swift
Swift Override Instance Variables
Unwind Segue from Navigation Back Button in Swift
Uicollectionview's Cell Registerclass in Swift