Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 5 years ago.
Improve this question
i have a project done with maps using Open Street Map in xcode mapkit i already added there map and created a polyline, polygon, markers with popups.
i have remaining two parts to do one is to add zoom buttons to map
second one is i need to add a onclick event when i touch somewhere in the map place on the map i need to show a
popup event showing "hey u touch this lat,long".
i used several ways doing researches but i could not archive my goal
First you need add a UITapGestureRecognizer to your MKMapView in your viewDidLoad method
like this
let tapGestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(self.showPopup(tapGesture:)))
self.mapView.addGestureRecognizer(tapGestureRecognizer)
after that you need to implement the Tap selector method, the main issue you will found is get the real location based on the touch screen coordinates your can do that using the MKMapView convert method
like this
let coordinate = self.mapView.convert(tapGesture.location(in: self.mapView), toCoordinateFrom: self.mapView) //here we convert touch location from Screen location to map coordinates
Your full code for show an alert popup with coordinates touched
func showPopup(tapGesture:UITapGestureRecognizer)
{
let coordinate = self.mapView.convert(tapGesture.location(in: self.mapView), toCoordinateFrom: self.mapView)
let alertViewController = UIAlertController(title: "TOUCH IN MAP", message: "coordinate is lat: \(coordinate.latitude) long: \(coordinate.longitude)", preferredStyle: .alert)
let action = UIAlertAction(title: "Accept", style: .destructive, handler: nil)
alertViewController.addAction(action)
self.present(alertViewController, animated: true, completion: nil)
}
Related
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 2 years ago.
Improve this question
In iOS 14, when I set up an AVPlayerViewController, and set the player's delegate, if I press the home button on an iPhone, the delegate function playerViewControllerDidStartPictureInPicture gets called and I can see the PiP on the phone's home screen. However, in the same app, if I press the home button on an iPad, that delegate method does not get called, and PiP doesn't start.
Is there anything I could possibly be missing? Is there a way to programmatically activate PiP? The goal is to show PiP on iPad when the user presses the home button.
This is what the code looks like:
let videoURL = URL(string: url)!
let player = AVPlayer(url: videoURL)
playerView = AVPlayerViewController()
guard let playerView = playerView else { return }
playerView.player = player
playerView.delegate = self
playerView.allowsPictureInPicturePlayback = true
I've been working on an app to annotate an MKMapView with all nightlife locations near a user. I have implemented a recenter function that is called by a SwiftUI button. The recenter works fine based on CLLocationManager.location, but after any MKLocalSearch query, the setRegion stops working. It must be the setRegion because the correct lat/long are still printed. I also know it is not due to the annotations because the same bug happens when the annotation add/remove part is commented out. Does it possibly have something to do with linking the searchRequest.region and map.region? manager is the CLLocationManager instance, map is the MapView
func recenter(){
print("Recenter called")
guard let center = manager.location?.coordinate else{
print("Could not get location for recenter")
return
}
let newRegion = MKCoordinateRegion(center: center, latitudinalMeters: 1000, longitudinalMeters: 1000)
print("\(center.latitude) and \(center.longitude)")
map.setRegion(newRegion, animated: true)
}
func queryAndAnnotate(){
let searchRequest = MKLocalSearch.Request()
searchRequest.naturalLanguageQuery = "nightlife"
searchRequest.region = map.region
let search = MKLocalSearch(request: searchRequest)
search.start{response, error in
guard let response = response else {
Alert(title:Text("Alert"), message: Text("Error: \(error?.localizedDescription ?? "Unknown Error")"))
return
}
var mapItemPlacemarks: [MKPointAnnotation] = []
self.barsList = []
for i in response.mapItems{
let x = MKPointAnnotation()
x.coordinate = i.placemark.coordinate
x.title = i.name
mapItemPlacemarks.append(x)
}
self.map.removeAnnotations(mapItemPlacemarks)
self.map.addAnnotations(mapItemPlacemarks)
}
}
MKLocalSearch.start calls the completionHandler in background task.
In this handler you are updating your mapView instance in background task.
Make sure to call all update methods of mapView in main task (removeAnnotations, addAnnotations, setRegion)
btw in
self.map.removeAnnotations(mapItemPlacemarks)
self.map.addAnnotations(mapItemPlacemarks)
you are removing mapItemPlacemarks that do not exist in the mapView. This makes no sense, but it is not your problem.
As it turns out the problem was coming from a dynamic update to a ScrollView. The ScrollView was within a slide up drawer that sat above the MapView on the Z axis. When the ScrollView was updated with the results from the local search, the MapView object lost track of userLocation (read 0,0) and the region could not be programmatically changed. I ended up fixing the problem by ditching the recenter() function altogether and instead implementing an MKUserTrackingButton within its own UIViewRepresentable (for SwiftUI). The MKUserTrackingButton is how the system maps cycles through user tracking modes. You can read the docs for it here: https://developer.apple.com/documentation/mapkit/mkusertrackingbutton
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 4 years ago.
Improve this question
I have cloudkit records that are downloaded, each with a location property (lat & long). When I set each record to my MKAnnotation Class in a for loop, a CLLocationCoordinate2D property, and run... I receive the error as the title states.
This is what I receive -
Why am I even dealing with an NSValue property? I only have coordinates in my class and CkRecord.
let location = res.value(forKey: "Location")
print("RUN PLEASE")
self.pin = AnnotationPin(title: res.value(forKey: "Name") as! String, subtitle: "Address", theCoordinates: location as! CLLocationCoordinate2D, theWeb: "https://google.com")
CLLocation and CLLocationCoordinate2D are different types which are not related. However CLLocation has a coordinate property.
Cast location to CLLocation and use coordinate
let location = res.value(forKey: "Location") as! CLLocation
self.pin = AnnotationPin(title: res.value(forKey: "Name") as! String,
subtitle: "Address",
theCoordinates: location.coordinate,
theWeb: "https://google.com")
i am using a QRCode-Scanner and when the scanner does scan it checks if the location given inside the QRCode is close to my current location. If so you are able to proceed if not its giving an error message. So far so good. But the problem is when i try to scan a second QRCode with a different location it still compares my current location to the location of the previously scanned QRCode.
Here is what i have done so far:
This is the Geocoding part:
CLGeocoder().geocodeAddressString(self.qrbaradresse, completionHandler: { (placemarks, error) -> Void in
if let placemark = placemarks?[0] {
let location = placemark.location
self.distanceCondition(locat: location!)
}
}
Then it goes into the distanceCondition function:
func distanceCondition (locat: CLLocation){
print(locat, "LOCAT")
self.distancebar = (self.locationManager.location?.distance(from: locat))!
print (distancebar, " entfernung")
let distanceint = Int(distancebar)
if distanceint < 50 {
let alert = UIAlertController(title: "Erfolgreich", message: "Du bist bei \(self.qrbarname)!", preferredStyle: .alert)
alert.addAction(UIAlertAction(title: "Weiter", style: .default, handler:{ (action) in self.performSegue(withIdentifier: "scansegue", sender: self)}))
self.present(alert, animated: true, completion: nil)
}else{
Inside the first line of the func distanceCondition im always printing the location that has been used for the distance check. And it is always the very first code that got scanned. The variable location doesn't ever change. So to make my point clear. I want to know how can i delete placemarks[0] and replace it with the new address.
Everytime a code gets scanned it gets added to the array placemarks but im always checking the array placemarks at position 0 and the variable location always remains the same. But how can i replace the new scanned address with the one in position 0 of the array placemarks ?
Ty !
Check and see if you are updating self.qrbaradresse when you scanning a new QR code. You should be getting a new CLPlacemark array for every call to geocodeAddressString.
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 8 years ago.
Improve this question
I'm quite new to Swift and iOS programming, and I was wondering how I would set up a Game Center leaderboard, add players' scores to the leaderboard and update players' scores using Swift.
If you Google how to set up Game Center, you should find some tutorials that will help you, they are a little out of date with iOS 8 so below are the bits that aren't so easy to translate over.
Authenticating a player
let lp = GKLocalPlayer.localPlayer()
if lp.authenticated == false {
lp.authenticateHandler() { (vc, error) -> Void in
println(error)
}
}
Add score to leader board
leaderboardName = "My first game"
let scoreObj = GKScore(leaderboardIdentifier: leadeboardName)
scoreObj.context = 0
scoreObj.value = score
GKScore.reportScores([scoreObj], withCompletionHandler: {(error) -> Void in
let alert = UIAlertView(title: "Success",
message: "Score updated",
delegate: self,
cancelButtonTitle: "Ok")
alert.show()
})