如何在iOS 11中实现音量快门?

时间:2017-01-12 16:16:25

标签: ios iphone ios10 avcapture shutter

我想在相机应用中实现音量快门。当用户按下音量按钮时,我应该得到一个事件来拍照。

我正在寻找符合以下要求的实施方案:

  • 即使音量当前处于最大音量,并且用户按下音量增大按钮,它也应该有效。
  • 屏幕上的UI不应显示音量已更改。
  • 应该没有已知的Apple拒绝使用此技术的应用程序的情况。

关于此主题存在其他问题和答案,但对于旧版本的iOS,我想找到一个可在iOS 11上运行的问题。

ProCamera,ProCam和Camera +等相机应用程序具有满足所有这些条件的音量快门,因此它显而易见。

2 个答案:

答案 0 :(得分:4)

所以这里的代码将满足您的所有要求 我已经从StackOverflow上的问题/答案中提取了所有这些代码。

Apple将拒绝使用此代码提交的所有应用。

  

在Xcode 8.3.1中使用iOS 10.2进行测试

您需要使用AVFoundationMediaPlayer框架才能实现此目的。

import UIKit
import AVFoundation
import MediaPlayer

class ViewController: UIViewController {

    //keeps track of the initial volume the user had set when entering the app
    //used to reset the volume when he exits the app
    var volume: Float = 0

    override func viewDidLoad() {
        super.viewDidLoad()

        let audioSession = AVAudioSession.sharedInstance()
        volume = audioSession.outputVolume-0.1 //if the user is at 1 (full volume)
        try! audioSession.setActive(true)
        audioSession.addObserver(self, forKeyPath: "outputVolume", options: NSKeyValueObservingOptions.new, context: nil)
        //prevents the volume hud from showing up
        let volView = MPVolumeView(frame: .zero)
        view.addSubview(volView)
    }

    override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) {
        //when the user changes the volume,
        //prevent the output volume from changing by setting it to the default volume we specified,
        //so that we can continue pressing the buttons for ever
        (MPVolumeView().subviews.filter{NSStringFromClass($0.classForCoder) == "MPVolumeSlider"}.first as? UISlider)?.setValue(volume, animated: false)

        //implement your photo-capturing function here
        print("volume changed")
    }
}

更新

如果您想在用户退出应用程序后确保您的代码仍然有效,请使用AppDelegate在应用程序变为活动状态时安装观察者,如下所示:

<强>的AppDelegate

import UIKit
import AVFoundation
import MediaPlayer

var volume: Float = 0.5

@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {

    var window: UIWindow?
    let audioSession = AVAudioSession.sharedInstance()

    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
        return true
    }

    override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) {
        (MPVolumeView().subviews.filter{NSStringFromClass($0.classForCoder) == "MPVolumeSlider"}.first as? UISlider)?.setValue(volume, animated: false)

        NotificationCenter.default.removeObserver(self)
        NotificationCenter.default.post(Notification(name: Notification.Name(rawValue: "volumeChanged")))
    }

    func applicationDidBecomeActive(_ application: UIApplication) {
        volume = audioSession.outputVolume
        if volume == 0 { volume += 0.1 } else if volume == 1 { volume -= 0.1 }
        try! audioSession.setActive(true)
        audioSession.addObserver(self, forKeyPath: "outputVolume", options: NSKeyValueObservingOptions.new, context: nil)
    }

    func applicationWillResignActive(_ application: UIApplication) {
        audioSession.removeObserver(self, forKeyPath: "outputVolume")
    }
}

<强>的ViewController

import UIKit
import AVFoundation
import MediaPlayer

class ViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()

        NotificationCenter.default.addObserver(self, selector: #selector(self.volumeChanged), name: Notification.Name(rawValue: "volumeChanged"), object: nil)
        //prevents the volume hud from showing up
        let volView = MPVolumeView(frame: .zero)
        view.addSubview(volView)
    }

    func volumeChanged() {
        print("volume changed")
    }
}

答案 1 :(得分:-1)

根据Apple的App Store Review Guidelines,这将是拒绝的明确理由。

  

2.5.9 将拒绝更改标准交换机功能的应用,例如音量调高/降低和振铃/静音开关,或其他本机用户界面元素或行为。

来源:Is it possible to disable volume buttons in iOS apps?