Later, when I'm not so deep in other code, I might can make a sample program that demonstrates the problem. But for now, I'll just try to explain it better.
- I instantiate my StrokeGestureRecognizer, which subclasses UIGestureRecognizer, when the user raises the pencils to go into edit mode.
- I add it to my MapView, which is a subclass of AGSMapView.
- When the user begins a stroke, triggering strokeGestureRecognizer, the following action is called:
func strokeUpdated(_ strokeRecognizer: StrokeGestureRecognizer) {
let workingStroke: WorkingStroke?
if strokeRecognizer.state != .cancelled {
workingStroke = strokeRecognizer.workingStroke
if strokeRecognizer.state == .began ||
(strokeRecognizer.state == .ended && mapViewModel.activeWorkingStroke.value == nil) {
mapViewModel.activeWorkingStroke.value = workingStroke
}
} else {
workingStroke = nil
mapViewModel.activeWorkingStroke.value = nil
}
if let workingStroke = workingStroke {
if strokeRecognizer.state == .ended {
if strokeRecognizer.isForApplePencil {
workingStroke.receivedAllNeededUpdatesBlock = { [weak self] in
self?.mapView.sketchView.setNeedsDisplay(for: workingStroke)
workingStroke.clearUpdateInfo()
}
}
mapViewModel.takeActiveWorkingStroke(mapView: mapView)
mapViewModel.activeWorkingStroke.value = nil
}
}
if let activeWorkingStroke = mapViewModel.activeWorkingStroke.value {
mapView.sketchView.setNeedsDisplay(for: activeWorkingStroke)
}
}
We want to disable map interaction only if the user is making a stroke. On Line 7 above, activeWorkingStroke is instantiated so it can begin taking touch samples. In the view controller, an observer is triggered whenever activeWorkingStroke changes:
mapViewModel.activeWorkingStroke.asObservable()
.subscribe(onNext: { [weak self] activeWorkingStroke in
if activeWorkingStroke == nil {
self?.mapView.interaction(isEnabled: true)
} else {
self?.mapView.interaction(isEnabled: false)
}
})
The following is the version of my MapView member function that used to work:
func interaction(isEnabled: Bool) {
self.interactionOptions.isEnabled = isEnabled
}
But somewhere along the way, it stopped working. Xcode, iOS and AGS have each gone through some recent updates so It is hard to say exactly when this problem began. The following is how I fixed it:
func interaction(isEnabled: Bool) {
self.interactionOptions.isEnabled = isEnabled
guard let gestureRecognizers = gestureRecognizers else { return }
for gestureRecognizer in gestureRecognizers {
if let panGestureRecognizer = gestureRecognizer as? UIPanGestureRecognizer {
panGestureRecognizer.isEnabled = isEnabled
} else if let pinchGestureRecognizer = gestureRecognizer as? UIPinchGestureRecognizer {
pinchGestureRecognizer.isEnabled = isEnabled
} else if let rotationGestureRecognizer = gestureRecognizer as? UIRotationGestureRecognizer {
rotationGestureRecognizer.isEnabled = isEnabled
}
}
}
My gesture recognizer, strokeGestureRecognizer, is added to the mapView object, the same object where all the AGS gesture recognizers reside. Is it possible my gesture recognizer has tripped up some code somewhere that assumes all the gesture recognizers are Esri's? Or, perhaps it is something Apple did that is tripping both of us up. When I get a chance, I'll verify the bug is still there by retrying the old interaction(isEnabled:) function.
For now, I'm happy leaving my fix in place. I just wanted you all to know about the problem and, if nothing else, recheck your code to verify it still works as intended for more normal use cases.
Thanks for the help.