-
Notifications
You must be signed in to change notification settings - Fork 35
Add change worldview boundaries example #382
base: master
Are you sure you want to change the base?
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I just reviewed the Swift example, since the way sources/layers are used here should be reconsidered.
In your current code, a new source and layer are created and added to the existing style. However, since Mapbox Light includes the mapbox-streets-v8
source, according to the documentation there is already a copy of the admin style layers in this source. That means we can remove all of the code that involves creating and adding a new source/style layer.
You can perform the same NSPredicate
filtering operations on the built-in admin layer. To access that layer, you'll need to call MGLStyle.layer(withIdentifier: String)
, with admin-0-boundary
being the string that represents the built-in admin boundary layer (I found this out by inspecting MGLStyle.layers
).
Feel free to message me if you have questions about how to approach this. Once you've got the changes squared away, you can re-tag me for review.
|
||
class ChangeWorldviewBoundariesExample: UIViewController, MGLMapViewDelegate { | ||
|
||
let mapView = MGLMapView() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You can take care of the map view's initialization and style setting in one shot with this initializer:
MGLMapView(frame: CGRect, styleURL: MGLStyleURL)
I recommend doing this in viewDidLoad
.
|
||
view.addSubview(mapView) | ||
|
||
// Create a UISegmentedControl to toggle between map styles |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
map style
-> map worldviews
The style itself isn't changing, we're just toggling source visibility.
styleToggle.backgroundColor = UIColor(red: 184/255, green: 205/255, blue: 212/255, alpha: 1) | ||
styleToggle.layer.cornerRadius = 4 | ||
styleToggle.clipsToBounds = true | ||
// styleToggle.selectedSegmentIndex = 0 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Did you want to uncomment this?
// at the bottom of the map view and above the Mapbox logo and attribution | ||
NSLayoutConstraint.activate([NSLayoutConstraint(item: styleToggle, attribute: NSLayoutConstraint.Attribute.centerX, relatedBy: NSLayoutConstraint.Relation.equal, toItem: mapView, attribute: NSLayoutConstraint.Attribute.centerX, multiplier: 1.0, constant: 0.0)]) | ||
NSLayoutConstraint.activate([NSLayoutConstraint(item: styleToggle, attribute: .bottom, relatedBy: .equal, toItem: mapView.logoView, attribute: .top, multiplier: 1, constant: -20)]) | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
An easier (and less lengthy) way to write constraints is to use the NSLayoutAnchor
-based API to create constraints. Here's an example of writing one of your existing constraints this way:
Before:
NSLayoutConstraint(item: styleToggle, attribute: NSLayoutConstraint.Attribute.centerX, relatedBy: NSLayoutConstraint.Relation.equal, toItem: mapView, attribute: NSLayoutConstraint.Attribute.centerX, multiplier: 1.0, constant: 0.0)
After, using NSLayoutAnchor
syntax:
styleToggle.centerX.constraint(equalTo: mapView.centerX)
I recommend having a look at this blog post for more context!
You can also put all of your constraints into one NSLayoutConstraint.activate([...])
call, since that accepts an array of NSLayoutConstraint
s.
view.addSubview(mapView) | ||
|
||
// Create a UISegmentedControl to toggle between map styles | ||
let styleToggle = UISegmentedControl(items: [" US ", " CN ", " IN "," All "]) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Because we're not actually changing the style, you may want to consider renaming this to worldViewToggle
.
override func viewDidLoad() { | ||
super.viewDidLoad() | ||
|
||
mapView.frame = CGRect(x: 0, y: 0, width: view.bounds.width, height: view.bounds.height) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You can assign this to self.view.frame
instead of using the entire CGRect
constructor.
|
||
@objc(ChangeWorldviewBoundariesExample_Swift) | ||
|
||
class ChangeWorldviewBoundariesExample: UIViewController, MGLMapViewDelegate { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The view controller is conforming to the MGLMapViewDelegate
protocol but is not using any of its associated delegate methods (yet).
} else { | ||
layer = MGLLineStyleLayer(identifier: "admin", source: source) | ||
style.addSource(source) | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
layer = MGLLineStyleLayer(identifier: "admin", source: source)
style.addSource(source)
This only happens the first time a user selects a segment. I don't think this code is necessary, since it appears that Mapbox Light already includes admin boundary style layers. That layer just needs to be accessed with MGLStyle.layer(withIdentifier: String)
, so we can avoid creating a new source and style layer for this.
view.insertSubview(styleToggle, aboveSubview: mapView) | ||
styleToggle.addTarget(self, action: #selector(changeStyle(sender:)), for: .valueChanged) | ||
|
||
// Configure autolayout constraints for the UISegmentedControl to align |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
autolayout
-> Auto Layout
case 0: | ||
|
||
layer?.predicate = NSPredicate(format: "CAST(worldview, 'NSString') == 'US'") | ||
style.addLayer(layer!) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Once you refactor this to use the built-in admin layer, you can remove all instances of addLayer
in this switch statement.
|
||
@property (nonatomic) MGLMapView *mapView; | ||
@property MGLLineStyleLayer *layer; | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
created new iOS example for changing worldview boundaries