ios - big - ionic p
¿Cómo seleccionar el pin del mapa al tocar la fila de la tabla que se asocia con él? (2)
Aquí tengo 2 vistas:
- WallViewController
- TableViewController
WallViewController contiene MKMapView y TableViewController es una subclase de PFQueryTableViewController que muestra filas de contenido que se asocian con el marcador de anotación en WallViewController . TableViewController se agrega como subvista en WallViewController , por lo que estas 2 vistas se muestran juntas. Ahora cuando toco el pin de anotación en el mapa, la vista de tabla en TableViewController se desplazará a la fila que se asocia con ese pin de anotación seleccionado con éxito. Pero lo que quiero hacer es tener también una acción invertida, así que cuando toco una fila, se seleccionará el pin de anotación que se asocia con esa fila y también se mostrará su llamada.
A continuación, proporcioné los códigos relevantes:
WallViewController.h
@interface WallViewController : UIViewController <MKMapViewDelegate, CLLocationManagerDelegate>
@property (nonatomic, strong) IBOutlet MKMapView *mapView;
@end
@protocol WallViewControllerHighlight <NSObject>
- (void)highlightCellForPost:(PAWPost *)post;
- (void)unhighlightCellForPost:(PAWPost *)post;
@end
WallViewController.m
- (void)viewDidLoad {
[super viewDidLoad];
self.tableViewController = [[TableViewController alloc] initWithStyle:UITableViewStylePlain];
[self addChildViewController:self.tableViewController];
self.tableViewController.view.frame = CGRectMake(6.0f, 215.0f, 308.0f, self.view.bounds.size.height - 215.0f);
[self.view addSubview:self.tableViewController.view];
self.wallPostsTableViewController.wallViewController = self;
....
}
- (void)mapView:(MKMapView *)mapView didSelectAnnotationView:(MKAnnotationView *)view {
id<MKAnnotation> annotation = [view annotation];
if ([annotation isKindOfClass:[PAWPost class]]) {
PAWPost *post = [view annotation];
[PostsTableViewController highlightCellForPost:post];
} else if ([annotation isKindOfClass:[MKUserLocation class]]) {
// Center the map on the user''s current location:
AppDelegate *appDelegate = [[UIApplication sharedApplication] delegate];
MKCoordinateRegion newRegion = MKCoordinateRegionMakeWithDistance(appDelegate.currentLocation.coordinate, appDelegate.filterDistance * 2, appDelegate.filterDistance * 2);
[self.mapView setRegion:newRegion animated:YES];
self.mapPannedSinceLocationUpdate = NO;
}
}
TableViewController.h
@interface TableViewController : PFQueryTableViewController <WallViewControllerHighlight>
@property (nonatomic, strong) PAWWallViewController *wallViewController;
- (void)highlightCellForPost:(PAWPost *)post;
- (void)unhighlightCellForPost:(PAWPost *)post;
@end
TableViewController.m
....
@synthesize wallViewController;
....
- (void)highlightCellForPost:(PAWPost *)post {
// Find the cell matching this object.
for (PFObject *object in [self objects]) {
PAWPost *postFromObject = [[PAWPost alloc] initWithPFObject:object];
if ([post equalToPost:postFromObject]) {
// We found the object, scroll to the cell position where this object is.
NSUInteger index = [[self objects] indexOfObject:object];
NSIndexPath *indexPath = [NSIndexPath indexPathForRow:index inSection:kTableViewMainSection];
[self.tableView scrollToRowAtIndexPath:indexPath atScrollPosition:UITableViewScrollPositionMiddle animated:YES];
[self.tableView selectRowAtIndexPath:indexPath animated:NO scrollPosition:UITableViewScrollPositionNone];
return;
}
}
// Don''t scroll for posts outside the search radius.
if ([post.title compare:kWallCantViewPost] != NSOrderedSame) {
// We couldn''t find the post, so scroll down to the load more cell.
NSUInteger rows = [self.tableView numberOfRowsInSection:kTableViewMainSection];
NSIndexPath *indexPath = [NSIndexPath indexPathForRow:(rows - 1) inSection:kTableViewMainSection];
[self.tableView scrollToRowAtIndexPath:indexPath atScrollPosition:UITableViewScrollPositionBottom animated:YES];
[self.tableView selectRowAtIndexPath:indexPath animated:NO scrollPosition:UITableViewScrollPositionNone];
[self.tableView deselectRowAtIndexPath:indexPath animated:YES];
}
}
- (void)unhighlightCellForPost:(PAWPost *)post {
// Deselect the post''s row.
for (PFObject *object in [self objects]) {
PAWPost *postFromObject = [[PAWPost alloc] initWithPFObject:object];
if ([post equalToPost:postFromObject]) {
NSUInteger index = [[self objects] indexOfObject:object];
NSIndexPath *indexPath = [NSIndexPath indexPathForRow:index inSection:0];
[self.tableView deselectRowAtIndexPath:indexPath animated:YES];
return;
}
}
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
// call super because we''re a custom subclass.
[super tableView:tableView didSelectRowAtIndexPath:indexPath];
[tableView deselectRowAtIndexPath:indexPath animated:YES];
// highlight annotation pin on map - my problem is here ????
NSLog(@"tap row --> %i", indexPath.row); //******1*****
NSLog(@"annotation count --> %i", [self.objects count]); //*****2*****
UITableViewCell *selectedCell = [tableView cellForRowAtIndexPath:indexPath];
UILabel *textLabel = (UILabel*) [selectedCell.contentView viewWithTag:kPAWCellTextLabelTag];
NSLog(@"textlabel at the table row tapped --> %@", textLabel.text); //*****3*****
for (NSInteger i = 0; i < [self.objects count]; i++) {
PFObject *object = [self.objects objectAtIndex:i];
PAWPost *postFromObject = [[PAWPost alloc] initWithPFObject:object];
NSString *text = postFromObject.title;
NSLog(@"text retrieved from PAWPost --> %@", text); //*****4*****
if ([text isEqualToString:textLabel.text]) {
NSLog(@"found matching at %i", i); //*****5*****
[wallViewController.mapView selectAnnotation:[[wallViewController.mapView annotations] objectAtIndex:i] animated:YES];
NSLog(@"wallViewController --> %@", wallViewController); //*****6*****
NSLog(@"wallViewController mapView --> %@", wallViewController.mapView); //*****7*****
}
}
}
Mi problema está en el último método (vacío) tableView: (UITableView *) tableView didSelectRowAtIndexPath: (NSIndexPath *) indexPath en TableViewController.m . Por ahora tengo el código como ves, usando:
[wallViewController.mapView selectAnnotation:[[wallViewController.mapView annotations] objectAtIndex:i] animated:YES];
Pero parece que no funciona. Debe haber algo mal aquí, pero no sé lo que es.
Aquí proporcioné mi salida de registro una vez que toqué la primera fila de la tabla:
2015-01-28 11:24:31.886 Test[8097:60b] tap row --> 0
2015-01-28 11:24:31.888 Test[8097:60b] annotation count --> 40
2015-01-28 11:24:31.890 Test[8097:60b] textlabel at the table row tapped --> Asddsdtest
2015-01-28 11:24:31.890 Test[8097:60b] text retrieved from PAWPost --> ...(40 texts here)
2015-01-28 11:24:31.897 Test[8097:60b] found matching at 0
2015-01-28 11:24:31.899 Test[8097:60b] wallViewController --> (null)
2015-01-28 11:24:31.900 Test[8097:60b] wallViewController mapView --> (null)
PD: Encontré esta pregunta, pero la respuesta y los comentarios no parecen proporcionar suficientes detalles para principiantes como yo.
Información adicional agregada
PAWPost.h
@interface PAWPost : NSObject <MKAnnotation>
//@protocol MKAnnotation <NSObject>
// Center latitude and longitude of the annotion view.
// The implementation of this property must be KVO compliant.
@property (nonatomic, readonly) CLLocationCoordinate2D coordinate;
// @optional
// Title and subtitle for use by selection UI.
@property (nonatomic, readonly, copy) NSString *title;
@property (nonatomic, readonly, copy) NSString *subtitle;
// @end
// Other properties:
@property (nonatomic, readonly, strong) PFObject *object;
@property (nonatomic, readonly, strong) PFGeoPoint *geopoint;
@property (nonatomic, readonly, strong) PFUser *user;
@property (nonatomic, assign) BOOL animatesDrop;
@property (nonatomic, readonly) MKPinAnnotationColor pinColor;
// Designated initializer.
- (id)initWithCoordinate:(CLLocationCoordinate2D)coordinate andTitle:(NSString *)title andSubtitle:(NSString *)subtitle;
- (id)initWithPFObject:(PFObject *)object;
- (BOOL)equalToPost:(PAWPost *)aPost;
- (void)setTitleAndSubtitleOutsideDistance:(BOOL)outside;
@end
PAWPost.m
@interface PAWPost ()
// Redefine these properties to make them read/write for internal class accesses and mutations.
@property (nonatomic, assign) CLLocationCoordinate2D coordinate;
@property (nonatomic, copy) NSString *title;
@property (nonatomic, copy) NSString *subtitle;
@property (nonatomic, strong) PFObject *object;
@property (nonatomic, strong) PFGeoPoint *geopoint;
@property (nonatomic, strong) PFUser *user;
@property (nonatomic, assign) MKPinAnnotationColor pinColor;
@end
@implementation PAWPost
- (id)initWithCoordinate:(CLLocationCoordinate2D)aCoordinate andTitle:(NSString *)aTitle andSubtitle:(NSString *)aSubtitle {
self = [super init];
if (self) {
self.coordinate = aCoordinate;
self.title = aTitle;
self.subtitle = aSubtitle;
self.animatesDrop = NO;
}
return self;
}
- (id)initWithPFObject:(PFObject *)anObject {
self.object = anObject;
self.geopoint = [anObject objectForKey:kPAWParseLocationKey];
self.user = [anObject objectForKey:kPAWParseUserKey];
[anObject fetchIfNeeded];
CLLocationCoordinate2D aCoordinate = CLLocationCoordinate2DMake(self.geopoint.latitude, self.geopoint.longitude);
NSString *aTitle = [anObject objectForKey:kPAWParseTextKey];
NSString *aSubtitle = [[anObject objectForKey:kPAWParseUserKey] objectForKey:kPAWParseUsernameKey];
return [self initWithCoordinate:aCoordinate andTitle:aTitle andSubtitle:aSubtitle];
}
- (BOOL)equalToPost:(PAWPost *)aPost {
if (aPost == nil) {
return NO;
}
if (aPost.object && self.object) {
// We have a PFObject inside the PAWPost, use that instead.
if ([aPost.object.objectId compare:self.object.objectId] != NSOrderedSame) {
return NO;
}
return YES;
} else {
// Fallback code:
if ([aPost.title compare:self.title] != NSOrderedSame ||
[aPost.subtitle compare:self.subtitle] != NSOrderedSame ||
aPost.coordinate.latitude != self.coordinate.latitude ||
aPost.coordinate.longitude != self.coordinate.longitude ) {
return NO;
}
return YES;
}
}
- (void)setTitleAndSubtitleOutsideDistance:(BOOL)outside {
if (outside) {
self.subtitle = nil;
self.title = kPAWWallCantViewPost;
self.pinColor = MKPinAnnotationColorRed;
} else {
self.title = [self.object objectForKey:kPAWParseTextKey];
//self.subtitle = [[self.object objectForKey:kPAWParseUserKey] objectForKey:kPAWParseUsernameKey];
self.subtitle = [NSString stringWithFormat:@"@%@",[[self.object objectForKey:kPAWParseUserKey] objectForKey:kPAWParseUsernameKey]];
self.pinColor = MKPinAnnotationColorGreen;
}
}
@end
Puede hacer su anotación como un objeto que admite el protocolo MSAnnotation. Entonces, cuando seleccione su celda, sabrá exactamente qué objeto está detrás de esta acción. Y en ese caso, tu anotación será exactamente el objeto que has seleccionado al tocar en UITableViewCell.
Entonces, su objeto PAWPost solo debería admitir el protocolo MKAnnotation:
@interface PAWPost : NSObject <MKAnnotation>
// Interface here
@end
@implementation PAWPost
// ...
- (CLLocationCoordinate2D)coordinate {
return <#your coordinate here#>;
}
// ...
@end
PS: no necesita crear una nueva instancia local de la clase WallViewController en el método didSelectRowAtIndexPath :. Porque en ese momento su WallViewController no tendrá MapView. En su lugar, cree una instancia de WallViewController antes y use un puntero a ella.
Puede usar PFObject.objectId para encontrar la anotación que desee.
PFObject *selectedObject = [self.objects objectAtIndex:i];
for (id annotation in wallViewController.mapView.annotations)
{
if ([annotation isKindOfClass:[PAWPost class]])
{
PAWPost *post = (PAWPost*)annotation;
if ([post.object.objectId isEqualToString:selectedObject.objectId])
{
[wallViewController.mapView selectAnnotation:annotation animated:YES];
break;
}
}
}