Skip to content
This repository has been archived by the owner on Jun 14, 2024. It is now read-only.

Add change worldview boundaries example #382

Open
wants to merge 1 commit into
base: master
Choose a base branch
from

Conversation

ZiZasaurus
Copy link
Contributor

created new iOS example for changing worldview boundaries

Copy link
Contributor

@captainbarbosa captainbarbosa left a 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()
Copy link
Contributor

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
Copy link
Contributor

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
Copy link
Contributor

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)])

Copy link
Contributor

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 NSLayoutConstraints.

view.addSubview(mapView)

// Create a UISegmentedControl to toggle between map styles
let styleToggle = UISegmentedControl(items: [" US ", " CN ", " IN "," All "])
Copy link
Contributor

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)
Copy link
Contributor

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 {
Copy link
Contributor

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)
}
Copy link
Contributor

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
Copy link
Contributor

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!)
Copy link
Contributor

@captainbarbosa captainbarbosa Dec 18, 2019

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;

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

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants