Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

create a halo view for reduced accuracy in userCourseView #2664

Merged
merged 9 commits into from
Nov 12, 2020

Conversation

ShanMa1991
Copy link
Contributor

@ShanMa1991 ShanMa1991 commented Sep 29, 2020

Description

Goal

This pr will create a halo view for the iOS 14 reduced Accuracy during the navigation, similar to mapbox/mapbox-gl-native-ios#381. To solve the issue to fix #2555 following #2693

Implementation

This pr create a UserHaloCourseView similar to UserCourseView following the same protocol. Add a property in NavigationMapView to control the swift between the two views. Using the navigationServiceDidChangeAuthorization to set the value of the property.

Testing

The following screenshot shows the new halo view during navigation under reduced location accuracy.
haloView

/cc @mapbox/navigation-ios

@ShanMa1991 ShanMa1991 linked an issue Sep 29, 2020 that may be closed by this pull request
@ShanMa1991 ShanMa1991 self-assigned this Sep 29, 2020
@ShanMa1991 ShanMa1991 added feature New feature request. topic: location labels Sep 29, 2020
@ShanMa1991 ShanMa1991 added this to the v1.1.0 milestone Sep 29, 2020
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 for your patience as we explore the best approach to implement this halo feature. Based on our discussion earlier, let’s consider an architecture that’s less closely tied to the existing puck implementation.

