Skip to content
This repository has been archived by the owner on Aug 8, 2023. It is now read-only.

[ios] Disable/enable related gesture recognizer when disabling/enabling user interactivity. #8304

Merged
merged 1 commit into from
Apr 11, 2017

Conversation

davidchiles
Copy link
Contributor

Fixes #7217

Added an example behavior of MGLMapView as a subview of UIScrollView in
iOS app.

@mention-bot
Copy link

@davidchiles, thanks for your PR! By analyzing this pull request, we identified @incanus, @1ec5 and @boundsj to be potential reviewers.

@1ec5 1ec5 added the iOS Mapbox Maps SDK for iOS label Mar 7, 2017
@boundsj boundsj requested review from incanus, friedbunny and 1ec5 March 7, 2017 23:44
@boundsj
Copy link
Contributor

boundsj commented Mar 7, 2017

Thanks! I think this is a good implementation of the suggestion in #7217 (comment) to fully disable gesture recognizers instead of short circuiting their handlers. When they are disabled, then containing view recognizers (like a UIScrollView) work as expected (as illustrated by the new demo in the iosapp in this PR).

The full list is of gesture recognizers affected with this proposal are:

  • UIPanGestureRecognizer pan handled by handlePanGesture and guarded by isScrollEnabled
  • UIPanGestureRecognizer twoFingerDrag handled by handleTwoFingerDragGesture and guarded by isZoomEnabled
  • UIPinchGestureRecognizer pinch handled by handlePinchGesture and guarded by isZoomEnabled
  • UITapGestureRecognizer doubleTap handled by handleDoubleTapGesture and guarded by isZoomEnabled
  • UILongPressGestureRecognizer quickZoom handled by handleQuickZoomGesture and guarded by isZoomEnabled
  • UITapGestureRecognizer twoFingerTap handled by handleTwoFingerTapGesture and guarded by isPitchEnabled
  • UIRotationGestureRecognizer rotate handled by handleRotateGesture and guarded by isRotateEnabled

All of the handlers noted in this list have guards like if ( ! self.isScrollEnabled) return;. I think we can probably remove those now since the handler methods will never get called since the gesture recognizers are fully disabled.

cc @incanus @friedbunny @1ec5

Copy link
Contributor

@incanus incanus left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great addition and fixes! Just some critiques and typos I've called out, many of which are minor nitpicks but contribute to overall code quality.

MBXSettingsMiscellaneousPrintLogFile,
MBXSettingsMiscellaneousDeleteLogFile,
MBXSettingsMiscellaneousDeleteLogFile

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nix this space.

MBXSettingsMiscellaneousPrintLogFile,
MBXSettingsMiscellaneousDeleteLogFile,
MBXSettingsMiscellaneousDeleteLogFile
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Our internal style is to retain commas in these situations to make it easier to rearrange and add new entries.

@@ -350,6 +353,7 @@ - (void)dismissSettings:(__unused id)sender
@"Start World Tour",
[NSString stringWithFormat:@"%@ Custom User Dot", (_customUserLocationAnnnotationEnabled ? @"Disable" : @"Enable")],
[NSString stringWithFormat:@"%@ Zoom Level", (_showZoomLevelEnabled ? @"Hide" :@"Show")],
@"Embeded Map View"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Another trailing comma to add.

UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"Main" bundle:nil];
MBXEmbededMapViewController *embeddedMapViewController = (MBXEmbededMapViewController *)[storyboard instantiateViewControllerWithIdentifier:@"MBXEmbededMapViewController"];
[self.navigationController pushViewController:embeddedMapViewController animated:YES];

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remove blank line.

@property (nonatomic) UIPanGestureRecognizer *pan;
@property (nonatomic) UIPinchGestureRecognizer *pinch;
@property (nonatomic) UIRotationGestureRecognizer *rotate;
@property (nonatomic) UITapGestureRecognizer *doubleTap;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Keep the taps all together?

self.mapView.transform = CGAffineTransformRotate(rotationGesture.view.transform, rotationGesture.rotation);
}

- (void)switchContorl:(MBXEmbeddedControl) control {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Typo.

[self.view addSubview:stackView];
}

- (void)didSwitch:(UISwitch *)sw {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We always try to write out variable names.


//Create list of all the possible control titles
NSMutableArray <UIView*>*items = [[NSMutableArray alloc] init];
for(NSInteger index =0; index < 4; index++) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Consistent spacing.

};


@interface MBXEmbededMapViewController () <UIScrollViewDelegate>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Class name is misspelled: Embeded.

//
// Created by David Chiles on 3/7/17.
// Copyright © 2017 Mapbox. All rights reserved.
//
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remove comment header & personal identification.

davidchiles added a commit to davidchiles/mapbox-gl-native that referenced this pull request Mar 8, 2017
switchControl.tag = index;
[switchControl addTarget:self action:@selector(didSwitch:) forControlEvents:UIControlEventValueChanged];
switchControl.translatesAutoresizingMaskIntoConstraints = NO;
switchControl.on = [self statusForControl:index];
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The body of this for loop seems like a good candidate to break out into a separate method. Considering that there are only four switch controls in all, perhaps it makes sense to set each switch’s title explicitly, track them with separate properties, and hook them up to separate action methods. Someone theoretically adding a “Roll Enabled” switch (!) would have fewer methods to update.

