Skobbler iOS SDK: Why are there borders around my map annotations? - ios

Creating an iOS mapping app using Skobbler's SDK (installed via CocoaPods. v2.5). I'm adding annotations to my Skobbler mapview, using custom views for my pins instead of using one of Skobbler's defaults. My pins will just be colored circles.
The problem is that my circles seem to be drawn with borders, but they shouldn't be.
My code is similar to the following:
let pin = UIView()
pin.layer.frame = CGRectMake(0, 0, 18, 18)
pin.layer.backgroundColor = UIColor.lightGrayColor().CGColor
pin.layer.cornerRadius = diameter/2
//Just for good measure... NO BORDER
pin.layer.borderColor = UIColor.clearColor().CGColor
pin.layer.borderWidth = 0
let annotation = SKAnnotation()
annotation.annotationView = SKAnnotationView(view: pin, reuseIdentifier: "viewID")
annotation.identifier = 1234
annotation.location = CLLocationCoordinate2DMake(44.1234, -111.1234)
mapView.addAnnotation(annotation, withAnimationSettings: animationSettings)
How can I avoid having borders drawn around my pins?

Turns out that a light border is added by the framework, and I'm told there is nothing I can do.
Here's a snippet from an email from Skobbler:
"Indeed we can see a light border (see attach)- that’s the way is
generated at our core level and we cannot change this. We’ve checked
also if we set a simple view on the map and if we add that view to an
annotation indeed the border appears (screenshot 2)."

Related

Determine proper zoom level on GMSMapView to fit all the locations needed?

In my iOS app I'm using GoogleMaps and APIs for maps and I'm not very familiar with it.
I know that with iOS native MKMapView you can set a visible map rect to fit all the points needed at a proper zoom level, like described here: Zooming MKMapView to fit annotation pins?
but I'm not sure how to do such thing for GMSMapView. Does anyone know how to do it?
Any kind of help is highly appreciated!
Add this after setting up markers on the Map:
var bounds = GMSCoordinateBounds()
for coordinate in testCoordinates {
bounds = bounds.includingCoordinate(coordinate)
}
let update = GMSCameraUpdate.fit(bounds, withPadding: 50)
mapView.animate(with: update)

Turn on occlusion with lines for mesh in scenekit

I would like to display a mesh with iOS ARKit with SceneKit and not RealityKit.
I am able to add a material to the mesh, like so which displays the mesh just fine
let edgesMaterial = SCNMaterial()
edgesMaterial.fillMode = .lines
edgesMaterial.lightingModel = .constant
edgesMaterial.transparency = 1.0
edgesMaterial.diffuse.contents = UIColor.red
scnGeom.materials = [edgesMaterial]
However, this adds overlapping lines of the wireframes in the scene. With RealityKit the fix is rather simple by just adding
arView.environment.sceneUnderstanding.options.insert(.occlusion)
How can I get the same effect with a scenekit scene? Basically I want to add a occlusion material with lines. Any pointers?
UPDATE:
I can get something close but not quite the same visualization by using this:
sceneView.debugOptions.insert([.showWireframe])
let occMaterial = SCNMaterial()
occMaterial.colorBufferWriteMask = SCNColorMask(rawValue: 0)
scnGeom.materials = [occMaterial]
The lines appear white and also any object I place in the scene will render the wireframe automatically now with this

How to draw a line under street name using MapBox

I would like to draw a route using Mapbox. I've tried adding polyline:
let polyline = MGLPolyline(coordinates: &coords, count: UInt(coords.count))
mapView?.add(polyline)
But it keeps drawing on top of street names. How can I move below street names?
If you add an MGLPolyline directly to an MGLMapView, you’re adding it as an annotation; currently the Mapbox iOS SDK only supports adding annotations on top of everything.
However, the SDK has a separate API called runtime styling, which allows you to place data under or above any layer of the map. From this example, you can use code like the following to add a shape source to the map’s style and a line layer that renders the shape source. (MGLLineStyleLayer is reminiscent of MapKit’s MKOverlayPathRenderer.)
let routeFeature = MGLPolylineFeature(coordinates: &coords, count: UInt(coords.count))
let routeSource = MGLShapeSource(identifier: "route", shape: routeFeature, options: nil)
mapView.style?.addSource(routeSource)
let routeLayer = MGLLineStyleLayer(identifier: "route", source: routeSource)
// Set properties like lineColor, lineWidth, lineCap, and lineJoin
mapView.style?.insertLayer(routeLayer, above: roadLayer) // or below: labelLayer
The code above works if you know the identifier of the road or label layer. You can obtain the identifier by opening the style in Mapbox Studio. For something more robust, you could iterate over all the layers in the map style, inserting the route layer above the first non-symbol layer you find. (Labels and icons are rendered using symbol layers.)
for layer in style.layers.reversed() {
if !(layer is MGLSymbolStyleLayer) {
style.insertLayer(routeLayer, above: layer)
break
}
}
By the way, if you need more than just a route line, Mapbox Navigation SDK for iOS comes with a complete turn-by-turn navigation UI, including a map that’s optimized for displaying a route.

