How to display 2 lines of text for subtitle of MKAnnotation and change the image for the button on the right?
- (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id <MKAnnotation>)annotation
{
MKAnnotationView *annotationView = [[MKPinAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:@"loc"];
// Button
UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
button.frame = CGRectMake(0, 0, 23, 23);
button.contentVerticalAlignment = UIControlContentVerticalAlignmentCenter;
button.contentHorizontalAlignment = UIControlContentHorizontalAlignmentCenter;
[button setImage:[UIImage imageNamed:yourImageName] forState:UIControlStateNormal];
[advertButton addTarget:self action:@selector(buttonPress:) forControlEvents:UIControlEventTouchUpInside];
annView.rightCalloutAccessoryView = button;
// Image and two labels
UIView *leftCAV = [[UIView alloc] initWithFrame:CGRectMake(0,0,23,23)];
[leftCAV addSubview : yourImageView];
[leftCAV addSubview : yourFirstLabel];
[leftCAV addSubview : yourSecondLabel];
annotationView.leftCalloutAccessoryView = leftCAV;
annotationView.canShowCallout = YES;
return pin;
}
UPDATE
The default style for annotations only supports the title and subtitle. Neither title nor subtitle can include line breaks. You cannot do this without subclassing.
To use a custom view review Apple's sample code:
http://developer.apple.com/library/ios/#samplecode/WeatherMap/Introduction/Intro.html
I also think there is a problem in your code
UILabel *l1=[[UILabel alloc] init];
l1.frame=CGRectMake(0, 15, 50, 50);
l1.text=@"First line of subtitle";
l1.font=[UIFont fontWithName:@"Arial Rounded MT Bold" size:(10.0)];
UILabel *l2=[[UILabel alloc] init];
l2.frame=CGRectMake(0, 30, 50, 50);
l2.text=@"Second line of subtitle";
l2.font=[UIFont fontWithName:@"Arial Rounded MT Bold" size:(10.0)];
[leftCAV addSubview : l1];
[leftCAV addSubview : l2];
l1 has a frame (0, 15, 50, 50) and l2 has (0, 30, 50, 50). Wont these two overlap? I mean l1 will start from y=15 and its height is 50. so when l2 starts from 30 it may overlap.. Can you pls check by changing the frames
Longer subtitles in MapView annotations (swift)
I figured it out, I added a label in viewForAnnotation and it just worked
¯\_(ツ)_/¯
func mapView(mapView: MKMapView, viewForAnnotation annotation: MKAnnotation) -> MKAnnotationView? {
if annotation is MKUserLocation {
//return nil so map view draws "blue dot" for standard user location
return nil
}
let reuseId = "pin"
var pinView = mapView.dequeueReusableAnnotationViewWithIdentifier(reuseId) as? MKPinAnnotationView
if pinView == nil {
pinView = MKPinAnnotationView(annotation: annotation, reuseIdentifier: reuseId)
pinView!.canShowCallout = true
}
else {
pinView!.annotation = annotation
}
//THIS IS THE GOOD BIT
let subtitleView = UILabel()
subtitleView.font = subtitleView.font.fontWithSize(12)
subtitleView.numberOfLines = 0
subtitleView.text = annotation.subtitle!
pinView!.detailCalloutAccessoryView = subtitleView
return pinView
}
Adding a title in front/below a custom annotation mapkit swift 4
You can create a label like so:
let annotationLabel = UILabel(frame: CGRect(x: -40, y: -35, width: 105, height: 30))
annotationLabel.numberOfLines = 3
annotationLabel.textAlignment = .center
annotationLabel.font = UIFont(name: "Rockwell", size: 10)
// you can customize it anyway you want like any other label
Set the text:
annotationLabel.text = annotation.title!!
And then add to annotation view:
annotationView.addSubview(annotationLabel)
Picture of annotation with label
I also added a background and border by doing:
annotationLabel.backgroundColor = UIColor.white
annotationLabel.layer.cornerRadius = 15
annotationLabel.clipsToBounds = true
You can also change where the label is in respect to the annotation by changing the X and Y when creating the label. Negative is to the left and up, positive right and down.
Use a text field to set the title of an MKAnnotation in Swift
There are several ways to do so, but you can choose one of the two for example.
In your view, you add a text field where the user set the title before you drop the pin. But that might not be intuitive or look bad (if you need to have a full screen map for example).
So, what I would suggest is to fire an UIAlertController with a text field inside. Here is an example of how you could do it.
Either you :
- Create the annotation
- Add it to the map
- An alert appear
- The user enter a name (keep it somewhere)
- You retrieve the last annotation you've added
- You set it's title with the name entered previously
Or :
- You detect your long press
- An alert appear
- The user enter a name (keep it somewhere)
- Create your annotation with the name entered previously
- Add it to the map
Those are just 2-3 examples. You might think of something else :)
Add extra detail to MKPointAnnotation other than title and subtitle
make your own annotation, new file or class
import MapKit
class MyAnnotation: NSObject, MKAnnotation {
var coordinate: CLLocationCoordinate2D
var EXTRA_INFORMATION: String?
var title: String?
init(coordinate: CLLocationCoordinate2D) {
self.coordinate = coordinate
}
}
and use it instead of normal MKPointAnnotation
var zoopin = MyAnnotation()
zoopin.coordinate = zoo
zoopin.title = "The zoo"
zoopin.subtitle = "hello this is the zoo"
zoopin.EXTRA_INFORMATION = "that is your new extra info that you wanted to add?"
mapView.addAnnotation(zoopin)
MKPointAnnotation subtitle
Instead of using the built-in MKPointAnnotation
class, create a custom annotation class that implements MKAnnotation
but with an additional property (not named subtitle
) to hold the data you don't want to show on the callout.
This answer contains an example of a simple, custom annotation class.
In that example, replace @property (nonatomic, assign) float myValue;
with the data you want to track with each annotation (eg. @property (nonatomic, copy) NSString *keyValue;
).
Then you would create your annotations like this:
MyAnnotation *annotationPoint2 = [[MyAnnotation alloc] init];
annotationPoint2.coordinate = anyLocation;
annotationPoint2.title = [NSString stringWithFormat:@"%@", obj];
annotationPoint2.subtitle = @""; //or set to nil
annotationPoint2.keyValue = [NSString stringWithFormat:@"%@", key];
Then the didSelectAnnotationView
method would look like this:
- (void)mapView:(MKMapView *)mapView didSelectAnnotationView:(MKAnnotationView *)view
{
if ([view.annotation isKindOfClass:[MyAnnotation class]])
{
MyAnnotation *myAnnot = (MyAnnotation *)view.annotation;
field.text = myAnnot.keyValue;
}
else
{
//handle other types of annotations (eg. MKUserLocation)...
}
}
You may also have to update other parts of your code that assume the annotation is a MKPointAnnotation
or that uses the annotation's subtitle
(that code should check for MyAnnotation
and use keyValue
).
Related Topics
Kvo Listener Issues in Swift 4
Why Do I Have to Unwrap a Weak Self
How to Replace My .Xib File with Pure Swift 3
Support Arkit in Lower End Devices
How to Separate The Date and Time Components of Nsdate() in Swift
Reactive Cocoa/Reactive Swift - Swift 3.0 Missing Methods
Swift Struct Adopting Protocol with Static Read-Write Property Doesn't Conform
Realitykit - Stored Entities & Load The Scene Aynchronously from The Url
How to Pass Text from Cell to Textview in Another View Controller
Uibutton Background Color Overlaps Text on Highlight
Lldb for Swift: Access Computed Property or Perform Function Call in Type Summary Python Script
Why Do I Get Rgb Values of (0,0,0) for an Nsimage with a Transparent Background
Animate UIlabel Width with Fixed Center
On Demand Resources "0 Asset Packs"