Añadir autocompletado de dirección en mapa
1) Añadir a Podfile : pod 'MLPAutoCompleteTextField'
2) Añadir campo Textfield a pantalla y asignar la clase MLPAutoCompleteTextField
3) Añadir a .h
#import <MLPAutoCompleteTextField/MLPAutoCompleteTextField.h>
delegates: UIActionSheetDelegate, MLPAutoCompleteTextFieldDelegate, MLPAutoCompleteTextFieldDataSource, UITextFieldDelegate
@property (weak, nonatomic) IBOutlet MLPAutoCompleteTextField *tfLocationAddress;
@property (strong, nonatomic) CLGeocoder *geocoder;
@property (strong, nonatomic) GMSGeocoder *reverseGeocoder;
@property (strong, nonatomic) NSArray *placemarksResult;
4) Añadir a .m:
#import "AutoCompleteAddress.h"
5) Añadir clase de AutoCompleteAddress
//
// AutoCompleteAddress.h
//
#import <Foundation/Foundation.h>
#import "MLPAutoCompletionObject.h"
#import <CoreLocation/CoreLocation.h>
@interface AutoCompleteAddress : NSObject <MLPAutoCompletionObject>
@property (strong, nonatomic) CLPlacemark* address;
@end
-------------------
//
// AutoCompleteAddress.m
//
#import "AutoCompleteAddress.h"
@implementation AutoCompleteAddress
-(NSString *)autocompleteString{
NSString *addressString = @"";
if(_address){
if (!([self.address thoroughfare] == (id)[NSNull null] || [self.address thoroughfare].length == 0 )){
addressString = [NSString stringWithFormat:@"%@", [self.address thoroughfare]];
}
if (!([self.address subThoroughfare] == (id)[NSNull null] || [self.address subThoroughfare].length == 0 )){
if(addressString.length>0){
addressString = [addressString stringByAppendingString:@", "];
}
addressString = [addressString stringByAppendingString:[self.address subThoroughfare]];
}
if (!([self.address locality] == (id)[NSNull null] || [self.address locality].length == 0 )){
if(addressString.length>0){
addressString = [addressString stringByAppendingString:@", "];
}
addressString = [addressString stringByAppendingString:[self.address locality]];
}
if (!([self.address country] == (id)[NSNull null] || [self.address country].length == 0 )){
if(addressString.length>0){
addressString = [addressString stringByAppendingString:@", "];
}
addressString = [addressString stringByAppendingString:[self.address country]];
}
}
return addressString;
}
@end
6) Añadir array de resultados en .m:
@implementation MapPageView{
NSMutableArray* results;
}
7) Añadir a didLoad o similar en .m:
self.tfLocationAddress.delegate = self;
[self.tfLocationAddress setAutoCompleteTableAppearsAsKeyboardAccessory:YES];
[self.tfLocationAddress setAutoCompleteTableCornerRadius:5];
[self.tfLocationAddress setAutoCompleteTableBorderWidth:1];
[self.tfLocationAddress setAutoCompleteTableBorderColor:[UIColor lightGrayColor]];
[self.tfLocationAddress setAutoCompleteDataSource:self];
[self.tfLocationAddress setAutoCompleteDelegate:self];
self.tfLocationAddress.autoCompleteTableBackgroundColor = [UIColor whiteColor];
[self.tfLocationAddress setAutoCompleteRegularFontName:FONT];
[self.tfLocationAddress setAutoCompleteTableCellTextColor:[UIColor blackColor]];
self.tfLocationAddress.maximumNumberOfAutoCompleteRows = 5;
self.tfLocationAddress.clearButtonMode = UITextFieldViewModeWhileEditing;
self.reverseGeocoder = [GMSGeocoder geocoder];
8) Añadir a .m
#pragma mark - MLPAutoCompleteTextField DataSource
-(void)autoCompleteTextField:(MLPAutoCompleteTextField *)textField possibleCompletionsForString:(NSString *)string completionHandler:(void (^)(NSArray *))handler
{
NSString* query = textField.text;
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.1 * NSEC_PER_SEC)), dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^{
if(![query isEqualToString:self.tfLocationAddress.text]){
return;
}
[self.geocoder geocodeAddressString:query completionHandler:^(NSArray *placemarks, NSError *error) {
results = [NSMutableArray new];
if(placemarks){
self.placemarksResult = [[NSArray alloc]init];
self.placemarksResult = placemarks;
for( CLPlacemark *address in placemarks) {
AutoCompleteAddress* res = [AutoCompleteAddress new];
res.address = address;
[results addObject:res];
}
}
if([query isEqualToString:self.tfLocationAddress.text]){
handler(results);
}
}];
});
}
#pragma mark - MLPAutoCompleteTextField Delegate
- (void)autoCompleteTextField:(MLPAutoCompleteTextField *)textField
didSelectAutoCompleteString:(NSString *)selectedString
withAutoCompleteObject:(id<MLPAutoCompletionObject>)selectedObject
forRowAtIndexPath:(NSIndexPath *)indexPath
{
if(selectedObject && [selectedObject isKindOfClass:[AutoCompleteAddress class]]){
NSLog(@"selected object from autocomplete menu %@ with string %@", selectedObject, [selectedObject autocompleteString]);
CLPlacemark* place = ((AutoCompleteAddress*)selectedObject).address;
[self.tfLocationAddress setText:[selectedObject autocompleteString]];
[self.map animateToLocation:place.location.coordinate];
} else {
NSLog(@"selected string '%@' from autocomplete menu", selectedString);
}
}
- (void)onSearch {
[self.view endEditing:YES];
[self.geocoder geocodeAddressString:self.tfLocationAddress.text completionHandler:^(NSArray *placemarks, NSError *error) {
if([placemarks count]){
if (([placemarks count]) == 1) {
CLPlacemark* place = [placemarks firstObject];
[self.map animateToLocation:place.location.coordinate];
} else {
self.placemarksResult = [[NSArray alloc]init];
self.placemarksResult = placemarks;
UIActionSheet *popup = [[UIActionSheet alloc] initWithTitle:NSLocalizedString(@"select_location", nil)
delegate:self
cancelButtonTitle:NSLocalizedString(@"cancel", nil)
destructiveButtonTitle:nil
otherButtonTitles:nil];
int i=0;
for( CLPlacemark *title in placemarks) {
AutoCompleteAddress* address = [AutoCompleteAddress new];
address.address = title;
[popup addButtonWithTitle: [address autocompleteString]];
i++;
if (i==3)
break;
}
popup.tag = 1;
[popup showInView:self.view];
}
}
}];
}
-(void)actionSheet:(UIActionSheet *)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex {
if (buttonIndex != 0) {
CLPlacemark* place = [self.placemarksResult objectAtIndex:buttonIndex-1];
[self.map animateToLocation:place.location.coordinate];
}
}
#pragma mark - Map delegate
- (CLGeocoder *)geocoder {
if (!_geocoder) {
_geocoder = [[CLGeocoder alloc] init];
}
return _geocoder;
}
-(void)mapView:(GMSMapView *)mapView idleAtCameraPosition:(GMSCameraPosition *)position{
NSLog(@"Cambio lat:%f, lon:%f", position.target.latitude, position.target.longitude);
CLLocationCoordinate2D pos = CLLocationCoordinate2DMake(position.target.latitude, position.target.longitude);
[self.reverseGeocoder reverseGeocodeCoordinate:pos completionHandler:^(GMSReverseGeocodeResponse *response, NSError *error){
[self.tfLocationAddress setText:@""];
for (GMSAddress* addressObj in [response results]) {
NSLog(@"Street found: %@", addressObj.lines);
if ([addressObj.lines count]==2){
[self.tfLocationAddress setText: [NSString stringWithFormat:@"%@ %@", addressObj.lines[0], addressObj.lines[1]]];
} else{
[self.tfLocationAddress setText: [NSString stringWithFormat:@"%@", addressObj.lines[0]]];
}
break;
}
}];
}
#pragma-mark Keyboard
- (BOOL)textFieldShouldReturn:(UITextField *)textField {
if ([textField isEqual:self.tfLocationAddress]) {
[textField resignFirstResponder];
[self performSelector:@selector(onSearch) withObject:nil];
}
return YES;
}