Custom user location marker with custom accuracy circle in MKMapView

I'm implementing simple navigation and to display user location I'm using custom MKAnnotationView:
let reuseId = "userLocationPin"
userLocationViewAnnotation = mapView.dequeueReusableAnnotationViewWithIdentifier(reuseId) as? MKPinAnnotationView
if userLocationViewAnnotation == nil {
userLocationViewAnnotation = MKAnnotationView(annotation: annotation, reuseIdentifier: reuseId)
userLocationViewAnnotation!.canShowCallout = true
userLocationViewAnnotation!.centerOffset = CGPoint(x: 0.9, y: -2)
userLocationViewAnnotation!.image = UIImage(named: "User_location_red_moving_x1")
}
And this code is working fine. Next I need to add accuracy circle. I'm adding it by MKCircle overlay:
userLocationCircle = MKCircle(centerCoordinate: location.coordinate, radius: location.horizontalAccuracy)
map.addOverlay(userLocationCircle!)
The problem is that user location is updating more frequently and with animation by MKMap internally, but circle is updating after user location change (in my code) so it's jumping from one point to another.
Is it possible to add this circle to MKAnnotationView, or maybe do you have any other ideas?
Solution 1 (which I did before)
Do not set MKMapView.showsUserLocation to true. Which means that you cannot use mapView:didUpdateUserLocation: of the delgate any more. That means that fetching the user's location is less convenient. You will have to use Core Location for that. (Tons of tutorials around)
Then you have to set the map's center ans span accordingly but yourself. By doing so you can add any annotation that you want for the user's location. Just respond to mapView(_:viewForAnnotation:) and return the view that you want to be displayed.
Solution 2: (Which I guess works but I never tried it myself)
Just go along with MKMapView.showsUserLocation as you did before but respond to mapView(_:viewForAnnotation:) in any case. Debug it. On the first call to this method it is handed in the standard user annotation. (I just don't know its type/class name out of the top of my head. It is the first one. That's why I ask you to debug for it.)
Just don't return nil but return the view that you want to be displayed.
It is worth a try. It is less work than solution 1 if it works.
However, solution 1 gives you much more flexibilty and full control over the part of the world that is currently displayed in the Map.

iOS CALayer and TapGestureRecognizer

I'm developing an app on iOS 6.1 for iPad.
I've a problem with the CALayer and a TapGestureRecognizer.
I've 7 CALayers forming a rainbow (every layer is a colour).
Every layer is built using a CAShapeLayer generate from a CGMutablePathRef. Everything works fine. All the layers are drawn on screen and I can see a beautiful rainbow.
Now I want to detect the tap above a single color/layer. I try this way:
- (void)tap:(UITapGestureRecognizer*)recognizer
{
//I've had the tapGestureRecognizer to rainbowView (that is an UIView) in viewDidLoad
CGLayer* tappedLayer = [rainbowView.layer.presentationlayer hitTest:[recognizer locationInView:rainbowView];
if (tappedLayer == purpleLayer) //for example
NSLog(#"PURPLE!");
}
I don't understand why this code won't work! I've already red other topics in here: all suggest the hitTest: method for solving problems like this. But in my case I can't obtain the desired result.
Can anyone help me? Thanks!!
EDIT:
Here's the code for the creation of paths and layers:
- (void)viewDidLoad
{
//Other layers
...
...
//Purple Arc
purplePath = CGPathCreateMutable();
CGPathMoveToPoint(purplePath, NULL, 150, 400);
CGPathAddCurveToPoint(purplePath, NULL, 150, 162, 550, 162, 550, 400);
purpletrack = [CAShapeLayer layer];
purpletrack.path = purplePath;
purpletrack.strokeColor = [UIColor colorWithRed:134.0/255.0f green:50.0/255.0f blue:140.0/255.0f alpha:1.0].CGColor;
purpletrack.fillColor = nil;
purpletrack.lineWidth = 25.0;
[rainbowView.layer insertSublayer:purpletrack above:bluetrack];
}
This was my first approach to the problem. And the touch didn't work.
I also tried to create a RainbowView class where the rainbow was drawing in drawRect method using UIBezierPaths.
Then I follow the "Doing Hit-Detection on a Path" section in http://developer.apple.com/library/ios/#documentation/2ddrawing/conceptual/drawingprintingios/BezierPaths/BezierPaths.html
In this case the problem was the path variable passed to the method. I try to compare the UIBezierPath passed with the paths in RainbowView but with no results.
I could try to create curves instead of paths. In this case maybe there isn't a fill part of figure and the touching area is limited to the stroke. But then how can I recognize the touch on a curve?
I'm so confused about all of these stuff!!! :D
The problem you are facing is that you are checking agains the frame/bounds of the layer when hit testing and not agains the path of the shape layer.
If your paths are filled you should instead use CGPathContainsPoint() to determine if the tap was inside the path. If your paths aren't filled but instead stroked I refer you to Ole Begemann's article about CGPath Hit Testing.
To make your code cleaner you could do the hit testing in your own subclass. Also, unless the layer is animating when hit testing it makes no sense using the presentationLayer.

Resources