这是我第一次处理注释和标注。我大部分时间都在工作(尽管可能不是正确的方法)
所以,我有我的mapView:
@interface MapViewController : BaseUIViewController
<MKMapViewDelegate, CLLocationManagerDelegate>
@property (strong, nonatomic) IBOutlet MKMapView *mapView;
@property (strong, nonatomic) NSMutableArray *friendsAnnotations;
@property (strong, nonatomic) NSMutableArray *friendsResults;
@property (strong, nonatomic) NSTimer *reloadTimer;
- (IBAction)zoomButtonPressed:(id)sender;
@property (strong, nonatomic) IBOutlet UIButton *zoomButton;
@end
计时器,我已经设置了在你屏幕上每分钟重新加载地图。它称这些函数为:
#pragma mark - Update Map Annotations
- (void) getFriendsForAnnotations {
[User syncUserWithCompletionHandler:^{
[ServerComm listCollection:UsersCollection withValues:[DEFAULTS objectForKey:userActiveFriendsKey] forKey:mongoIDKey withCompletionHandler:^(NSDictionary *response) {
[self.mapView removeAnnotations:self.friendsAnnotations];
[self.friendsAnnotations removeAllObjects];
self.friendsResults = [[response objectForKey:@"results"] mutableCopy];
dispatch_group_t group = dispatch_group_create();
for (id userDic in self.friendsResults) {
User *theUser = [User userFromDictionary:userDic];
dispatch_group_enter(group);
if ([[userDic objectForKey:userPrivacyLevelKey] integerValue] == 0 ||
[[userDic objectForKey:userPrivacyLevelKey] integerValue] == 1
){
NSDictionary *locationDic = [userDic objectForKey: userLastLocationKey];
BOOL checkedIn = FALSE;
if(![theUser.checkedInLocationName isEqualToString:EMPTYSTRING]) {
checkedIn = TRUE;
}
CustomAnnotation *CA = [[CustomAnnotation alloc] initWithTitle:[userDic objectForKey:userUsernameKey] Location:CLLocationCoordinate2DMake([[locationDic objectForKey:@"latitude"] doubleValue], [[locationDic objectForKey:@"longitude"] doubleValue]) UserImage:[userDic objectForKey:userProfilePictureURLKey] isCheckedIn:checkedIn];
[CA setCalloutUser:theUser];
[self.friendsAnnotations addObject: CA];
}
dispatch_group_leave(group);
}
dispatch_group_notify(group, dispatch_get_main_queue(), ^{
[self plotAnnotationsOnMap:self.friendsAnnotations];
});
}];
}];
}
- (void) plotAnnotationsOnMap: (NSArray *) arrayOfLocations {
[self.mapView addAnnotations: self.friendsAnnotations];
}
关键是,设置初始注释以与标准initWithAnnotation
方法一起使用。
在地图上绘制注释的最后一步是viewForAnnotation
方法:
- (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id<MKAnnotation>)annotation {
if ([annotation isKindOfClass:[CustomAnnotation class]]) {
CustomAnnotation *myAnnotation = ((CustomAnnotation *)annotation);
CustomAnnotation *annotationView = (CustomAnnotation *) [self.mapView dequeueReusableAnnotationViewWithIdentifier:@"customAnnotation"];
if (annotationView == nil) {
annotationView = [[CustomAnnotation alloc] initWithAnnotation:myAnnotation.annotation reuseIdentifier:@"customAnnotation"];
}
[annotationView setAnnotation:annotation];
[annotationView.userImage sd_setImageWithURL:[NSURL URLWithString:myAnnotation.userImageString]];
[annotationView setUserImageString:myAnnotation.userImageString];
[annotationView setCalloutUser:myAnnotation.calloutUser];
if (myAnnotation.isCheckedIn) {
annotationView.markerImage.image = [annotationView.markerImage.image imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate];
[annotationView.markerImage setTintColor:COLOR_BLUE_MUTED];
} else {
annotationView.markerImage.image = [annotationView.markerImage.image imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate];
[annotationView.markerImage setTintColor:COLOR_GREY_LIGHT];
}
annotationView.centerOffset = CGPointMake(0, -39);
annotationView.rightCalloutAccessoryView = [UIButton buttonWithType: UIButtonTypeDetailDisclosure];
annotationView.canShowCallout = NO;
return annotationView;
} else {
return nil;
}
}
此注释使用您通常期望的CustomAnnotation.h / m文件定义,并从xib中提取。
#import <Foundation/Foundation.h>
#import "CustomAnnotationCallout.h"
#import <MapKit/MapKit.h>
@interface CustomAnnotation : MKAnnotationView <MKAnnotation>
@property (nonatomic, assign) IBOutlet UIView* loadedView;
@property (nonatomic, strong) User *calloutUser;
@property (nonatomic, strong) UIView *calloutView;
@property (retain, nonatomic) IBOutlet UIImageView *markerImage;
@property (retain, nonatomic) IBOutlet UIImageView *userImage;
@property (retain, nonatomic) NSString *userImageString;
@property (copy, nonatomic) NSString *title;
@property (nonatomic, assign) CLLocationCoordinate2D coordinate;
@property (assign, nonatomic) BOOL isCheckedIn;
@property (assign, nonatomic) BOOL showCustomCallout;
@property (assign, nonatomic) CGRect endFrame;
- (id) initWithTitle:(NSString *)newTitle Location:(CLLocationCoordinate2D)location UserImage:(NSString *)userImageString isCheckedIn:(BOOL)checkedIn;
- (void) setShowCustomCallout:(BOOL)showCustomCallout;
- (void) setShowCustomCallout:(BOOL)showCustomCallout animated:(BOOL)animated;
@end
和.m文件:
#import "CustomAnnotation.h"
#import "CustomAnnotationCallout.h"
#import "Utilities.h"
#import "UIImageView+WebCache.h"
@implementation CustomAnnotation
- (id) initWithTitle:(NSString *)newTitle Location:(CLLocationCoordinate2D)location UserImage:(NSString *)userImageString isCheckedIn:(BOOL)checkedIn{
self = [super init];
[[NSBundle mainBundle] loadNibNamed:@"AnnotationView" owner:self options:nil];
if (self) {
if (_loadedView) {
_loadedView.frame = CGRectMake(_loadedView.frame.origin.x, _loadedView.frame.origin.y, 80, 80);
[self addSubview:_loadedView];
self.userImageString = userImageString;
}
self.userImageString = userImageString;
_title = newTitle;
_coordinate = location;
self.isCheckedIn = checkedIn;
self.enabled = YES;
self.canShowCallout = NO;
self.image = [UIImage imageNamed:@"icon_clear"];
self.frame = CGRectMake(self.frame.origin.x, self.frame.origin.y, 80, 80);
self.rightCalloutAccessoryView = [UIButton buttonWithType:UIButtonTypeDetailDisclosure];
}
return self;
}
- (id)initWithAnnotation:(id <MKAnnotation>)annotation reuseIdentifier:(NSString*)reuseIdentifier
{
self = [super initWithAnnotation:annotation reuseIdentifier:reuseIdentifier];
if (self != nil)
{
[[NSBundle mainBundle] loadNibNamed:@"AnnotationView" owner:self options:nil];
if (_loadedView){
_loadedView.frame = CGRectMake(_loadedView.frame.origin.x, _loadedView.frame.origin.y, 80, 80);
[self addSubview:_loadedView];
}
self.enabled = YES;
self.canShowCallout = NO;
self.image = [UIImage imageNamed:@"icon_clear"];
self.frame = CGRectMake(self.frame.origin.x, self.frame.origin.y, 80, 80);
self.rightCalloutAccessoryView = [UIButton buttonWithType:UIButtonTypeDetailDisclosure];
}
return self;
}
- (void) setShowCustomCallout:(BOOL)showCustomCallout {
[self setShowCustomCallout:showCustomCallout animated:NO];
}
- (void) setShowCustomCallout:(BOOL)showCustomCallout animated:(BOOL)animated {
if (_showCustomCallout == showCustomCallout) return;
_showCustomCallout = showCustomCallout;
void (^animationBlock)(void) = nil;
void(^completionBlock)(BOOL finished) = nil;
if (_showCustomCallout) {
self.calloutView.alpha = 0.0f;
animationBlock = ^ {
self.calloutView.alpha = 1.0f;
[self addSubview:self.calloutView];
};
} else {
animationBlock = ^{ self.calloutView.alpha = 0.0f; };
completionBlock = ^(BOOL finished) { [self.calloutView removeFromSuperview]; };
}
if (animated) {
[UIView animateWithDuration:0.2f animations:animationBlock completion:completionBlock];
} else {
animationBlock();
completionBlock(YES);
}
}
@end
现在,如果我们点击注释,我们就会获得自定义标注:
MapViewController代码:
- (void) mapView:(MKMapView *)mapView didSelectAnnotationView:(MKAnnotationView *)view {
if ([view isKindOfClass:CustomAnnotation.class]) {
CustomAnnotation *annotationView = (CustomAnnotation *)view;
CustomAnnotationCallout *callout = [CustomAnnotationCallout new];
callout.userImageString = annotationView.userImageString;
[callout.userImage sd_setImageWithURL:[NSURL URLWithString:callout.userImageString]];
[callout.nameLabel setText:[NSString stringWithFormat:@"%@ @%@", annotationView.calloutUser.name, annotationView.calloutUser.username]];
[callout setUserID:annotationView.calloutUser.userID];
annotationView.calloutView = callout.loadedView;
annotationView.calloutView.center = CGPointMake(annotationView.bounds.size.width*0.5f, -annotationView.calloutView.bounds.size.height*0.5f);
[annotationView setShowCustomCallout:YES animated:YES];
CGRect annotationViewWithCalloutViewFrame = annotationView.frame;
annotationViewWithCalloutViewFrame.size.width += annotationView.calloutView.frame.size.width;
annotationViewWithCalloutViewFrame.size.height += annotationView.calloutView.frame.size.height;
CGRect mapRect = [self.mapView convertRegion:self.mapView.region toRectToView:self.mapView];
mapRect.origin.y = annotationView.frame.origin.y-annotationView.calloutView.frame.size.height;
mapRect.origin.x = annotationView.frame.origin.x+annotationView.calloutView.frame.origin.x;
MKCoordinateRegion finalRegion = [self.mapView convertRect:mapRect toRegionFromView:self.mapView];
[self.mapView setRegion:finalRegion animated:YES];
[self.mapView setScrollEnabled:NO];
[self.mapView setZoomEnabled:NO];
[self.reloadTimer invalidate];
}
}
CustomAnnotationCallout也从xib中拉入。
#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h>
@interface CustomAnnotationCallout : UIView
@property (strong, nonatomic) IBOutlet UIView *loadedView;
@property (strong, nonatomic) IBOutlet UIImageView *userImage;
@property (assign, nonatomic) NSString *userImageString;
@property (strong, nonatomic) IBOutlet UILabel *nameLabel;
@property (strong, nonatomic) NSString *userID;
- (IBAction)profilePressed:(id)sender;
- (IBAction)button1:(id)sender;
- (IBAction)button2:(id)sender;
@end
和.m:
#import "CustomAnnotationCallout.h"
@implementation CustomAnnotationCallout
- (instancetype)init {
[[NSBundle mainBundle] loadNibNamed:@"CustomAnnotationCallout" owner:self options:nil];
_loadedView.frame = CGRectMake(_loadedView.frame.origin.x, _loadedView.frame.origin.y, [[UIScreen mainScreen] bounds].size.width, 178.0);
return self;
}
- (IBAction)profilePressed:(id)sender {
}
- (IBAction)button1:(id)sender {
}
- (IBAction)button2:(id)sender {
}
@end
现在,当我们选择注释时,我们的自定义标注会更改,并且地图会将自身重新定位到我选择的位置。我们得到了这个观点:
现在您已经看到我所拥有的功能,以及我的目标。我遇到的问题是如何在点击时获取标注上的按钮以执行特定任务。
我已经用Google搜索并阅读了有关hitTest的信息,但是无法正确地弄清楚如何正确实现它,特别是在寻求使用特定元素时。
我整个星期都从头到尾都在这里,这就是我被困的地方。请注意我已经进行了大约4个月的iOS开发,所以我还是比较新的。