1200字范文,内容丰富有趣,写作的好帮手!
1200字范文 > IOS - Swift高德地图自定义标注 气泡

IOS - Swift高德地图自定义标注 气泡

时间:2020-04-11 20:00:11

相关推荐

IOS - Swift高德地图自定义标注 气泡

高德地图官方文档:/api/ios-sdk/guide/draw-on-map/draw-marker

之前那些SDK导入就不做说明了,直接导入后,开始。

看高德地图官方文档基本都是OC语言写的,swift也就没这么详细说明了。

这种高度自定义,用的也是oc自定义,没有给出swift版本的demo出来,所以我们想做到后面这个效果来:

气泡在iOS中又称为callout,它由背景气泡内容构成,如下图所示:

也就是官方的效果。今天我们就用Swift来实现他了:

添加自定义气泡

(1) 新建自定义气泡类 CustomCalloutViewSwift,继承 UIView。

(2)在类中重写UIView的drawRect方法,绘制弹出气泡的背景,可以自己更改背景颜色。

(3)定义用于显示气泡内容的控件,并添加到SubView中。如上图所示气泡,我们需要一个UIImageView和两个UILabel

(4)在CustomCalloutView.m中给控件传入数据。

import UIKitclass CustomCalloutViewSwift: UIView{var portraitView : UIImageView!var subtitleLabel : UILabel!var titleLabel : UILabel!//初始化定义气泡的背景override func draw(_ rect: CGRect) {drawInContext(context: UIGraphicsGetCurrentContext()!)self.layer.shadowColor = UIColor.red.cgColorself.layer.shadowOpacity = 1.0self.layer.shadowOffset = CGSize.init(width: 0.0, height: 0.0)}override init(frame: CGRect) {super.init(frame: frame)// self.backgroundColor = UIColor.redinitSubViews()}required init?(coder aDecoder: NSCoder) {super.init(coder: aDecoder)initSubViews()fatalError("init(coder:) has not been implemented")}func drawInContext(context : CGContext) {context.setLineWidth(2.0)context.setFillColor(red: 0.3, green: 0.3, blue: 0.3, alpha: 0.8)getDrawPath(context: context)context.fillPath()}func getDrawPath(context : CGContext) {let kArrorHeight = 10let rect = self.boundslet radius = 6.0let minx = rect.minXlet midx = rect.midXlet maxx = rect.maxXlet miny = rect.minYlet maxy = rect.maxY - 10context.move(to: CGPoint.init(x: midx + CGFloat(kArrorHeight), y: maxy))context.addLine(to: CGPoint.init(x: midx, y: maxy + CGFloat(kArrorHeight)))context.addLine(to: CGPoint.init(x: midx - CGFloat(kArrorHeight), y: maxy))context.addArc(tangent1End: CGPoint.init(x: minx, y: maxy), tangent2End: CGPoint.init(x: minx, y: miny), radius: CGFloat(radius))context.addArc(tangent1End: CGPoint.init(x: minx, y: minx), tangent2End: CGPoint.init(x: maxx, y: miny), radius: CGFloat(radius))context.addArc(tangent1End: CGPoint.init(x: maxx, y: miny), tangent2End: CGPoint.init(x: maxx, y: maxx), radius: CGFloat(radius))context.addArc(tangent1End: CGPoint.init(x: maxx, y: maxy), tangent2End: CGPoint.init(x: midx, y: maxy), radius: CGFloat(radius))context.closePath();}//初始化定义气泡的内容func initSubViews() {backgroundColor = UIColor.clearlet kPortraitMargin = 5.0let kPortraitWidth = 70.0let kPortraitHeight = 50.0let kTitleWidth = 120.0let kTitleHeight = 20.0// 添加图片,即商户图portraitView = UIImageView.init(frame: CGRect.init(x: kPortraitMargin, y: kPortraitMargin, width: kPortraitWidth, height: kPortraitHeight))portraitView.backgroundColor = UIColor.blackaddSubview(portraitView)// 添加标题,即商户名titleLabel = UILabel.init(frame: CGRect.init(x: kPortraitMargin * 2 + kPortraitWidth, y: kPortraitMargin, width: kTitleWidth, height: kTitleHeight))titleLabel.font = UIFont.systemFont(ofSize: 14)titleLabel.textColor = UIColor.whitetitleLabel.text = "我是商户名"addSubview(titleLabel)// 添加副标题,即商户地址subtitleLabel = UILabel.init(frame: CGRect.init(x: kPortraitMargin * 2 + kPortraitWidth, y: kPortraitMargin * 2 + kTitleHeight, width: kTitleWidth, height: kTitleHeight))subtitleLabel.font = UIFont.systemFont(ofSize: 12)subtitleLabel.textColor = UIColor.lightGraysubtitleLabel.text = "我是商户地址"addSubview(subtitleLabel)}//给控件传入数据func setTitle(title : NSString) {titleLabel.text = title as String;}func setSubtitle(subtitle : NSString) {subtitleLabel.text = subtitle as String;}func setImage(image : UIImage) {portraitView.image = image;}///导航事件@objc func guidBtnAction() {// self.guideActionCallBack?()}func guideActionCallBack() {print("click btn")}}

以上就是自定义气泡的全部过程,但是为了在点击标注时,弹出自定义的气泡,还需要。步骤如下:

添加自定义AnnotationView

(1) 新建类CustomAnnotationViewSwift,继承MAAnnotationView或MAPinAnnotationView。若继承MAAnnotationView,则需要设置标注图标;若继承MAPinAnnotationView,使用默认的大头针标注

(2) 在CustomAnnotationViewSwift中定义自定义气泡属性,可修改calloutView属性

(3) 重写选中方法setSelected。选中时新建并添加calloutView,传入数据;非选中时删除calloutView。

import UIKitclass CustomAnnotationViewSwift: MAAnnotationView {//定义气泡背景与内容对象var calloutView : CustomCalloutViewSwift?var content : String?//重写选中效果override func setSelected(_ selected: Bool, animated: Bool) {if self.isSelected == selected{return;}if selected {if calloutView == nil {calloutView = CustomCalloutViewSwift.init(frame: CGRect.init(x: 0, y: 0, width: 200, height: 70))calloutView!.center = CGPoint.init(x: bounds.width/2 + calloutOffset.x, y: -calloutView!.bounds.height/2 + calloutOffset.y)}//传入数据给气泡内容let image = UIImage.init(named: "MyImageName")calloutView?.setImage(image: image!)calloutView?.setTitle(title: "我是商家名")calloutView?.setSubtitle(subtitle: "我是商家地址")addSubview(calloutView!)} else {calloutView!.removeFromSuperview()}super.setSelected(selected, animated: animated)}func setContent(content : String){self.content = content}}

定义了上面两个类,我们直接在地图上调用就好了,

func mapView(_ mapView: MAMapView!, viewFor annotation: MAAnnotation!) -> MAAnnotationView! {//MAPointAnnotation,自定义POI点数据,参考demo河马if annotation is MAPointAnnotation {let customReuseIndetifier: String = "customReuseIndetifier"//从复用内存池中获取制定复用标识的annotation view,自定义气泡样式CustomAnnotationView// var annotationView = mapView.dequeueReusableAnnotationView(withIdentifier: customReuseIndetifier) as? CustomAnnotationViewvar annotationView = mapView.dequeueReusableAnnotationView(withIdentifier: customReuseIndetifier) as? CustomAnnotationViewSwiftif annotationView == nil {annotationView = CustomAnnotationViewSwift.init(annotation: annotation, reuseIdentifier: customReuseIndetifier)//是否允许弹出calloutannotationView?.canShowCallout = false///添加到地图时是否使用下落动画效果// annotationView!.animatesDrop = false///是否支持拖动annotationView?.isDraggable = true///弹出框默认位于view正中上方,可以设置calloutOffset改变view的位置,正的偏移使view朝右下方移动,负的朝左上方,单位是屏幕坐标annotationView?.calloutOffset = CGPoint.init(x: 0, y: -5)}let wellBlueState = UIImage(named: "restaurant")annotationView?.image = wellBlueState//背景颜色,透明annotationView?.backgroundColor = Theme.transparentannotationView?.frame = CGRect(x: 0, y: 0, width: 20, height: 20)// annotationView?.portrait = UIImage.init(named: "login")// annotationView?.name = "河马"return annotationView}return nil}

自定义调用:var annotationView = mapView.dequeueReusableAnnotationView(withIdentifier: customReuseIndetifier) as? CustomAnnotationViewSwift

运行程序,效果如下:

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。