ios - 使用什么代替 indexPath.row?对于非表?

标签 ios swift mkmapview cloudkit ckrecord

我正在使用 mapview 而不是 tableview,但我不知道用什么来替换 indexPath.row。

我有一个带有注释的 map View ,当按下注释的信息按钮时,我然后查询我的 CK 数据库并返回具有与所按下的注释名称匹配的名称字段的记录。这将返回一个包含单个记录的 [CKRecord],因为没有匹配的名称。

此时,使用 tableview 我将执行以下操作来访问数据...

let placeInfo = selectedData[indexPath.row]
let placeName = placeInfo.objectForKey("Name") as! String
let placeCity = placeInfo.objectForKey("City") as! String

但是,因为我没有使用 tableview,所以我没有要使用的 indexPath。由于我的 [CKRecord] 对象只包含一条记录,我想我可以用记录的数组位置替换 indexPath.row...

let placeInfo = selectedPlace[0] //also tried 1

该行产生索引超出范围错误。
我已经尝试了我所知道的一切,正如您可能想象的那样,我目前并不十分擅长 swift 或一般编程。

这是我正在使用的完整 mapView 函数...

    func mapView(mapView: MKMapView, annotationView: MKAnnotationView, calloutAccessoryControlTapped control: UIControl) {

    let cloudContainer = CKContainer.defaultContainer()
    let publicData = cloudContainer.publicCloudDatabase

    let tappedPlace = annotationView.annotation!.title!! as String

    let predi = NSPredicate(format: "Name = %@", tappedPlace)
    let iquery = CKQuery(recordType: "Locations", predicate: predi)

    publicData.performQuery(iquery, inZoneWithID: nil, completionHandler: {
        (results, error) -> Void in

        if error != nil {
            print(error)
            return
        }

        if let results = results {
            print("Downloaded data for selected location for \(tappedPlace)")

            NSOperationQueue.mainQueue().addOperationWithBlock() {
                self.selectedPlace = results
            }
        }
    })

    let placeInfo = selectedPlace[0]
    let placeName = placeInfo.objectForKey("Name") as! String
    //returns Index out of range error for placeInfo line


    //need data before segue
    //performSegueWithIdentifier("fromMap", sender: self)
}

最佳答案

您的问题是,您尝试在完成处理程序实际签名之前访问 selectedPlace。您的“publicData.performQuery”似乎是一个异步操作,这意味着,即使在执行完成处理程序之前,控件也会从此调用中退出(这在异步调用的情况下是预期的)。你马上就到了——

let placeInfo = selectedPlace[0]

但是数据还没有准备好,你得到了异常。现在要解决这个问题,移动位置信息提取,并在完成处理程序中执行 segue 代码,如图所示-

publicData.performQuery(iquery, inZoneWithID: nil, completionHandler: {
    (results, error) -> Void in

    if error != nil {
        print(error)
        return
    }

    if let results = results {
        print("Downloaded data for selected location for \(tappedPlace)")

        NSOperationQueue.mainQueue().addOperationWithBlock() {
            self.selectedPlace = results
               if(results.count > 0){

               let placeInfo = selectedPlace[0]
               let placeName = placeInfo.objectForKey("Name") as! String
               //Do any other computations as needed.
               performSegueWithIdentifier("fromMap", sender: self)
            }
        }
    }
})

这应该可以解决您的问题。

关于ios - 使用什么代替 indexPath.row?对于非表?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36193203/

相关文章:

ios - 设置 UI 元素的默认颜色

iOS MapKit在mapView为3D时获取MKMapView的实际可见区域

ios - Swift 3 - 每次添加位置坐标时 UIView 都会加载

ios - 使用 Xcode 8.3.3 和 Swift 3 从移动应用程序向服务器发送 NS 用户身份验证数据问题

objective-c - 如何重用 UIView 和方法 - iOS 中的 DRY 代码

iphone - 仅从目录获取图像文件

ios - 如何在 Sprite Kit 场景外时删除节点

ios - 有没有办法将 images.xcassets 中的每个图像加载到 uicollectionview 中而无需手动输入图像名称?

ios - 在 Swift 中有一个具有多种类型的变量

ios - 如何在mapVIew中添加多重标注