首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >iOS 10 MKUserLocation点的标题箭头

iOS 10 MKUserLocation点的标题箭头
EN

Stack Overflow用户
提问于 2016-09-29 06:16:50
回答 4查看 10.9K关注 0票数 22

iOS 10中的地图应用程序现在在MKUserLocation MKAnnotationView上有一个标题方向箭头。有什么方法可以在我自己的应用程序中添加到MKMapView中吗?

编辑:,我很乐意手动做这件事,但我不确定这是否可能?我是否可以在地图上添加一个注释,并让它跟随用户的位置,包括动画动作?

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2016-10-10 05:47:00

我通过在MKUserLocation annotationView中添加一个子视图来解决这个问题,如下所示

代码语言:javascript
运行
复制
func mapView(mapView: MKMapView, didAddAnnotationViews views: [MKAnnotationView]) {
if annotationView.annotation is MKUserLocation {
    addHeadingViewToAnnotationView(annotationView)
    }
}

func addHeadingViewToAnnotationView(annotationView: MKAnnotationView) {
    if headingImageView == nil {
        if let image = UIImage(named: "icon-location-heading-arrow") {
            let headingImageView = UIImageView()
            headingImageView.image = image
            headingImageView.frame = CGRectMake((annotationView.frame.size.width - image.size.width)/2, (annotationView.frame.size.height - image.size.height)/2, image.size.width, image.size.height)
            self.headingImageView = headingImageView
        }
    }

    headingImageView?.removeFromSuperview()
    if let headingImageView = headingImageView {
        annotationView.insertSubview(headingImageView, atIndex: 0)
    }

    //use CoreLocation to monitor heading here, and rotate headingImageView as required
}
票数 3
EN

Stack Overflow用户

发布于 2016-11-25 15:55:39

我也经历过同样的问题(需要一个定位指示器而不用地图旋转,类似于Apple Maps应用程序)。不幸的是,苹果公司还没有推出“标题的蓝色图标”API。

