MapViewPlus 0.1.3

MapViewPlus 0.1.3

Okhan Okbay 维护。



  • 作者
  • okhanokbay

MapViewPlus

Swift 4.0 iOS 9.0+ Version License Platform

关于

MapViewPlus 提供了 MapKit 缺失的方法:imageForAnnotationcalloutViewForAnnotationView 代理方法。

  • imageForAnnotation 返回任何 UIImage(图片不应有边距)
  • 创建任何 UIView 并用作自定义 Callout 视图,然后从 calloutViewForAnnotationView 返回它
  • MapViewPlus 将
    1. 将锚点视图添加到 Callout 视图的底部
    2. 将 Callout 视图与锚点视图结合,并对它们添加阴影
    3. CalloutAndAnchorView 添加一个酷炫的动画
    4. 使之可响应用户交互(这可能很容易但有时候也很棘手)
    5. 在点击标记视图后滚动地图视图以完全显示 Callout 视图
    6. 甚至提供 Callout 视图的现成模板
    7. 转发了 MKMapView 的所有代理方法(除了 mapView:viewForAnnotation:)到您的 MapViewPlus 子类

要求

  • Swift 4.0
  • iOS 9.0+

安装

MapViewPlus 通过 CocoaPods 可用。要安装它,只需将以下行添加到您的 Podfile 中

pod 'MapViewPlus'

如果您不使用 CocoaPods,可以拖放所有类并在您的项目中使用它。

如何使用

1) 如果您正在使用 Interface Builder,将您的地图视图的类和模块设置为 MapViewPlus

2) 设置您的 Callout 视图模型

import UIKit
import MapViewPlus

// CalloutViewModel is a protocol of MapVieWPlus. Currently, it has no requirements to its conformant classes.
class YourCalloutViewModel: CalloutViewModel {

  var title: String
  var image: UIImage

  init(title: String, image: UIImage) {
    self.title = title
    self.image = image
  }
}

3) 设置您的 CalloutView

  • 在一个 xib 文件中创建任何视图(或通过编程方式)

  • 将视图连接到您的 callout 视图类
import UIKit
import MapViewPlus

// CalloutViewPlus is a protocol of MapViewPlus. 
// Currently, it has just one requirement -> func configureCallout(_ viewModel: CalloutViewModel)
class YourCalloutView: UIView, CalloutViewPlus {

  @IBOutlet weak var label: UILabel!
  @IBOutlet weak var imageView: UIImageView!

  func configureCallout(_ viewModel: CalloutViewModel) {
    let viewModel = viewModel as! YourCalloutViewModel

    label.text = viewModel.title
    imageView.image = viewModel.image
  }
}

4) 在视图控制器中设置您的标注

import UIKit
import CoreLocation
import MapViewPlus

class YourViewController: UIViewController {

  @IBOutlet weak var mapView: MapViewPlus!

  override func viewDidLoad() {
    super.viewDidLoad()

    //Required
    mapView.delegate = self

    let viewModel = YourCalloutViewModel(title: "Cafe", image: UIImage(named: "cafe.png")!)

    let annotation = AnnotationPlus(viewModel: viewModel,
                                    coordinate: CLLocationCoordinate2DMake(50.11, 8.68))

    var annotations: [AnnotationPlus] = []
    annotations.append(annotation)

    mapView.setup(withAnnotations: annotations)
  }
}

5) 返回标注的图像和 Callout 的视图

extension YourViewController: MapViewPlusDelegate {

  func mapView(_ mapView: MapViewPlus, imageFor annotation: AnnotationPlus) -> UIImage {
    return UIImage(named: "your_annotation_image.png")!
  }

  func mapView(_ mapView: MapViewPlus, calloutViewFor annotationView: AnnotationViewPlus) -> CalloutViewPlus{
    let calloutView = Bundle.main.loadNibNamed("YourCalloutView", owner: nil, options: nil)!.first as! YourCalloutView
    return calloutView
  }
}

这就完成了。您现在已经准备好了。

自定义(可选)

MapViewPlus 可以高度自定义

CalloutViewCustomizerDelegate

  • 更改与锚视图和 Callout 视图相关的 Callout 视图的中心
