我想在我的Swift应用程序中添加手电筒功能。 我该如何操作?
更新 #1: (torchActive
没有返回预期的值; 可能是因为它已被修改)
更新 #2: 适用于Swift 2.0
要切换闪光灯从开到关(不仅仅像疯狂猪的答案中所说的“开”),您可以使用以下方法:
func toggleFlash() {
let device = AVCaptureDevice.defaultDeviceWithMediaType(AVMediaTypeVideo)
if (device.hasTorch) {
do {
try device.lockForConfiguration()
if (device.torchMode == AVCaptureTorchMode.On) {
device.torchMode = AVCaptureTorchMode.Off
} else {
do {
try device.setTorchModeOnWithLevel(1.0)
} catch {
print(error)
}
}
device.unlockForConfiguration()
} catch {
print(error)
}
}
}
我使用嵌套的 do-catch 块来实现 Awesomeness 在评论中的建议。这种方式,即使 try device.setTorchModeOnWithLevel(1.0)
失败,设备也能正确解锁以进行配置。
更新 #3: 适用于 Swift 4:
(我对代码进行了一些个人喜好上的编辑)
func toggleFlash() {
guard let device = AVCaptureDevice.default(for: AVMediaType.video) else { return }
guard device.hasTorch else { return }
do {
try device.lockForConfiguration()
if (device.torchMode == AVCaptureDevice.TorchMode.on) {
device.torchMode = AVCaptureDevice.TorchMode.off
} else {
do {
try device.setTorchModeOn(level: 1.0)
} catch {
print(error)
}
}
device.unlockForConfiguration()
} catch {
print(error)
}
}
要将闪光灯从打开状态切换到关闭状态(不仅仅是像疯狂的猪所说的“打开”),您可以使用以下方法:
func toggleFlash() {
let device = AVCaptureDevice.defaultDeviceWithMediaType(AVMediaTypeVideo)
if (device.hasTorch) {
device.lockForConfiguration(nil)
let torchOn = !device.torchActive
device.setTorchModeOnWithLevel(1.0, error: nil)
device.torchMode = torchOn ? AVCaptureTorchMode.On : AVCaptureTorchMode.Off
device.unlockForConfiguration()
}
}
更新的Swift 4答案:
func toggleTorch(on: Bool) {
guard
let device = AVCaptureDevice.default(for: AVMediaType.video),
device.hasTorch
else { return }
do {
try device.lockForConfiguration()
device.torchMode = on ? .on : .off
device.unlockForConfiguration()
} catch {
print("Torch could not be used")
}
}
要实际打开或关闭它,请调用该函数并传递一个true或false的布尔值。
toggleTorch(on: true)
或 toggleTorch(on: false)
我从Hacking with Swift获得了这个答案,但他们的示例中有一个错误。
他们使用了AVCaptureDevice.defaultDevice(withMediaType: AVMediaTypeVideo)
,但这会导致一个错误,说defaultDevice
不存在。所以我把它改成了AVCaptureDevice.default(for: AVMediaType.video)
。
我已经更新了@Lyndsey Scott的优秀答案,以适应Swift 2.0
let device = AVCaptureDevice.defaultDeviceWithMediaType(AVMediaTypeVideo)
if (device.hasTorch) {
do {
try device.lockForConfiguration()
if (device.torchMode == AVCaptureTorchMode.On) {
device.torchMode = AVCaptureTorchMode.Off
} else {
try device.setTorchModeOnWithLevel(1.0)
}
device.unlockForConfiguration()
} catch {
print(error)
}
}
Swift 5
许多人已经写了这个解决方案,但我想提出我在项目中想到的更简洁的方法:
func toggleTorch(on: Bool) {
guard let device = AVCaptureDevice.default(for: AVMediaType.video) else { return }
guard device.hasTorch else { print("Torch isn't available"); return }
do {
try device.lockForConfiguration()
device.torchMode = on ? .on : .off
// Optional thing you may want when the torch it's on, is to manipulate the level of the torch
if on { try device.setTorchModeOn(level: AVCaptureDevice.maxAvailableTorchLevel.significand) }
device.unlockForConfiguration()
} catch {
print("Torch can't be used")
}
}
正如评论中所提到的,当手电筒正在使用时,您也可以更改它的亮度级别,我发现这非常方便。
还需导入AVFoundation来使用手电筒功能。
对于Swift 3
func toggleFlash() {
if let device = AVCaptureDevice.defaultDevice(withMediaType: AVMediaTypeVideo), device.hasTorch {
do {
try device.lockForConfiguration()
let torchOn = !device.isTorchActive
try device.setTorchModeOnWithLevel(1.0)
device.torchMode = torchOn ? .on : .off
device.unlockForConfiguration()
} catch {
print("error")
}
}
}
就像这样:
func turnTorchOn(){
let device = AVCaptureDevice.defaultDeviceWithMediaType(AVMediaTypeVideo)
if device.hasTorch {
device.lockForConfiguration(nil)
device.setTorchModeOnWithLevel(1.0, error: nil)
device.unlockForConfiguration()
}
}
对于Xcode 9.1,Swift 4(更新后不会崩溃,即使没有手电筒):
func toggleFlash() {
let device = AVCaptureDevice.default(for: AVMediaType.video)
if (device != nil) {
if (device!.hasTorch) {
do {
try device!.lockForConfiguration()
if (device!.torchMode == AVCaptureDevice.TorchMode.on) {
device!.torchMode = AVCaptureDevice.TorchMode.off
} else {
do {
try device!.setTorchModeOn(level: 1.0)
} catch {
print(error)
}
}
device!.unlockForConfiguration()
} catch {
print(error)
}
}
}
}
func toggleTorch() {
guard
let device = AVCaptureDevice.default(for: AVMediaType.video),
device.hasTorch
else { return }
do {
try device.lockForConfiguration()
if device.torchMode == AVCaptureDevice.TorchMode.on
{
device.torchMode = .off
} else {
device.torchMode = .on
}
device.unlockForConfiguration()
} catch {
print("Torch could not be used")
}
}
解决方案适用于Swift 4,条件是是否有torch
func flashlight() {
guard let device = AVCaptureDevice.default(for: AVMediaType.video) else{
return
}
if (device.hasTorch) {
do {
try device.lockForConfiguration()
if (device.torchMode == .on) {
device.torchMode = .off
} else {
device.torchMode = .on
}
device.unlockForConfiguration()
} catch {
print("Torch could not be used")
print(error)
}
}
else{
print("Torch is not available")
}
}
// TorchState.swift
import SwiftUI
import AVFoundation
class TorchState: ObservableObject {
@Published var isOn: Bool = false {
didSet {
toggleTorch(isOn)
}
}
private func toggleTorch(_ isOn: Bool) {
guard let device = AVCaptureDevice.default(for: .video), device.hasTorch else { return }
do {
try device.lockForConfiguration()
device.torchMode = isOn ? .on : .off
if isOn {
try device.setTorchModeOn(level: AVCaptureDevice.maxAvailableTorchLevel)
}
device.unlockForConfiguration()
} catch {
print("Error: \(error)")
}
}
}
//ContentView.swift
import SwiftUI
struct ContentView: View {
@StateObject var torchState = TorchState()
var body: some View {
Toggle(isOn: $torchState.isOn) {
Text("Torch")
}
}
}
setTourchModeOnWithLevel
调用需要在自己的try块中,以便在出现问题时可以解锁设备进行配置。do { try device.setTorchModeOnWithLevel(1.0) } catch { device.unlockForConfiguration() }
- Awesomeness