How to disable Google Maps SDK double tap zooming (but not pinch zooming) in iOS SDK?
Thank You
For Swift 2.1
You can do this on your GMSMapView object,
mapView.settings.zoomGestures = false
Same goes for disabling tilt gesture, rotate gesture, scroll gestures,
mapView.settings.tiltGestures = false
mapView.settings.rotateGestures = false
mapView.settings.scrollGestures = false
Read more here: https://developers.google.com/maps/documentation/ios-sdk/controls#map_gestures
Unfortunately there is no way to disable double tap zoom while still keeping pinch zoom gestures. (I could be wrong, but I have went through their docs and haven't found a way to do so)
try this :
[googleMapView.settings setAllGesturesEnabled:NO];
install your own tapgesturerecognizer and make it receive double taps. that way it won't be given to the google map.
put this in controller
/// this gesture will disable zoom gesture temporarily
var tmpDisableZoom: UITapGestureRecognizer!
/// how long you want to lock
let lockDoubleTapTimeDelay = 0.3
/// finally unlock time
var unlockDoubleTapTime = Date().timeIntervalSince1970
override func viewDidLoad() {
mapView.settings.consumesGesturesInView = false
tmpDisableZoom = UITapGestureRecognizer(target: self, action: #selector(removeZoomGesturesTemporarily))
tmpDisableZoom.numberOfTapsRequired = 1
}
#objc func removeZoomGesturesTemporarily(sender:UIGestureRecognizer){
mapView.settings.zoomGestures = false
unlockDoubleTapTime = Date().timeIntervalSince1970
DispatchQueue.main.asyncAfter(deadline: .now() + lockDoubleTapTimeDelay) { [weak self] in
guard self != nil else {return}
let timeNow = Date().timeIntervalSince1970
if timeNow - self!.unlockDoubleTapTime > self!.lockDoubleTapTimeDelay{
self!.mapView.settings.zoomGestures = true
}
}
}
Related
I'm trying to add UILongPressGesture to the cell. It is working but only when I long press and move in any direction.
It should call the selector method on long press but it is calling when I long press and started to move. I'm also handling the state of the gesture but selector is not calling until I long press and start moving.
I have also tried with adding gesture to cell's content view and its UIlable element, but no luck.
let longPressGesture: UILongPressGestureRecognizer = {
let gesture = UILongPressGestureRecognizer()
gesture.addTarget(self, action: #selector(MyViewController.handleLongPressGetureForRow(_:)))
gesture.delaysTouchesBegan = false
gesture.cancelsTouchesInView = false
gesture.numberOfTouchesRequired = 1
gesture.minimumPressDuration = 0.2
return gesture
}()
cell.addGestureRecognizer(longPressGesture)
cell.tag = indexPath.row
Cells where adding gesture
Please help me. Thanks in advance.
Instead of handleLongPressGetureForRow(_:) change to self.handleLongPressGetureForRow(v:) with #objc before func
let longPressGesture: UILongPressGestureRecognizer = {
let gesture = UILongPressGestureRecognizer()
gesture.addTarget(self, action: #selector(self.handleLongPressGetureForRow(v:)))
gesture.delaysTouchesBegan = false
gesture.cancelsTouchesInView = false
gesture.numberOfTouchesRequired = 1
gesture.minimumPressDuration = 0.2
return gesture
}()
cell.addGestureRecognizer(longPressGesture)
cell.tag = indexPath.row
return cell
}
#objc func handleLongPressGetureForRow(v: UILongPressGestureRecognizer )
{
print("saghsaghghsgfsgsaghghsaghsaghghsaghashgsasa")
}
I want to move the UISlider knob to the middle, or 0.0 value in my case, when the double tap event is occurred on it.
Knob is moving to 0.0 on double tap but immediately it resume to the old position/value.
I have tried the below code. Any help would be much appreciated.
override func viewDidLoad() {
super.viewDidLoad()
let eqSlider = UISlider(frame:CGRectMake(0, 0, 160, 40))
eqSlider.minimumValue = -12.0
eqSlider.maximumValue = 12.0
eqSlider.value = 0.0
self.view.addSubview(eqSlider)
// detecting double tap on slider method
eqSlider.addTarget(self, action: #selector(EQViewController.doubleTappedSlider(_:event:)), forControlEvents: .TouchDownRepeat)
}
func doubleTappedSlider(sender: UISlider, event: UIEvent) {
if let firstTouchObj = event.allTouches()?.first {
if 2 == firstTouchObj.tapCount {
sender.value = 0.0
}
}
}
The problem is that the two taps in your double tap will also be acted upon by the slider itself, so after you set its position manually, the user is setting it straight back.
To avoid this, you can add the following line after you set the .value:
sender.cancelTracking(with: nil)
This will "cancel any ongoing tracking" as stated in the documentation.
I am creating a simple point annotation with a callout inside the UITapGestureRecognizer delegate.
The first time I tap on the map, the pin appears with the callout but the callout immediately disappears after that.
The second time I tap on the same pin, the callout appears and stays there, not sure why it disappears at the first time.
#IBAction func handleMapTouch(recognizer: UITapGestureRecognizer){
let view = recognizer.view
let touchPoint=recognizer.locationInView(view)
var touchCord=CLLocationCoordinate2D()
touchCord = mapView.convertPoint(touchPoint, toCoordinateFromView:
mapView)
mapView.removeAnnotations(mapView.annotations)
pointAnnotation.coordinate=touchCord
pointAnnotation.title="ABC"
pointAnnotation.subtitle="DEF"
mapView.addAnnotation(pointAnnotation)
mapView.selectAnnotation(pointAnnotation, animated: true)
}
Just in case someone else has the same problem, although Keith's answer works, in my case it disrupts other gestures associated to the map, like pinch and zoom.
For me, delaying some milliseconds the action of showing the callout worked better.
In Swift 3:
let deadlineTime = DispatchTime.now() + .milliseconds(500)
DispatchQueue.main.asyncAfter(deadline: deadlineTime) {
mapView.addAnnotation(pointAnnotation)
mapView.selectAnnotation(pointAnnotation, animated: true)
}
I have the same problem. I don't know how to solve it, either, but I found a workaround. Maybe it can help you too.
I used LongPressGesture to replace TapGesture
In Viewdidload:
let longPress = UILongPressGestureRecognizer(target: self, action: "addAnnotation:")
longPress.minimumPressDuration = 0.1
self.mapView.addGestureRecognizer(longPress)
In function addAnnotation:
if(gestureRecognizer.state == .Ended){
self.mapView.removeGestureRecognizer(gestureRecognizer)
//remove all annotation on the map
self.mapView.removeAnnotations(self.mapView.annotations)
//convert point user tapped to coorinate
let touchPoint: CGPoint! = gestureRecognizer.locationInView(self.mapView)
let touchMapCoordinate: CLLocationCoordinate2D = self.mapView.convertPoint(touchPoint, toCoordinateFromView: self.mapView)
showCustomAnnotation(touchMapCoordinate)
}
self.mapView.addGestureRecognizer(gestureRecognizer)
Using shinobi charts
Looking for examples how to add gesture recognizers (on touch up) to Tick Marks and schart annoations
I see the documentation for interacting with a series data series, but I need to add GestureRecognizers to tick marks and annotation events
I tried this for the tickMark/datapoint labels with no luck:
func sChart(chart: ShinobiChart!, alterTickMark tickMark: SChartTickMark!, beforeAddingToAxis axis: SChartAxis!) {
if let label = tickMark.tickLabel {
//added a gesture recognizer here but it didn't work
}
For the SchartAnnotations no idea how to go about adding one there
I think you're nearly there with labels. I found I just needed to set userInteractionEnabled = true e.g.
func sChart(chart: ShinobiChart!, alterTickMark tickMark: SChartTickMark!, beforeAddingToAxis axis: SChartAxis!) {
if let label = tickMark.tickLabel {
let tapRecognizer = UITapGestureRecognizer(target: self, action: "labelTapped")
tapRecognizer.numberOfTapsRequired = 1
label.addGestureRecognizer(tapRecognizer)
label.userInteractionEnabled = true
}
}
Annotations are a little trickier, as they're on a view below SChartCanvasOverlay (responsible for listening for gestures). This results in the gestures being 'swallowed' before they get to the annotation.
It is possible however, but you'll need to add a UITapGestureRecognizer to your chart and then loop through the chart's annotations to check whether the touch point was inside an annotation. E.g.:
In viewDidLoad:
let chartTapRecognizer = UITapGestureRecognizer(target: self, action: "annotationTapped:")
chartTapRecognizer.numberOfTapsRequired = 1
chart.addGestureRecognizer(chartTapRecognizer)
And then the annotationTapped function:
func annotationTapped(recognizer: UITapGestureRecognizer) {
var touchPoint: CGPoint?
// Grab the first annotation so we can grab its superview for later use
if let firstAnnotation = chart.getAnnotations().first as? UIView {
// Convert touch point to position on annotation's superview
let glView = firstAnnotation.superview!
touchPoint = recognizer.locationInView(glView)
}
if let touchPoint = touchPoint {
// Loop through the annotations
for item in chart.getAnnotations() {
let annotation: SChartAnnotation = item as SChartAnnotation
if (CGRectContainsPoint(annotation.frame, touchPoint as CGPoint)) {
chart.removeAnnotation(annotation)
}
}
}
}
Does anyone know a way to temporarily turn off zooming when using a UIScrollView?
I see that you can disable scrolling using the following:
self.scrollView.scrollEnabled = false;
but I'm not seeing a similar command for zooming. Any thoughts?
If you want to disable the user's ability to zoom through gestures then in iOS 5 and above you can disable the pinch gesture. This still allows you to control the scroll view from code...
scrollView.pinchGestureRecognizer.enabled = NO;
similarly for pan...
scrollView.panGestureRecognizer.enabled = NO;
This must be called in - (void)viewDidAppear:(BOOL)animated or later as otherwise the system resets it to enabled.
Swift 4.x and above:
imageZoomView.pinchGestureRecognizer?.isEnabled = false / true
Following fbrereto's advice above, I created two functions lockZoom and unlockZoom. When locking Zoom i copied my max and min zoom scales to variables then set the max and min zoom scale to 1.0. Unlocking zoom just reverses the process.
-(void)lockZoom
{
maximumZoomScale = self.scrollView.maximumZoomScale;
minimumZoomScale = self.scrollView.minimumZoomScale;
self.scrollView.maximumZoomScale = 1.0;
self.scrollView.minimumZoomScale = 1.0;
}
-(void)unlockZoom
{
self.scrollView.maximumZoomScale = maximumZoomScale;
self.scrollView.minimumZoomScale = minimumZoomScale;
}
Also you can return "nil" as zooming view in UIScrollViewDelegate:
- (UIView *) viewForZoomingInScrollView:(UIScrollView *) scrollView
{
return canZoom?view:nil;
}
Check setting minimumZoomScale and maximumZoomScale; According to the docs:
maximumZoomScale must be greater than minimumZoomScale for zooming to be enabled.
So, setting the values to be the same should disable zooming.
I have tried setting minimumZoomScale and maximumZoomScale properties of UIScrollView to 1 or isMultipleTouchEnabled property of UIView to false or return nil from viewForZooming(in:) of UIScrollViewDelegate but none worked. In my case, after several trial and error, the following works in my case [Tested on iOS 10.3]:
class MyViewController: UIViewController {
var webView: WKWebView?
override viewDidLoad() {
super.viewDidLoad()
//...
self.webView.scrollView.delegate = self
//...
}
}
extension MyViewController: UIScrollViewDelegate {
func scrollViewWillBeginZooming(_ scrollView: UIScrollView, with view: UIView?) {
scrollView.pinchGestureRecognizer?.isEnabled = false
}
}
I know this is a really old question but I made a slight variation for my purposes.
I wanted to be able to easily tell if the zooming was in fact enabled/disabled without relying on a comparison between scrollView.minimumZoomScale == scrollView.maximumZoomScale, which could possibly not reflect whether zooming was actually enabled/disabled.
So I did this
// .h
#property (assign, nonatomic, getter=isZoomEnabled) BOOL zoomEnabled;
// .m
#synthesize zoomEnabled = _zoomEnabled;
- (void)setZoomEnabled:(BOOL)zoomEnabled;
{
_zoomEnabled = zoomEnabled;
UIScrollView *scrollView = self.scrollView;
if (zoomEnabled) {
scrollView.minimumZoomScale = self.minimumZoomScale;
scrollView.maximumZoomScale = self.maximumZoomScale;
} else {
scrollView.minimumZoomScale = 0.0f;
scrollView.maximumZoomScale = 0.0f;
}
}
The values for self.minimumZoomScale and self.maximumZoomScale are set at the time the UIScrollView is configured.
This gives me the ability to set/ask if zooming is enabled.
myViewController.zoomEnabled = YES;
myViewController.isZoomEnabled;
here, my solution for stop zooming on scrollview.
self.scrollView.minimumZoomScale=self.scrollView.maximumZoomScale;
Swift 3 Version:
func lockScrollViewZooming() {
scrollView.minimumZoomScale = 1.0
scrollView.maximumZoomScale = 1.0
scrollView.bounces = false
scrollView.bouncesZoom = false
// Also, if you have double tap recognizer,
// remember to remove it
scrollView.removeGestureRecognizer(doubleTapGestureRecognizer)
}
func unlockScrollViewZooming() {
scrollView.minimumZoomScale = 1.0
scrollView.maximumZoomScale = 4.0
scrollView.bounces = true
scrollView.bouncesZoom = true
// Also, if you have double tap recognizer,
// remember to add it
scrollView.removeGestureRecognizer(doubleTapGestureRecognizer)
}
Note that doubleTapGestureRecognizer should be an instance variable. It should be similar to:
private lazy var doubleTapGestureRecognizer: UITapGestureRecognizer = {
let doubleTapGestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(handleDoubleTap(_:)))
doubleTapGestureRecognizer.numberOfTapsRequired = 2
doubleTapGestureRecognizer.delegate = self
return doubleTapGestureRecognizer
}()
#objc private func handleDoubleTap(_ recognizer: UITapGestureRecognizer) {
//scrollView.setZoomScale((scrollView.zoomScale > scrollView.minimumZoomScale) ? scrollView.minimumZoomScale : scrollView.maximumZoomScale, animated: true)
if scrollView.zoomScale > scrollView.minimumZoomScale {
scrollView.setZoomScale(scrollView.minimumZoomScale, animated: true)
} else {
let touchLocation = recognizer.location(in: recognizer.view)
scrollView.zoom(to: CGRect(origin: touchLocation, size: CGSize(width: 22.0, height: 20.0)), animated: true)
}
}
You need to turn off Two Fingers and Double Tap of scroll view
self.scrollView.delegate = self
And
extension YourViewController: UIScrollViewDelegate {
func scrollViewWillBeginZooming(_ scrollView: UIScrollView, with view: UIView?) {
scrollView.pinchGestureRecognizer?.isEnabled = false
}
func viewForZooming(in scrollView: UIScrollView) -> UIView? {
return nil
}
}
If you want to disable only zooming with pinch gesture, below code does the trick.
scrollView.pinchGestureRecognizer?.requireGestureRecognizerToFail(scrollView.panGestureRecognizer)