123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437 |
- //
- // IHHotelMapView.swift
- // Inhealth
- //
- // Created by weclouds on 2019/12/13.
- // Copyright © 2019 weclouds. All rights reserved.
- //
- import UIKit
- import MapKit
- import CoreLocation
- let kNotificationIHHotelMapViewGetAllHotelData = "kNotificationIHHotelMapViewGetAllHotelData"
- protocol IHHotelMapViewDelegate : NSObjectProtocol {
- func getMapViewRegin(_ lat_low:String,long_low:String,lat_high:String,long_high:String)
-
- func didSelectCalloutView(_ annotation: IHAnotation)
-
- func locationManagerDidFailWithError()
-
- }
- class IHHotelMapView: UIView {
- fileprivate var isStartLocation : Bool? = true
-
- var selectedCoordinate:CLLocationCoordinate2D?{
- didSet{
-
- //处理事件
- if let coordinate = self.selectedCoordinate {
- isStartLocation = false
- let location = CLLocation(latitude: coordinate.latitude, longitude: coordinate.latitude)
- centerMapOnLocation(location: location)
-
- }else{
- isStartLocation = true
- }
- }
- }
-
- var AllHotelData:[HotelMapData]? //所有的酒店数据
- var fillterResult: [HotelMapData]? //过滤的结果
- {
- didSet{
- }
- }
- var searchFiled:UITextField?
- var showAnonations:[IHAnotation]? = [IHAnotation]()
- var receviceAnonations: [IHAnotation]? = [IHAnotation]()
- lazy var resultView: IHMapResultView = {//搜索结果view
- let resultView = IHMapResultView()
- resultView.frame = CGRect(x: 0, y: 0, width: KSCREENWIDTH, height: KSCREENHEIGHT - KNavBarHeight - 50)
- resultView.isHidden = true
- return resultView
- }()
- weak var delegate: IHHotelMapViewDelegate?
- private var isOnce = true
-
- var mapDatas :[HotelMapData]?{
- didSet{
- addAnnotationsToMapView()
- }
- }
-
- public var mapView : MKMapView!
-
- let locationManager = CLLocationManager()
-
-
- lazy var locationBtn: UIButton = {
- let locationBtn = UIButton(type: .custom)
- locationBtn.setImage(UIImage(named: "定位当前位置"), for: .normal)
- locationBtn.backgroundColor = .white
- locationBtn.addTarget(self, action: #selector(locationAction), for: .touchUpInside)
- return locationBtn
- }()
- lazy var callOut: IHCallView = {
- let callOut = Bundle.main.loadNibNamed("IHCallView", owner: nil, options: nil)?.last as! IHCallView
- /// callOut.backgroundColor = UIColor.red
- callOut.isHidden = true
- return callOut
- }()
- override init(frame: CGRect) {
- super.init(frame: frame)
- NotificationCenter.default.addObserver(self, selector: #selector(notifyAllHotelData(_:)), name: NSNotification.Name(kNotificationIHHotelMapViewGetAllHotelData), object: nil)
- createMapView()
-
- }
-
- deinit {
- log.debug("IHHotelMapView销毁")
- NotificationCenter.default.removeObserver(self)
- }
- required init?(coder: NSCoder) {
- fatalError("init(coder:) has not been implemented")
- }
-
- @objc func notifyAllHotelData(_ notify:Notification) {
- self.AllHotelData = notify.object as? [HotelMapData]
- self.resultView.mapHotelArr = AllHotelData
- }
- override func layoutSubviews() {
- super.layoutSubviews()
- mapView.snp.makeConstraints { (make) in
- make.right.left.top.bottom.equalToSuperview()
- }
-
- locationBtn.snp.makeConstraints { (make) in
- make.right.equalToSuperview().offset(-12)
- make.bottom.equalToSuperview().offset(-167)
- make.width.height.equalTo(37)
- }
-
- callOut.snp.makeConstraints({ (make) in
- make.bottom.equalToSuperview().offset(-34)
- make.left.equalTo(0)
- make.right.equalTo(0)
- make.height.equalTo(140 + 50)
- })
-
- }
- @objc func locationAction() {
- isStartLocation = true
- //重新开始定位
- startLocation()
- }
- func createMapView() {
- mapView = MKMapView()
- mapView.delegate = self
- addSubview(mapView)
- backgroundColor = .blue
-
- //设置地图类型
- mapView.mapType = .standard
- mapView.showsUserLocation = true
- mapView.userTrackingMode = .follow
- locationManager.delegate = self
- locationManager.requestWhenInUseAuthorization()
- locationManager.requestAlwaysAuthorization()
- locationManager.desiredAccuracy = kCLLocationAccuracyBest
- //开始update user位置
- startLocation()
- mapView.userTrackingMode = .none //不跟随移动
- //addAnnotationsToMapView()
- addSubview(locationBtn)
-
- addSubview(callOut)
-
- locationBtn.layer.masksToBounds = true
- locationBtn.layer.cornerRadius = 9
-
- addSubview(resultView)
-
- let searchView = UIView(frame: CGRect(x: 20, y: 15, width: KSCREENWIDTH - 40, height: 38))
- searchView.backgroundColor = UIColor(hexString: "ffffff")
- searchView.layer.cornerRadius = 19
- searchView.layer.masksToBounds = true
- self.addSubview(searchView)
-
-
- let searchfiled = UITextField(frame: CGRect(x: 15 , y: 5, width: KSCREENWIDTH - 40 - 30 - 20, height: 30))
- searchfiled.delegate = self
- searchfiled.placeholder = "输入关键字进行查找..."
- searchfiled.font = UIFont(name: PingFangSC_Medium, size: 12)
- searchfiled.textColor = UIColor(hexString: "333333")
- searchfiled.returnKeyType = .search
- searchfiled.clearButtonMode = .always
- searchView.addSubview(searchfiled)
- self.searchFiled = searchfiled
- let searchIcon = UIImageView(image: UIImage(named: "搜索"))
- searchView.addSubview(searchIcon)
-
- searchIcon.snp.makeConstraints { (make) in
- make.centerY.equalToSuperview()
- make.right.equalToSuperview().offset(-10)
- make.width.height.equalTo(15)
- }
- resultView.callback = {[unowned self] (hotel) in
- self.mapSelectedHotel(hotel)
- }
- }
- //选择酒店回调
- func mapSelectedHotel(_ hotel :HotelMapData) {
- if let latitude = hotel.latitude,let longitude = hotel.longitude {
- self.resultView.isHidden = true
- let lat = Double(latitude)
- let lng = Double(longitude)
- // let coordinte = CLLocationCoordinate2D(latitude: lat!, longitude: lng!)
- let location = CLLocation(latitude: lat!, longitude: lng!)
- centerMapOnLocation(location: location)
- self.endEditing(true) //收起键盘
- self.searchFiled?.text = ""
- //显示当前气泡
- delay(1) {
- for ano in self.showAnonations! {
- if ano.id == hotel.id {
- self.mapView.selectAnnotation(ano, animated: true)
- self.callOut.hotelData = hotel
- self.callOut.isHidden = false
- }
- }
- }
-
-
-
- }
- }
- func startLocation() {
- print("进入普通定位态");
- locationManager.startUpdatingLocation()
- mapView.showsUserLocation = false//先关闭显示的定位图层
- mapView.showsUserLocation = true//显示定位图层
- }
- func stopLocation() {
- locationManager.stopUpdatingLocation()
- mapView.showsUserLocation = false
-
- }
-
- //显示周围1000米的区域
- let regionRadius: CLLocationDistance = 1000
- func centerMapOnLocation(location: CLLocation) {
-
- let coordinateRegion = MKCoordinateRegion(center: location.coordinate,
- latitudinalMeters: regionRadius, longitudinalMeters: regionRadius)
- mapView.setRegion(coordinateRegion, animated: true)
- }
-
-
- func addAnnotationsToMapView() {
- if showAnonations!.count > 0 && showAnonations != nil {
- self.mapView.removeAnnotations(showAnonations!)
- }
-
- if let mapDatas = mapDatas {
- if mapDatas.count > 0 {//如果有值的时候,
- for map in mapDatas {
- if let lat = map.latitude ,let lng = map.longitude,let id = map.id,let name = map.name{
- let latitude = Double(lat)
- let longitude = Double(lng)
- let location = CLLocationCoordinate2DMake(latitude!, longitude!)
- let annotation = IHAnotation(coordinate: location, icon: UIImage(named: "地图未选中点"),id:id,name: name ,hotelData:map )
-
- receviceAnonations?.append(annotation)
- }
- }
- }
- }
-
- showAnonations = receviceAnonations
- self.mapView.addAnnotations(showAnonations!)
-
- }
- }
- extension IHHotelMapView:MKMapViewDelegate{
-
-
- //地图缩放完毕触发
- func mapView(_ mapView: MKMapView, regionDidChangeAnimated animated: Bool) {
- log.debug("地图缩放完毕触法")
- if isOnce == false{
- return
- }
- isOnce = false
-
- let point1 = CGPoint(x: 0, y: 0)
- let point2 = CGPoint(x: mapView.width, y: mapView.height)
- //屏幕坐标转地图坐标
- let coor1 = mapView.convert(point1, toCoordinateFrom: mapView)
- let coor2 = mapView.convert(point2, toCoordinateFrom: mapView)
- //获取坐标
- let lat_high = String(coor1.latitude)
- let lng_low = String(coor1.longitude)
- let lat_low = String(coor2.latitude)
- let lng_high = String(coor2.longitude)
- if let delegate = self.delegate {
- delegate.getMapViewRegin(lat_low, long_low: lng_low, lat_high: lat_high, long_high: lng_high)
- }
-
- IHHotelMapService.share.getHotelMapData("-180", lng_high: "180", lat_low: "-90", lat_high: "90", requestSuccess: { (data) in
-
- self.mapDatas = data
-
- }) {
-
- }
- }
- func mapView(_ mapView: MKMapView, viewFor annotation: MKAnnotation) -> MKAnnotationView? {
- if annotation.isKind(of: IHAnotation.self) {
- let annotationIH = annotation as! IHAnotation
- let key = "AnnotationIdentifier"
- //重用机制
- var view = self.mapView.dequeueReusableAnnotationView(withIdentifier: key) as? IHAnotationView
- if view == nil {
- view = IHAnotationView(annotation: annotation, reuseIdentifier: key)
- }
- //设置大头针数据
- view?.annotation = annotation
- view?.image = annotationIH.icon
-
- return view
-
- }
- return nil
- }
- // mapView 跟tableView的结构不一样,有顺序,map只可以把数据绑定到Anotation中
- func mapView(_ mapView: MKMapView, didSelect view: MKAnnotationView) {
- if view.isKind(of: IHAnotationView.self) == false {
- return
- }
- view.image = UIImage(named: "地图选中点")
- let annotion = view.annotation as? IHAnotation
- //callOut.backgroundColor = .random
- callOut.isHidden = false
- callOut.hotelName = annotion?.name
- callOut.hotelData = annotion?.hotelData
- callOut.closeCallback = { // 关闭callOut
- [unowned self] in
- self.callOut.isHidden = true
- view.image = UIImage(named: "地图未选中点")
- }
-
- //选中callout
- callOut.didSelectedCallout = { [unowned self] in
-
- self.delegate?.didSelectCalloutView(annotion!)
- }
- }
-
- func mapView(_ mapView: MKMapView, didDeselect view: MKAnnotationView) {
- if view.isKind(of: IHAnotationView.self) == false {
- return
- }
- callOut.isHidden = true
- view.image = UIImage(named: "地图未选中点")
-
- }
-
-
- }
- extension IHHotelMapView:CLLocationManagerDelegate{
-
- func locationManager(_ manager: CLLocationManager, didFailWithError error: Error) {
- manager.stopUpdatingLocation()
- if let delegate = self.delegate {
- delegate.locationManagerDidFailWithError()
- }
- }
- func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
- let userLocation : CLLocation = locations.first! //最新位置
- //
- // let coordinate = userLocation.coordinate
- // let _lat = coordinate.latitude
- // let _lng = coordinate.longitude
- // //火星坐标系
- // let (lat, lng) = LocationTransform.wgs2gcj(wgsLat: _lat, wgsLng: _lng)
- // let _location : = CLLocation(latitude: lat, longitude: lng)
- if isStartLocation == true {
- centerMapOnLocation(location: userLocation)
- }
-
- manager.stopUpdatingLocation()
-
- }
- }
- extension IHHotelMapView : UITextFieldDelegate{
- func textFieldShouldReturn(_ textField: UITextField) -> Bool {
- self.endEditing(true)
- return true
- }
-
- func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
-
- let currentText = searchFiled?.text ?? ""
- let newText = (currentText as NSString).replacingCharacters(in: range, with: string)
- log.debug("搜索内容 - \(newText) -- \(currentText)")
- if #available(iOS 13, *) {
- //iOS 13 九空格切换有问题
- }else{
- filterContent(for: newText)
- }
-
- return true
- }
- func textFieldShouldClear(_ textField: UITextField) -> Bool {
- log.debug("点击了清楚按钮 ")
- return true
- }
- //iOS 13 新增api
- func textFieldDidChangeSelection(_ textField: UITextField) {
- //iOS 13之后使用
- if #available(iOS 13, *){
- let currentText = searchFiled?.text ?? ""
- filterContent(for: currentText)
- }
-
-
- }
- ///过滤
- func filterContent(for searchText:String) {
- resultView.isHidden = false
- // guard let hotellist = AllHotelData else { return }
- let hotelName = searchText
- var fillterHotelNS : [HotelMapData]?
- if hotelName == "" || self.AllHotelData == nil || self.AllHotelData?.count == 0 { //没有输入则为传入的内容
- fillterHotelNS = AllHotelData
- }else{
- fillterHotelNS = (AllHotelData?.filter({ (hotel) -> Bool in
- //全部转为小写 在比较
- let name = hotel.name!.lowercased()
- let search = searchText.lowercased()
- return name.contains(search) == true
- // return province.name!.contains(searchText) == true
- }))!
- }
- fillterResult = fillterHotelNS
- //23log.debug(fillterResult)
- NotificationCenter.default.post(name: NSNotification.Name(rawValue: kNotifactionIHMapResultViewReloadData), object: fillterHotelNS)
- }
- }
|