Swift: Segue to another view when Map View is tapped - swift

I would like to perform a segue to another view once a map view is tapped like when you check a location and tap on map on instagram, or like in foursquare.
I could not connect map view itself to another view directly like we do in buttons, and I don't want to perform segue when callout button is tapped.
I found a workaround by placing an invisible button into mapView, and performing segue when the button is tapped(user thinks mapView is tapped)
But I would like to know if there is a better solution for it, without a button.

You can use UITapGestureRecognizer
let gestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(self.tapHandler(_:)))
mapView.addGestureRecognizer(gestureRecognizer)
#objc func tapHandler(_ gestureReconizer: UIGestureRecognizer) {
// let location = gestureReconizer.location(in: mapView)
// coordinatte of taplocation
// let coordinate = mapView.convert(location,toCoordinateFrom: mapView)
// **you can navigate or perform Your Actions there**
}

Related

How can I load a website by clicking a UIImage View?

I have created a UI Image view. Is it possible for the user to click on the UI Image view and have the link pop up? If so how would I go about incorporating that? I was thinking possibly through my View Controller using Touches Began and then specifically with a tag, but I'm using Swift's Game View Controller so the Touches Began function is not working properly and won't allow me to convert my SKNODE to Game View Controller type. Any suggestions on how you would do this? Thanks
You are going to want to look at UITapGestureRecognizer. Here is an example below.
if let imageView = yourImageView {
let tap = UITapGestureRecognizer(target: self, action: #selector(self.openLink(_:)))
imageView.addGestureRecognizer(tap)
}
Here is a link if you are also wondering how to open a link in safari.
Swift Open Link in Safari
I just used a gesture recognizer and it worked perfectly
Check out this :
let recognizer = UITapGestureRecognizer(target: self, action: #selector(webViewTapped))
recognizer.delegate = self
webView.addGestureRecognizer(recognizer)
and :
#objc func webViewTapped(_ recognizer: UITapGestureRecognizer) {
if let selectedWebView = recognizer.view as? WKWebView {
selectWebView(selectedWebView)
}
}
func selectWebView(_ webView: WKWebView) {
activeWebView = webView
updateUI(for: webView)
}

#IBSegueAction with condition

In my app I want to perform a segue based on a UITapGestureRecognizer. In case the tap is in the top area of the screen, a segue to the SettingsView should be performed.
In UIKit this was quite simple. I've triggered the performSegue in the UITapGestureRecognizer by wrapping it in an if-statement.
Now I would like to write the SettingsView() in SwiftUI. The SettingsView() will be embedded in a UIHostingController.
My question is:
How can I perform the segue to this UIHostingController (while telling the UIHostingController which View to display)?
I tried to use the new #IBSegueAction. The reason to use this #IBSegueAction is that I can use it to tell the UIHostingController which View to display. The problem is that I can't insert a condition now. Wherever the tap is on the screen, the segue is performed. I haven't found a way to cancel the segue in #IBSegueAction.
My code currently looks like this:
#IBSegueAction func showSettingsHostingControler(_ coder: NSCoder, sender: UITapGestureRecognizer, segueIdentifier: String?) -> UIViewController? {
let location = sender.location(in: self.tableView)
if let _ = self.tableView.indexPathForRow(at: location) {
return nil
} else {
if location.y < 32 {
if location.x < view.bounds.midX {
direction = .left
} else {
direction = .right
}
return UIHostingController(coder: coder, rootView: SettingsView())
}
}
return nil
}
The result currently is that the app segues to a non-existing Nil-view when the tap is in the wrong area.
based on a UITapGestureRecognizer. In case the tap is in the top area of the screen
It sounds to me like your tap gesture recognizer is attached to the wrong view. There should not be any decision to make here. Position a view in the top area of the screen and attach the tap gesture recognizer to that. That way, if this view gets a tap, there is no decision to be made: the tap is in the right place.

How can I have a button and scroll view in the same spot?

To build context, my app has a stack of cards (similar to Tinder) that flip and each could contain a lot of text on one side that require a UITextView for scrolling. It's basically a flashcard app, so once the user is done looking at the card, they swipe it away to view the next one.
I'm trying to make it so the user can tap anywhere on the card to flip it, so I added a clear button that fills up the card. My problem is that when the button is at the front, it blocks the text view from being scrollable, and when the button is at the back, the text view blocks it from being pressed.
Is there a way around this somehow to allow for both functionalities?
You can create a UITapGestureRecognizer, like so:
let gesture = UITapGestureRecognizer(target: self, action: #selector(tap(gesture:)))
addGestureRecognizer(gesture)
And the function to trigger:
#objc func tap(gesture: UITapGestureRecognizer) {
print("Tap!")
}
Maybe you can add a UITapGestureRecognizer to the text view itself. Something like:
let tapGesture = UITapGestureRecognizer(target: self, action: #selector(ViewController.didTap(_:)))
textView.addGestureRecognizer(tapGesture)
#objc func didTap(_ gesture: UITapGestureRecognizer) {
// Handle the tap
}
did you try a tableView or a collectionView, you can customize your cell to look like a card then when a user clicks the cell it will flip or present a popup view, thats easier.

How to call a function when the Compass Button of a mapView is pressed

I have developed an app showing a map view with a compass button. The natural function when pressing this compass button is that the map is being oriented to north.
Now I want to call a function when pressing this compass button.
A view of the app with a map can be found there (compass button is visible in the upper right corner)
http://aceingolf.com/wp-content/uploads/2018/12/0.jpg
The code below is working fine. It is just shown to give a complete view.
#IBOutlet weak var mapView: MKMapView!
let compassButton = MKCompassButton(mapView: mapView)
compassButton.compassVisibility = .visible
mapView.addSubview(compassButton)
I am looking for a way to create an action when the user presses the compass button on the map view.
I believe MKCompassButton inherits from UIView, So you can just add a UITapGestureRecognizer to the compassButton with an action like following:
let tapGestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(handleCompassTap))
compassButton.addGestureRecognizer(tapGestureRecognizer)
#objc func handleCompassTap() {
// Implement your feature when the compass button tapped.
}
Take emrepuns code
let tapGestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(handleCompassTap))
compassButton.addGestureRecognizer(tapGestureRecognizer)
#objc func handleCompassTap() {
// Implement your feature when the compass button tapped.
}
and add this line
tapGestureRecognizer.numberOfTouchesRequired = 1
or
tapGestureRecognizer.numberOfTapsRequired = 1

Deselect table cell when clicking away. Swift

I have the below table view but I want to be able to deselect the target cell when I click off to the side onto my view controller. I checked about using the deselect row at index path but not sure if theres a way to trigger that by clicking off to the side.
]
When you click off your table view, some event handler must be triggered in order for you to do a row deselection. So if the rest of your view controller is a static without user interaction, you can simply place a transparent UIView over the rest of your view controller and do deselect like this:
let gesture = UITapGestureRecognizer(target: self, action: #selector (self.checkAction(sender:)))
self.YourTransparentView.addGestureRecognizer(gesture)
func checkAction(sender : UITapGestureRecognizer) {
if let indexPath = self.tableView.indexPathForSelectedRow{
self.tableView.deselectRow(at: indexPath, animated: true)
}
}