Custom callout not shown properly

1825
8
Jump to solution
07-14-2020 12:05 PM
by Anonymous User
Not applicable

Hi there, I would like to show a callout with text in a different font. I created a simple view with a UILabel in the center, when I set the callout custom view to this view it isn't shown properly. I'm fine with the default callout for now but I intend to have more complex custom callouts and was surprised this didn't work as I expected. I'd like to know what I'm doing wrong here.

how I set the callout custom view 

How I create the view, 

The view:

The result: 

What I've tried:

  • Different values for the view frame's properties (x, y ,width and height)
Tags (1)
0 Kudos
1 Solution

Accepted Solutions
MarkDostal
Esri Contributor

Kenneth,

Take a look at the code Nick posted, it show's how he's creating the custom view.  Specifically:

class MyCustomView: UIView {

    static let instance = Bundle.main.loadNibNamed("CustomCalloutView", owner: nil, options: nil)?.first as? MyCustomView

and:

        mapView.callout.customView = MyCustomView.instance

I think with both Nick and I helping out we'll get you sorted.  😉

Mark

View solution in original post

0 Kudos
8 Replies
MarkDostal
Esri Contributor

I would suggest removing the call to set the self.frame property in the MapCalloutMessageView.init method.  The documentation for the AGSCallout.customView property states: The callout will expand
to fit the dimensions of the custom view.  That should handle the sizing for you.

You can also look at the ArcGIS Runtime Samples for iOS repo on GitHub, specifically, the Geometry/Project sample which uses a custom callout similar to what you want.  The code for that is here.

Let me know if you still have problems.

Mark

0 Kudos
by Anonymous User
Not applicable

I tried removing the line that sets the frame property, unfortunately still nothing. Thanks for the sample, I noticed the custom view used in that sample is created on the storyboard. Is there a constraint to the callouts custom view option that makes it not work with views from xib files? I plan to have a number of different custom views it would be tough to manage if they were all on the storyboard.

0 Kudos
MarkDostal
Esri Contributor

I tried it here and got it to work.  The `AGSCallout` uses constraints to set up the custom view.  What I did was use constraints in the .xib, along with setting the "layout" to `Automatic` (as opposed to translating mask to constraints).  See the screenshots below.

Let me know if that doesn't work for you and I can dig further.

Mark

this was both for the view and the label:

The code from `didTapAtScreenPoint`:

let projectedPoint = AGSGeometryEngine.projectGeometry(mapPoint, to: .wgs84()) as! AGSPoint

customCallout.message = "Coordinates\n Original: \(mapPoint.x), \(mapPoint.y)\n Projected: \(projectedPoint.x), \(projectedPoint.y)"

0 Kudos
by Anonymous User
Not applicable

May I see how you are instantiating the view in its init function?

Used the same constraints you did just to rule that out. 

as well as the Automatic layout option

Same problem

0 Kudos
Nicholas-Furness
Esri Regular Contributor

Hi Kenneth.

I pulled together a sample project as Mark was answering. Turns out it does just about the same thing as his. Download this, take a look in Xcode, and hopefully it can help you figure out what you're doing that's different.

0 Kudos
MarkDostal
Esri Contributor

Kenneth,

Take a look at the code Nick posted, it show's how he's creating the custom view.  Specifically:

class MyCustomView: UIView {

    static let instance = Bundle.main.loadNibNamed("CustomCalloutView", owner: nil, options: nil)?.first as? MyCustomView

and:

        mapView.callout.customView = MyCustomView.instance

I think with both Nick and I helping out we'll get you sorted.  😉

Mark

0 Kudos
by Anonymous User
Not applicable

Oooh, I needed a reference to the view loaded from the xib and not the instance of the class. I think that's what you get when you get the first object in the array returned from loadNibNamed. Just to be sure I created an outlet in the swift file for the view that holds the label (topmost view), passed it to the callout and it worked. Thank you both so much for your help!

Nicholas-Furness
Esri Regular Contributor

Happy to help!

Yeah, when you call loadNibNamed(), you'll get instantiated views as defined in the XIB file. In this case we just have one, so we grab the first.

In the XIB itself, in the Identity Inspector, we declared that this view class was MyCustomView (in your case MapCalloutMessageView) which is a UIView subclass. So you already have a handle to the root view of what you defined in your XIB, and it will be the class you configured it to be in the XIB. Just mentioning this to be clear that you don't need your custom outlet for the view that holds the label. That's what you get back from loadNibNamed().first.

Glad it's working!

0 Kudos