mapView.centerCoordinate seems to create new map instance - ios

I'm starting an iOS project, and when I try to use the user's location, the map seems to reset every time I set the center coordinate. I have a function mapView(mapView: MKMapView!, didUpdateUserLocation userLocation: MKUserLocation! where the only thing is mapView.centerCoordinate = userLocation.location.coordinate. When I comment out this code, the map seems to use the same region I had set in a button that zooms in. When I uncomment the code, the map zooms back out to the original setting when the location is updated. The memory use continues to increase each time, which leads me to believe a new map instance is being created over the current one for some reason. I didn't have this problem when I used a single view application, but now I'm using the tabbed view application default. The secondViewController is set to the default when it is created. Pretty much all of the code:
class FirstViewController: UIViewController, MKMapViewDelegate {
#IBOutlet var mapView: MKMapView!
#IBOutlet var startButton: UIButton!
override func viewDidLoad() {
super.viewDidLoad()
mapView.delegate=self
mapView.showsUserLocation = true
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
#IBAction func startEnd(sender: AnyObject) {
if (startButton.currentTitle == "Start") {
startButton.setTitle("Running", forState: .Normal)
let userLocation=mapView.userLocation
let region=MKCoordinateRegionMakeWithDistance(userLocation.location.coordinate,2000,2000)
mapView.setRegion(region,animated:true)
} else {
startButton.setTitle("Start", forState: .Normal)
}
}
func mapView(mapView: MKMapView!, didUpdateUserLocation userLocation: MKUserLocation!) {
mapView.centerCoordinate = userLocation.location.coordinate
}
How do I stop the map from resetting the map view region to the default (or, possibly, creating a new map on top of the one I already have)

Related

GoogleMaps old behaviour, when I tap a marker

I'm using xcode 9.0, GoogleMaps SDK 2.5.0 and GooglePlaces 2.5.0.
In the method func mapView(_ mapView: GMSMapView, didTap marker: GMSMarker) -> Bool I'm trying to disable the auto center map, when I select a marker and go back to the old behaviour of only showing the marker and no auto center enabled. The problem is that the marker doesn't appear when I implement that behaviour (lines that are commented), all stack overflow I searched implements those lines. I'm lost
class MapViewController: UIViewController, GMSMapViewDelegate
{
//MARK: Class Life Cycle
#IBOutlet weak var mapView: UIView!
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
setupUI()
setupMap()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
//MARK: -Setup
func setupUI() {
navigationController?.hideBar()
}
func setupMap() {
let map = MapManager.sharedInstance.setupMap(view: mapView, latitude: GoogleMap.latitude, longitude: GoogleMap.longitude, zoom: GoogleMap.zoom)
map.delegate = self
mapView.addSubview(map)
MapManager.sharedInstance.setupMapMarkers(map: map, file: File.geoFence, fileType: File.json)
}
func mapView(_ mapView: GMSMapView, didTap marker: GMSMarker) -> Bool {
// mapView.selectedMarker = marker
// return true
return false
}
}
If anyone comes across this odd bug, the odd solution is adding the delegate again:
func mapView(_ mapView: GMSMapView, didTap marker: GMSMarker) -> Bool {
mapView.delegate = self
mapView.selectedMarker = marker
return true
return false
}

Unable to display map on view

I've been learning Xcode (swift 1.2) for the past week, I've just started looking into the Map Kit and I've hit a brick wall.
I'm following this tutorial : MapKit Location
I've added the mapkit to my view, and added the following code into the controller:
#IBOutlet weak var mapView: MKMapView!
let regionRadius: CLLocationDistance = 1000
#IBOutlet var menuButton: UIBarButtonItem!
override func viewDidLoad() {
super.viewDidLoad()
let initialLocation = CLLocation(latitude: 21.282778, longitude: -157.829444)
centerMapOnLocation(initialLocation)
// Do any additional setup after loading the view.
}
func centerMapOnLocation(location: CLLocation) {
let coordinateRegion = MKCoordinateRegionMakeWithDistance(location.coordinate, regionRadius * 2.0, regionRadius * 2.0)
mapView.setRegion(coordinateRegion, animated: false)
}
Yet when I run the app, I see the following image:
Can someone please shed some light into why I'm unable to see the actual map instead of the tiles?
Update
Code below afer feedback from ansers:
#IBOutlet weak var mapView: MKMapView!
#IBOutlet var menuButton: UIBarButtonItem!
var locationManage = CLLocationManager()
var locateCoordinate = CLLocationCoordinate2D()
override func viewDidLoad() {
super.viewDidLoad()
let initialLocation = CLLocation(latitude: 21.282778, longitude: -157.829444)
centerMapOnLocation(initialLocation)
}
func centerMapOnLocation(location: CLLocation) {
var coordin: CLLocationCoordinate2D = location.coordinate
var viewRegion: MKCoordinateRegion = MKCoordinateRegionMakeWithDistance(coordin, 500, 500)
var adjustedRegion: MKCoordinateRegion = self.mapView.regionThatFits(viewRegion)
self.mapView.setRegion(adjustedRegion, animated: true)
}
Some troubleshooting ideas:
double check that your IBOutlet is connected
check if your simulator has network connection
make the change in viewDidAppear to get visual feedback
try on actual device
try different location, greater radius
double check that you are not changing the coordinates or zoom level again after viewDidLoad
try zooming out and panning on the map to see if the contents changes
Set the delegate and delegate methods, Use this example Code,
import UIKit
import MapKit
class ViewController: UIViewController, MKMapViewDelegate, CLLocationManagerDelegate,UITableViewDelegate,UITableViewDataSource {
#IBOutlet weak var mapViewOwn: MKMapView!
var locationManage = CLLocationManager()
var locateCoordinate = CLLocationCoordinate2D()
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib..
mapViewOwn.delegate = self
locationManage.delegate = self
if CLLocationManager.authorizationStatus() == .NotDetermined {
self.locationManage.requestWhenInUseAuthorization()
}
mapViewOwn.showsUserLocation = true
mapViewOwn.mapType = MKMapType.Standard
mapViewOwn.zoomEnabled = true
mapViewOwn.scrollEnabled = true
locationManage.distanceFilter = kCLDistanceFilterNone
locationManage.desiredAccuracy = kCLLocationAccuracyBest
}
//delegate Methods:
func mapView(mapView: MKMapView, annotationView view: MKAnnotationView, calloutAccessoryControlTapped control: UIControl) {
}
func mapView(mapView: MKMapView, didUpdateUserLocation userLocation: MKUserLocation) {
let region : MKCoordinateRegion = MKCoordinateRegionMakeWithDistance(userLocation.coordinate, 1000, 1000)
mapViewOwn.setRegion(mapViewOwn.regionThatFits(region), animated: true)
}
func mapView(mapView: MKMapView, didSelectAnnotationView view: MKAnnotationView) {
//code here
}
func mapView(mapView: MKMapView, viewForAnnotation annotation: MKAnnotation) -> MKAnnotationView? {
//code here
}

MapBox iOS SDK: add map event

I'm trying to setup an iOS app with the latest MapBox iOS idk (3.2). How much i seek the internet, I can't find an example how to add a map event to the mapview.
For example: i want to add an event when the map becomes idle. Any suggestions?
UPDATE
I think this is the right method to implement:
func mapView(mapView: MGLMapView, regionDidChangeAnimated animated: Bool) {
}
If you’re asking how to use delegate methods, here’s how:
import Mapbox
// Declare conformance to the MGLMapViewDelegate protocol
class ViewController: UIViewController, MGLMapViewDelegate {
var mapView: MGLMapView!
override func viewDidLoad() {
super.viewDidLoad()
mapView = MGLMapView(frame: view.bounds)
mapView.autoresizingMask = [.FlexibleWidth, .FlexibleHeight]
view.addSubview(mapView)
// Set the delegate property of our map view to self after instantiating it.
mapView.delegate = self
}
func mapView(mapView: MGLMapView, regionDidChangeAnimated animated: Bool) -> Bool {
// look at mapView properties and do something
}
}
See https://www.mapbox.com/ios-sdk/examples/ for examples of how to implement basic features with the Mapbox iOS SDK.

Configure UIView in viewDidLoad or var's didSet

Consider this example of configuring MKMapView's map type. Should it be done in viewDidLoad()
override func viewDidLoad() {
super.viewDidLoad()
mapView.mapType = MKMapType.Hybrid
}
or in the var's didSet?
#IBOutlet weak var mapView: MKMapView! {
didSet {
mapView.mapType = MKMapType.Hybrid
}
}
Both work, what's the Swift preferred way?
They each have a different use.
If you want the mapType set every time the property is set, use didSet.
If you only want the mapType set once when the view is loaded, use viewDidLoad.
Given what you are doing I would say that didSet is the more correct choice here.
BTW - this has nothing to do with "the Swift preferred way". The same logic applies regardless of language.

Cant interact with custom infowindow in google map

I have a google map and I've created a custom info window for my markers. I've put a couple buttons on the window, but I can't interact with them for the life of me. Here is my custom view:
class MarkerWindowView: UIView, UIGestureRecognizerDelegate {
//#IBOutlet weak var thumbNail: UIImageView!
#IBOutlet weak var userName: UILabel!
#IBOutlet weak var videoLocation: UILabel!
#IBOutlet weak var tags: UILabel!
override func awakeFromNib() {
println("awake From Nib")
self.userInteractionEnabled = true
print(self.userInteractionEnabled)
/*let recognizer = UITapGestureRecognizer(target: self, action:Selector("handleTap:"))
recognizer.delegate = self
/*for test in layer.sublayers {
println(test)
}*/*/
}
#IBAction func playVideoPressed(sender: AnyObject) {
println("play video")
}
#IBAction func markerWindowViewWasTapped(sender: UITapGestureRecognizer) {
println("playvideo")
}
/*func handleTap(recognizer: UITapGestureRecognizer) {
println("tapped")
}*/
}
and here is the method that returns the view in the view controller:
func mapView(mapView: GMSMapView!, markerInfoWindow marker: GMSMarker!) -> UIView! {
println("markeInfoWindow")
var newView = NSBundle.mainBundle().loadNibNamed("MarkerWindowView", owner: self, options: nil).first! as! MarkerWindowView
//println(newView.description)
newView.userName.text = "Kazuma"
newView.videoLocation.text = "Harvard"
newView.tags.text = "Kazuma is crazy"
//view.bringSubviewToFront(newView)
//view.insertSubview(newView, atIndex: 0)
//newView.userInteractionEnabled = true
/*for subView in self.view.subviews {
println(subView)
}*/
//view.bringSubviewToFront(newView)
return newView
}
I have tried a bunch of stuff to try to interact with this view including shifting views in the stack, moving layers etc. Has anyone had this problem before? Any idea what I'm doing wrong. The stuff I commented out is mostly me trying to hack it.
A custom info window is rendered as an UIImage, so you cannot interact with anything on it. I had a similar problem, and ended up making the entire window one "button" that caused an embed segue to push a view over the map, giving me details (think Yelp app style).
My info window was contained in a separate .xib. Here is some code in my GMSMapViewDelegate:
func mapView(mapView: GMSMapView!, didTapInfoWindowOfMarker marker: GMSMarker!)
{
ShowDetailView(mapMarkerManager!.GetMapMarker(marker)!)
}
func mapView(mapView: GMSMapView!, markerInfoWindow marker: GMSMarker!) -> UIView!
{
let markerInfoWindow = UINib(nibName: "MarkerInfoPopup", bundle: nil).instantiateWithOwner(nil, options: nil)[0] as! MarkerInfoPopup
markerInfoWindow.setValues(mapMarkerManager!.GetMapMarker(marker)!)
return markerInfoWindow
}
private func ShowDetailView(mapMarker: MapMarker)
{
delegate!.SetMapMarker(self, mapMarker: mapMarker)
self.view.bringSubviewToFront(mapDetailView)
mapDetailView.hidden = false
mapView.hidden = true
BackToMapButton.hidden = false
}
(mapMarker is more or less a GMSMarker wrapper. It does other stuff but is not important in this context)
I know this isn't exactly what you wanted, but unfortunately there aren't many options when using Google Maps' built in markerInfoWindow/didTapInfoWindowOfMarker.
Reference: https://developers.google.com/maps/documentation/ios-sdk/marker?hl=en#info_windows
"Note: The info window is rendered as an image each time it is displayed on the map. This means that any changes to its properties while it is active will not be immediately visible. The contents of the info window will be refreshed the next time that it is displayed."

Resources