最近开发中遇到个需求,自定义大头针,记录一下自己在开发的过程中遇到的问题和解决的思路,以供在以后的开发的过程中学习!
0.先看看效果
截屏2020-06-17 上午9.10.04.png1.配置高德
这个不用详细介绍了吧,自己去官方文档配置下,超简单的,主要是pod几个库,
看你们的需求,需要什么导入什么我这边导入这两个:
#高德地图搜索
pod 'AMapSearch'
pod 'AMap3DMap'
2.显示地图 获取数据
- 懒加载地图显示出来
private lazy var mapView:MAMapView = {[unowned self] in
let mapView = MAMapView(frame: self.view.bounds)
mapView.delegate = self
mapView.showsUserLocation = true
mapView.userTrackingMode = .follow
mapView.isZoomEnabled = true
mapView.zoomLevel = 13
//显示比例尺 及位置
mapView.showsScale = true
mapView.scaleOrigin = CGPoint(x: WMRatio(20), y: WMRatio(100))
//设置自定义位置精度圈
mapView.customizeUserLocationAccuracyCircleRepresentation = true
return mapView
}()
- 添加到试图上 并且创建数据,这里有个问题,就是在我们点击的时候我需要获取到每个点击试图的所有信息,所以自己自定义一个myAnnotation继承至MAPointAnnotation,并且多帮他添加一个属性model,这样这里面就包含了你需要的所有数据,当点击的时候就可以拿到
for item in users {
let annation = myAnnotation()
let latDouble = item.lat?.doubleValue
let lngDouble = item.lng?.doubleValue
annation.coordinate = CLLocationCoordinate2D(latitude: latDouble! , longitude: lngDouble!)
annation.model = item
self.arr.append(annation)
}
mapView.addAnnotations(arr)
3.实现地图代理方法
- 写这里的时候有个问题就是定位位置,但不展示自身定位的大头针,我开始本来不想去代理方法里面去设置空图片解决,当时用过这个方法 就是在创建大头针数据的时候,移除掉自身定位的大头针数据,再展示,但是并没有什么卵用,具体不知道是什么原因?有了解的可以在下方评论,一起学习,谢谢!
在创建完数据的时候用这个去移除自身定位的大头针的数据,没有作用
mapView.removeAnnotation(self.mapView.userLocation)
最终还是在代理方法中去设置自身定位的图片为空的实现的(本来我是拒绝的....)
func mapView(_ mapView: MAMapView!, viewFor annotation: MAAnnotation!) -> MAAnnotationView! {
if annotation.isKind(of: MAUserLocation.self) {
//去掉定位的图片
let identifier = "item1"
var annotationView = mapView.dequeueReusableAnnotationView(withIdentifier: identifier)
if annotationView == nil {
annotationView = MAPinAnnotationView(annotation: annotation, reuseIdentifier: identifier)
}
annotationView?.image = UIImage(named: "")
return annotationView
}
if annotation.isKind(of: MAPointAnnotation.self) {
//自定义一个大头针的数据
let identifier = "item"
var annotationView = mapView.dequeueReusableAnnotationView(withIdentifier: identifier) as? WMDreamSquareViewController.DreamMapView.customAnnotationView
if annotationView == nil {
annotationView = customAnnotationView(annotation: annotation, reuseIdentifier: identifier)
}
annotationView?.annotation = annotation// 重要
annotationView?.canShowCallout = false// 设置弹框
let ata = annotation as? WMDreamSquareViewController.myAnnotation
annotationView?.dataModel = ata?.model
return annotationView
}
return nil
}
//MARK:大头针点击事件
func mapView(_ mapView: MAMapView!, didSelect view: MAAnnotationView!)
{
mapView.deselectAnnotation(view.annotation, animated: true)
let ata = view.annotation as? WMDreamSquareViewController.myAnnotation
self.didAnnationViewBlock!(ata!.model!)
}
//MARK:缩放回调 用于刷新数据,因为不可能一次性在界面上请求所有数据,所以我想了下叫后台接收一个我返回的距离给他 主要计算的方式是在指定的缩放级别下, 基于地图中心点, 1 screen point 对应的距离(单位是米)*屏幕的宽度
func mapView(_ mapView: MAMapView!, mapDidZoomByUser wasUserAction: Bool) {
let unit = CGFloat(mapView.metersPerPoint(forZoomLevel: mapView.zoomLevel)) * iphone.width
print("2=======\(mapView.zoomLevel)============\(CGFloat(mapView.metersPerPoint(forZoomLevel: mapView.zoomLevel)))--\(iphone.width)----\(unit)")
self.touchZoomRefreshBlock!(Int(ceil(unit)))
}
4.自定义大头针试图
- 自定义一个大头针的试图
//MARK:继承MAAnnotationView来创建一个自己的大头针视图
class customAnnotationView:MAAnnotationView {
private lazy var bgImageView:UIImageView = {
let view = UIImageView()
view.contentMode = .scaleAspectFit
view.image = UIImage(named: "椭圆45")
view.isUserInteractionEnabled = true
return view
}()
private lazy var headView:UIImageView = {
let view = UIImageView()
view.layer.cornerRadius = WMRatio(17.5)
view.layer.masksToBounds = true
view.backgroundColor = UIColor.clear
return view
}()
var dataModel: WMDreamSquareViewController.User?{
didSet {
guard let dataModel = dataModel else {
return
}
bgImageView.image = (dataModel.type?.stringValue == "1") ? UIImage(named: "xygc_tx_bg_r") : UIImage(named: "xygc_tx_bg_y")
headView.yy_setImage(with: URL(string: dataModel.avatar_url!.stringValue), placeholder: UIImage(named: "face"))
}
}
override init!(annotation: MAAnnotation!, reuseIdentifier: String!) {
super.init(annotation: annotation, reuseIdentifier: reuseIdentifier)
//这里需要设置一个大小要不然点击响应不了
self.bounds = CGRect(x: 0, y: 0, width: WMRatio(45), height: WMRatio(45))
addSubview(bgImageView)
bgImageView.addSubview(headView)
bgImageView.layoutSubviews()
bgImageView.snp.makeConstraints { (make) in
make.centerX.centerY.equalToSuperview()
make.width.height.equalTo(WMRatio(45))
}
headView.snp.makeConstraints { (make) in
make.centerX.equalToSuperview()
make.centerY.equalTo(bgImageView).offset(-WMRatio(3))
make.width.height.equalTo(WMRatio(35))
}
}
override func hitTest(_ point: CGPoint, with event: UIEvent?) -> UIView? {
let rect = self.convert(self.frame, from: self.superview)
//print("point---------\(point)========rect------\(rect)*********self.frame------\(self.frame)")
if rect.contains(point) {
return self
}else{
return nil
}
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}
5.扩展 还需要实现一个弹出的试图
-
具体效果
截屏2020-06-17 上午9.38.10.png
class DatouzhenView:WMView {
private lazy var bgView:UIView = {
let view = UIView()
view.layer.cornerRadius = WMRatio(10)
view.layer.masksToBounds = true
view.backgroundColor = UIColor.white
return view
}()
///头像
private lazy var headView:UIImageView = {
let imageView = UIImageView()
imageView.image = UIImage(named: "love")
imageView.layer.cornerRadius = WMRatio(50)/2
imageView.layer.masksToBounds = true
return imageView
}()
///昵称
private lazy var titleLabel:UILabel = {
let label = UILabel()
label.font = WMFont(14)
label.text = "会飞的鱼"
return label
}()
///l年龄
private lazy var ageAdnSexButton: UIButton = {
let view = UIButton()
view.titleLabel?.font = WMFont(12)
view.setImage(UIImage(named: "Fate_girl"), for: .normal)
view.setImage(UIImage(named: "Fate_boy"), for: .selected)
view.setTitleColor(UIColor.white, for: .normal)
view.setBackgroundImage(UIImage(color: color("#FB5798")!), for: .normal)
view.setBackgroundImage(UIImage(color: color("#5EA1FD")!), for: .selected)
view.setTitle("12", for: .normal)
view.titleEdgeInsets.left = 2.5
view.imageEdgeInsets.left = -2.5
view.layer.cornerRadius = 3
view.clipsToBounds = true
return view
}()
///星座
private lazy var constellationButton: UIButton = {
let view = UIButton()
view.titleLabel?.font = WMFont(12)
view.setTitleColor(UIColor.white, for: .normal)
view.backgroundColor = WMColor("#F29600")
view.setTitle("水瓶座", for: .normal)
view.layer.cornerRadius = WMRatio(3)
return view
}()
///心愿
private lazy var xinyuanButton: UIButton = {
let view = UIButton()
view.titleLabel?.font = WMFont(12)
view.setTitleColor(UIColor.white, for: .normal)
view.backgroundColor = WMColor("#E8B916")
view.setTitle("心愿", for: .normal)
view.layer.cornerRadius = WMRatio(3)
return view
}()
///内容
private lazy var contentLabel:YYLabel = {
let view = YYLabel()
view.text = "附近又好看的小姐姐吗?一起尝尝去"
view.textColor = color("#333333")
view.font = WMFont(14)
return view
}()
///套餐背景图
private lazy var iconImageView:UIButton = {
let view = UIButton()
view.clipsToBounds = true
view.contentMode = .scaleAspectFill
view.layer.cornerRadius = WMRatio(10)
view.layer.masksToBounds = true
view.setImage(UIImage(named: "myCollection_img1"), for: .normal)
view.imageView?.contentMode = .scaleAspectFill
view.action(event: .touchUpInside) { (button) in
self.router(event: Event.商品详情)
}
return view
}()
///喜欢
private lazy var likeButton:UIButton = {
let view = UIButton()
view.setImage(UIImage(named: "ShowMerchants_collection1"), for: .normal)
//view.setTitle("0人", for: .normal)
view.setTitleColor(color("#999999"), for: .normal)
view.titleLabel?.font = WMFont(11)
view.contentHorizontalAlignment = .right
return view
}()
///套餐名称和说明
private lazy var nameLabel:YYLabel = {
let view = YYLabel()
view.text = "佐客优选双人套餐,提供免费WIFI"
view.textColor = color("#333333")
view.font = WMFont(15)
return view
}()
///时间/距离
private lazy var remainingAndSoldLabel:YYLabel = {
let view = YYLabel()
view.text = "6小时前·2.6km·366人看过"
view.textColor = color("#999999")
view.font = WMFont(11)
return view
}()
///等待完成心愿
private lazy var waitfinshLabel:YYLabel = {
let view = YYLabel()
view.text = "等待完成心愿"
view.textColor = color("#FFFFFF")
view.font = WMFont(12)
return view
}()
///价格
private lazy var priceLabel:YYLabel = {
let view = YYLabel()
let att = NSMutableAttributedString()
var temp = NSMutableAttributedString(string: "¥66")
temp.yy_font = WMFont(16)
temp.yy_color = color("#F14545")
att.append(temp)
att.yy_appendString(" ")
temp = NSMutableAttributedString(string: "¥86")
temp.yy_font = WMFont(12)
temp.yy_color = color("#666666")
temp.yy_strikethroughStyle = [.thick]
att.append(temp)
view.attributedText = att
return view
}()
private lazy var lineView:UIView = {
let view = UIView()
view.backgroundColor = color("#EEEEEE")
return view
}()
///打招呼
private lazy var dazhaohuButton:UIButton = {
let view = UIButton()
view.setTitle("打招呼", for: .normal)
view.setTitleColor(UIColor.white, for: .normal)
view.titleLabel?.font = WMFont(16)
view.backgroundColor = UIColor.redBackground
view.layer.cornerRadius = WMRatio(20)
view.layer.masksToBounds = true
view.action(event: .touchUpInside) {[weak self] (button) in
self?.router(event: Event.打招呼)
}
return view
}()
//MARK:数据赋值
var dataModel:User?{
didSet{
guard let dataModel = dataModel else {
return
}
headView.yy_setImage(with: URL(string: dataModel.avatar!.stringValue), options: YYWebImageOptions(rawValue: 0))
titleLabel.text = dataModel.nickname?.stringValue
ageAdnSexButton.isSelected = dataModel.sex?.intValue == 0 ? true : false
ageAdnSexButton.setTitle(dataModel.age?.stringValue, for: .normal)
constellationButton.setTitle("水瓶座", for: .normal)
xinyuanButton.setTitle(dataModel.type?.intValue == 0 ? "心愿" : "约会", for: .normal)
// contentLabel.text = dataModel.content?.stringValue
// iconImageView.setImage(UIImage(named: dataModel.goodsPic.stringValue), for: .normal)
// nameLabel.text = dataModel.goodstitle?.stringValue
// priceLabel.text = "¥ \(dataModel.price!)"
// remainingAndSoldLabel.text = "\(dataModel.time!)·\(dataModel.distent!.stringValue)·\(dataModel.seepeoples!.stringValue)"
// likeButton.setTitle(dataModel.loves?.stringValue, for: .normal)
}
}
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
if (touches.first?.view?.isEqual(self))! {
self.router(event: Event.空白)
}
}
override func setUI() {
backgroundColor = UIColor.clear
layer.cornerRadius = 7.5
clipsToBounds = true
backgroundColor = color("#EEEEEE")
addSubview(bgView)
bgView.addSubview(headView)
bgView.addSubview(titleLabel)
bgView.addSubview(ageAdnSexButton)
bgView.addSubview(constellationButton)
bgView.addSubview(xinyuanButton)
bgView.addSubview(contentLabel)
bgView.addSubview(iconImageView)
bgView.addSubview(remainingAndSoldLabel)
bgView.addSubview(likeButton)
bgView.addSubview(nameLabel)
bgView.addSubview(waitfinshLabel)
bgView.addSubview(priceLabel)
bgView.addSubview(lineView)
bgView.addSubview(dazhaohuButton)
bgView.snp.makeConstraints { (make) in
make.centerX.centerY.equalToSuperview()
make.width.equalTo(WMRatio(350))
make.height.equalTo(WMRatio(400))
}
headView.snp.makeConstraints { (make) in
make.top.equalTo(WMRatio(12))
make.left.equalTo(WMRatio(12))
make.height.width.equalTo(WMRatio(50))
}
titleLabel.snp.makeConstraints { (make) in
make.left.equalTo(headView.snp.right).offset(WMRatio(8))
make.top.equalTo(headView.snp.top)
make.right.equalToSuperview().offset(-WMRatio(12))
}
ageAdnSexButton.snp.makeConstraints { (make) in
make.left.equalTo(headView.snp.right).offset(WMRatio(5))
make.top.equalTo(titleLabel.snp.bottom).offset(WMRatio(5))
make.width.equalTo(WMRatio(43))
make.height.equalTo(WMRatio(16))
}
constellationButton.snp.makeConstraints { (make) in
make.centerY.equalTo(ageAdnSexButton)
make.left.equalTo(ageAdnSexButton.snp.right).offset(WMRatio(5))
make.width.equalTo(WMRatio(43))
make.height.equalTo(WMRatio(16))
}
xinyuanButton.snp.makeConstraints { (make) in
make.centerY.equalTo(ageAdnSexButton)
make.left.equalTo(constellationButton.snp.right).offset(WMRatio(5))
make.width.equalTo(WMRatio(43))
make.height.equalTo(WMRatio(16))
}
contentLabel.snp.makeConstraints { (make) in
make.left.equalTo(WMRatio(12))
make.right.equalTo(-WMRatio(12))
make.top.equalTo(headView.snp.bottom).offset(WMRatio(12))
}
iconImageView.snp.makeConstraints { (make) in
make.left.equalTo(WMRatio(12))
make.right.equalTo(-WMRatio(12))
make.height.equalTo(WMRatio(140))
make.top.equalTo(contentLabel.snp.bottom).offset(WMRatio(5))
}
dazhaohuButton.snp.makeConstraints { (make) in
make.bottom.equalToSuperview().offset(-WMRatio(12))
make.centerX.equalToSuperview()
make.width.equalTo(WMRatio(150))
make.height.equalTo(WMRatio(40))
}
likeButton.snp.makeConstraints { (make) in
make.right.equalToSuperview().offset(-WMRatio(12))
make.bottom.equalTo(dazhaohuButton.snp.top).offset(-WMRatio(12))
make.width.height.equalTo(WMRatio(30))
}
remainingAndSoldLabel.snp.makeConstraints { (make) in
make.left.equalTo(WMRatio(12))
make.bottom.equalTo(dazhaohuButton.snp.top).offset(-WMRatio(12))
}
nameLabel.snp.makeConstraints { (make) in
make.left.equalTo(WMRatio(12))
make.top.equalTo(iconImageView.snp.bottom).offset(WMRatio(8))
}
priceLabel.snp.makeConstraints { (make) in
make.left.equalTo(WMRatio(12))
make.top.equalTo(nameLabel.snp.bottom).offset(WMRatio(5))
}
lineView.snp.makeConstraints { (make) in
make.left.equalToSuperview().offset(WMRatio(5))
make.right.equalToSuperview().offset(-WMRatio(5))
make.height.equalTo(0.5)
make.top.equalTo(priceLabel.snp.bottom).offset(WMRatio(8))
}
waitfinshLabel.snp.makeConstraints { (make) in
make.right.equalTo(-WMRatio(12))
make.centerY.equalTo(priceLabel)
}
}
}
6.总结
在这个过程中遇到的两个问题1.就是关掉自身的大头针,除了去代理方法中设置空图片,我试了好多中其他的方式都实现不了2.点击大头针试图传值。开始没有想到继承,直接用系统的,一直带不过来数据,后面还想着用title做对比得到数据中的索引,但是这样做感觉太麻烦了,有点得不偿失!
网友评论