2017-03-14 1 views
0

Aidez-moi s'il vous plaît.Supprimer l'annotation sur la carte virtuelle swift3

Premier travail sur un projet, avec iBeacon impliqué, ce qui crée Carte virtuelle de l'intérieur d'un magasin.

Je sais comment faire tomber des épingles, avec un MapKit, mais comment puis-je le faire, si je n'ai que des CGPoints sur View? J'ai réussi à égoutter UIImage (avec une image de broche), sur une vue. Mais quand je tourne ou pince, il ne reste pas sur les coordonnées que j'ai abandonnées. est ici un code:

import UIKit 



class MapViewController: UIViewController{ 


    private var scaleView: CGFloat = 1 
    private var rotateView: CGFloat = 0 
    private var anchorPoint = CGPoint(x: 0.5, y: 0.5) 
    private let gestureRecognizerDelegate = GestureRecognizerDelegate() 

    @IBOutlet weak var mapView: MapView! 
    @IBOutlet var pinchGestureRecognizer: UIPinchGestureRecognizer! 
    @IBOutlet var panGestureRecognizer: UIPanGestureRecognizer! 
    @IBOutlet var rotateGestureRecognizer: UIRotationGestureRecognizer! 
    @IBOutlet weak var pin: UIImageView! 

    override func viewDidAppear(_ animated: Bool) { 
     if !cartIsEmpty { 
      cartBtn.setImage(UIImage(named: "haveitem"), for: .normal) 

     } else { 
      cartBtn.setImage(UIImage(named: "2772"), for: .normal) 

     } 
     cartBtn.addTarget(self, action: #selector(openCart), for: .touchUpInside) 
     let item1 = UIBarButtonItem(customView: cartBtn) 
     self.navigationItem.rightBarButtonItem = item1 
    } 
    override func viewDidDisappear(_ animated: Bool) { 
     cartBtn.removeTarget(self, action: #selector(openCart), for: .touchUpInside) 

    } 

    override func viewDidLoad() { 
     super.viewDidLoad() 
      ApplicationManager.sharedInstance.onApplicationStart() 
     NotificationCenter.default.addObserver(self, selector: #selector(self.onOrientationChanged), name: NSNotification.Name.UIDeviceOrientationDidChange, object: nil) 
     self.panGestureRecognizer.delegate = gestureRecognizerDelegate 
     self.pinchGestureRecognizer.delegate = gestureRecognizerDelegate 
     self.rotateGestureRecognizer.delegate = gestureRecognizerDelegate 
     ApplicationManager.sharedInstance.gotFloorData = drawFloor 
     ApplicationManager.sharedInstance.currentUserPoint = drawCurrentUserPoint 
    } 

    func drawFloor (floor: Floor) { 
     mapView.setFloor(currentFloor: floor) 
     mapView.setNeedsDisplay() 
    } 

    func drawCurrentUserPoint(currentUserPoint: CurrentUserLocation, beaconRangingData: [BeaconRangingPoint]) { 
     mapView.setUserPoint(currentUserPoint: currentUserPoint, beaconRangingData: beaconRangingData) 
     mapView.setNeedsDisplay() 
    } 

    @IBAction func handlePan(recognizer:UIPanGestureRecognizer) { 
     let translation = recognizer.translation(in: mapView) 
     if recognizer.view != nil { 
      let offsetX = translation.x * CGFloat(cosf(Float(rotateView))) - translation.y * CGFloat(sinf(Float(rotateView))) 
      let offsetY = translation.x * CGFloat(sinf(Float(rotateView))) + translation.y * CGFloat(cosf(Float(rotateView))) 
      mapView.center = CGPoint(x:mapView.center.x + offsetX * scaleView, 
            y:mapView.center.y + offsetY * scaleView) 
     } 
     recognizer.setTranslation(CGPoint(x: 0, y: 0), in: mapView) 
    } 

    @IBAction func handlePinch(recognizer : UIPinchGestureRecognizer) { 
     if recognizer.view != nil { 
      setAnchor(point: recognizer.location(in: mapView)) 
      mapView.transform = mapView.transform.scaledBy(x: recognizer.scale, y: recognizer.scale) 
      scaleView = recognizer.scale * scaleView 
      recognizer.scale = 1 
     } 
    } 

    @IBAction func handleRotate(recognizer : UIRotationGestureRecognizer) { 
     if recognizer.view != nil { 
      setAnchor(point: recognizer.location(in: mapView)) 
      mapView.transform = mapView.transform.rotated(by: recognizer.rotation) 
      rotateView = rotateView + recognizer.rotation 
      recognizer.rotation = 0 
     } 
    } 

    private func setAnchor(point : CGPoint) { 
     let anchor = CGPoint(x: point.x/mapView.bounds.width, y: point.y/mapView.bounds.height) 
     mapView.layer.anchorPoint = CGPoint(x: anchor.x, y: anchor.y) 
     let translationX = (mapView.bounds.width * (anchor.x - anchorPoint.x)) * scaleView 
     let translationY = (mapView.bounds.height * (anchor.y - anchorPoint.y)) * scaleView 
     let offsetX = translationX * CGFloat(cosf(Float(rotateView))) - translationY * CGFloat(sinf(Float(rotateView))) 
     let offsetY = translationX * CGFloat(sinf(Float(rotateView))) + translationY * CGFloat(cosf(Float(rotateView))) 
     mapView.layer.position = CGPoint(x: mapView.layer.position.x + offsetX, 
             y: mapView.layer.position.y + offsetY) 
     anchorPoint = anchor 
    } 

    private func showAlert(title: String, message: String?, style: UIAlertControllerStyle = .alert) { 
     let alertController = UIAlertController(title: title, message: message, preferredStyle: style) 
     let tryAgainAction = UIAlertAction(title: "Try again", style: .default) { 
      alertAction in 
      ApplicationManager.sharedInstance.onApplicationStart() 
     } 
     let cancelAction = UIAlertAction(title: "Cancel", style: .default, handler: nil) 
     alertController.addAction(tryAgainAction) 
     alertController.addAction(cancelAction) 
     present(alertController, animated: true, completion: nil) 
    } 

    func onOrientationChanged() { 
     self.mapView.setNeedsDisplay() 
    } 

    override func didReceiveMemoryWarning() { 
     super.didReceiveMemoryWarning() 
     // Dispose of any resources that can be recreated. 
    } 


} 

également le code de Mapview:

import UIKit 

classe MapView: UIView {

private var floor = Floor(walls: [], doors: [], beacons: []) 
private let wallColor = UIColor.black 
private let doorColor = UIColor.red 
private let triangleColor = UIColor.red 
private let perpendicularColor = UIColor.darkGray 
private let doorLength = 3.0 
private let beaconColor = UIColor.green 
private let beaconNoActiveColor = UIColor(red: 20/255.0, green: 154.0/255.0, blue: 53.0/255.0, alpha: 1.0) 
private let beaconFrameColor = UIColor.brown 
private let lineWidthBeaconFrame:CGFloat = 0.25 
private let beaconRadius: CGFloat = 5.0 
private let userColor = UIColor.blue 
private let userFrameColor = UIColor.brown 
private let lineWidthUserFrame:CGFloat = 0.25 
private let userRadius: CGFloat = 5.0 
private let distanceBeaconColor = UIColor.clear 
private let distanceBeaconFrameColor = UIColor.green 
private let lineWidthOfDistanceFrame: CGFloat = 0.5 
private let userRawRadius: CGFloat = 3.0 
private let userRawColor = UIColor.darkGray 
private let userRawFrameColor = UIColor.lightGray 
private let lineWidthOfuserRawFrame: CGFloat = 0.8 

private var beaconText: NSString = "" 
private let textColor: UIColor = UIColor.red 
private let textFont: UIFont = UIFont(name: "Helvetica Neue", size: 5)! 


private var currentUserLocation = CurrentUserLocation() 
private var beaconRangingData: [BeaconRangingPoint] = [] 

func setFloor (currentFloor: Floor) { 
    floor = currentFloor 
} 
func setUserPoint(currentUserPoint: CurrentUserLocation, beaconRangingData: [BeaconRangingPoint]) { 
    self.currentUserLocation = currentUserPoint 
    self.beaconRangingData = beaconRangingData 
} 
func dropPin(location: CGPoint) { 
} 

override func draw(_ rect: CGRect) { 
    let frameToDraw = CoordinatesConverter(boundsWidth: bounds.width, boundsHeight: bounds.height, paddingX: 5, paddingY: 5) 
    let mapWithScaleCoordinaates = frameToDraw.getSuitableCoordinates(floor: floor, currentUserLocation: currentUserLocation, beaconRangingData: beaconRangingData) 
    let lines = mapWithScaleCoordinaates.lines 
    let circles = mapWithScaleCoordinaates.circles 

    drawLines(lines: lines) 
    drawCircles(circles: circles) 
} 

private func drawLines(lines :[Line]) { 
    let wallPath = UIBezierPath() 
    let doorPath = UIBezierPath() 
    let trianglePath = UIBezierPath() 
    let perpendicularPath = UIBezierPath() 

    for line in lines { 
     if line.type == .wall { 
      wallPath.move(to: CGPoint(x: line.x1, y: line.y1)) 
      wallPath.addLine(to: CGPoint(x: line.x2, y: line.y2)) 
      wallColor.setStroke() 
      wallPath.stroke() 
     } 
     if line.type == .door { 
      doorPath.move(to: CGPoint(x: line.x1, y: line.y1)) 
      doorPath.addLine(to: CGPoint(x: line.x2, y: line.y2)) 
      doorPath.lineWidth = CGFloat(doorLength) 
      doorColor.setStroke() 
      doorPath.stroke() 
     } 
     if line.type == .triangle { 
      trianglePath.move(to: CGPoint(x: line.x1, y: line.y1)) 
      trianglePath.addLine(to: CGPoint(x: line.x2, y: line.y2)) 
      triangleColor.setStroke() 
      trianglePath.stroke() 
     } 
     if line.type == .perpendicular { 
      perpendicularPath.move(to: CGPoint(x: line.x1, y: line.y1)) 
      perpendicularPath.addLine(to: CGPoint(x: line.x2, y: line.y2)) 
      perpendicularColor.setStroke() 
      perpendicularPath.stroke() 
     } 
    } 
} 

private func drawCircles(circles: [Circle]) { 
    let layerViews = layer.sublayers 
    if layerViews != nil { 
     for view in layerViews! { 
      if type(of: view) === CAShapeLayer.self { 
       view.removeFromSuperlayer() 
      } 
     } 
    } 

    for circle in circles { 

     if type(of: circle) === BeaconCircle.self { 
      if (circle as! BeaconCircle).correctedDistance == 0 { 
       infoToDrawCircle(circle: circle, radius: beaconRadius, color: beaconNoActiveColor.cgColor, frameColor: beaconFrameColor.cgColor, frameWidth: lineWidthBeaconFrame) 
       drawBeaconText(circle: circle as! BeaconCircle) 
      } else { 
       infoToDrawCircle(circle: circle, radius: beaconRadius, color: beaconColor.cgColor, frameColor: beaconFrameColor.cgColor, frameWidth: lineWidthBeaconFrame) 
       drawBeaconText(circle: circle as! BeaconCircle) 
      } 

      if type(of: circle) === BeaconCircle.self && (circle as! BeaconCircle).correctedDistance != 0 { 
       infoToDrawCircle(circle: circle, radius: CGFloat((circle as! BeaconCircle).correctedDistance), color: distanceBeaconColor.cgColor, frameColor: distanceBeaconFrameColor.cgColor, frameWidth: lineWidthOfDistanceFrame) 
       // infoToDrawCircle(circle: circle, radius: CGFloat((circle as! BeaconCircle).notCorrectedDistance), color: UIColor.gray.cgColor, frameColor: distanceBeaconFrameColor.cgColor, frameWidth: lineWidthOfDistanceFrame) 
      } 

     } else if type(of: circle) === UserCircle.self { 
      infoToDrawCircle(circle: circle, radius: userRadius, color: userColor.cgColor, frameColor: userFrameColor.cgColor, frameWidth: lineWidthUserFrame) 
     } else if type (of: circle) === UserRawCircle.self { 
      infoToDrawCircle(circle: circle, radius: userRawRadius, color: userRawColor.cgColor, frameColor: userRawFrameColor.cgColor, frameWidth: lineWidthOfuserRawFrame) 
     } else { 
      Logger.logMessage(message: "incorrect circle type", level: .error) 
      break 
     } 
    } 
} 



private func drawBeaconText (circle: BeaconCircle) { 
    let attributes: NSDictionary = [ 
     NSForegroundColorAttributeName: textColor, 
     NSFontAttributeName: textFont 
    ] 
    let minor = circle.minor 
    let correctDistance = Int(round(100 * circle.correctDistanceForText)/100) 
    let notCorrectDistance = Int(round(100 * circle.notCorrectDistanceForText)/100) 
    beaconText = "m: \(minor), cd: \(correctDistance), nd: \(notCorrectDistance)" as NSString 
    if circle.x > Int((bounds.width - 50)) { 
     beaconText.draw(at: CGPoint(x: circle.x - 70, y: circle.y + 5), withAttributes: attributes as? [String : Any]) 
    } else if circle.x < 20 { 
     beaconText.draw(at: CGPoint(x: circle.x + 5, y: circle.y + 5), withAttributes: attributes as? [String : Any]) 
    } else { 
     beaconText.draw(at: CGPoint(x: circle.x + 6, y: circle.y + 5), withAttributes: attributes as? [String : Any]) 
    } 
} 

private func infoToDrawCircle (circle: Circle, radius: CGFloat, color: CGColor, frameColor: CGColor, frameWidth: CGFloat) { 
    let center = CGPoint(x: circle.x, y: circle.y) 
    let path = UIBezierPath(arcCenter: center, radius: radius, startAngle: 0, endAngle: 360, clockwise: true) 
    let shapeLayer = CAShapeLayer() 
    shapeLayer.path = path.cgPath 
    shapeLayer.fillColor = color 
    shapeLayer.lineWidth = frameWidth 
    shapeLayer.strokeColor = frameColor 
    layer.addSublayer(shapeLayer) 
} 

}

Répondre

0

Je vous suggère conformez votre MapViewController au MKMapViewDelegate . De cette façon, vous pouvez ajouter des annotations (également animées) à la carte et vous n'aurez plus à vous en soucier puisque tout est géré par le délégué de la carte.

Vous pouvez utiliser:

self.map.showAnnotations(pins, animated: true)

pins est un tableau de MKAnnotation. Here is the link à la documentation de la méthode.

Cheers