创建指向指定位置方向的自定义指南针箭头

Posted

技术标签:

【中文标题】创建指向指定位置方向的自定义指南针箭头【英文标题】:Creating a custom compass arrow that points in the direction of a specified location 【发布时间】:2018-03-09 13:31:54 【问题描述】:

基本上我想要一个旋转的箭头图像,以便将用户引导到附近的位置。我正在使用核心位置航向数据来获取方向信息,代码如下。

 func locationManager(_ manager: CLLocationManager, didUpdateHeading newHeading: CLHeading) 
    print("MAGNETIC HEADING: \(newHeading.magneticHeading)")
    print("TRUE HEADING  \(newHeading.trueHeading)")

    var degrees = newHeading.trueHeading
    //Rotate the arrow image
    if self.arrowImageView != nil 

        self.arrowImageView.transform = CGAffineTransform(rotationAngle: CGFloat(degrees * (180.0 / M_PI)))
    



我不确定这是否是正确的方法。

【问题讨论】:

【参考方案1】:

我设法使用此处找到的 C# 解决方案 How to rotate a Direction Arrow to particular location

func UpdateCompass(origin: CLLocationCoordinate2D,target:CLLocationCoordinate2D, heading: CLHeading)

    var angle1 = GetAngleBetweenPoints(origin: origin, target: target);
    var angle2 = GetAngleFromHeading(heading: heading);
    var radian = .pi * (angle1 + angle2) / 180.0;
    let res =  radiansToDegrees(radians:radian)
    self.arrowImageView.transform = CGAffineTransform(rotationAngle: CGFloat(radian))
    //self.CompassImageView.transform = CGAffineTransform(rotationAngle: CGFloat(radian))
    UIView.animate(withDuration: 0.5, animations: 
       self.CompassImageView.transform = CGAffineTransform(rotationAngle: CGFloat(radian))
    )


func GetAngleBetweenPoints(origin:CLLocationCoordinate2D,target: CLLocationCoordinate2D) -> Double

var n = 270 - (atan2(origin.latitude - target.latitude, origin.longitude - target.longitude)) * 180 / .pi;
return n.truncatingRemainder(dividingBy: 360);


func GetAngleFromHeading(heading:CLHeading) -> Double

var radians = -heading.magneticHeading / 180.0 * .pi;
return radians * (180.0 / .pi);

【讨论】:

【参考方案2】:

嗯,一个大问题是您启动 locationManager 的线程。它在同一个线程上调用其委托方法。现在你可能在主线程上启动了它,但我不知道看这段代码。当然,除了主线程(技术上是主队列)之外,您不希望在任何东西上转换 UIView。

另一个问题是我会将轮换代码与 locationManager 代码分开。您希望能够独立测试它们,并且有时您可能希望将标题强制为特定值。

另一个想法是性能。一秒钟可以调用多少次标题委托?如果有时超过 10 个,您应该跳过这些 - 人眼不会识别出更多的运动。事实上,出于这个目的,我将其限制在 1 秒。

您还应该考虑检查航向准确度。您想接受并显示最不准确的航向“猜测”吗?

至于旋转视图,如果自动布局对您来说很重要,您可能会遇到布局约束问题。有关详细信息,请参阅this SO。我想知道您是否可以旋转视图的图层。

另一件需要担心的事情是您的视图在设备方向更改期间和之后的行为方式。 This SO code,如果根据您的目标进行更改,如果设备方向被证明是一个问题,将会很有用。

总而言之,我会选择更改视图的图像(通过绘制到视图中)或分层旋转整个视图,以避免上述一些问题。我敢打赌它也会更高效。

【讨论】:

感谢您的指点,我正在旋转放置在 UIViewcontroller 内的图像视图。它自身的 imageView 的大小很小,小于 70pt。所有位置代码与地图视图设置一起在 viewDidLoad 中设置。这些的委托方法在类中被拆分为单独的扩展。希望这能给你更多的洞察力和澄清。

以上是关于创建指向指定位置方向的自定义指南针箭头的主要内容,如果未能解决你的问题,请参考以下文章

iPhone 指南针 GPS 方向

带有2个位置的Android点方向

C#WPF - 创建自定义控件。不确定如何正确对齐文本

如何检查指南针航向是不是指向特定位置?

在 Android 上查找指南针方向

Android自定义指南针指向自定义位置[重复]