gpt4 book ai didi

ios - 如何将点击与注释匹配(或比较)?

转载 作者:行者123 更新时间:2023-11-30 13:02:14 25 4
gpt4 key购买 nike

环境

  • Xcode 8
  • Swift 3
问题陈述
    我希望能够确定用户是否点击 MKPointAnnotation,然后从该注释中提取信息(例如 titlesubtitle)以供使用在我的应用程序中。
    我想这并不是非常困难,但是我对我需要做什么/需要使用哪些类/对象/方法/等来做到这一点感到有点迷失。
    所以我寻找指针/指导 - 欢迎代码,但在这一点上,指针/指导对我来说将是向前迈出的重要一步。
代码片段
    到目前为止代码的删节版本(试图将其限制为仅相关部分)

class NewLocationViewController: UIViewController, CLLocationManagerDelegate, UITextFieldDelegate {

//... various @IBOutlet's for text fields, buttons, etc. ...
@IBOutlet weak var map: MKMapView!

var coords: CLLocationCoordinate2D?
var locationManager: CLLocationManager = CLLocationManager()
var myLocation: CLLocation!
var annotation: MKPointAnnotation!
var annotationList: [MKPointAnnotation] = []
var matchingItems: [MKMapItem] = [MKMapItem]()

override func viewDidLoad() {
super.viewDidLoad()

//... text field delegates, and other initilizations ...
locationManager.requestWhenInUseAuthorization()
if CLLocationManager.locationServicesEnabled() {
locationManager.desiredAccuracy = kCLLocationAccuracyBest
locationManager.delegate = self
}
myLocation = nil
//... other initializations...
}

// Search for things that match what my app is looking for ("<search string>")
func performSearch() {
annotationList.removeAll() // clear list
matchingItems.removeAll() // clear list
var closest = MKMapItem()
var distance = 10000.0
let request = MKLocalSearchRequest()
let span = MKCoordinateSpan(latitudeDelta: 0.001, longitudeDelta: 0.001)
request.naturalLanguageQuery = "<search string>"
request.region = MKCoordinateRegionMake(myLocation.coordinate, span)
let search = MKLocalSearch(request: request)

if search.isSearching {
search.cancel()
}
search.start(completionHandler: {
(_ response, _ error) in
if error != nil {
self.showAlert(msg: "Error occurred in search\nERROR: \(error?.localizedDescription)")
}
else if response!.mapItems.count == 0 {
self.showAlert(msg: "No matches found")
}
else {
for item in response!.mapItems {

// Track the closest placemark to our current [specified] location
let (distanceBetween, prettyDistance) = self.getDistance(loc1: self.myLocation, loc2: item.placemark.location!)
let addrObj = self.getAddress(placemark: item.placemark)
//... some code omitted ...

// Add markers for all the matches found
self.matchingItems.append(item as MKMapItem)
let annotation = MKPointAnnotation()
annotation.coordinate = item.placemark.coordinate
annotation.title = item.name
annotation.subtitle = "\(addrObj.address!) (\(prettyDistance))"
self.map.addAnnotation(annotation)
self.annotationList.append(annotation)
}

//... some code omitted ...
}
})
}

//... code for getDistance(), getAddress() omitted for brevity - they work as designed ...
//... other code omitted as not being relevant to the topic at hand
}

我想我需要重写 touchesEnded 和可能的 touchesBegan 以及 touchesMoved 才能检测到点击。
我不知道如何将 touch 的位置(在屏幕上表示为 X/Y 坐标)与 MKPointAnnotationMKMapItem< 进行比较 的位置(在 map 上表示为纬度/经度坐标)
所以 - 这就是我目前陷入困境的地方。我在网上搜索了各种术语,但找不到任何[简单地]回答我的问题的内容 - 并且以 Swift 代码格式(有许多帖子看起来可能有帮助,但是所提供的代码不是用 Swift 编写的,我不会那么容易地进行翻译)。

