My objective is to show a blue or yellow colored circle of a given radius so that later on I can search for cafes and pin them within that location.
I have this code so far and I have done everything I could! There is no error and the main location gets easily pinned and the annotation shows as well but just the circle doesn't appear.
// ViewController2.swift
import UIKit
import MapKit
class ViewController2: UIViewController,MKMapViewDelegate,CLLocationManagerDelegate
{
#IBOutlet weak var mapView: MKMapView!
#IBAction func search(_ sender: Any)
{
//get location
var dec = location1.text
}
#IBOutlet weak var location1: UITextField!
#IBOutlet weak var label2: UILabel!
#IBOutlet weak var label11: UILabel!
#IBOutlet weak var baclbtn: UIButton!
#IBOutlet weak var map1: MKMapView!
var gllat:Double=0
var gllong:Double=0
var loc:String=""
override func viewDidLoad()
{ super.viewDidLoad()
map1.delegate=self
//pin location on required area
let anotaion = MKPointAnnotation()
anotaion.coordinate=CLLocationCoordinate2DMake(gllat, gllong)
self.mapView.addAnnotation(anotaion)
//zoom in to the required location
let coordinate:CLLocationCoordinate2D=CLLocationCoordinate2DMake(gllat,gllong)
let span1 = MKCoordinateSpan(latitudeDelta:0.1,longitudeDelta:0.1)
let region = MKCoordinateRegion(center:coordinate,span:span1)
self.mapView.setRegion(region, animated: true)
//add the circle object overlay
let _coordinate:CLLocationCoordinate2D=CLLocationCoordinate2DMake(gllat, gllong)
let radius1=CLLocationDistance(bitPattern: 1000)
let cl = MKCircle(center: _coordinate, radius: radius1)
self.mapView.addOverlay(cl)
}
func mapView(_ mapView: MKMapView, rendererFor overlay: MKOverlay) -> MKOverlayRenderer
{
guard let circelOverLay = overlay as? MKCircle else {return MKOverlayRenderer()}
let circleRenderer = MKCircleRenderer(circle: circelOverLay)
circleRenderer.fillColor = .blue
//circleRenderer.alpha = 0.2
return circleRenderer
}
}
Related
I want to implement a MapKit with an UIView that has the same effect of TripAdvisor and ClassPass app. Basically, I want to add a scrollable view in the bottom of the view and when the user scroll in the map, the bottom view with the marker's information changes with the new marker's details.
Examples of what I want to achieve:
https://uigarage.net/maps-on-ios-by-tripadvisor/
Second example with ClassPass app:
https://medium.com/classpass-engineering/creating-a-fluid-scroll-experience-on-ios-faeb29be3bdb
Third example, with the code in React Native:
https://codedaily.io/tutorials/9/Build-a-Map-with-Custom-Animated-Markers-and-Region-Focus-when-Content-is-Scrolled-in-React-Native
I was able to create the Apple map with the markers, and the UIView, as can be seen on the next pictures in the links below:
Storyboard's Screenshot
Simulator's Screenshot
However, I want that to change the UIView dynamically, based on the map region, or when tapping the marker. How can I reach that result?
Here's the current code:
#IBOutlet weak var reviewView2: DesignableView!
#IBOutlet weak var authorLabel: UILabel!
#IBOutlet weak var reviewLabel: UILabel!
#IBOutlet weak var Star1: UIImageView!
#IBOutlet weak var Star2: UIImageView!
#IBOutlet weak var Star3: UIImageView!
#IBOutlet weak var Star4: UIImageView!
#IBOutlet weak var Star5: UIImageView!
#IBOutlet weak var authorImageView: UIImageView!
#IBOutlet weak var reviewView: DesignableView!
var gpxURL: NSURL? {
didSet {
clearWaypoints()
if let url = gpxURL {
GPX.parse(url: url as URL) { gpx in // asynchronous
if gpx != nil {
self.addWayPoints(waypoints: gpx!.waypoints)
}
}
}
}
}
let urlstring = "Long_Lat"
override func viewDidLoad() {
super.viewDidLoad()
// gpxURL = URL(string: urlstring)
gpxURL = Bundle.main.url(forResource: urlstring, withExtension: "gpx") as NSURL?
reviewView.isHidden = true
reviewView2.isHidden = true
}
#IBAction func reviewViewsTapped(_ sender: UITapGestureRecognizer) {
print("Button tapped")
}
// MARK: - MKMapViewDelegate
func mapView(_ mapView: MKMapView, viewFor annotation: MKAnnotation) -> MKAnnotationView? {
var view = mapView.dequeueReusableAnnotationView(withIdentifier: Constants.AnnotationViewReuseIdentifier)
if view == nil {
view = MKPinAnnotationView(annotation: annotation, reuseIdentifier: Constants.AnnotationViewReuseIdentifier)
}else{
view?.annotation = annotation
}
view?.canShowCallout = false
guard !annotation.isKind(of: MKUserLocation.self) else {
//for the custom image on current location
view?.image = #imageLiteral(resourceName: "gift")
return view
}
view?.image = UIImage(named: "gift")
let scaleTransform = CGAffineTransform(scaleX: 0.0, y: 0.0) // Scale
UIView.animate(withDuration: 0.2, animations: {
view?.transform = scaleTransform
view?.layoutIfNeeded()
}) { (isCompleted) in
// Nested block of animation
UIView.animate(withDuration: 0.3, animations: {
view?.alpha = 1.0
view?.transform = CGAffineTransform(scaleX: 1.0, y: 1.0)
AnimationUtility.viewSlideInFromBottom(toTop: view!)
view?.layoutIfNeeded()
})
}
return view
}
Any idea on how to do that using Swift 5 and UIKit?
Thanks in advance
u can use google maps,
set your custom map markers it has all methods you can read more here
https://developers.google.com/maps/documentation/ios-sdk/intro
I have prepared the app and I am stuck at adding the code to turn the ringer silent. When I press the button a notification is sent but I want to turn the ringer volume to 0. This is my code. ALSO I AM CONFUSED WHERE TO PUT THE CODE.
import UIKit
import MapKit
protocol AddViewControllerDelegate {
func addViewController(controller: AddViewController, didAddCoordinate coordinate: CLLocationCoordinate2D, radius: Double, identifier: String, note: String, eventType: EventType)
}
class AddViewController: UITableViewController {
#IBOutlet var addButton: UIBarButtonItem!
#IBOutlet var zoomButton: UIBarButtonItem!
#IBOutlet weak var eventTypeSegmentedControl: UISegmentedControl!
#IBOutlet weak var radiusTextField: UITextField!
#IBOutlet weak var noteTextField: UITextField!
#IBOutlet weak var mapView: MKMapView!
var delegate: AddViewControllerDelegate?
override func viewDidLoad() {
super.viewDidLoad()
navigationItem.rightBarButtonItems = [addButton, zoomButton]
addButton.isEnabled = false
}
#IBAction func textFieldEditingChanged(sender: UITextField) {
addButton.isEnabled = !radiusTextField.text!.isEmpty && !noteTextField.text!.isEmpty
}
#IBAction func onCancel(sender: AnyObject) {
dismiss(animated: true, completion: nil)
}
#IBAction private func onAdd(sender: AnyObject) {
let coordinate = mapView.centerCoordinate
let radius = Double(radiusTextField.text!) ?? 0
let identifier = NSUUID().uuidString
let note = noteTextField.text
let eventType: EventType = (eventTypeSegmentedControl.selectedSegmentIndex == 0) ? .onEntry : .onExit
delegate?.addViewController(controller: self, didAddCoordinate: coordinate, radius: radius, identifier: identifier, note: note!, eventType: eventType)
}
#IBAction private func onZoomToCurrentLocation(sender: AnyObject) {
mapView.zoomToUserLocation()
}
}
hey all i am brand new into coding iOS apps, and find it rather enjoyable so far..
I am having an issue assigning lat and lng to a text field. I have been following along in a tutorial but it crapped out and most examples i have found are in objective C and not swift.. and the ones in swift aren't all the best..
my ViewController is below:
import UIKit
import MapKit
class LocationVC: UIViewController, MKMapViewDelegate {
#IBOutlet weak var map: MKMapView!
#IBOutlet weak var latField: UITextField!
#IBOutlet weak var lngField: UITextField!
#IBOutlet weak var locateBtn: UIButton!
#IBOutlet weak var saveBtn: UIButton!
let regionRadius: CLLocationDistance = 500
let locationManager = CLLocationManager()
override func viewDidLoad() {
super.viewDidLoad()
map.delegate = self
locationManager.desiredAccuracy = kCLLocationAccuracyBest
}
override func viewDidAppear(animated: Bool) {
locationAuthStatus()
}
func locationAuthStatus() {
if CLLocationManager.authorizationStatus() == .AuthorizedWhenInUse {
map.showsUserLocation = true
} else {
locationManager.requestWhenInUseAuthorization()
}
}
func centerMapOnLocation(location: CLLocation) {
let coordinateRegion = MKCoordinateRegionMakeWithDistance(location.coordinate, regionRadius * 1, regionRadius * 1)
map.setRegion(coordinateRegion, animated: true)
}
func mapView(mapView: MKMapView, didUpdateUserLocation userLocation: MKUserLocation) {
if let loc = userLocation.location {
centerMapOnLocation(loc)
}
let latField = location.longitude
let lngField = location.latitude
}
}
So far the map is moving, works on my device but I have no idea how to get the coords to appear..
Please forgive me if this is a noob question, but I just cant get this damn thing to go..
Replace your mapView(_ :,didUpdatedUserLocation:) with this...
func mapView(mapView: MKMapView, didUpdateUserLocation userLocation: MKUserLocation) {
if let loc = userLocation.location
{
centerMapOnLocation(loc)
self.latField.text = "\(loc.coordinate.latitude)"
self.lngField.text = "\(loc.coordinate.longitude)"
}
}
Note: If you only need show the lat/lng could be a better idea to use an UILabel instead of UITextFiel
I am currently not able to clear the overlay.I would like to clear my overlay that was traveled and then start again. I have looked at a ton of different lines of code and can't seem to figure it out. Could you please help me out on this? I am new to Swift so please play nice :)
import UIKit
import CoreLocation
import MapKit
class ViewController: UIViewController, CLLocationManagerDelegate, MKMapViewDelegate {
#IBOutlet weak var theMap: MKMapView!
#IBOutlet weak var theLabel: UILabel!
#IBOutlet weak var startTracking: UIButton!
#IBOutlet weak var stopTracking: UIButton!
#IBOutlet weak var clearTrack: UIButton!
var polyline:MKPolyline = MKPolyline()
var manager:CLLocationManager!
var myLocations: [CLLocation] = []
func clearTrack(sender: UIButton){
//label.text = String(myLocations.count)
//stopTracking()
theMap.removeOverlay (polyline)
}
func stopTracking(sender: UIButton) {
manager.stopUpdatingLocation()
myLocations = []
println("Stop making a line")
}
func startTracking(sender: UIButton) {
manager.startUpdatingLocation()
myLocations = []
println("Making a line")
}
override func viewDidLoad() {
super.viewDidLoad()
//Setup our Location Manager
manager = CLLocationManager()
manager.delegate = self
manager.desiredAccuracy = kCLLocationAccuracyBest
manager.requestAlwaysAuthorization()
manager.startUpdatingLocation()
//Setup our Map View
theMap.delegate = self
theMap.mapType = MKMapType.Hybrid
theMap.showsUserLocation = true
}
func locationManager(manager:CLLocationManager, didUpdateLocations locations:[AnyObject]) {
theLabel.text = "\(locations[0])"
myLocations.append(locations[0] as CLLocation)
let spanX = 0.002
let spanY = 0.002
var newRegion = MKCoordinateRegion(center: theMap.userLocation.coordinate, span: MKCoordinateSpanMake(spanX, spanY))
theMap.setRegion(newRegion, animated: true)
if (myLocations.count > 1){
var sourceIndex = myLocations.count - 1
var destinationIndex = myLocations.count - 2
let c1 = myLocations[sourceIndex].coordinate
let c2 = myLocations[destinationIndex].coordinate
var a = [c1, c2]
var polyline = MKPolyline(coordinates: &a, count: a.count)
theMap.addOverlay(polyline)
}
}
func mapView(mapView: MKMapView!, rendererForOverlay overlay: MKOverlay!) -> MKOverlayRenderer! {
if overlay is MKPolyline {
var polylineRenderer = MKPolylineRenderer(overlay: overlay)
polylineRenderer.strokeColor = UIColor.yellowColor()
polylineRenderer.lineWidth = 3
return polylineRenderer
}
return nil
}
}
Have you tried using:
func clearTrack(sender: UIButton){
theMap.removeOverlays(theMap.overlays)
}
I am writing an app that has the ability to track a user's location and trace it on a map. There are three buttons, one that starts tracing the path that the user lays down, one is to stop tracing the path the user lays down, and the last is to clear the map of the traced line. I am having trouble setting up the clear button. Can someone please help me set up the #IBAction for the clear path button.
import UIKit
import CoreLocation
import MapKit
class ViewController: UIViewController, CLLocationManagerDelegate, MKMapViewDelegate {
#IBOutlet weak var theMap: MKMapView!
#IBOutlet weak var startStopTracking: UISegmentedControl!
#IBOutlet weak var clearPath: UIButton!
#IBOutlet weak var label: UILabel!
var manager:CLLocationManager!
var myLocations: [CLLocation] = []
override func viewDidLoad() {
super.viewDidLoad()
//Setup our Location Manager
manager = CLLocationManager()
manager.delegate = self
manager.desiredAccuracy = kCLLocationAccuracyBest
manager.requestAlwaysAuthorization()
//manager.startUpdatingLocation()
//Setup our Map View
theMap.delegate = self
theMap.mapType = MKMapType.Hybrid
theMap.showsUserLocation = true
//Setup startStopTracking button?
startStopTracking.selectedSegmentIndex = -1
}
#IBAction func indexChanged(sender: UISegmentedControl) {
switch startStopTracking.selectedSegmentIndex
{
case 0:
manager.startUpdatingLocation()
case 1:
manager.stopUpdatingLocation()
default:
break;
}
}
#IBAction func clearPath(sender: UIButton) {
//label.text = String(myLocations.count)
//stopTracking()
//theMap.removeOverlay(overlay: MKOverlay) -> Void
}
func stopTracking() {
manager.stopUpdatingLocation()
myLocations = []
}
func locationManager(manager:CLLocationManager, didUpdateLocations locations:[AnyObject]) {
//theLabel.text = "\(locations[0])"
myLocations.append(locations[0] as CLLocation)
let spanX = 0.007
let spanY = 0.007
var newRegion = MKCoordinateRegion(center: theMap.userLocation.coordinate, span: MKCoordinateSpanMake(spanX, spanY))
theMap.setRegion(newRegion, animated: true)
if (myLocations.count > 1){
var sourceIndex = myLocations.count - 1
var destinationIndex = myLocations.count - 2
let c1 = myLocations[sourceIndex].coordinate
let c2 = myLocations[destinationIndex].coordinate
var a = [c1, c2]
var polyline = MKPolyline(coordinates: &a, count: a.count)
theMap.addOverlay(polyline)
}
}
func mapView(mapView: MKMapView!, rendererForOverlay overlay: MKOverlay!) -> MKOverlayRenderer! {
if overlay is MKPolyline {
var polylineRenderer = MKPolylineRenderer(overlay: overlay)
polylineRenderer.strokeColor = UIColor.blueColor()
polylineRenderer.lineWidth = 6
return polylineRenderer
}
return nil
}
}
try this : removes all
for poll in mapkit.overlays {
mapkit.removeOverlay(poll)
}
You have to make your polyline a class property so you have access to it in your clearPath method:
class ViewController: UIViewController, CLLocationManagerDelegate, MKMapViewDelegate {
...
var polyline: MKPolyline = MKPolyline()
#IBAction func clearPath(sender: UIButton) {
//label.text = String(myLocations.count)
//stopTracking()
theMap.removeOverlay(polyline)
}
}