@@ -56,8 +59,20 @@ public class UserPuckCourseView: UIView, CourseUpdatable {
let duration: TimeInterval = animated ? 1 : 0
UIView.animate(withDuration: duration, delay: 0, options: [.beginFromCurrentState, .curveLinear], animations: {
let angle = tracksUserCourse ? 0 : CLLocationDegrees(direction - location.course)
let dataSource = PassiveLocationDataSource()
let locationManager = PassiveLocationManager(dataSource: dataSource)
Copy link
Contributor

Choose a reason for hiding this comment

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

It makes sense that the map would need to show a different-looking puck depending on the accuracy authorization. However, it’s problematic to have the puck view create a location manager, which under the hood brings in a lot of other machinery around location tracking. Instead of making the view responsible for tracking the user’s location and authorization, let’s move this logic up a few levels:

  • NavigationMapView is contained inside RouteMapViewController, and a developer can also choose to use NavigationMapView independently within their own view controller. The view controller is the appropriate level at which to conditionalize the display based on location accuracy authorization, because it already has access to the location manager.
  • NavigationMapView itself can have a property that indicates whether to display a puck or a halo, and it can maintain a separate halo view property that’s an instance of a new UserHaloView class you create. NavigationMapView can show and hide userCourseView and userHaloView, alternating between the two.
  • UserHaloView can be an instance of CourseUpdatable but otherwise doesn’t need to implement everything that UserPuckCourseView does.
  • DayStyle and NightStyle can customize the UserHaloView separately, and it only needs to customize the properties that make sense, like the halo color, not puck-specific aspects like the arrow color.

This approach piggy-backs on the existing CourseUpdatable protocol that gives developers the ability to customize the puck’s appearance by providing a different implementation. Conceptually, the approximate location halo is an altogether different user location indicator than the normal one, so hopefully developers will find it intuitive that approximate location causes the map to switch to a different user location indicator automatically.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Thanks for the suggestion! I'll make the following change based on the suggestion.

  • remove the change in UserCourseView

  • create a new UserHaloView similar to UserCourseView

  • create a new property of the location accuracy in NavigationMapView to switch UserHaloView similar to UserCourseView

  • add judgement in RouteMapViewController to change the property of NavigationMapView's location accuracy

  • add the customize style of the UserHaloView in DayStyle and NightStyle

Copy link
Contributor

Choose a reason for hiding this comment

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

When it comes to NavigationViewController as per original ticket, it'd also make sense to show Weak GPS Signal in top banner.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yes. I'll talk with Jill about that, because the top banner also needs the judgement of the location accuracy. Thanks for the suggestion!

@@ -1,9 +1,9 @@
import UIKit
import Turf
import Mapbox
import MapboxCoreNavigation

let PuckSize: CGFloat = 45
Copy link
Contributor

Choose a reason for hiding this comment

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

I don't see that PuckSize is used anywhere, can probably be safely removed.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yes, I'll remove it.

@@ -56,8 +59,20 @@ public class UserPuckCourseView: UIView, CourseUpdatable {
let duration: TimeInterval = animated ? 1 : 0
UIView.animate(withDuration: duration, delay: 0, options: [.beginFromCurrentState, .curveLinear], animations: {
let angle = tracksUserCourse ? 0 : CLLocationDegrees(direction - location.course)
let dataSource = PassiveLocationDataSource()
let locationManager = PassiveLocationManager(dataSource: dataSource)
Copy link
Contributor

Choose a reason for hiding this comment

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

When it comes to NavigationViewController as per original ticket, it'd also make sense to show Weak GPS Signal in top banner.

@@ -146,6 +176,51 @@ public class UserPuckCourseView: UIView, CourseUpdatable {
}
}

class UserApproximateStyleKitView: UIView {
Copy link
Contributor

Choose a reason for hiding this comment

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

Please also make sure to run some tests with different use cases in active guidance: e.g. in Overview/Follow modes, different zoom levels, Day/Night styles, vanishing route line enabled/disabled.

Copy link
Contributor

Choose a reason for hiding this comment

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

Also when it comes to testing I also recommend moving to Xcode 12.0. Thanks to @1ec5 you can now easily build Carthage dependencies by running $ ./scripts/wcarthage.sh bootstrap --use-netrc --use-ssh --platform ios.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Thanks for the suggestion! I'll test the iOS14 with that.

@ShanMa1991 ShanMa1991 changed the base branch from master to main October 6, 2020 19:22
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.

Consider rebasing this PR branch against the main branch, to eliminate the non-linear history involving the master branch.

Comment on lines 125 to 126
self.userCourseView = reducedAccuracyActivatedMode ? UserHaloCourseView(frame: CGRect(origin: .zero, size: 75.0)) : UserPuckCourseView(frame: CGRect(origin: .zero, size: 75.0))
//TODO: add the weak gps connection banner below
Copy link
Contributor

Choose a reason for hiding this comment

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

#2693 will add the banner code to NavigationViewController at a spot where it’ll be convenient to set this property as well.

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 see. I'll rebase this branch and follow the #2693 to add the property setting value here.

@ShanMa1991 ShanMa1991 modified the milestones: v1.1.0, v1.2.0 Oct 16, 2020
@MaximAlien MaximAlien added iOS UI Work related to visual components, Android Auto, Camera, 3D, voice, etc. labels Oct 30, 2020
@ShanMa1991 ShanMa1991 force-pushed the shan-halo-reduced-accuracy-2555 branch from a1c546d to 79c7f11 Compare November 4, 2020 21:29
@ShanMa1991 ShanMa1991 requested review from 1ec5 and MaximAlien November 4, 2020 21:47
@ShanMa1991 ShanMa1991 marked this pull request as ready for review November 5, 2020 15:37
Comment on lines 2 to 3
import Turf
import Mapbox
Copy link
Contributor

Choose a reason for hiding this comment

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

I think neither Turf nor Mapbox are needed here.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Thanks for the suggestion! I'll remove the Turf and Mapbox

@@ -119,6 +119,11 @@ open class NavigationMapView: MGLMapView, UIGestureRecognizerDelegate {
@objc dynamic public var maneuverArrowStrokeColor: UIColor = .defaultManeuverArrowStroke
@objc dynamic public var buildingDefaultColor: UIColor = .defaultBuildingColor
@objc dynamic public var buildingHighlightColor: UIColor = .defaultBuildingHighlightColor
@objc dynamic public var reducedAccuracyActivatedMode: Bool = false {
Copy link
Contributor

Choose a reason for hiding this comment

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

Indentation can be improved here.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yes. I'll improve it!

/**
Transforms the location of the user puck.
*/
public func update(location: CLLocation, pitch: CGFloat, direction: CLLocationDegrees, animated: Bool, tracksUserCourse: Bool) {
Copy link
Contributor

Choose a reason for hiding this comment

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

As I can see this public method is present in UserPuckCourseView as well, but not called. Do we really need it?

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 think we need it. Because when the location accuracy changes, the user course view switches between UserPuckCourseView and UserHaloCourseView . Both of them follow the same protocol of CourseUpdatable, which has the update function to support the location and pitch change during the navigation.

}
}

@objc public dynamic var haloRingColor: UIColor = #colorLiteral(red: 0.149, green: 0.239, blue: 0.341, alpha: 0.3) {
Copy link
Contributor

Choose a reason for hiding this comment

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

Please add more descriptive comments for public properties. Indentation can also be improved for already existing comments.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Thanks for the suggestion! I'll improve this part!

haloView.backgroundColor = .clear
addSubview(haloView)

NotificationCenter.default.addObserver(self, selector: #selector(locationDidUpdate(_ :)), name: .routeControllerProgressDidChange, object: nil)
Copy link
Contributor

Choose a reason for hiding this comment

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

Is routeControllerProgressDidChange needed here? If not, can be probably removed.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Thanks for the suggestion, I'll remove the routeControllerProgressDidChange

drawHaloView()
}

//var opacity: CGFloat = 0.25
Copy link
Contributor

Choose a reason for hiding this comment

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

Please remove unused commented code.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Thanks for the suggestion, I've removed the unused code and comments.

@@ -309,6 +309,7 @@
AE87207E22CF97B900D7DAB7 /* InstructionsCardCollectionDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = AE87207D22CF97B900D7DAB7 /* InstructionsCardCollectionDelegate.swift */; };
AEC3AC9A2106703100A26F34 /* HighwayShield.swift in Sources */ = {isa = PBXBuildFile; fileRef = AEC3AC992106703100A26F34 /* HighwayShield.swift */; };
AED6285622CBE4CE00058A51 /* ViewController+GuidanceCards.swift in Sources */ = {isa = PBXBuildFile; fileRef = AED6285522CBE4CE00058A51 /* ViewController+GuidanceCards.swift */; };
B430D2FA25534FDC0088CC23 /* UserHaloCourseView.swift in Sources */ = {isa = PBXBuildFile; fileRef = B430D2F925534FDC0088CC23 /* UserHaloCourseView.swift */; };
Copy link
Contributor

Choose a reason for hiding this comment

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

As I can see in #2693 Enable precise location to navigate banner was added. Whenever we enable Precise Location banner disappears, but simulation banner is not present. @jill-cardamon, @1ec5 is it intentional? In my opinion it'd be a good idea to keep location simulation banner if Precise Location is switched on.

Copy link
Contributor

Choose a reason for hiding this comment

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

That was not intentional. To be clear, you mean the Simulating Navigation at 1x banner correct? There's some tail work to do for #2693 (linked here: #2723), and I can look into making sure the simulation banner stays as part of that work.

Copy link
Contributor

Choose a reason for hiding this comment

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

Yep, thanks for clarifying this. it'd be good if Simulating Navigation at 1x banner is available whenever Precise Location is On.

@@ -696,6 +696,7 @@ extension NavigationViewController: NavigationServiceDelegate {
if #available(iOS 14.0, *), accuracyAuthorization == .reducedAccuracy {
let title = NSLocalizedString("ENABLE_PRECISE_LOCATION", bundle: .mapboxNavigation, value: "Enable precise location to navigate", comment: "Label indicating precise location is off and needs to be turned on to navigate")
showStatus(title: title, spinner: false, duration: 20, animated: true, interactive: false)
mapView?.reducedAccuracyActivatedMode = true
} else {
//Fallback on earlier versions
Copy link
Contributor

@MaximAlien MaximAlien Nov 9, 2020

Choose a reason for hiding this comment

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

Currently UserHaloCourseView doesn't change its look when Precise Location is switched on. I think we should update it whenever navigationServiceDidChangeAuthorization(_:didChangeAuthorizationFor:) is called.

Copy link
Contributor

Choose a reason for hiding this comment

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

you could add an observer to the notification that's posted whenever navigationServiceDidChangeAuthorization(_:didChangeAuthorizationFor:) is called:

let info: [NotificationUserInfoKey: Any] = [
.locationAuthorizationKey: manager.value(forKey: "accuracyAuthorization") ?? 0
]
NotificationCenter.default.post(name: .locationAuthorizationDidChange, object: manager, userInfo: info)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Thanks for the suggestion, I add the mapView?.reducedAccuracyActivatedMode = false when the Precise Location if switched on so right now it could switch between the two types of course view.

}

//var opacity: CGFloat = 0.25
var boarderSize = 5.0
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
var boarderSize = 5.0
var borderWidth = 5.0

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Thanks for the suggestion, I'll update this part.

@ShanMa1991 ShanMa1991 requested a review from MaximAlien November 9, 2020 21:10
@ShanMa1991 ShanMa1991 force-pushed the shan-halo-reduced-accuracy-2555 branch 3 times, most recently from b910962 to 5871e35 Compare November 10, 2020 07:35
CHANGELOG.md Outdated
Comment on lines 7 to 10
* Added the `NavigationServiceDelegate.navigationService(_:didChangeAuthorizationFor:)` method and `Notification.Name.locationAuthorizationDidChange` to detect when the user changes the Location Services permissions for the current application, including for approximate location on iOS 14. ([#2693](https://github.com/mapbox/mapbox-navigation-ios/pull/2693))
* When approximate location is enabled on iOS 14, a banner appears reminding the user to disable approximate location to continue navigating. ([#2693](https://github.com/mapbox/mapbox-navigation-ios/pull/2693))
=======

Copy link
Contributor

Choose a reason for hiding this comment

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

I think those changes are no longer part of 1.2 since they were released in 1.1. Please also use rebasing instead of using merge commits when catching-up from main, as I can see conflict wasn't fixed cleanly in this case.

A view representing the user’s reduced accuracy location on screen.
*/

public class UserHaloCourseView: UIView, CourseUpdatable {
Copy link
Contributor

Choose a reason for hiding this comment

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

Since UserHaloCourseView is now part of public API please update jazzy.yml to contain new symbol.

Comment on lines 66 to 67


Copy link
Contributor

Choose a reason for hiding this comment

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

Nit: please use similar one-liner as a separator between methods.

drawHaloView()
}

var borderSize = 5.0
Copy link
Contributor

Choose a reason for hiding this comment

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

Since borderSize is only used in a drawHaloView please move it there, it should also be let instead of var. Probably also better to rename it to something like borderWidth or width.

@ShanMa1991 ShanMa1991 force-pushed the shan-halo-reduced-accuracy-2555 branch from 28d486b to e15a3b6 Compare November 11, 2020 05:15
@@ -199,6 +199,9 @@ open class DayStyle: Style {
TopBannerView.appearance().backgroundColor = #colorLiteral(red: 1, green: 1, blue: 1, alpha: 1)
UserPuckCourseView.appearance().puckColor = #colorLiteral(red: 0.149, green: 0.239, blue: 0.341, alpha: 1)
UserPuckCourseView.appearance().stalePuckColor = #colorLiteral(red: 0.6000000238, green: 0.6000000238, blue: 0.6000000238, alpha: 1)
UserHaloCourseView.appearance().haloColor = #colorLiteral(red: 1, green: 1, blue: 1, alpha: 0.5)
Copy link
Contributor

Choose a reason for hiding this comment

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

Good idea, we can also style UserHaloCourseView a bit differently for NightStyle.

CHANGELOG.md Outdated
## v1.1.0

### Packaging

* MapboxNavigationNative dependency was updated to v22.0.5 and MapboxCommon to v7.1.2. ([#2648](https://github.com/mapbox/mapbox-navigation-ios/pull/2648))

### User location

Copy link
Contributor

Choose a reason for hiding this comment

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

Please try to be as clean as possible when doing rebase onto main (e.g. this line wasn't meant to be removed).

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Thanks for the suggestion! I just cleaned the code to remove unnecessary change, and rebase the branch to main.

Copy link
Contributor

@MaximAlien MaximAlien left a comment

Choose a reason for hiding this comment

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

Overall looks good to me. I think one last rebase onto main will be required. We should also do additional round of testing after merging to main.

@ShanMa1991 ShanMa1991 force-pushed the shan-halo-reduced-accuracy-2555 branch from e15a3b6 to a826475 Compare November 12, 2020 18:34
@ShanMa1991 ShanMa1991 merged commit 1a589d9 into main Nov 12, 2020
@ShanMa1991 ShanMa1991 deleted the shan-halo-reduced-accuracy-2555 branch November 12, 2020 19:09
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
feature New feature request. topic: location UI Work related to visual components, Android Auto, Camera, 3D, voice, etc.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Indicate reduced accuracy location mode
4 participants