更新(东部时间 19:48)

    我找到这篇文章: How do I implement the UITapGestureRecognizer into my application并尝试遵循它,但是...

    我稍微修改了代码(添加了UIGestureRecognizerDelegate):

    class NewLocationViewController: UIViewController, CLLocationManagerDelegate, UITextFieldDelegate, UIGestureRecognizerDelegate {

    override func viewDidLoad() {
    super.viewDidLoad()
    //...other code...
    let tapHandler = UITapGestureRecognizer(target: self, action: Selector(("handleTap:"))) //<<<== See notes below
    tapHandler.numberOfTapsRequired = 1
    tapHandler.numberOfTouchesRequired = 1
    tapHandler.delegate = self
    print("A")//#=#
    map.addGestureRecognizer(tapHandler)
    map.isUserInteractionEnabled = true
    print("B")//#=#
    }

    func handleTap(tap: UITapGestureRecognizer) {
    print("ARRIVED")//#=#
    let here = tap.location(in: map)
    print("I AM HERE: \(here)")//#=#
    }

    //...
    }

    关于tapHandler的声明/定义,我尝试了以下方法:

        let tapHandler = UITapGestureRecognizer(target: self, action: "handleTap:")
    let tapHandler = UITapGestureRecognizer(target: self, action: Selector("handleTap:"))
    let tapHandler = UITapGestureRecognizer(target: self, action: Selector(("handleTap:"))) // supresses warning

    前两个导致 Xcode 中显示警告,最后一个只是抑制警告:

    [W] No method declared with Objective-C selector 'handleTap:'

    当我运行我的应用程序并点击图钉时 - 我在日志中收到以下内容:

    A
    B
    libc++abi.dylib: terminating with uncaught exception of type NSException

    (对我来说)这似乎表明 viewDidLoad 中的一般设置没问题,但是一旦它尝试处理点击,它就会死掉而不会到达我的 handleTap 函数 - 因此警告(如上所示)似乎要严重得多。

    所以,我不确定我是否可以算作取得了进展,但我正在努力......

最佳答案

感谢这个MKAnnotationView and tap detection我找到了解决方案。我的代码与最初发布的代码相比发生了变化:

class NewLocationViewController: UIViewController, CLLocationManagerDelegate, UITextFieldDelegate, UIGestureRecognizerDelegate {

override func viewDidLoad() {
super.viewDidLoad()
//...other code...
let tapHandler = UITapGestureRecognizer() //<<<== No parameters
tapHandler.numberOfTapsRequired = 1
tapHandler.numberOfTouchesRequired = 1
tapHandler.delegate = self
map.addGestureRecognizer(tapHandler)
map.isUserInteractionEnabled = true
}

// Not sure who calls this and requires the Bool response, but it seems to work...
func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldReceive touch: UITouch) -> Bool {
return self.handleTap(touch: touch).count > 0
}

// Major Changes
private func handleTap(touch: UITouch) -> [MKAnnotationView] {
var tappedAnnotations: [MKAnnotationView] = []
for annotation in self.map.annotations {
if let annotationView: MKAnnotationView = self.map.view(for: annotation) {
let annotationPoint = touch.location(in: annotationView)
if annotationView.bounds.contains(annotationPoint) {
self.name.text = annotationView.annotation?.title!
let addr = AddrInfo(composite: ((annotationView.annotation?.subtitle)!)!)
self.address.text = addr.street!
self.city.text = addr.city!
self.state.text = addr.state!
self.zipcode.text = addr.zip!
tappedAnnotations.append(annotationView)
break
}
}
}
return tappedAnnotations
}

//...
}

AddrInfo 片段是我自己的小子类,除其他外,它采用类似“1000 Main St., Pittsburgh, PA 15212, United States”的字符串,并且将其分成单独的部分,以便可以单独访问它们(如上面的代码所示)。

可能有一种更简单或更好的方法来实现我正在寻找的目标 - 但上述确实实现了它,所以我认为它是我的问题的答案。

关于ios - 如何将点击与注释匹配(或比较)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39799737/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com