最近開發(fā)中遇到個(gè)需求庞瘸,自定義大頭針,記錄一下自己在開發(fā)的過(guò)程中遇到的問(wèn)題和解決的思路妻柒,以供在以后的開發(fā)的過(guò)程中學(xué)習(xí)祝沸!
0.先看看效果
1.配置高德
這個(gè)不用詳細(xì)介紹了吧,自己去官方文檔配置下麻养,超簡(jiǎn)單的褐啡,主要是pod幾個(gè)庫(kù),
看你們的需求鳖昌,需要什么導(dǎo)入什么我這邊導(dǎo)入這兩個(gè):
#高德地圖搜索
pod 'AMapSearch'
pod 'AMap3DMap'
2.顯示地圖 獲取數(shù)據(jù)
- 懶加載地圖顯示出來(lái)
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))
//設(shè)置自定義位置精度圈
mapView.customizeUserLocationAccuracyCircleRepresentation = true
return mapView
}()
- 添加到試圖上 并且創(chuàng)建數(shù)據(jù),這里有個(gè)問(wèn)題备畦,就是在我們點(diǎn)擊的時(shí)候我需要獲取到每個(gè)點(diǎn)擊試圖的所有信息低飒,所以自己自定義一個(gè)myAnnotation繼承至MAPointAnnotation,并且多幫他添加一個(gè)屬性model懂盐,這樣這里面就包含了你需要的所有數(shù)據(jù)褥赊,當(dāng)點(diǎn)擊的時(shí)候就可以拿到
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.實(shí)現(xiàn)地圖代理方法
- 寫這里的時(shí)候有個(gè)問(wèn)題就是定位位置,但不展示自身定位的大頭針莉恼,我開始本來(lái)不想去代理方法里面去設(shè)置空?qǐng)D片解決拌喉,當(dāng)時(shí)用過(guò)這個(gè)方法 就是在創(chuàng)建大頭針數(shù)據(jù)的時(shí)候,移除掉自身定位的大頭針數(shù)據(jù)类垫,再展示司光,但是并沒(méi)有什么卵用,具體不知道是什么原因悉患?有了解的可以在下方評(píng)論残家,一起學(xué)習(xí),謝謝售躁!
在創(chuàng)建完數(shù)據(jù)的時(shí)候用這個(gè)去移除自身定位的大頭針的數(shù)據(jù)坞淮,沒(méi)有作用
mapView.removeAnnotation(self.mapView.userLocation)
最終還是在代理方法中去設(shè)置自身定位的圖片為空的實(shí)現(xiàn)的(本來(lái)我是拒絕的....)
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) {
//自定義一個(gè)大頭針的數(shù)據(jù)
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// 設(shè)置彈框
let ata = annotation as? WMDreamSquareViewController.myAnnotation
annotationView?.dataModel = ata?.model
return annotationView
}
return nil
}
//MARK:大頭針點(diǎn)擊事件
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:縮放回調(diào) 用于刷新數(shù)據(jù),因?yàn)椴豢赡芤淮涡栽诮缑嫔险?qǐng)求所有數(shù)據(jù)陪捷,所以我想了下叫后臺(tái)接收一個(gè)我返回的距離給他 主要計(jì)算的方式是在指定的縮放級(jí)別下, 基于地圖中心點(diǎn), 1 screen point 對(duì)應(yīng)的距離(單位是米)*屏幕的寬度
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.自定義大頭針試圖
- 自定義一個(gè)大頭針的試圖
//MARK:繼承MAAnnotationView來(lái)創(chuàng)建一個(gè)自己的大頭針視圖
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)
//這里需要設(shè)置一個(gè)大小要不然點(diǎn)擊響應(yīng)不了
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.擴(kuò)展 還需要實(shí)現(xiàn)一個(gè)彈出的試圖
-
具體效果
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 = "會(huì)飛的魚"
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
}()
///內(nèi)容
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
}()
///套餐名稱和說(shuō)明
private lazy var nameLabel:YYLabel = {
let view = YYLabel()
view.text = "佐客優(yōu)選雙人套餐,提供免費(fèi)WIFI"
view.textColor = color("#333333")
view.font = WMFont(15)
return view
}()
///時(shí)間/距離
private lazy var remainingAndSoldLabel:YYLabel = {
let view = YYLabel()
view.text = "6小時(shí)前·2.6km·366人看過(guò)"
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
}()
///價(jià)格
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:數(shù)據(jù)賦值
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 ? "心愿" : "約會(huì)", 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.總結(jié)
在這個(gè)過(guò)程中遇到的兩個(gè)問(wèn)題1.就是關(guān)掉自身的大頭針市袖,除了去代理方法中設(shè)置空?qǐng)D片啡直,我試了好多中其他的方式都實(shí)現(xiàn)不了2.點(diǎn)擊大頭針試圖傳值。開始沒(méi)有想到繼承苍碟,直接用系統(tǒng)的酒觅,一直帶不過(guò)來(lái)數(shù)據(jù),后面還想著用title做對(duì)比得到數(shù)據(jù)中的索引微峰,但是這樣做感覺(jué)太麻煩了舷丹,有點(diǎn)得不償失!