[scrollView addGestureRecognizer:gestureRecognizer];

CGRect mapRect = CGRectMake(0, 0, CGRectGetWidth(scrollView.frame) * 2, CGRectGetHeight(scrollView.frame) * 2);
self.mapView = [[MGLMapView alloc] initWithFrame:mapRect];
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since the view controller itself is already defined in the storyboard, I wonder if it would make the demo clearer if we moved some of this setup to the storyboard as well. Then most of this class’s code would relate to the switches’ behavior instead of the layout code.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Aye, this is a bit awkward — let’s go one way or the other.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not very fluent in storyboard so I can just remove the view controller from there.

[scrollView addGestureRecognizer:gestureRecognizer];

CGRect mapRect = CGRectMake(0, 0, CGRectGetWidth(scrollView.frame) * 2, CGRectGetHeight(scrollView.frame) * 2);
self.mapView = [[MGLMapView alloc] initWithFrame:mapRect];
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Aye, this is a bit awkward — let’s go one way or the other.

[self.view addSubview:scrollView];
[scrollView addGestureRecognizer:gestureRecognizer];

CGRect mapRect = CGRectMake(0, 0, CGRectGetWidth(scrollView.frame) * 2, CGRectGetHeight(scrollView.frame) * 2);
Copy link
Contributor

@friedbunny friedbunny Mar 8, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I’m not following the purpose of a gigantic map within a scrollview — is this a common use case that we’re demoing? It seems like multiple smaller maps within a regular viewport frame (with only a vertical scroll axis) is a potential use case that would demonstrate these conditionally disabled gestures in a more straightforward way.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's true that #7217 demonstrated the need for only vertical (and perhaps horizontal) gesture overrides. However, the solution implemented in this PR technically allows for all possible UIScrollView gestures to function instead of the built in map view gestures. This demo may not be realistic but it is comprehensive and I don't think it would make sense to throw away the pinch and rotate parts in iosapp.

That said, a more realistic example in mapbox/ios-sdk-examples would be helpful, I think.

incanus
incanus previously requested changes Mar 8, 2017

@interface MBXEmbeddedMapViewController () <UIScrollViewDelegate>

@property (nonatomic, strong) MGLMapView *mapView;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Again, super minor, but strong is the default so can be left out.

{
switch (control) {
case MBXEmbeddedControlZoom:
return @"Zoom Enabled";
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Missing break?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A break isn’t needed after a return.

@@ -350,6 +352,7 @@ - (void)dismissSettings:(__unused id)sender
@"Start World Tour",
[NSString stringWithFormat:@"%@ Custom User Dot", (_customUserLocationAnnnotationEnabled ? @"Disable" : @"Enable")],
[NSString stringWithFormat:@"%@ Zoom Level", (_showZoomLevelEnabled ? @"Hide" :@"Show")],
@"Embeded Map View",
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Typo.

_pitchEnabled = pitchEnabled;
self.twoFingerDrag.enabled = pitchEnabled;
}

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Love these routines BTW. Great way to see what the setters impact across the view.

@friedbunny friedbunny dismissed their stale review March 9, 2017 18:23

🙆‍♂️

@boundsj boundsj added this to the ios-v3.6.0 milestone Mar 14, 2017
@boundsj
Copy link
Contributor

boundsj commented Mar 14, 2017

Adding this to the 3.6.0 milestone.

@boundsj boundsj assigned boundsj and unassigned davidchiles Mar 21, 2017
@boundsj boundsj added the bug label Mar 28, 2017
boundsj pushed a commit that referenced this pull request Apr 7, 2017
@boundsj boundsj force-pushed the 7217-disable-gesture-handlers branch from 96c81e9 to 2cefd09 Compare April 7, 2017 06:39
@boundsj
Copy link
Contributor

boundsj commented Apr 7, 2017

2cefd09 makes the changes suggested above. This includes moving all view setup boilerplate to the storyboard so the salient bits of the example are clearer.

cc @incanus @1ec5

@boundsj boundsj requested review from incanus and 1ec5 April 7, 2017 06:42
Copy link
Contributor

@1ec5 1ec5 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks!


self.scrollView.delegate = self;
self.scrollView.contentSize = CGSizeMake(CGRectGetWidth(self.view.bounds),
CGRectGetHeight(self.view.bounds));
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

self.view.bounds.size would have the same effect.

@boundsj boundsj force-pushed the 7217-disable-gesture-handlers branch from 6c7efef to 4999fc0 Compare April 10, 2017 20:08
@boundsj boundsj dismissed incanus’s stale review April 10, 2017 21:57

Comments have been addressed. Thanks!

@boundsj boundsj force-pushed the 7217-disable-gesture-handlers branch from 4999fc0 to 96d96d9 Compare April 10, 2017 22:07
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
bug iOS Mapbox Maps SDK for iOS
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants