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

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

【问题讨论】:

    标签: ios swift xcode6 flashlight


    【解决方案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)
                                  }
                              }
                          }
                      

                      【讨论】:

                        猜你喜欢
                        • 1970-01-01
                        • 2019-10-05
                        • 1970-01-01
                        • 1970-01-01
                        • 2014-06-17
                        • 2019-03-18
                        • 2020-06-04
                        • 1970-01-01
                        • 1970-01-01
                        相关资源
                        最近更新 更多