如何在 Swift 3/4 中使用相机获取位置?

Posted

技术标签:

【中文标题】如何在 Swift 3/4 中使用相机获取位置?【英文标题】:How to get location within the camera use in Swift 3/4? 【发布时间】:2017-06-29 12:14:24 【问题描述】:

我遇到了这个问题,我有一个相机和一个地图视图,如果使用应用程序拍摄照片,我想要做的就是获取位置,您可以在捕获图像的那一刻访问用户的位置并扩展 UIImage 以包含位置属性,并将此位置同时保存到地图视图或 tableView 上,当使用手机的相机拍摄照片时保存图像。感谢您的任何帮助。

这是我的代码。 (相机控制器)

import UIKit

class ViewController: UIViewController, UINavigationControllerDelegate 

    @IBOutlet weak var imageView: UIImageView!
    @IBOutlet weak var resultLbl: UILabel!

    override func viewDidLoad() 
        super.viewDidLoad()
    

    override func viewWillAppear(_ animated: Bool) 

    

    override func didReceiveMemoryWarning() 
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    


    @IBAction func CamBtn(_ sender: Any) 
        if !UIImagePickerController.isSourceTypeAvailable(.camera) 
            return
        

        let cameraPicker = UIImagePickerController()
        cameraPicker.delegate = self
        cameraPicker.sourceType = .camera
        cameraPicker.allowsEditing = false
        MapViewController.location.requestLocation()
        guard let userLocation = MapViewController.location.location else return
        present(cameraPicker, animated: true)
    


    @IBAction func LibBtn(_ sender: Any) 
        let picker = UIImagePickerController()
        picker.allowsEditing = false
        picker.delegate = self
        picker.sourceType = .photoLibrary
        present(picker, animated: true)
    

   extension ViewController: UIImagePickerControllerDelegate 
    func imagePickerControllerDidCancel(_ picker: UIImagePickerController) 
        dismiss(animated: true, completion: nil)
    

    func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : Any]) 
        picker.dismiss(animated: true)
        resultLbl.text = "Analyzing Image..."
        guard let image = info["UIImagePickerControllerOriginalImage"] as? UIImage else 
            return
        


地图视图控制器

import Foundation
import UIKit
import MapKit

class MapViewController: UIViewController, CLLocationManagerDelegate 

    @IBOutlet weak var mapView: MKMapView!
    @IBOutlet weak var tableView: UITableView!

    let regionRadius: CLLocationDistance = 1000
    var location: CLLocationManager!
    let nearbyRequest = MKLocalSearchRequest()

    override func viewDidLoad() 
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.

        location = CLLocationManager()
        location!.delegate = self
        location.desiredAccuracy = kCLLocationAccuracyBest
        location.requestAlwaysAuthorization()
        location.startUpdatingLocation()

        if CLLocationManager.authorizationStatus() == .authorizedWhenInUse 
            location!.startUpdatingLocation()
         else 
            location!.requestWhenInUseAuthorization()
        
    

    override func viewWillAppear(_ animated: Bool) 
        super.viewWillAppear(true)
        mapView.showsUserLocation = true
    

    override func viewWillDisappear(_ animated: Bool) 
        mapView.showsUserLocation = false
    


    func location(manager: CLLocationManager, didChangeAuthorizationStatus status: CLAuthorizationStatus) 
        switch status 
        case .notDetermined:
            print("Not Determined")
        case .restricted:
            print("Restricted")
        case .denied:
            print("Denied")
        case .authorizedAlways:
            print("AuthorizedAlways")
        case .authorizedWhenInUse:
            print("AuthorizedWhenInUse")
        location!.startUpdatingLocation()
          
    

    func locationManager(manager: CLLocationManager, didFailWithError error: NSError) 
        print("Failed to initialize Map: ", error.description)
    


【问题讨论】:

那么你的问题是什么,什么不起作用?请解释您所面临的问题,而不仅仅是您想要实现的目标。 好吧,@DavidPasztor 问题是,我正在获取用户位置,但是当用户拍照时它并没有完全得到它。我要做的就是,当相机打开时,将用户位置同时获取到地图视图或tableView上,何时捕获 【参考方案1】:

如果您想在拍照时获取用户的位置,您需要在用户拍照时请求位置更新,而不仅仅是在您的其他ViewController 中开始位置更新。您可以使用CLLocationManager().requestLocation() 请求一次位置更新,但请注意这是一个异步调用,因此用户可能会在返回时完成拍照。

为缓解此问题,您可以使用PromiseKit 让您的函数仅在异步方法完成时返回,或者您可以使用CLLocationManagerDelegate func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) 方法并在位置更新后立即更新图片/MapView收到了。

MapViewController 中将var location: CLLocationManager! 更改为static var location = CLLocationManager(),相应地更新您的MapViewController 类以使用location 作为类型属性而不是隐式展开的实例属性。然后在CameraController 中更改您的函数,如下所示:

@IBAction func CamBtn(_ sender: Any) 
        if !UIImagePickerController.isSourceTypeAvailable(.camera) 
            return
        

        let cameraPicker = UIImagePickerController()
        cameraPicker.delegate = self
        cameraPicker.sourceType = .camera
        cameraPicker.allowsEditing = false
        MapViewController.location.requestLocation()
        guard let userLocation = MapViewController.location.location else return
        present(cameraPicker, animated: true)
    

这不是一个完整的示例,您仍然需要将userLocation 添加到您的图像/MapView,但您应该能够自己弄清楚这部分。此外,通过这种实现,requestLocation() 不能保证在您检查其值时返回,所以我宁愿使用PromiseKitCLLocationManager.promise() 函数,它只在位置更新后返回。

【讨论】:

以上是关于如何在 Swift 3/4 中使用相机获取位置?的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 Swift 在 SpriteKit 程序中初始化/移动相机?

如何在 Swift 2 中获得 SKSpriteNode 的真正中心?

SceneKit:在 Swift 4 中缩放相机

如何确保 SceneKit 相机始终指向特定位置

如何在 Swift 中使用 AVCaptureSession 捕获图片?

如何在 Swift 中使用 URL 从库中获取图像? [复制]