func mapView(_ mapView: MapViewPlus, centerForCalloutViewOf annotationView: AnnotationViewPlus) -> CalloutViewPlusCenter
  • 更改 Callout 视图的范围而不更改 Interface Builder 中的帧。如果您不使用此代理方法,那么您的 Callout 视图的框架将与 Interface Builder 文件相同。您也可以使用它根据 Callout 视图中的数据动态更改框架!
func mapView(_ mapView: MapViewPlus, boundsForCalloutViewOf annotationView: AnnotationViewPlus) -> CalloutViewPlusBound
  • 更改与 Callout 视图相关的锚视图的内边距。锚视图将位于 Callout 视图下方,值为您从此方法返回的量。默认值为 0。
func mapView(_ mapView: MapViewPlus, insetFor calloutView: CalloutViewPlus) -> CGFloat
  • 更改 显示 Callout 视图的动画类型。默认为 .fromBottom,可用类型有,.fromTop.fromBottom.fromLeft.fromRight
func mapView(_ mapView: MapViewPlus, animationTypeForShowingCalloutViewOf annotationView: AnnotationViewPlus) -> CalloutViewShowingAnimationType
  • 更改 隐藏 Callout 视图的动画类型。默认为 .toBottom,可用类型有,.toTop.toBottom.toLeft.toRight
func mapView(_ mapView: MapViewPlus, animationTypeForHidingCalloutViewOf annoationView: AnnotationViewPlus) -> CalloutViewHidingAnimationType

AnchorViewCustomizerDelegate

  • 更改变量的高度。锚点视图始终会以您提供的值作为三角形的高度来绘制一个等边三角形。您可以更改高度,锚点视图将为您计算所需的大小。
func mapView(_ mapView: MapViewPlus, heightForAnchorOf calloutView: CalloutViewPlus) -> CGFloat
  • 更改锚点视图的背景颜色。这非常重要。您可以为锚点视图提供任何颜色。通常希望将其颜色与调用视图的背景颜色相同。只需更改即可:
func mapView(_ mapView: MapViewPlus, fillColorForAnchorOf calloutView: CalloutViewPlus) -> UIColor

注释

默认调用视图

  • MapViewPlus为您提供了调用视图的现成模板。您可以在示例项目中查看它的用法示例。
  • 它允许您指定图片的来源。它有三种选项:
    1. .downloadable(imageURL: URL, placeholder: UIImage?)
      • 使用Kingfisher框架下载图片
    2. .fromBundle(image: UIImage)
    3. .none

其他

  • 这是一个最小可用品,将得到维护,还将开发新功能。非常感谢任何帮助。

  • 源代码本身采用基于协议的MVVM方法。试图强使用户使用相同的方法。

  • 如果您想要添加某些功能,可以查看未来计划部分

未来计划

  • 添加Kingfisher作为subspect,也有其他选项作为subspects下载图片。

  • 添加更多模板,并将它们作为subspects。因此,任何需要模板的人都不需要下载所有模板。欢迎提出想法或添加功能。

  • 通过利用iOS 11的本地聚类和iOS 11-使用开源聚类框架进行注释聚类

  • 注释的自定义视图选项

转发委托方法

MapViewPlus 使用了 MKMapViewDelegate 的方法,但并非全部。它转发除 mapView:viewForAnnotation: 之外的所有委托方法。此方法在内部使用,不会被转发到您的子类。

通常,当您不想使用 MKMapViewDelegate 的其他方法时,MapViewPlus 会将您从 MapKit 中抽象出来。但是,当您想使用 MKMapViewDelegate 的其他方法时,您可以轻松做到这一点而无需任何额外的工作。只需写下它们,它们将通过 MapViewPlusDelegate 被调用。请查看在例子项目(DefaultCalloutViewController.swift)中如何调用 mapView(_:regionDidChangeAnimated:) 方法,即使您没有遵循 MKMapViewDelegate。如果在将来,MKMapViewDelegate 中添加了新的方法,它们将通过 MapViewPlusDelegate 自动转发给您,而不需要新版本的框架。后台不会发生封装。

示例

要运行示例项目,克隆仓库,然后首先从 Example 目录运行 pod install

截图

许可

MapViewPlus 提供 MIT 许可。有关更多信息,请参阅 LICENSE 文件。