Я хотел бы добавить функциональность фонарика в свое приложение в Swift. Как я могу это сделать?
Как включить и выключить фонарик в Swift?
Ответы (12)
Обновление №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()
}
}
setTourchModeOnWithLevel
должен находиться в собственном блоке try, чтобы он мог разблокировать устройство для настройки в случае, если что-то пойдет не так. ` do { try device.setTorchModeOnWithLevel(1.0) } catch { device.unlockForConfiguration() } `
- person Awesomeness; 02.12.2015
Обновленный ответ 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)
of toggleTorch(on: false)
Я получил этот ответ от Взлом с помощью 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)
}
}
Свифт 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, чтобы использовать факел.
Для свифт 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)
}
}
}
}
Решение для Swift 4 с условием факел доступен или нет
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")
}
}
Решение - это комбинация @Joshua Dance И @Lance
Свифт 4.2
if let device = AVCaptureDevice.default(for: AVMediaType.video) {
if (device.hasTorch) {
do {
try device.lockForConfiguration()
let torchOn = !device.isTorchActive
try device.setTorchModeOn(level: 1.0)
device.torchMode = torchOn ? AVCaptureDevice.TorchMode.on : AVCaptureDevice.TorchMode.off
device.unlockForConfiguration()
} catch {
print(error.localizedDescription)
}
}
}
Свифт версии 5.2.4
func toggleFlash(on: Bool ) {
guard let device = AVCaptureDevice.default(for: .video), device.hasTorch else { return }
do {
try device.lockForConfiguration()
device.torchMode = on ? .on : .off
if on {
try device.setTorchModeOn(level: AVCaptureDevice.maxAvailableTorchLevel)
}
device.unlockForConfiguration()
} catch {
print("Error: \(error)")
}
}
SwiftUI
// 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)")
}
}
}
Пример (iOS 14.0):
//ContentView.swift
import SwiftUI
struct ContentView: View {
@StateObject var torchState = TorchState()
var body: some View {
Toggle(isOn: $torchState.isOn) {
Text("Torch")
}
}
}
Рефакторинг. Свифт 5.4
import AVFoundation
extension UIDevice {
static func toggleFlashLight() {
guard let device = AVCaptureDevice.default(for: AVMediaType.video),
device.hasTorch else { return }
do {
try device.lockForConfiguration()
try device.setTorchModeOn(level: 1.0)
device.torchMode = device.isTorchActive ? .off : .on
device.unlockForConfiguration()
} catch {
assert(false, "error: device flash light, \(error)")
}
}
}