我从@alku83 83的实现中创建了以下解决方案。

  1. 确保类符合MKViewDelegate
  2. 添加委托方法以将蓝色箭头图标添加到映射位置点 func mapView(_ mapView: MKMapView,didAdd视图: MKAnnotationView) { if views.last?.annotation是MKUserLocation { addHeadingView(toAnnotationView: views.last!) }}
  3. 添加创建“蓝色箭头图标”的方法。 func addHeadingView(toAnnotationView annotationView: MKAnnotationView) { if headingImageView == nil { let headingImageView == ICON# headingImageView=UIImageView(图像:图像) headingImageView!.frame = CGRect(x:(annotationView.frame.size.width - image.size.width)/2,y:(annotationView.frame.size.height - image.size.width )/2,y:(annotationView.frame.size.height-/2),宽度:MKAnnotationView,高度:en0 20#)at: 0) headingImageView!.isHidden = true }
  4. var headingImageView: UIImageView?添加到类中。这主要用于转换/旋转蓝色箭头图像。
  5. (根据体系结构的不同,在不同的类/对象中)创建一个位置管理器实例,类符合CLLocationManagerDelegate协议 惰性变量locationManager: CLLocationManager ={ let manager = CLLocationManager() //在这里设置管理器属性manager.delegate = self返回管理器}()
  6. 确保您的位置管理器正在跟踪用户标题数据locationManager.startUpdatingHeading(),并且它在适当的locationManager.stopUpdatingHeading()时停止跟踪。
  7. 添加var userHeading: CLLocationDirection?,它将保存方向值
  8. 添加要通知标题值何时更改的委托方法,并适当地更改userHeading值。 locationManager(_ manager: CLLocationManager,didUpdateHeading newHeading: CLHeading) {如果newHeading.headingAccuracy <0{返回} let标题= newHeading.trueHeading >0?newHeading.trueHeading : newHeading.magneticHeading userHeading =标题NotificationCenter.default.post(名称: Notification.Name(rawValue:#YOUR KEY#),object: self,userInfo: nil) }
  9. 现在,在符合MKMapViewDelegate的类中,添加方法以“转换”标题图像的方向 updateHeadingRotation() {如果让标题=#您的locationManager instance#,则让headingImageView = headingImageView { headingImageView.isHidden = false let旋转=CGFloat(标题/180* Double.pi) headingImageView.transform = CGAffineTransform(rotationAngle:旋转)}}
票数 23
EN

Stack Overflow用户

发布于 2016-10-07 14:20:57

是的,你可以手动完成。

其基本思想是使用CLLocationManager跟踪用户的位置,并使用它的数据在地图上放置和旋转注释视图。

这是密码。我省略了一些与这个问题没有直接关系的东西(例如,我假设用户已经授权您的应用程序访问位置,等等),所以您可能想修改一下这段代码。

ViewController.swift

代码语言:javascript
运行
复制
import UIKit
import MapKit

class ViewController: UIViewController, CLLocationManagerDelegate, MKMapViewDelegate {
    @IBOutlet var mapView: MKMapView!
    lazy var locationManager: CLLocationManager = {
        let manager = CLLocationManager()
        manager.delegate = self
        return manager
    }()

    var userLocationAnnotation: UserLocationAnnotation!

    override func viewDidLoad() {
        super.viewDidLoad()

        locationManager.desiredAccuracy = kCLLocationAccuracyBestForNavigation

        locationManager.startUpdatingHeading()
        locationManager.startUpdatingLocation()

        userLocationAnnotation = UserLocationAnnotation(withCoordinate: CLLocationCoordinate2D(), heading: 0.0)

        mapView.addAnnotation(userLocationAnnotation)
    }

    func locationManager(_ manager: CLLocationManager, didUpdateHeading newHeading: CLHeading) {
        userLocationAnnotation.heading = newHeading.trueHeading
    }

    func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
        userLocationAnnotation.coordinate = locations.last!.coordinate
    }

    public func mapView(_ mapView: MKMapView, viewFor annotation: MKAnnotation) -> MKAnnotationView? {
        if let annotation = annotation as? UserLocationAnnotation {
            let annotationView = mapView.dequeueReusableAnnotationView(withIdentifier: "UserLocationAnnotationView") ?? UserLocationAnnotationView(annotation: annotation, reuseIdentifier: "UserLocationAnnotationView")
            return annotationView
        } else {
            return MKPinAnnotationView(annotation: annotation, reuseIdentifier: nil)
        }
    }

}

在这里,我们正在做地图视图的基本设置,并开始跟踪用户的位置和使用CLLocationManager的标题。

UserLocationAnnotation.swift

代码语言:javascript
运行
复制
import UIKit
import MapKit

class UserLocationAnnotation: MKPointAnnotation {
    public init(withCoordinate coordinate: CLLocationCoordinate2D, heading: CLLocationDirection) {
        self.heading = heading

        super.init()
        self.coordinate = coordinate
    }

    dynamic public var heading: CLLocationDirection
}

非常简单的MKPointAnnotation子类,能够存储标题方向。dynamic关键字是这里的关键。它允许我们用KVO观察对heading属性的更改。

UserLocationAnnotationView.swift

代码语言:javascript
运行
复制
import UIKit
import MapKit

class UserLocationAnnotationView: MKAnnotationView {

    var arrowImageView: UIImageView!

    private var kvoContext: UInt8 = 13

    override public init(annotation: MKAnnotation?, reuseIdentifier: String?) {
        super.init(annotation: annotation, reuseIdentifier: reuseIdentifier)

        arrowImageView = UIImageView(image: #imageLiteral(resourceName: "Black_Arrow_Up.svg"))
        addSubview(arrowImageView)
        setupObserver()
    }

    required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)

        arrowImageView = UIImageView(image: #imageLiteral(resourceName: "Black_Arrow_Up.svg"))
        addSubview(arrowImageView)
        setupObserver()
    }

    func setupObserver() {
        (annotation as? UserLocationAnnotation)?.addObserver(self, forKeyPath: "heading", options: [.initial, .new], context: &kvoContext)
    }

    override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) {
        if context == &kvoContext {
            let userLocationAnnotation = annotation as! UserLocationAnnotation
            UIView.animate(withDuration: 0.2, animations: { [unowned self] in
                self.arrowImageView.transform = CGAffineTransform(rotationAngle: CGFloat(userLocationAnnotation.heading / 180 * M_PI))
            })
        }
    }

    deinit {
        (annotation as? UserLocationAnnotation)?.removeObserver(self, forKeyPath: "heading")
    }
}

MKAnnotationView子类,它对heading属性进行观察,然后将适当的旋转转换设置为它的子视图(在我的例子中,它只是一个带有箭头的图像。您可以创建更复杂的注释视图,只旋转其中的某些部分,而不是整个视图。)

UIView.animate是可选的。它的加入,使旋转更平稳。CLLocationManager无法以每秒60次的速度观察航向值,因此当旋转速度较快时,动画可能有点不稳定。UIView.animate调用解决了这个小问题。

coordinate值更新的正确处理已经在MKPointAnnotationMKAnnotationViewMKMapView类中为我们实现了,因此我们不必自己动手。

票数 5
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/39762732

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档