如何快速打开和关闭手电筒?

Posted

技术标签:

【中文标题】如何快速打开和关闭手电筒?【英文标题】:How to turn flashlight ON and OFF in swift? 【发布时间】:2015-01-28 05:05:26 【问题描述】:

我想在我的 Swift 应用中添加手电筒功能。我该怎么做呢?

【问题讨论】:

【参考方案1】:

更新 #1:torchActive 没有返回预期值;可能是因为它是 modified)

更新 #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 块来实现来自 cmets 的 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 块中,以便在出现问题时解锁设备进行配置。 ` 做 尝试 device.setTorchModeOnWithLevel(1.0) 捕捉 device.unlockForConfiguration() ` @Awesomeness 我实现了你的建议,但使用了嵌套的 do-catch 块,因为它少了一行代码......无需在 setTorchModeOnWithLevel 内外调用 device.unlockForConfiguration() (1.0) 捕获块。 当你快速按下手电筒按钮时,这个解决方案不是最快的,它会稍微延迟 我建议使用 AVCaptureDevice.maxAvailableTorchLevel 而不是 1.0。【参考方案2】:

更新 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)

【讨论】:

我喜欢这段代码的编写方式。在我的应用程序中完美运行。请记住导入 AVFoundation 以使用火炬。【参考方案3】:

我更新了@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 文件的顶部包含“import AVFoundation”。 仅供参考,几个月前我也更新了我对 Swift 2.0 的答案(这个答案所基于的答案),与这个答案不同,我的答案还处理了尝试 device.setTorchModeOnWithLevel(1.0) 的情况失败。【参考方案4】:

斯威夫特 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 以使用 Torch。

【讨论】:

【参考方案5】:

对于 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")
        
    

【讨论】:

【参考方案6】:

像这样:

 func turnTorchOn()

    let device = AVCaptureDevice.defaultDeviceWithMediaType(AVMediaTypeVideo)
    if device.hasTorch 
        device.lockForConfiguration(nil)
        device.setTorchModeOnWithLevel(1.0, error: nil)
        device.unlockForConfiguration()
    



【讨论】:

【参考方案7】:

对于 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)
            
        
    

【讨论】:

【参考方案8】:

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")
            
        

解决方案是@Joshua Dance和@Lance的组合

【讨论】:

【参考方案9】:

斯威夫特 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)
        
    

【讨论】:

【参考方案10】:

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")
          
    

        

【讨论】:

干净整洁。正是我需要的。谢谢!【参考方案11】:

如果您只想使用一个按钮来打开或关闭手电筒,这是代码;

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")
        
    

你可以在按钮点击函数中调用toggleTorch()来打开和关闭手电筒。

【讨论】:

【参考方案12】:

Swift 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)")
        
    

【讨论】:

【参考方案13】:

重构。斯威夫特 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)")
        
    


【讨论】:

【参考方案14】:
Swift 4.1

@objc func Flash() 
        let device = AVCaptureDevice.default(for: AVMediaType.video)
        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)
            
        
    

【讨论】:

以上是关于如何快速打开和关闭手电筒?的主要内容,如果未能解决你的问题,请参考以下文章

设备屏幕关闭时如何打开手电筒?

CameraX 库如何打开/关闭手电筒?

NodeJS - 在移动 Android/iPhone 中打开和关闭 Tourch/手电筒

有没有办法打开和关闭前置摄像头的手电筒? [复制]

如何让手电筒应用程序中的手电筒关闭?

如何打开安卓设备的前置手电筒(不是后置手电筒)