在swift iOS Map应用程序中创建动态子视图

时间:2015-09-17 22:02:55

标签: ios swift

这是我第一次涉足应用程序世界,因此需要进行大量研究才能达到这一点。我正在构建一个地图应用程序,我正在寻找类似于下面所见的zillow应用程序的界面。我正在尝试提出正确的方法,允许我单击地图注释,它会显示一个较小的视图,我可以与它进行交互。基本上我有几个问题:

  1. 我应该在地图控制器中使用子视图,还是使用容器视图。或者还有另一种我没见过的方法吗?

  2. 如何将注释中的数据推送到该功能?

  3. 如果在点击注释之前如何隐藏此子视图?

  4. 到目前为止,这是我能找到的最接近的事情:Customize MKAnnotation Callout View?

    谢谢!

    enter image description here

1 个答案:

答案 0 :(得分:0)

我也是iOS新手,但我做了类似于你想做的事情。我有一个显示一些统计数据,速度,方位等的视图。当有人点击注释时,我切换显示和隐藏统计信息。可能有更好的方法,但这就是我所做的。

“您的问题的执行摘要”

1和3)在您隐藏和取消隐藏的地图上使用子视图

2)MKAnnotation和MKAnnotationView的子类。将要传递的数据放在子类化MKAnnotationView的属性中,然后在创建时将属性传递给MKAnnotationView。然后,您可以从传入didSelectAnnotationView的视图中检索它。

详细

1)和3)我创建了一个位于mapView上的子视图,并将其设置为最初隐藏在故事板中。然后我有一个toggeleMarkerStatistics()函数 切换视图的可见性。像这样的东西

func toggleMarkerStatistics() {
  if mapMarkerStatistics.hidden {
    mapMarkerStatistics.hidden = false
  } else {
    mapMarkerStatistics.hidden = true
  }
}

中调用此函数
func mapView(mapView: MKMapView, didSelectAnnotationView view: MKAnnotationView) { }

2)要将数据导入didSelectAnnotationView,我就是这么做的。 我将MKAnnotation和MKAnnotationView子类化,并添加了属性来保存我想传递给didSelectAnnotationView的数据。所以像这样:

class MyAnnotation: MKPointAnnotation {
  var myMarker: MyMapMarker?
}

class MyMKAnnotationView: MKAnnotationView {  
  var myMarker: MyMapMarker?  
}

创建注释时,请在将注释添加到地图之前设置属性。

let annotation = MyAnnotation()
annotation.myMarker = marker
annotation.coordinate = location
annotation.title = "btw, you MUST have a title or bad things happen"
mapView.addAnnotation(annotation)

然后在viewForAnnotation中,您将获得自定义注释,其中包含您在创建后设置的属性,并且系统会要求您为此注释创建视图。现在,在创建此视图时,请在返回视图之前将view属性设置为annotation属性。现在,要传递给didSelectAnnotationView的数据将在传递给didSelectAnnotationView的视图中可用

func mapView(mapView: MKMapView, viewForAnnotation annotation: MKAnnotation) -> MKAnnotationView? {
    let view: MKAnnotationView! = mapView.dequeueReusableAnnotationViewWithIdentifier("marker")  ?? MyMKAnnotationView(annotation: annotation, reuseIdentifier: "marker")
    view.annotation = annotation
    view.canShowCallout = false  // you need this to make this work
    if let annotation = annotation as? MyAnnotation {
      if let view = view as? MyMKAnnotationView {
        view.myMarker = annotation.myMarker
      }
    }
    return view
  }

现在在didSelectAnnotationView中,检索您在创建注释时设置的数据:

  func mapView(mapView: MKMapView, didSelectAnnotationView view: MKAnnotationView) {
    if let view = view as? MyMKAnnotationView {
      if let marker = view.myMarker {
        toggleMarkerStatistics()  // hide or unhide the view
        // do something with your data
      }
    }
  }

注意:
我试图从我的代码中复制并简化这一点,实际上我试图支持Apple和Google地图,所以我希望我没有任何拼写错误,但我认为这是我采取的步骤的良好表现。

还有一些事项需要注意:

  1. 我认为你必须为annotaion提供一个标题
  2. 我认为你必须将视图的canShowCallout设置为false
  3. 我认为这两个要求都可以在文档中找到,但我现在没有指向这个要求。